通过二郎山写Excel文件(Writing Excel FIle through Erlang)

2019-07-29 14:14发布

我想写通过二郎山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 Office的或自由报办公室)将自动解析它??。

2)是否有任何其他的方式来写通过二郎的Excel工作表..?

Answer 1:

你必须写一个CSV , Comma delimited text file 。 你将不得不将其与保存.csv文件扩展名。 你写这个文件中的行,由行。 确保每一行结尾\r\n 。 此文件可以从Excel中读得非常好。

您确保标题出现在第一行,像这样:

  姓名,性别,项目\ r \ n  乔·阿姆斯特朗,男,二郎\ r \ n  Klacke Wickstrom,男,雅司病\ r \ n  生锈的R,男,氮\ r \ n  比尔·盖茨,男,\ r \ n  Muzaaya约书亚,男,ZeePay \ r \ n 
另外,文件编码的问题。 ANSI编码是更好的。 您可以在二郎以及处理Excel文件,首先转换/重新将文件保存为.csv , comma delimited file使用Excel。
然后使用这个csv file parser module
  %%% ---在二郎山CSV解析器。  ------  %%%为了帮助处理大型的CSV文件,而不要将其装入  %%%内存。  类似SAX的XML解析技术 
-module(CSV)。 -compile(export_all)。
解析(文件路径,ForEachLine,不透明) - > 情况下的文件:打开(文件路径,[读])的 {_,S} - > start_parsing(S,ForEachLine,不透明); 错误 - >错误 结束。

start_parsing(S,ForEachLine,不透明) - > 线= 10:get_line(S, ''),
的情况下,行 EOF - > {OK,不透明}; “\ n” 个 - > start_parsing(S,ForEachLine,不透明); 为 “\ r \ n” 个 - > start_parsing(S,ForEachLine,不透明); _ - > NewOpaque = ForEachLine(扫描器(清洁(清洁(线10),13)),不透明), start_parsing(S,ForEachLine,NewOpaque) 结束。
扫描(InitString,CHAR,[杆头|缓冲器])时头部==字符 - > {列表:反向(InitString),缓冲}; 扫描(InitString,CHAR,[杆头|缓冲器])当头部= / =字符 - > 扫描([杆头| InitString],字符,缓冲液); 扫描(X,_,缓冲液)时缓冲== [] - > {完成,列表:反转(X)}。 扫描器(文本) - >列表:反向(traverse_text(文字,[]))。
traverse_text(文字,浅黄色) - > 情况下扫描( “”,$ ,,文本) {完成后,SomeText} - > [SomeText |巴夫]; {值以下,REM} - > traverse_text(REM,[值|巴夫]) 结束。
干净(文字,字符) - > 字符串:带材(字符串:带材(文本,右,CHAR),左,CHAR)。

如何使用本模块从Excel解析CSV文件。 以上我们简单的csv文件的一个例子,在外壳

C:\Windows\System32>erl
Eshell V5.9  (abort with ^G)
1> ForEachLine = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),Buffer end.
#Fun<erl_eval.12.111823515>
2> InitialBuffer = [].
[]
3> csv:parse("E:/erlang_projects.csv",ForEachLine,InitialBuffer).
Line: ["Name","Sex","Project"]
Line: ["Joe Armstrong","Male","Erlang"]
Line: ["Klacke Wickstrom","Male","Yaws"]
Line: ["Rusty R","Male","Nitrogen"]
Line: ["Bill Gates","Male",[]]
Line: ["Muzaaya Joshua","Male","ZeePay"]
{ok,[]}
4> ForEachLine2 = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),[Line|Buffer] end.
#Fun<erl_eval.12.111823515>
5> csv:parse("E:/erlang_projects.csv",ForEachLine2,InitialBuffer).
Line: ["Name","Sex","Project"]
Line: ["Joe Armstrong","Male","Erlang"]
Line: ["Klacke Wickstrom","Male","Yaws"]
Line: ["Rusty R","Male","Nitrogen"]
Line: ["Bill Gates","Male",[]]
Line: ["Muzaaya Joshua","Male","ZeePay"]
{ok,[["Muzaaya Joshua","Male","ZeePay"],
     ["Bill Gates","Male",[]],
     ["Rusty R","Male","Nitrogen"],
     ["Klacke Wickstrom","Male","Yaws"],
     ["Joe Armstrong","Male","Erlang"],
     ["Name","Sex","Project"]]}
6>

所以,你可以在后面使用此模块从Excel解析您的CSV文件以及。 现在,只要学会如何编写一行csv文件行,阅读文件章二郎务实编程的书,或Erlang的文档。



Answer 2:

从以下链接下面的信息,它直接创建Excel数据并满足您的要求:

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

3个例子

关于如何使用彗星3.1彗星的例子详细的例子

本章描述在彗星使用明细索姆示例; 简单的那些第一和最先进的最后一次。

四个例子给出:

Browsing to a specified address

Opening Excel, dumping some data, showing a graph

Calling a function in a C++ library

这些源代码包含在分布,在目录彗星/例子。

缩写VB和VBA用于Visual Basic和Visual Basic应用程序。 3.2要求

第一个例子需要Internet Explorer 4.0或更高版本。

例二需要Excel从Office 97或Office 2000。

最后一个例子中,可以运行,因为它是,但修改COM库时,Visual C ++ 5.0或更高是必需的。 3.3实施例之一,打开浏览器到特定的URL

这个例子说明如何打开一个浏览器(Internet Explorer)中,并通过它导航到一个特定的地址。

要获取COM接口,为浏览器,我们使用的工具如OLE / COM对象查看器,它包括在微软的Windows平台SDK的Visual C和Visual Basic。

检查Internet Explorer的界面,我们发现一对夫妇,我们需要的东西。 首先,我们需要的类ID。 然后,我们需要创建和使用浏览器所需的funcions和属性的名称和参数列表。

由于打开浏览器是不是性能关键任务,我们可以用最慢的,最安全的方法,从二郎做到这一点。 这意味着在开始erl_com作为端口的过程,并且使用IDispatch接口访问的Internet Explorer。

虽然Internet Explorer中提供了一个双接口,(也就是同时具有方法表和一个IDispatch接口的接口),IDispatch接口是更安全和更慢。 给它一个坏的参数列表,返回错误代码,而不是一个核心转储。

要使用COM对象,我们要启动服务器(这将启动端口),并启动一个线程。 然后,我们可以创建对象,做我们想做的事情。

为了能够使用常量,我们把源模块中,而不是在Erlang shell的交互方式调用它。

-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应用程序的一个实例。 我们使用的程序名称“Excel.Application”,它可以用来代替类ID。 这将选择所安装的Excel;具有 Excel中从Office 97或Office 2000。

做任何事情与Excel的最简单方法是先录制VBA宏。 将得到的VBA宏如图1所示。该宏手动重写的位,使其更简单。 我们尝试一下,并且结果如图2所示。

现在,执行到二郎,我们有两个选择:要么我们可以调用VB代码,使用COM从二郎子程序,或者我们可以在二郎山重新实现VB宏。 由于这是一个用户指南中,我们当然选择后者。

要到达的接口,我们使用OLE / COM对象查看,并得到IDL为Excel。 有可用的Excel类型库。 我们不希望所有的,因为它是巨大的。 我们只挑选所需要的接口,这是_Application,_Graph和_Range。 我们还提取了一些枚举,它是用于在COM调用参数常量。

有两种调用从二郎COM时,一些棘手的问题

首先,VB处理隐含的COM接口释放。 Erlang和COM并没有这样做,所以我们要呼吁erl_com:发布/ 1每次我们得到的界面。 例如,每_Range我们从财产_Application.Range得到,有被释放。 我们这样做是在帮助函数data_to_column / 3。

其次,当返回一个接口,它会返回一个整数。 此整数实际上是一个索引到包含在erl_com_drv端口程序的接口阵列。 当调用erl_com功能,我们必须同时提供PID和线程数,所以有一个辅助功能erl_com :: package_interface / 2,即重新包装与给定的线程或其它接口的接口整数。 当给出的界面作为一个参数到COM功能(通过erl_com:呼叫或erl_com:调用),然而,该接口应该被转换到一个指针,它与所述元组符号做了COM类型:{VT_UNKNOWN,接口}。

当Excel启动时,我们执行了一系列的Excel命令来输入数据并绘制图形。 该命令是从,我们得到了使用Excel的标准宏录制VBA宏翻译。

我们使用的是需要为Excel命令一些常量。 这些都是从Visual Basic的代码生成取自Excel的界面。 虽然这些可以从Excel中使用COM,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对象++

要完成。



文章来源: Writing Excel FIle through Erlang
标签: excel erlang