我想写通过二郎山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工作表..?
你必须写一个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的文档。
从以下链接下面的信息,它直接创建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对象++
要完成。