Java可以对xls使用SQL吗?

间接的方式是用JAVA内嵌数据库,即先入库再执行SQL,这种方式可以充分利用SQL的计算能力,缺点是时效性非常差,而且入库过程繁琐,要检查表名重复、删表、建表、解析文件、插入数据、建索引等等,还经常遇到格式不够规范无法入库的情况。直接的方式是在JAVA中调用基于xls的JDBC驱动,常见的有XLSJDBC/xlSQL/CDATA Excel JDBC,这种方式的好处是整体效率高,架构也简单,缺点是计算能力太差,连集合计算、子查询、关联查询都不支持。

计算能力强,又可以直接在xls上执行SQL的JAVA开源库,集算器SPL是个更好的选择。

SPL的基本用法简单,比如sOrders.xlsx是tab分隔的订单表,对该表进行条件查询:

…
Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();

String str="$select * from d:/sOrder.xlsx   where Client like'%S%'or (Amount>1000 and Amount<=2000)";
ResultSet result = statement.executeQuery(str);
…

SPL 支持常见的SQL语法,可实现各类日常计算,下面再举一些例子:

#sort
$select   * from sales.xls order by Client,Amont desc
#distinct
$   select distinct(sellerid) from sales.xls
#group   by…having
$select   year(orderdate) y,sum(amount) s from sales.xls group by year(orderdate)   having sum(amount)>=2000000
#join
$select   e.name, s.orderdate, s.amount from sales.xls    s left join employee.csv e on s.sellerid= e.eid

SPL支持高级SQL语法,可实现难度较大的计算,比如集合计算、case  when、with、嵌套子查询等,详见《在文件上使用 SQL 查询的示例》

 

对于格式不规范的xls,一般的SQL工具很难解析,而SPL提供了扩展函数,可轻松解析此类文件,下面试举几例:

#没有列名,首行直接是数据:
$select   * from {file("D:/Orders.xlsx").xlsimport()}
#跳过前2行的标题区:
$select   * from {file("D:/Orders.xlsx").xlsimport@t(;,3)}
#读取名为"sheet3"的特定sheet:
$select   * from {file("D:/Orders.xlsx").xlsimport@t(;"sheet3")}

利用扩展函数,SPL还可解析更多格式复杂的文件,比如从第M行读到第N行、密码打开xls等,这里不再详述。

有时计算逻辑较为复杂,即使存储过程也难以实现,而SPL的扩展函数有足够的计算能力,可轻松解决此类问题。比如:商品在出库\入库时,日期上通常不连续,要据此计算出多种商品在指定的连续日期内的库存情况。首先,编写代码并存为SPL脚本文件。脚本文件的作用相当于存储过程,可降低代码耦合性,而且修改时无须编译:

A
1 =T("d:/inout.xls").group(product;~.align(A2,date):g)
2 =periods(argBeginDate,argEndDate)
3 =A2.news(g;A1.product,A2(#):date,ifn(in,0):in,   ifn(out,0):out, stock[-1]+in-out:stock)
4 $select * from {A3}

再在JAVA代码中以存储过程的方式调用脚本文件:

…
Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn   =DriverManager.getConnection("jdbc:esproc:local://");
CallableStatement statement = conn.prepareCall("{call getStock(?,   ?)}");
statement.setObject(1,   "2020-01-01");
statement.setObject(2,   "2020-01-31");
statement.execute();
...

对于计算逻辑较复杂的脚本,SPL提供了专业的IDE,不仅有完整的调试功能,还能用表格的形式观察每一步的中间计算结果:

IDEpng

SPL不仅计算能力强,还支持多种数据源和跨源计算,包括csv、XML、Json、各类NoSQL和数据库,也支持超出内存的大xls的计算,感兴趣可到官网了解。