1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
| /**
* 测试导出 excel
* @author jamesaks
* @since 2025/10/25
*/
@Slf4j
@SpringBootTest(classes = MaterialApplication.class)
public class TestExportExcelStyle {
public void reportExport(ExcelTemplate template) {
// 1. 检查数据
template.checkIsEmpty();
// 2. 文件路径
String filePath = "/Users/jamesaks/Downloads/excel-test/" + System.currentTimeMillis() + ".xlsx";
File file = new File(filePath);
if (!file.getParentFile().exists()) {
boolean mkdirSuccess = file.getParentFile().mkdirs();
if (!mkdirSuccess) {
throw new RuntimeException("创建目录失败");
}
}
// 3. 写文件(注册样式)
try (ExcelWriter writer = template.getWriterBuilder(EasyExcel.write(file)).build()) {
WriteSheet sheet = EasyExcel.writerSheet(template.sheetName()).build();
writer.writeContext().writeWorkbookHolder().getWorkbook().setForceFormulaRecalculation(true);
// 写 head + rows:使用 Table 的 head 仅用于表头,实际我们写的是原始行数据
WriteTable table = EasyExcel.writerTable(0).needHead(true).head(template.getHead()).build();
writer.write(template.getBody(), sheet, table);
//TODO 这里写不写都无所谓,不影响
//Workbook workbook = writer.writeContext().writeWorkbookHolder().getCachedWorkbook();
// 设置强制计算公式:不然公式会以字符串的形式显示在excel中
//workbook.setForceFormulaRecalculation(true);
// 新增:预计算所有公式,缓存结果值到 cell(解决显示 0 问题)
//FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
// 计算整个 workbook 的公式,并设置 cached value
//formulaEvaluator.evaluateAll();
}
}
@Test
void testExcel() {
//测试excel带公式导出
reportExport(getTemplate());
log.info("生成成功");
}
private ExcelTemplate getTemplate() {
return new ExcelTemplate() {
@Override
public String sheetName() {
return "测试EXCEL";
}
@Override
public List<List<ExcelCell>> rows() {
return List.of(
List.of(new ExcelCell("2025-11-03"), new ExcelCell(1.0), new ExcelCell(2.0), new ExcelCell("=B2+C2")),
List.of(new ExcelCell("2025-11-04"), new ExcelCell(1.0), new ExcelCell(2.0), new ExcelCell("=SUM(B2,C2)")),
List.of(new ExcelCell("2025-11-05"), new ExcelCell(1.0), new ExcelCell(2.0), new ExcelCell("=IFERROR(B2 / 7 + C2,0)"))
);
}
@Override
public List<List<ExcelCell>> head() {
return List.of(
List.of(new ExcelCell("时间")),
List.of(new ExcelCell("常量1")),
List.of(new ExcelCell("常量2")),
List.of(new ExcelCell("SUM"))
);
}
@Override
public ExcelWriterBuilder getWriterBuilder(ExcelWriterBuilder writerBuilder) {
return writerBuilder.registerWriteHandler(new ExcelFormulaHandler());
}
private record ExcelFormulaHandler() implements CellWriteHandler {
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (!isHead && CellType.STRING.equals(cell.getCellType()) && cell.getStringCellValue().contains("=")) {
//设置计算类型,去除=
cell.setCellFormula(cell.getStringCellValue().substring(1));
}
//筛选出数值类型的 cell
if (StrUtil.isNumeric(cell.getStringCellValue())) {
cell.setCellValue(Integer.parseInt(cell.getStringCellValue()));
}
}
}
};
}
}
|