一、业务背景
1.1 技术演进
在业务系统的开发中,我们会经常遇见各类各样的Excel
导出,按照传统的做法,我们会引入第三方工具jar: POI
来实现我们的导出功能。但是这也有缺点,我们的业务代码中充斥着重复且没有很多意义的代码。
于是EasyExcel
诞生了,它的出现了大大降低了我们开发的工作量,给我们提供了不少便利。
EasyExcel
在这里,对EasyExcel
我们就不做过多介绍,有不了解的同学可以根据上述的官方地址进行自行学习。
本篇文章所探求的主旨均是建立在有EasyExcel使用的经验的基础进行的。
二、模板制作
我们发现:税价和总价是需要引入公式进行计算所得。这也是本篇文章锁探讨的主题(毕竟EasyExcel官方没有直接给出填充公式的示例):利用EasyExcel进行动态填充公式。
三、导出示例
3.1 模型
public class DemoData implements Serializable
{
private String orderId;
private String goodName;
private BigDecimal goodPrice;
private Integer num;
/**
* 税价:公式单元格(给一个空串的默认值)
*/
private String taxMoney = "";
/**
* 总价:公式单元格(给一个空串的默认值)
*/
private String totalMoney = "";
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getGoodName() {
return goodName;
}
public void setGoodName(String goodName) {
this.goodName = goodName;
}
public BigDecimal getGoodPrice() {
return goodPrice;
}
public void setGoodPrice(BigDecimal goodPrice) {
this.goodPrice = goodPrice;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getTaxMoney() {
return taxMoney;
}
public void setTaxMoney(String taxMoney) {
this.taxMoney = taxMoney;
}
public String getTotalMoney() {
return totalMoney;
}
public void setTotalMoney(String totalMoney) {
this.totalMoney = totalMoney;
}
}
3.2 运行主类
public class Main
{
public static void main(String[] args)
{
// 1. 路径定义
// 输入模板路径
String templatePath = "D:/test/test-template.xlsx";
// 结果输出路径
String outputPath = "D:/test/output.xlsx";
// 2. 真实的模拟数据
List<DemoData> list = dataList();
// 3. 数据写出
ExcelWriter writer = EasyExcel.write(new File(outputPath)).withTemplate(new File(templatePath)).build();
// 3.1 操作第一个sheet(记得注册自定义的CellWriteHandler)
WriteSheet sheet = EasyExcel.writerSheet(0).registerWriteHandler(new CustomCellWriteHandler()).build();
// 3.2 填充列表数据
writer.fill(list, FillConfig.builder().forceNewRow(Boolean.TRUE).build(), sheet);
// 3.3 填充其它动态信息
Map<String, Object> extra = new LinkedHashMap<>();
// 单位:10%
extra.put("taxRate", 10);
//3.4 设置强制计算公式:不然公式会以字符串的形式显示在excel中
Workbook workbook = writer.writeContext().writeWorkbookHolder().getWorkbook();
workbook.setForceFormulaRecalculation(true);
// 3.5 数据刷新
writer.fill(extra, sheet).finish();
System.out.println("over");
}
/**
* 模拟的数据列表
* @return 列表
*/
private static List<DemoData> dataList()
{
ArrayList<DemoData> list = new ArrayList<>();
for (int i = 1; i <= 20; i++)
{
DemoData demoData = new DemoData();
demoData.setOrderId("202001180000" + i);
demoData.setGoodName("商品名称" + i);
demoData.setGoodPrice(new BigDecimal(i));
demoData.setNum(i);
list.add(demoData);
}
return list;
}
static class CustomCellWriteHandler implements CellWriteHandler
{
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class);
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead)
{
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead)
{
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean)
{
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead)
{
// 这里可以对cell进行任何操作
System.out.println("进入第" + cell.getRowIndex() + "行,第" + cell.getColumnIndex() + "列数据...");
if (cell.getRowIndex() >= 4 && 4 == cell.getColumnIndex())
{
// 税价 = 含税单价 * 数量 * 税率
// 以第4行数据为例:税价 = C5*D5*$C$1
int actualCellRowNum = cell.getRowIndex() + 1;
cell.setCellFormula("C" + actualCellRowNum +"*D" + actualCellRowNum + "*$C$1");
System.out.println("第" + cell.getRowIndex() + "行,第" + cell.getColumnIndex() + "税价写入公式完成");
}
if (cell.getRowIndex() >= 4 && 5 == cell.getColumnIndex())
{
// 总价 = 含税单价 * 数量
// 以第4行数据为例:税价 = C5*D5
int actualCellRowNum = cell.getRowIndex() + 1;
cell.setCellFormula("C" + actualCellRowNum + "*D" + actualCellRowNum);
System.out.println("第" + cell.getRowIndex() + "行,第" + cell.getColumnIndex() + "总价写入公式完成");
}
}
}
}
3.3 结果预览
四、小节
- 填充公式主要是通过
CellWriteHandler
来实现的