动态透视报表 + 查询接口 + Excel导出

下面给你一套 企业报表常用的 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 行核心代码,很多公司报表系统都是这样实现的。

相关推荐
m0_60916049几秒前
Golang怎么实现数据库连接重试_Golang如何在启动时重试连接直到数据库就绪【技巧】
jvm·数据库·python
花米徐11 分钟前
技术洞察精选 | 2026年4月28日 — 5月4日
后端·python·flask
神仙别闹1 小时前
基于 C# OpenPGP 的文件管理系统
开发语言·c#
宝贝儿好1 小时前
【LLM】第三章:项目实操案例:智能输入法项目
人工智能·python·深度学习·算法·机器人
m0_624578591 小时前
如何在phpMyAdmin中导入GZIP压缩格式文件_加速传输并突破文件大小限制
jvm·数据库·python
m0_495496411 小时前
mysql数据库表名区分大小写吗_通过lower case table names配置
jvm·数据库·python
番石榴AI1 小时前
纯 CPU 推理!0.1B 超轻量级端到端OCR模型,使用 Java 进行文档解析
java·开发语言·ocr
likerhood1 小时前
ConcurrentHashMap详细讲解(java)
java·开发语言·性能优化
机器学习之心1 小时前
集成BWM法、熵权法、改进博弈论组合赋权与三角直觉模糊云模型的多属性评价模型,MATLAB代码
开发语言·matlab·熵权法·三角直觉模糊云模型·bwm法·改进博弈论组合赋权·多属性评价模型