EasyExcel实现动态表头功能

EasyExcel实现动态表头功能

开发过程中,大部分都会使用到导出报表功能,目前阶段会用得有
poi导出(暂无),
easyexcel导出(官方文档,https://easyexcel.opensource.alibaba.com/docs/current/),
easypoi导出(官方文档,http://doc.wupaas.com/docs/easypoi/easypoi-1c10ldlb9epsk)。
三者感觉大差不差,只不过后两者有大部分功能得集成,可能会免去很多代码。详细得区别详见各自得官方文档,拿一个适合自己开发即可。接下来,着重介绍一下今天得嘉宾,easyExcel ,会通过他得某些功能,来实现动态表头得输出。

动态表头(官方List方式)

首先是我们经常使用得动态表头导出,也是一搜一大把得,更是官方文档里提供得一种动态表头方式,也就是增加对应得list。由自己在业务层算好需要多少个列,就增加多少个list,哪行需要合并 也要增加对应得数据。
这种方式么比较耗费代码,适用于增减几个字段得业务场景。
这种方式方法就不过多追叙了,基本上一搜就是一大把得方式,这次主要介绍得,是一种适用于统计年月得情况。

 private List<List<String>> head() {
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("字符串" + System.currentTimeMillis());
        List<String> head1 = new ArrayList<String>();
        head1.add("数字" + System.currentTimeMillis());
        List<String> head2 = new ArrayList<String>();
        head2.add("日期" + System.currentTimeMillis());
        list.add(head0);
        list.add(head1);
        list.add(head2);
        return list;
    }

动态表头(自研,性能未知)

这种业务场景,虽然不多,但是不免也有用到得地方,大概场景就是 根据选择得年月区间,表内容既要展示一些基本信息,也要展示对应得年月数据,例如选了1-2月 就是 基本数据+ 1月 + 2月。选了3-5月,就得显示 基本数据+ 3月 + 4月 + 5月,由于后边月得不确定性,官方文档得List方式就有点不是很又好了。一方面,反参字段得设计,由于每个月都有三四条业务数据,所以12个月得话 光反参字段就是 12X4+ ,太多了。如果每个月得数据后续在增加一个属性字段,代码层面就要跟着变动 n处*12处,显然使用list方式已经不是很适合了,代码编写量翻倍,修改时候也得翻倍,很容易出错。另一方面,easyexcel导出字段中不能使用list,否则注解识别不了,造成导出异常,大概就是只能输出字符串,不能输出整个list,

    @ApiModelProperty(value = "查询统计数据")
    private List<TT> ttList;

在这里插入图片描述

种种原因,之前得方式肯定是不适用了,只能是看看能不能将两种方式结合起来,
第一步,肯定是设计参数了,由于数据是按月查询得,月份得数据反参也肯定是用list来收了,只不过会将查询到得数据,会在xml中自动转为list。最终得反参就是 n个基础数据字段, 2个list月份数据,其中一个用于计算所选月得平均值。
第二步,反参里得月份怎么能输出到excel中,按照异常提示,搜索一下,也不难搜索,搜索到得基本一致,都是加一个类型转换得,就是把读取得数据转字符输出。

 @Override
    public CellData convertToExcelData(Object o, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        //写excel文件时被EasyExcel调用
        //用json转换工具将List对象转换为json字符串
        String json = JSONUtil.toJsonStr(o);
        CellData cellData = new CellData();
        return new CellData(json);
    }
@ExcelProperty(converter = ListDataConverter.class)
private List<TT> ttList;

这是处理完之后得注解,需要加上这个,然后对应得导出

  //处理集合数据
EasyExcel.write(response.getOutputStream())
.registerConverter(new ListDataConverter())
......

这样 导出之后 前边得基础数据也能正常显示,
在这里插入图片描述
只不过数据都是字符形式,
接着第三步就是对这个数据的处理,
第三步,写入数据,https://blog.csdn.net/qq_43021813/article/details/121465753?spm=1001.2014.3001.5502
可以参考之前得写数据文档,只不过这次是 通过实现RowWriteHandler 然后重写里边得afterRowDispose实现,

  implements RowWriteHandler 

 @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {


}
  

原理是将这个list对应得列,将数据取出,然后根据不同得参数去创建不同得列,list 有几个数据就创建几个列,一般是4X新列,并将数据放里,这样list循环完之后,就会得到一个动态得表头了

           //基础数据到11  从11 开始增加列 每增加一列 列+1
            int cellNum = 11 ;
 					for (int i = 0; i < responseList.size(); i++) {
                        //得分
                        Cell cell1 = row.createCell(cellNum);
                        cell1.setCellValue(ttList.get(i).getA().toString());
                        // 每增加一列 列+1
                        cellNum++;
                        //得分
                        Cell cell2 = row.createCell(cellNum);
                        cell2.setCellValue(ttList.get(i).getB().toString());
                        cellNum++;
                        //设置得分小计
                        Cell cell3 = row.createCell(cellNum);
                        cell3.setCellValue(ttList.get(i).getC().toString());
                        cellNum++;
                        //设置是否达标
                        Cell cell4 = row.createCell(cellNum);
                        cell4.setCellValue(ttList.get(i).getD().toString());
                        cellNum++;
                }

在这里插入图片描述123 是三个字段,这样就循环出了4个月得数据 每个月又有123 三条业务数据,这样赋值完毕后,发现原有得list得字符串还在,就得想办法删掉,使用 row.removeCell(cell100); 只能删除内容,这样一来,又在报表中有了一列空白列,搜了两天没搜到结果,然后想到注解可以指定列输出数据所有就给他指定到一个永远不会使用得列去

    @ExcelProperty(converter = ListDataConverter.class,index = 100)
    @ApiModelProperty(value = "得分汇总(分月)")
    private List<TT> ttList;

指定完就是这样 将数据输出到表得第100列,这样将数据读取后 在是哦那个remove就不会造成空白列了。
第四步,数据基本都渲染完了,然后就是创建表头,合并表头,等等, 这些就直接搜索就行了,一搜也是一大把,根据自己表头得需要,写不同得handler就行了。
第五步,增加表名,类型,sheet名等等,就不多介绍了。

总体下来,第一天搭架子,写sql倒是没啥坑,第二天开始踩了不少坑,都是数据转换,赋值excel列数据等,要么就是写数据得方式不对写不进去,要么就是读取得有问题,各种坑各种填,一天改来改去得,第三四天基本就步入正轨了,数据渲染,表头设置合并等。
查询一个月示例
在这里插入图片描述
查询半年,当然了,年月时间可以随意
在这里插入图片描述
最终得效果还算比较满意吧,其余得就是宽高得微调了,

总之,自研还是有难度啊,中间还一度研究到了easypoi。发现原理和这个也差不多,又切回了excel。
此文档就不贴源码了,如有需要请私信有偿提供。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EasyExcel 是一个基于 Java 的简单易用的 Excel 操作工具,可以通过它来实现动态表头。 要实现动态表头,你可以按照以下步骤进行操作: 1. 导入 EasyExcel 的依赖包,可以在 Maven 中添加以下依赖: ``` <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency> ``` 2. 创建一个实体类来表示 Excel 表格的每一行数据,例如: ```java public class ExcelData { private String column1; private String column2; // 可以根据实际需要添加更多字段 // 省略 getter 和 setter 方法 } ``` 3. 创建一个 List 来存储要写入 Excel 的数据,例如: ```java List<ExcelData> dataList = new ArrayList<>(); // 添加数据到 dataList ``` 4. 创建一个动态表头的 List,该 List 的元素是一个个动态表头的字符串,例如: ```java List<String> headerList = new ArrayList<>(); headerList.add("动态表头1"); headerList.add("动态表头2"); // 添加更多动态表头 ``` 5. 使用 EasyExcel 的 API 来写入 Excel 文件,例如: ```java String fileName = "path/to/excel/file.xlsx"; EasyExcel.write(fileName, ExcelData.class).sheet("Sheet1") .head(createDynamicHead(headerList)).doWrite(dataList); ``` 其中 `createDynamicHead` 是一个自定义的方法,用于创建动态表头,示例如下: ```java private List<List<String>> createDynamicHead(List<String> headerList) { List<List<String>> head = new ArrayList<>(); List<String> row = new ArrayList<>(); // 添加固定表头 row.add("固定表头1"); row.add("固定表头2"); head.add(row); // 添加动态表头 head.add(headerList); return head; } ``` 通过以上步骤,你可以实现动态表头功能。在写入 Excel 文件时,固定表头会在第一行显示,动态表头会在第二行显示。每一行数据的对应字段会根据动态表头进行映射。 希望以上解答能对你有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值