GridExcel是基于Java8函数式编程和POI EventModel实现的用于Excel简单读写的通用解决方案。
GridExcel基于Java8函数式编程使用Lambda表达式来处理Excel的读写逻辑。就像这样:
/**
* 业务逻辑处理方式三选一:
* 1.启用windowListener,并将业务逻辑放在该函数中。
* 2.不启用windowListener,使用get()方法取回全部数据集合,做后续处理。
* 3.readFunction函数,直接放在函数中处理 或 使用final or effective final的局部变量存放这写数据,做后续处理。
* 注意:使用EventModel时readFunction函数的输入为每行的cell值集合List<String>。
* @throws Exception
*/
@Test
public void readXlsxByEventModel() throws Exception {
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("2007.xlsx");
GridExcel.readByEventModel(resourceAsStream,TradeOrder.class,ExcelType.XLSX)
.window(2,ts -> System.out.println(JSON.toJSONString(ts)))//推荐在这里执行自己的业务逻辑
.process(cs ->{
TradeOrder tradeOrder = new TradeOrder();
tradeOrder.setTradeOrderId(Long.valueOf(cs.get(0)));
Consultant consultant = new Consultant();
consultant.setConsultantName(cs.get(3));
tradeOrder.setConsultant(consultant);
tradeOrder.setPaymentRatio(cs.get(16));
return tradeOrder;
},1);
}
/**
* 使用Streaming UserModel写出数据到Excel
* @throws Exception
*/
@Test
public void writeExcelByStreaming() throws Exception {
GridExcel.writeByStreaming(TradeOrder.class)
.head(writeFunctionMap())//对象字段到Excel列的映射
.createSheet()
.process(MockData.data())//模拟数据。在这里设置业务数据集合。
.write(FileUtils.openOutputStream(new File("/excel/test.xlsx")));
}
具体代码可参考:
- https://github.com/liuhuagui/gridexcel/blob/master/src/test/java/ReadTest.java
- https://github.com/liuhuagui/gridexcel/blob/master/src/test/java/WriteTest.java
将业务逻辑写在Lambda表达式中,像下面这样:
(业务对象)-> {
编写处理逻辑...
}
- 这种形式很像是
用匿名对象实现回调函数
,但是Java8的Lambda是基于第五条字节码指令invokeDynamic
实现的,更加轻量,性能更高。 - 同时,比起匿名对象没有复杂的垂直结构,代码更简洁,更容易理解。
- 解析逻辑放在代码块里,允许用户随意操作(更加直观,一眼就能看出处理逻辑,代码可阅读性更强),比如:
- 只导出或导入某些列
- 复杂对象处理
- 条件判断处理
- 解析逻辑都直接定义在代码块里了,所以使用GridExcel不需要复杂的注解,没有额外的学习成本,更没有代码侵入。
- 同理,GridExcel不需要对实体类进行注解,无代码侵入,同时也意味着对Excel的读写逻辑完全可以不需要实体类。
无实体类读写Excel
/**
* No Entity无实体类读Excel文件
* 业务逻辑处理方式三选一:
* 1.启用windowListener,并将业务逻辑放在该函数中。
* 2.不启用windowListener,使用get()方法取回全部数据集合,做后续处理。
* 3.readFunction函数,直接放在函数中处理 或 使用final or effective final的局部变量存放这写数据,做后续处理。
* 注意:使用EventModel时readFunction函数的输入为每行的cell值集合List<String>。
* @throws Exception
*/
@Test
public void readXlsxByEventModelWithoutEntity() throws Exception {
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("2007.xlsx");
GridExcel.readByEventModel(resourceAsStream,Map.class,ExcelType.XLSX)
.window(2,ts -> System.out.println(JSON.toJSONString(ts)))//推荐在这里执行自己的业务逻辑
.process(cs ->{
Map<String, Object> map = new HashMap<String, Object>();
map.put("tradeOrderId",cs.get(0));
map.put("consultantName",cs.get(3));
map.put("paymentRatio",cs.get(16));
return map;
},1);
}
由于没有自定义业务实体类,这里我们可以使用Map.class来代替。上面是读入Excel的例子,写Excel可以参照实现。