当前位置: 首页 > news >正文

springboot 之 使用easyexcel导出数据到多个sheet,动态表头,自动计算列宽

软件版本

springboot 2.7.17
easyexcel 3.0.5

代码

import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.util.CollectionUtils;import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 自动计算列宽
*/
public class ExcelCellWriteWidthConfig extends AbstractColumnWidthStyleStrategy {private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);if (needSetWidth) {Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());Integer columnWidth = this.dataLength(cellDataList, cell, isHead);// 单元格文本长度大于60换行if (columnWidth >= 0) {if (columnWidth > 60) {columnWidth = 60;}Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);Sheet sheet = writeSheetHolder.getSheet();sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 2 * 256);}}}}/*** 计算长度*/private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {if (isHead) {return cell.getStringCellValue().getBytes().length;} else {CellData<?> cellData = cellDataList.get(0);CellDataTypeEnum type = cellData.getType();if (type == null) {return -1;} else {switch (type) {case STRING:// 换行符(数据需要提前解析好)int index = cellData.getStringValue().indexOf("\n");return index != -1 ?cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;case BOOLEAN:return cellData.getBooleanValue().toString().getBytes().length;case NUMBER:return cellData.getNumberValue().toString().getBytes().length;default:return -1;}}}}
}
//动态表头
private List<List<String>> getDynamicHeadList() {List<List<String>> headList = new ArrayList<>();List<String> head1 = new ArrayList<>();head1.add("Group Name");headList.add(head1);List<String> head2 = new ArrayList<>();head2.add("Model Name");headList.add(head2);return headList;
}
//动态数据
private List<List<String>> getDynamicBodyList() {List<List<String>> bodysList = new ArrayList<>();for(int i = 0; i < 5; i++){List<String> bodyList = new ArrayList<>();bodyList.add("Group " + i);bodyList.add("Model " + i);bodysList.add(bodyList);}return bodysList;
}
//写多sheet
final ExcelWriter excelWriter = EasyExcel.write(excel)//这里LocalDateTimeConverter类参考上一篇内容.registerConverter(new LocalDateTimeConverter()).registerWriteHandler(new ExcelCellWriteWidthConfig()).build();
WriteSheet writeSheet;
int index = 1for (List<List<String>> dataList : ListUtil.split(bodysList, 2)) {// 构建sheet对象writeSheet = EasyExcel.writerSheet(index,"Sheet"+index++).head(getDynamicHeadList()).build();excelWriter.write(getDynamicBodyList(), writeSheet);
}
excelWriter.finish();

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Docker核心技术:Docker原理之Cgroups
  • 全年销售7亿块,巧克力企业如何通过相邻业务打造极致产品力?
  • LCD 横屏切换为竖屏-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板
  • 初阶数据结构之栈和队列
  • huawei 路由 RIP 协议中三种定时器的工作原理
  • 快手可灵视频生成大模型全方位测评
  • CrowdStrike更新致850万Windows设备宕机,微软紧急救火!
  • JAVA学习笔记
  • QT--进程
  • qt初入门9:qt记录日志的方式,日志库了解练习(qInstallMessageHandler,qslog, log4qt)
  • 【Python】文本对齐方式
  • 大模型技术:发展历程、经典模型、微调与应用[更新中...]
  • Kafka之存储设计
  • 2024最新手机软件APP下载排行网站源码 软件下载站PHP源码
  • 每日一题~960 div2 A+B+C(简单奇偶博弈,构造,观察性质算贡献)
  • hexo+github搭建个人博客
  • 2019年如何成为全栈工程师?
  • 345-反转字符串中的元音字母
  • 78. Subsets
  • Angular6错误 Service: No provider for Renderer2
  • AWS实战 - 利用IAM对S3做访问控制
  • C++入门教程(10):for 语句
  • js中forEach回调同异步问题
  • maven工程打包jar以及java jar命令的classpath使用
  • React-生命周期杂记
  • SpiderData 2019年2月16日 DApp数据排行榜
  • windows下mongoDB的环境配置
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 编写符合Python风格的对象
  • 程序员最讨厌的9句话,你可有补充?
  • 从PHP迁移至Golang - 基础篇
  • 工作手记之html2canvas使用概述
  • 离散点最小(凸)包围边界查找
  • 前端学习笔记之观察者模式
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 异常机制详解
  • ### RabbitMQ五种工作模式:
  • #git 撤消对文件的更改
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (离散数学)逻辑连接词
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (原創) 未来三学期想要修的课 (日記)
  • (源码分析)springsecurity认证授权
  • (自适应手机端)行业协会机构网站模板
  • *** 2003
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .net项目IIS、VS 附加进程调试
  • @Bean有哪些属性
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [Algorithm][动态规划][路径问题][不同路径][不同路径Ⅱ][珠宝的最高价值]详细讲解
  • [Algorithm][综合训练][体育课测验(二)][合唱队形][宵暗的妖怪]详细讲解