3

私はerlangを介してExcelファイルを書き込もうとしています。次のコードを使用してExcelファイルを作成しました

-module(excel).
-export([start/1]).

start(Val)->
        case  file:open("office-test.xls",[append]) of
        {ok,Fd} -> io:format(" file created"),
                io:fwrite(Fd,"~p\t~p\t~p~n", ["Name","Date","Number"]),
                export(Fd,Val),
                file:close(Fd);
        {error,_} ->  io:format("~nerror in creation of file")
        end.


export(_,0)->
        ok;

export(Fd,Val) ->
        io:fwrite(Fd, "~p\t~p\t~p\t~n" ,["B123","2012/10/11 12:12:12","val"++integer_to_list(Val)]),
        export(Fd,Val-1).

正常に書き込むことができましたが、LibreOfficeで開くと. で区切られたデータを尋ねるポップアップ ウィンドウが表示されました。エンドユーザーに作業してほしくありません。

1) オフィス (ms オフィスまたは libre オフィス) が自動的に解析する方法はありますか??

2) erlang を使用して Excel シートを作成する他の方法はありますか??

4

2 に答える 2

4

を書く必要がありますCSV , Comma delimited text file.csv ファイル拡張子を付けて保存する必要があります。このファイルに 1 行ずつ書き込みます。各行が で終わっていることを確認して\r\nください。このファイルは、Excel から非常によく読み取ることができます。

次のように、見出しが最初の行に表示されるようにします。

名前、性別、プロジェクト\r\n
ジョー・アームストロング、男性、アーラン\r\n
Klacke Wickstrom、男性、ヨーズ\r\n
さびた R、男性、窒素\r\n
ビル・ゲイツ、男性、\r\n
Muzaaya Joshua、男性、ZeePay\r\n
また、ファイルのエンコーディングも重要です。ANSI エンコードの方が優れています。Excel を使用して最初にファイルを変換/再保存することで、Erlang で Excel ファイルを処理することもできます.csv , comma delimited file
次に、これを使用しますcsv file parser module
%%% --- Erlang の csv パーサー。------
%%% 大きな csv ファイルをロードせずに処理できるようにするため
%%% メモリー。SAX の xml 解析手法に似ています。
-モジュール(csv)。 -compile(export_all)。
parse(FilePath,ForEachLine,Opaque)-> ケースファイル:open(FilePath,[read]) of {_,S} -> start_parsing (S、ForEachLine、不透明); エラー -> エラー 終わり。

start_parsing(S,ForEachLine,Opaque)-> Line = io:get_line(S,''),
case Line の eof -> {ok,不透明}; "\n" -> start_parsing(S,ForEachLine,Opaque); "\r\n" -> start_parsing(S,ForEachLine,Opaque); _ -> NewOpaque = ForEachLine(scanner(clean(clean(Line,10),13)),Opaque), start_parsing(S,ForEachLine,NewOpaque) 終わり。
scan(InitString,Char,[Head|Buffer]) when Head == Char -> {lists:reverse(InitString),Buffer}; scan(InitString,Char,[Head|Buffer]) when Head =/= Char -> scan([Head|InitString],Char,Buffer); scan(X,_,Buffer) when Buffer == [] -> {done,lists:reverse(X)}. スキャナー(テキスト)-> リスト:リバース(traverse_text(テキスト,[]))。
traverse_text(テキスト、バフ)-> case scan("",$,,Text) の {done,SomeText}-> [SomeText|バフ]; {値,レム}-> traverse_text(レム,[値|バフ]) 終わり。
クリーン (テキスト、文字)-> string:strip(string:strip(Text,right,Char),left,Char)。

このモジュールを使用して Excel から csv ファイルを解析する方法。上記のシェル内の単純な csv ファイルの例

C:\Windows\System32>erl
Eshell V5.9 (^G で中止)
1> ForEachLine = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),Buffer end.
#楽しい<erl_eval.12.111823515>
2> InitialBuffer = [].
[]
3> csv:parse("E:/erlang_projects.csv",ForEachLine,InitialBuffer)。
行: [「名前」、「性別」、「プロジェクト」]
行: ["Joe Armstrong","Male","Erlang"]
行: ["Klacke Wickstrom","Male","Yaws"]
ライン: ["Rusty R","Male","Nitrogen"]
行: ["ビル・ゲイツ","男性",[]]
行: ["ムザーヤ ジョシュア","男性","ZeePay"]
{わかった、[]}
4> ForEachLine2 = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),[Line|Buffer] end.
#楽しい<erl_eval.12.111823515>
5> csv:parse("E:/erlang_projects.csv",ForEachLine2,InitialBuffer)。
行: [「名前」、「性別」、「プロジェクト」]
行: ["Joe Armstrong","Male","Erlang"]
行: ["Klacke Wickstrom","Male","Yaws"]
ライン: ["Rusty R","Male","Nitrogen"]
行: ["ビル・ゲイツ","男性",[]]
行: ["ムザーヤ ジョシュア","男性","ZeePay"]
{ok,[["ムザーヤ ジョシュア","男性","ZeePay"],
     ["ビル・ゲイツ","男性",[]],
     ["Rusty R","男性","窒素"],
     ["Klacke Wickstrom","男性","ヨーズ"],
     ["ジョー・アームストロング","男性","アーラン"],
     ["名前","性別","プロジェクト"]]}
6>

したがって、後でこのモジュールを使用して、Excel からの csv ファイルも解析できます。次に、csv ファイルを 1 行ずつ記述する方法を学び、実用的な Erlang プログラミング ブックのファイルの章を読むか、erlang のドキュメントを読んでください。

于 2012-05-30T05:53:36.937 に答える
-1

次のリンクからの次の情報は、Excel データを直接作成し、要件を満たしています。

http://www.erlang.org/documentation/doc-5.0.1/lib/comet-1.0/doc/html/ch_examples.html

3例

Comet 3.1 の使用方法に関する詳細な例 Comet の例

この章では、Comet の使用に関するいくつかの例を詳細に説明します。単純なものが最初で、最も高度なものが最後です。

以下に 4 つの例を示します。

Browsing to a specified address

Opening Excel, dumping some data, showing a graph

Calling a function in a C++ library

これらのソース コードは、ディストリビューションの comet/examples ディレクトリに含まれています。

Visual Basic および Visual Basic for Applications には、略語 VB および VBA が使用されます。3.2 要件

最初の例では、Internet Explorer 4.0 以降がインストールされている必要があります。

例 2 では、Office 97 または Office 2000 の Excel が必要です。

最後の例はそのまま実行できますが、COM ライブラリを変更するには、Visual C++ 5.0 以降が必要です。3.3 例 1、ブラウザを開いて特定の URL を開く

この例では、ブラウザー (Internet Explorer) を開き、特定のアドレスに移動する方法を示します。

ブラウザ用の COM インターフェイスを取得するには、Microsoft の Windows Platform SDK、Visual C、および Visual Basic に含まれている OLE/COM Object Viewer などのツールを使用します。

Internet Explorer のインターフェイスを確認すると、必要なものがいくつか見つかります。まず、クラス ID が必要です。次に、ブラウザを作成して使用するために必要な関数とプロパティの名前とパラメータ リストが必要です。

ブラウザーの起動はパフォーマンスが重要なタスクではないため、Erlang から最も遅く安全な方法を使用できます。これは、erl_com をポート プロセスとして開始し、IDispatch インターフェイスを使用して Internet Explorer にアクセスすることを意味します。

Internet Explorer はデュアル インターフェイス (メソッド テーブルと IDispatch インターフェイスの両方を備えたインターフェイス) を提供しますが、IDispatch インターフェイスはより安全で低速です。不正なパラメータ リストを指定すると、コア ダンプではなくエラー コードが返されます。

COM オブジェクトを使用するには、(ポートを開始する) サーバーを開始し、スレッドを開始する必要があります。次に、オブジェクトを作成し、それを使ってやりたいことができます。

定数を使用できるようにするために、Erlang シェルで対話的に呼び出すのではなく、ソースをモジュールに入れます。

-module(win_browse).

-include("erl_com.hrl").

-export([open/1, example/0]).
open(Url) ->
    {ok, Pid}= erl_com:start_process(),
    T= erl_com:new_thread(Pid),
    Obj= erl_com:create_dispatch(T, "InternetExplorer.Application", 
                                 ?CLSCTX_LOCAL_SERVER),
    erl_com:invoke(Obj, "Navigate", [Url]),
    erl_com:property_put(Obj, "Visible", true),
    Obj.

example() ->
    open("www.erlang.org").

Internet Explorer アプリケーションには、IWebBrowser インターフェイスを実装するディスパッチ インターフェイスがあります。多くの方法があります。Navigate メソッドを使用して特定の URL を開き、Visible プロパティを使用してブラウザーを表示します。(既定では、COM から使用される他の Microsoft プログラムと同様に、ブラウザーは非表示に作成されます。) 3.4 例 2、Excel でグラフを作成する

この例では、Excel アプリケーションのインスタンスも開始します。クラス ID の代わりに使用できるプログラム名 "Excel.Application" を使用します。これにより、インストールされている Excel が選択されます。Office 97 または Office 2000 の Excel。

Excel で何かを行う最も簡単な方法は、最初に VBA マクロを記録することです。結果の VBA マクロを図 1 に示します。このマクロは、簡単にするために手動で少し書き直されています。試してみた結果を図 2 に示します。

これを Erlang で実行するには、2 つの選択肢があります。Erlang から COM を使用して VB コードをサブルーチンとして呼び出すか、Erlang で VB マクロを再実装するかです。これはユーザーズ ガイドなので、もちろん後者を選択します。

インターフェイスにアクセスするには、OLE/COM オブジェクト ビューアーを使用し、IDL for Excel を取得します。利用可能な Excel タイプ ライブラリがあります。それは巨大なので、すべてを望んでいるわけではありません。_Application、_Graph、および _Range である必要なインターフェイスを選択するだけです。また、COM 呼び出しのパラメーターに使用される定数であるいくつかの列挙型も抽出します。

Erlang から COM を呼び出す場合、いくつかのトリッキーな問題があります

まず、VB は COM インターフェイスの解放を暗黙的に処理します。Erlang と COM はこれを行わないため、取得するすべてのインターフェイスに対して erl_com:release/1 を呼び出す必要があります。たとえば、プロパティ _Application.Range から取得したすべての _Range を解放する必要があります。ヘルパー関数 data_to_column/3 でこれを行います。

次に、インターフェイスが返されるとき、整数として返されます。この整数は、実際には、erl_com_drv ポート プログラムに含まれるインターフェイス配列へのインデックスです。erl_com で関数を呼び出す場合、pid とスレッド番号の両方を提供する必要があるため、指定されたスレッドまたは他のインターフェイスでインターフェイス整数を再パッケージ化するヘルパー関数 erl_com::package_interface/2 があります。ただし、(erl_com:call または erl_com:invoke を介して) COM 関数にパラメーターとしてインターフェイスを与える場合、インターフェイスはポインターに変換する必要があります。これは、COM タイプのタプル表記法で行われます: {vt_unknown, Interface}。

Excel を起動すると、一連の Excel コマンドを実行してデータを入力し、グラフを描画します。コマンドは、Excel の標準マクロ レコーダーを使用して取得した VBA マクロから変換されます。

Excel コマンドに必要ないくつかの定数を使用します。これらは、Excel インターフェイスからの Visual Basic のコード生成から取得されます。これらは COM を使用して Excel から取得できますが、erl_com はまだこれをサポートしていません。(将来のリリースには、大きな COM インターフェイスの使用を大幅に簡素化するコード生成が含まれます。

-module(xc).
-author('jakob@erix.ericsson.se').

-include("erl_com.hrl").

%% enum XlChartFormat
-define(XlPieExploded, 69).
-define(XlPie, 5).

%% enum XlChartLocation
-define(xlLocationAsNewSheet, 1).
-define(xlLocationAsObject, 2).
-define(xlLocationAutomatic, 3.


%% enum XlRowCol
-define(xlColumns, 2).
-define(xlRows, 1).


-export([populate_area/4, f/3, make_graph/6, sample1/0]).

to_cell_col(C) when C > 26 ->
        [C / 26 + 64, C rem 26 + 64];
to_cell_col(C) ->
        [C+64].

populate_area(E, _, _, []) ->
        ok;
populate_area(E, Row, Col, [Data | Resten]) ->
        Cell= to_cell_col(Col)++integer_to_list(Row),
        io:format(" ~s ~n ", [Cell]),
        N= erl_com:property_get(E, "range", [Cell]),
        Range= erl_com:package_interface(E, N),
        erl_com:property_put(Range, "Value", Data),
        erl_com:release(Range),
        populate_area(E, Row+1, Col, Resten).

f(E, _, []) ->
        ok;
f(E, Startcell, [Data | Resten]) ->
        {R, C}= Startcell,
        Cell= "R"++integer_to_list(R)++"C"++integer_to_list(C),
        io:format(" ~p ~n ", [Cell]),
        f(E, {R+1, C}, Resten).

make_graph(E, Row1, Col1, Row2, Col2, Title) ->
        Charts = erl_com:package_interface(E, erl_com:property_get(E, "Charts")),
        erl_com:invoke(Charts, "Add"),
        ActiveChart= erl_com:package_interface(E, erl_com:property_get
                                               (E, "ActiveChart")),
        erl_com:property_put(ActiveChart, "ChartType", {vt_i4, ?XlPieExploded}),
        erl_com:invoke(ActiveChart, "Location", [{vt_i4, ?xlLocationAsObject}, 
                                                 "Sheet1"]),
        Chart= erl_com:package_interface(E, erl_com:property_get(E, "ActiveChart")),
        R= to_cell_col(Col1)++integer_to_list(Row1)++":"
         ++to_cell_col(Col2)++integer_to_list(Row2),
        io:format(" ~s ~n ", [R]),
        Range= erl_com:property_get(E, "Range", [R]),
        erl_com:invoke(Chart, "SetSourceData", [{vt_unknown, Range}, 
                                                {vt_i4, ?xlColumns}]),
        erl_com:property_put(Chart, "HasTitle", true),
        ChartTitle= erl_com:package_interface(E, erl_com:property_get
                                              (Chart, "ChartTitle")),
        erl_com:property_put(ChartTitle, "Caption", Title).
        %erl_com:release(erl_com:package_interface(E, Range)),
        %erl_com:release(ActiveChart),
        %erl_com:release(Charts).

sample1() ->
        {ok, Pid}= erl_com:start_process(),
        T= erl_com:new_thread(Pid),
        E= erl_com:create_dispatch(T, "Excel.Application", ?CLSCTX_LOCAL_SERVER),
        erl_com:property_put(E, "Visible", true),
        Wb= erl_com:package_interface(T, erl_com:property_get(E, "Workbooks")),
        erl_com:invoke(Wb, "Add"),
        populate_area(E, 1, 1, ["Erlang", "Java", "C++"]),
        populate_area(E, 1, 2, ["25", "100", "250"]),
        make_graph(E, 1, 1, 3, 2, "Programming errors, by programming language"),
        {T, E, Wb}.

3.5 例 3、C++ での COM オブジェクトの呼び出し

行われなければ。

于 2012-05-28T10:19:26.250 に答える