EasyExcel之填充公式导出Excel

一、业务背景

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来实现的
瘦子没有夏天 CSDN认证博客专家 博客专家 Java深度用户
大家好,我是Leon。一个专业与Java领域的程序员,偶尔理理财。欢迎大家来阅读我博客,如果你发现极个别文章和书籍内容雷同,请叫我勤奋的code搬运工٩(๑❛ᴗ❛๑)۶。我的邮箱:gyoomi0709@foxmail.com
相关推荐
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页