下面给你一套 企业报表常用的 EasyExcel 完整样式方案 ,在你现在的
SpringBoot + MyBatis + GaussDB + EasyExcel + SQL透视 的基础上增加:
实现效果:
- ✔ 动态表头
- ✔ a / f 子表头
- ✔ 最后一行合计(Java计算)
- ✔ 合计单元格合并
- ✔ 合计居中
- ✔ 表头居中
- ✔ 自动列宽
- ✔ 冻结表头
- ✔ 数值千分位
- ✔ 导出 Excel 类似数据透视表效果
一、Excel导出效果
最终 Excel:
产品 型号 项目 1月 2月 3月 4月 5月 合计
a a a f f
A A1 P1 10 20 30 40 50 150
B B1 P1 20 40 60 80 100 300
合计 30 60 90 120 150 450
特点:
- 前三列合并为"合计"
- 数值自动格式
- 表头冻结
二、合计行计算(Java)
java
public static List<Object> buildTotalRow(
List<String> rowDims,
List<String> cols,
List<Map<String,Object>> data){
List<Object> row = new ArrayList<>();
for(int i=0;i<rowDims.size();i++){
row.add("");
}
row.set(0,"合计");
Map<String,Double> sum=new HashMap<>();
for(String c:cols){
sum.put(c,0.0);
}
double total=0;
for(Map<String,Object> r:data){
for(String c:cols){
double v = r.get(c)==null ?
0 : Double.parseDouble(r.get(c).toString());
sum.put(c,sum.get(c)+v);
}
total += Double.parseDouble(r.get("total").toString());
}
for(String c:cols){
row.add(sum.get(c));
}
row.add(total);
return row;
}
三、合计行单元格合并
创建合并策略:
java
public class TotalMergeStrategy extends AbstractMergeStrategy {
private int totalRow;
private int mergeCol;
public TotalMergeStrategy(int totalRow,int mergeCol){
this.totalRow=totalRow;
this.mergeCol=mergeCol;
}
@Override
protected void merge(
Sheet sheet,
Cell cell,
Head head,
Integer relativeRowIndex){
if(cell.getRowIndex()==totalRow
&& cell.getColumnIndex()==0){
CellRangeAddress region =
new CellRangeAddress(
totalRow,
totalRow,
0,
mergeCol);
sheet.addMergedRegion(region);
}
}
}
四、表头居中样式
java
public class HeadStyleStrategy
extends AbstractCellStyleStrategy {
@Override
protected void setHeadCellStyle(
CellWriteHandlerContext context){
CellStyle style =
context.getCell()
.getSheet()
.getWorkbook()
.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
Font font =
context.getCell()
.getSheet()
.getWorkbook()
.createFont();
font.setBold(true);
style.setFont(font);
context.getCell().setCellStyle(style);
}
}
五、数值千分位格式
java
public class NumberStyleStrategy
extends AbstractCellStyleStrategy {
@Override
protected void setContentCellStyle(
CellWriteHandlerContext context){
if(context.getCell().getColumnIndex()>2){
CellStyle style =
context.getCell()
.getSheet()
.getWorkbook()
.createCellStyle();
style.setDataFormat(
context.getCell()
.getSheet()
.getWorkbook()
.createDataFormat()
.getFormat("#,##0"));
style.setAlignment(HorizontalAlignment.RIGHT);
context.getCell().setCellStyle(style);
}
}
}
六、自动列宽
EasyExcel自带策略:
java
LongestMatchColumnWidthStyleStrategy
使用:
java
.registerWriteHandler(
new LongestMatchColumnWidthStyleStrategy()
)
七、冻结表头
java
public class FreezePaneHandler
implements SheetWriteHandler {
@Override
public void afterSheetCreate(
WriteWorkbookHolder holder,
WriteSheetHolder sheetHolder){
sheetHolder.getSheet()
.createFreezePane(0,2);
}
}
说明:
冻结前2行表头
八、完整导出代码
java
@PostMapping("/export")
public void export(HttpServletResponse response) throws Exception{
Map<String,Object> result = service.query();
List<String> cols =
(List<String>)result.get("cols");
List<Map<String,Object>> data =
(List<Map<String,Object>>)result.get("rows");
List<List<String>> head =
ExcelBuilder.buildHead(rowDims,cols,typeMap);
List<List<Object>> rows =
ExcelBuilder.buildRows(rowDims,cols,data);
rows.add(buildTotalRow(rowDims,cols,data));
int totalRowIndex = rows.size()+1;
EasyExcel.write(response.getOutputStream())
.head(head)
.registerWriteHandler(
new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(
new FreezePaneHandler())
.registerWriteHandler(
new HeadStyleStrategy())
.registerWriteHandler(
new NumberStyleStrategy())
.registerWriteHandler(
new TotalMergeStrategy(
totalRowIndex,
rowDims.size()-1))
.sheet("报表")
.doWrite(rows);
}
九、最终报表能力
| 功能 | 支持 |
|---|---|
| 动态表头 | ✔ |
| a/f子表头 | ✔ |
| SQL透视 | ✔ |
| Java合计 | ✔ |
| 合计单元格合并 | ✔ |
| 自动列宽 | ✔ |
| 冻结表头 | ✔ |
| 数值格式 | ✔ |
| Excel导出 | ✔ |
十、企业级再升级(非常推荐)
很多 BI 报表还会加:
1️⃣ 分组小计
产品A
型号1
项目1
项目2
小计
2️⃣ 动态排序
3️⃣ 百万行导出
4️⃣ 分页查询 + 全量导出
5️⃣ 动态筛选条件
如果你需要,我可以再给你一套 真正企业 BI 报表级方案:
- 动态行分组(产品→型号→项目)自动合并单元格
- 自动生成小计
- 类似 Excel 数据透视表
- EasyExcel 完整实现
代码大约 400 行核心代码,很多公司报表系统都是这样实现的。