使用开源计算引擎提升Excel格式文件处理效率( 二 )


esProc SPL就是其中的佼佼者 。
SPL内置高级读写函数SPL是JVM下开源的计算引擎,它对POI也进行了封装,内置简单易用的高级函数 , 可解析\生成各类格式规则或不规则的xls , 并自动生成结构化数据对象 。
解析格式规则的行式Excel,SPL提供了T函数 。比如解析前面的xls文件,用封装前的POI要几十行,封装后只要一句:
=T("d:\Orders.xls")
解析行式Excel是很常见的任务,SPL用T函数封装了POI的功能,接口简单易用 。无论xls还是xlsx,T函数都可以统一解析 。可自动进行类型转换,开发者无须在细节浪费时间 。T函数可自动区分首行的列名和其他行的数据,并根据列名创建序表(SPL的结构化数据对象)并填入数据:

使用开源计算引擎提升Excel格式文件处理效率

文章插图
读入并解析成序表后,就可以使用SPL提供的丰富的结构化数据处理方法了:
取第3条记录:A1(3)
取后3条记录:A1.m([-1,-2,-3])
取记录的字段值:A1(3).Amount*0.05
修改记录的字段值:A1(3).Amount = A1(3). Amount*1.05
取一列 , 返回集合:A1.(Amount)
取几列,返回集合的集合:A1.([CLIENT,AMOUNT])
追加记录:A1.insert(200,"APPL",10,2400.4,date("2010-10-10"))
先按字段取再按记录序号?。篈1.(AMOUNT)(2);等价于先按记录序号取再按字段?。篈1(2).AMOUNT
解析格式较不规则的行式xls,SPL提供了xlsimport函数,内置丰富而简洁的读取功能:
没有列名 , 首行直接是数据:file("D:\Orders.xlsx").xlsimport()
跳过前2行的标题区:file("D:/Orders.xlsx").xlsimport@t(;,3)
从第3行读到第10行:file("D:/Orders.xlsx").xlsimport@t(;,3:10)
只读取其中3个列:file("D:/Orders.xlsx").xlsimport@t(OrderID,Amount,OrderDate)
读取名为"sales"的特定sheet:file("D:/Orders.xlsx").xlsimport@t(;"sales")
函数xlsimport还具有读取倒数N行、密码打开文件、读大文件等功能,这里不再详述 。
解析格式很不规则的xls,SPL提供了xlscell函数,可以读写指定sheet里指定片区的数据,比如读取第1个sheet里的A2格:
=file("d:/Orders.xlsx").xlsopen().xlscell("C2")
配合SPL灵活的语法,就可以解析自由格式的xls,比如将下面的文件读为规范的二维表(序表):
使用开源计算引擎提升Excel格式文件处理效率

文章插图
这个文件格式很不规则,直接基于POI写Java代码是个浩大的工程,而SPL代码就简短得多:
使用开源计算引擎提升Excel格式文件处理效率

文章插图
生成规则的行式xls,SPL提供了xlsexport函数,用法也很简单 。比如,上面例子的解析结果是个序表,存在SPL的A1格中 , 下面将A1写入新xls的第一个sheet,首行为列名,只要一句代码:=file("e:/result.xlsx").xlsexport@t(A1)
xlsexport函数的功能丰富多样,可以将序表写入指定sheet,或只写入序表的部分行,或只写入指定的列:=file("e:/scores.xlsx").xlsexport@t(A1,No,Name,Class,Maths)
xlsexport函数还可以方便地追加数据,比如对于已经存在且有数据的xls , 将序表A1追加到该文件末尾,外观风格与原文件末行保持一致:=file("e:/scores.xlsx").xlsexport@a(A1)
不规则片区写入数据,可以使用前面的xlscell函数 。比如,xls中蓝色单元格是不规则的表头,需要在相应的白色单元格中填入数据,如下图:
使用开源计算引擎提升Excel格式文件处理效率

文章插图
直接用POI要大段冗长的代码,而SPL代码就简短许多:
使用开源计算引擎提升Excel格式文件处理效率

文章插图
注意,第6、9、11行有连续单元格,SPL可以简化代码一起填入,POI只能依次填入 。
SPL提供足够的查询计算能力查询计算是Excel处理任务的重点 , SPL提供了丰富的计算函数、字符串函数、日期函数,以及标准SQL语法,不仅支持日常的xls计算,也能计算内容不规则的xls和逻辑复杂的xls 。
SPL提供了丰富的计算函数,可直接完成基础计算 。比如前面的分组汇总,只要一句:
A1.groups(SellerId;sum(Amount))
更多计算:
条件查询:A1.select(Amount>1000 && Amount<=3000 && like(Client,"

推荐阅读