人生若只如初见

WXY

EasyExcel导出带合计行表格

2022-10-09

前言

最近在做报表导出,需要带合计行。发现 EasyExcel官方并不支持这个功能需要自己实现 issues
当然方法有很多,我这里选择用Table来实现。

官方文档Table使用

点击跳转文档

exceldemo

结合文档示例我们可以得到实现思路: 用两个table来实现,table0 包含表头和数据行,table1去掉表头 用来实现合计行。

代码实现

这里注意 table0带表头needHead设置为TRUE,table1不需要表头设置为FALSE

			// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
			WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(Boolean.FALSE).build();
			// 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
			WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build();
			 // 加上合计行 样式
			WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.FALSE).build();

给合计行增加样式 (给table1加样式)

			// 合计行样式
			WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
			// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
			contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
			// 背景绿色
			contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
			// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
			HorizontalCellStyleStrategy horizontalCellStyleStrategy =
				new HorizontalCellStyleStrategy(null, contentWriteCellStyle);
                
                 // 加上合计行 样式
			WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.FALSE)
				.registerWriteHandler(horizontalCellStyleStrategy).build();

完整代码

/**
	 * 带合计行导出
	 * 官方并不支持合计列 https://github.com/alibaba/easyexcel/issues/1735
	 * 利用table来实现  table0带表头和数据   table1来实现合计行
	 * 参考: https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#使用table去写入
	 * @param list
	 * @param sheetName
	 * @param clazz
	 * @param listSum   合计数据
	 * @param response
	 * @param <T>
	 */
	public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, List<T> listSum, HttpServletResponse response) {
		try {
			// 合计行样式
			WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
			// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
			contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
			// 背景绿色
			contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
			// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
			HorizontalCellStyleStrategy horizontalCellStyleStrategy =
				new HorizontalCellStyleStrategy(null, contentWriteCellStyle);

			// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
			WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(Boolean.FALSE).build();
			// 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
			WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build();
			 // 加上合计行 样式
			WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.FALSE)
				.registerWriteHandler(horizontalCellStyleStrategy).build();

			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			response.setCharacterEncoding("utf-8");
			String filename = encodingFilename(sheetName);
			FileUtils.setAttachmentResponseHeader(response, filename);

			ServletOutputStream os = response.getOutputStream();
			ExcelWriter excelWriter = EasyExcel.write(os, clazz).autoCloseStream(false)
				// 自动宽度
				.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
				// 大数值自动转换 防止失真
				.registerConverter(new ExcelBigNumberConvert()).build();

			// 第一次写入会创建头
			excelWriter.write(list, writeSheet, writeTable0);
			// 第二次写不创建头,然后在第一次的后面写入数据
			excelWriter.write(listSum, writeSheet, writeTable1);
			excelWriter.finish();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}


/**
	 * 编码文件名
	 */
	public static String encodingFilename(String filename) {
		return filename + "_" + System.currentTimeMillis() + ".xlsx";
	}

导出效果

wxy_2022-10-09_15-51-01