
EasyExcel 自定义策略,实现动态列宽,非注解方式
·
1 背景:
excel 导出时,可能会遇到 导出列表 表头项 不固定,且每项的宽度不统一,例如:性别 可能只需要 10个宽度,但是地址 可能就需要 30个甚至50个宽度。
2 EasyExcel 官方提供的动态列宽解决方案
2.1 实体类中使用注解
以下代码为官方示例代码
@Getter
@Setter
@EqualsAndHashCode
@ContentRowHeight(10)
@HeadRowHeight(20)
@ColumnWidth(25)
public class WidthAndHeightData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
/**
* 宽度为50
*/
@ColumnWidth(50)
@ExcelProperty("数字标题")
private Double doubleData;
}
因为 我们是动态表头,没有固定的实体类没法使用,不符合需求,PASS
2.2 官方提供的自动调整列宽的策略LongestMatchColumnWidthStyleStrategy
实体类
@Getter
@Setter
@EqualsAndHashCode
public class LongestMatchColumnWidthData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题很长日期标题很长日期标题很长很长")
private Date date;
@ExcelProperty("数字")
private Double doubleData;
}
具体代码
/**
* 自动列宽(不太精确)
* <p>
* 这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。 当然也可以自己参照
* {@link LongestMatchColumnWidthStyleStrategy}重新实现.
* <p>
* poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好。目前没找到很好的算法。 有的话可以推荐下。
*
* <p>
* 1. 创建excel对应的实体对象 参照{@link LongestMatchColumnWidthData}
* <p>
* 2. 注册策略{@link LongestMatchColumnWidthStyleStrategy}
* <p>
* 3. 直接写即可
*/
@Test
public void longestMatchColumnWidthWrite() {
String fileName =
TestFileUtil.getPath() + "longestMatchColumnWidthWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName, LongestMatchColumnWidthData.class)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong());
}
private List<LongestMatchColumnWidthData> dataLong() {
List<LongestMatchColumnWidthData> list = new ArrayList<LongestMatchColumnWidthData>();
for (int i = 0; i < 10; i++) {
LongestMatchColumnWidthData data = new LongestMatchColumnWidthData();
data.setString("测试很长的字符串测试很长的字符串测试很长的字符串" + i);
data.setDate(new Date());
data.setDoubleData(1000000000000.0);
list.add(data);
}
return list;
}
方案二 和 方案一 有一样的问题,动态表头没有具体的实体类,且 此方案 生成的列宽不太精确,故也PASS ,但是 这个方案为我们提供了一种思路,我们是否可以通过自定义一个策略来实现动态表头的策略。
3 最终方案:自定义列宽策略
通过读取表头的配置,借助easyexcel 提供的 回调方法对 表头列宽进行设置。
3.1 定义 表头信息的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TableHeaderVO implements Serializable {
/**
* 序列化ID
*/
private static final long serialVersionUID = 1L;
/**
* 字段对应数据
*/
private String prop;
/**
* 表头名称
*/
private String label;
/**
* 展示顺序
*/
private Integer index;
/**
* 展示宽度
*/
private Long width;
/**
* 是否自适应
* true为自适应
* false为非自适应
* 默认为false
*/
private Boolean fixed = false;
}
表头信息,包括表头的列中文名 label、列属性 prop 、列宽 width 等属性,我们可以配置在数据库中,查询后使用TableHeaderVO 类进行接收查询结果。
3.2 自定义列宽策略
public class ColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
private static final int MAX_COLUMN_WIDTH = 255;
private Map<String, List<TableHeaderVO>> sheetHeaderMap;
public ColumnWidthStyleStrategy(Map<String, List<TableHeaderVO>> sheetHeaderMap) {
this.sheetHeaderMap = sheetHeaderMap;
}
@Override
protected void setColumnWidth(
WriteSheetHolder writeSheetHolder,
List<WriteCellData<?>> cellDataList,
Cell cell,
Head head,
Integer relativeRowIndex,
Boolean isHead) {
final int rowIndex = cell.getRowIndex();
// 只在第一行设置列宽即可
if (rowIndex != 0) {
return;
}
final List<TableHeaderVO> list = sheetHeaderMap.get(writeSheetHolder.getSheetName());
Integer columnWidth = dataLength(list, cell);
if (columnWidth < 0) {
return;
}
if (columnWidth > MAX_COLUMN_WIDTH) {
columnWidth = MAX_COLUMN_WIDTH;
}
Integer maxColumnWidth = 1;
if (columnWidth > maxColumnWidth) {
writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
}
}
// 根据 cell 中写入的内容,查找该列配置的表头列宽
private Integer dataLength(List<TableHeaderVO> list, Cell cell) {
final String cellValue = cell.getStringCellValue();
final Optional<TableHeaderVO> headerOptional =
list.stream().filter(k -> cellValue.equals(k.getLabel())).findFirst();
return headerOptional.map(tableHeaderVO -> tableHeaderVO.getWidth().intValue()).orElse(1);
}
最终效果如下:
生效,完美解决
阅读全文
AI总结
更多推荐
相关推荐
查看更多
鸿蒙开发工具大赶集

本仓将收集和展示鸿蒙开发工具,欢迎大家踊跃投稿。通过pr附上您的工具介绍和使用指南,并加上工具对应的链接,通过的工具将会成功上架到我们社区。
OpenManus

No fortress, purely open ground. OpenManus is Coming.
G-Star公益行

G-Star 公益行 是 GitCode G-Star 计划旗下专为公益机构打造的技术赋能计划,依托 GitCode 开源平台、生态流量、云计算与 AI 支持,旨在连接开源技术与公益组织,通过技术赋能帮助公益组织实现数字化转型,以提升运营效率、优化资源配置、拓展公益影响力。
热门开源项目
活动日历
查看更多
直播时间 2025-03-13 18:32:35

全栈自研企业级AI平台:Java核心技术×私有化部署实战
直播时间 2025-03-11 18:35:18

从0到1:Go IoT 开发平台的架构演进与生态蓝图
直播时间 2025-03-05 14:35:37

国产工作流引擎 终结「996」开发困局!
直播时间 2025-02-25 14:38:13

免费开源宝藏 ShopXO,电商系统搭建秘籍大公开!
直播时间 2025-02-18 14:31:04

从数据孤岛到数据智能 - 企业级数据管理利器深度解析
目录
所有评论(0)