POI Excel单元格样式超过最大数(4000或64000)的解决方案
aliases: []
tags : " #QA #Java "
summary: [POI生成Excel超出的单元格样式的最大数量]
author : [yaenli]
notekey: [20230322-100908]
问题现象
使用Apache POI生成Excel时,如果创建的单元格样式过多,会报样式超出最大数的错误,
.xls的异常错误:
java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook
at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:1144)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:88)
.xlsx的异常错误:
java.lang.IllegalStateException: The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook
at org.apache.poi.xssf.model.StylesTable.createCellStyle(StylesTable.java:830)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.createCellStyle(XSSFWorkbook.java:750)
问题分析
同一个Workbook创建CellStyle有最大数限制,其中.xls(Excel 97) 的最大数是4000,.xlsx(Excel 2007) 的最大数是64000 。
xls 参数限制于org.apache.poi.hssf.usermodel.HSSFWorkbook :
private static final int MAX_STYLES = 4030;
public HSSFCellStyle createCellStyle() {
if (this.workbook.getNumExFormats() == MAX_STYLES) {
throw new IllegalStateException("The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook");
}
ExtendedFormatRecord xfr = this.workbook.createCellXF();
short index = (short)(getNumCellStyles() - 1);
return new HSSFCellStyle(index, xfr, this);
}
xlsx 参数限制于org.apache.poi.xssf.model.StylesTable :
private static final int MAXIMUM_STYLE_ID = SpreadsheetVersion.EXCEL2007.getMaxCellStyles();// 64000
public XSSFCellStyle createCellStyle() {
if (getNumCellStyles() > MAXIMUM_STYLE_ID) {
throw new IllegalStateException("The maximum number of Cell Styles was exceeded. You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook");
}
int xfSize = this.styleXfs.size();
CTXf xf = CTXf.Factory.newInstance();
xf.setNumFmtId(0L);
xf.setFontId(0L);
xf.setFillId(0L);
xf.setBorderId(0L);
xf.setXfId(0L);
int indexXf = putCellXf(xf);
return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, this.theme);
}
因此,在生成Excel时,如果同一个Workbook不停的创建CellStyle,超限时就会产生样式最大数异常,最直接的体现就是在某些代码中,对每个单元格去独立的设置样式,生成大数据量的Excel报错。
解决方案
网上最热门的解决方案是所谓的将createCellStyle 放在循环外面,这只能应付表格样式单一的情况。
由于单元格样式CellStyle 并不是单元独立拥有的,每个单元格只是保存了样式的索引,一般的Excel真正使用到的样式也不会超过4000/64000 ,因此更好的解决方案是实现单元格样式的复用(注意不同的Workbook创建的CellStyle是不能混用的)。
方案1:缓存样式实现复用
提取样式关键字作为key,将CellStyle缓存至Map:
Workbook workBook = new HSSFWorkbook();// or new XSSFWorkbook();
Sheet sheet = workBook.createSheet(strSheetName);
Map cellStyleMap = new HashMap<String, CellStyle>();// 缓存样式
// 样式代码
for (int rowIndex = 0; rowIndex < maxRow; rowIndex++) {
Row row = sheet.createRow(rowIndex);
for (int colIndex = 0; colIndex < maxCol; colIndex++) {
Cell cell = row.createCell((short) colIndex);
String styKey = getCellStyleKey(rowIndex, colIndex);// 根据获取样式key
CellStyle cellStyle = (CellStyle) cellStyleMap.computeIfAbsent(styKey, k-> workBook.createCellStyle());// 获取样式
cell.setCellStyle(cellStyle);
}
}
方案2:修改限制参数
修改POI中的限制参数( org.apache.poi.hssf.usermodel.HSSFWorkbook.MAX_STYLES 或org.apache.poi.ss.SpreadsheetVersion.EXCEL2007)。
过多的创建样式会影响性能,建议仅在真正使用的样式超过限制时再去修改此参数。
方案3:延迟指定单元格样式实现复用
参见文章:
POI 操作Excel的单元格样式超过64000的异常问题解决
根据模版填充Excel并导出的工具 · GitCode
POI Excel单元格样式超过最大数(4000或64000)的解决方案的更多相关文章
- java POI Excel 单元格样式
正如Html需要CSS一样,我们的POI生成的Excel同样需要样式才能更完美的表现我们的数据.下面还是从简单的例子出发,学习和了解POI的样式设计. 一.我的位置. 1 package com.my ...
- poi 升级至4.x 的问题总结(POI Excel 单元格内容类型判断并取值)
POI Excel 单元格内容类型判断并取值 以前用 cell.getCachedFormulaResultType() 得到 type 升级到4后获取不到了 换为:cell.getCellType( ...
- POI HSSFCellStyle 设置 Excel 单元格样式
POI中可能会用到一些需要设置EXCEL单元格格式的操作小结: 先获取工作薄对象: HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb ...
- POI Excel 单元格内容类型判断并取值
个人用到的 String birthdayVal = null; ...
- poi excel单元格的校验
switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC://数值类型 if (0 == cell.getCellType()) { ...
- POI实现EXCEL单元格合并及边框样式
POI实现EXCEL单元格合并及边框样式 下面例子为创建产生一个excel,合并单元格,然后为合并后的单元格添加边框 package test; import java.io.FileOutp ...
- POI解析Excel时,如何获取单元格样式以及单元格Style的一些操作
最近,公司运营平台需要上传Excel文件并进行解析导入数据库,在开发完成后出现了一个始料不及的生产bug,下面是具体原因: 1.在用POI解析Excel时,默认如果Excel单元格中没有数据,且单元格 ...
- poi的各种单元格样式以及一些常用的配置
之前我做过一个poi到处excel数据的博客,但是,后面使用起来发现,导出的数据单元格样式都不对. 很多没有居中对齐,很多单元格的格式不对,还有就是单元格的大小不对,导致数据显示异常,虽然功能可以使用 ...
- poi合并单元格同时导出excel
poi合并单元格同时导出excel POI进行跨行需要用到对象HSSFSheet对象,现在就当我们程序已经定义了一个HSSFSheet对象sheet. 跨第1行第1个到第2个单元格的操作为 sheet ...
- POI如何自动调整Excel单元格中字体的大小
问题 目的是要将Excel中的文字全部显示出来,可以设置对齐格式为[缩小字体填充],但是这样的话只能展示出一行数据,字体会变得很小.还有一种办法,设置对齐格式为[自动换行],然后让单元格中的字体自动调 ...
随机推荐
- Codeforces Round #728 (Div. 2) C. Great Graphs
Great Graphs 题意 给你一个数组\(d\),\(d[i]\)表示从节点\(1\)到其他各个节点的最短路的长度,然后你可以对这个图进行加边(可以是负边),但不允许存在一个权值和为负数的回路. ...
- python3+selenium+BeautifulReport生成自动化测试报告
https://www.jianshu.com/p/3d2c0e092ffb 自动化测试,最重要的还是测试报告,下面就教大家使用BeautifulReport生成自动化测试报告GitHub:https ...
- noi 1.1 4 保留三位的浮点数
描述 输入一个单精度浮点数,保留3位小数输出这个浮点数. 输入 只有一行,一个单精度浮点数. 输出 也只有一行,输入的单精度浮点数. 样例输入 12.34521 样例输出 12.345 题意 就是输入 ...
- MongoDB 分片模式
Sharding (分片模式) 副本集可以解决主节点发生故障导致数据丢失或不可用的问题,但遇到需要存储海量数据的情况时,副本集机制就束手无策了.副本集中的一台机器可能不足以存储数据,或者说集群不足以提 ...
- python-官网下载安装教程
1.官网地址:https://www.python.org/ 2.点击Downloads,选择Windows版本 3.找到对应版本,这里以3.9.12为例,选择结尾为executable instal ...
- 将本地文件复制到docker 容器中
查询容器id: docker ps 查询完整容器id docker inspect -f '{{.ID}}'短容器id cp docker cp 本地路径 完整容器ID:容器路径例: docker c ...
- 三,打包electron
1,在当前项目下运行 npm install --save-dev @electron-forge/cli npx electron-forge import 此时package.json内容如下: ...
- base64与中文字符串互转
实现代码如下 // 字符串转base64 getEncode64(str){ return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g ...
- MAC读写模式自动挂载硬盘/不自动挂载硬盘
一.卸载硬盘 sudo umount /dev/disk1s1 自己从磁盘工具获取设备ID 或使用终端命令:diskutil list 来获取 二.新建文件夹以供挂载,位子自选 sudo mkdir ...
- 洛谷 P2212 [USACO14MAR]Watering the Fields S 题解
2021-08-03 20:31:13 链接: https://www.luogu.com.cn/problem/P2212 题目详情: Due to a lack of rain, Farmer J ...