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中的文字全部显示出来,可以设置对齐格式为[缩小字体填充],但是这样的话只能展示出一行数据,字体会变得很小.还有一种办法,设置对齐格式为[自动换行],然后让单元格中的字体自动调 ...
随机推荐
- Java基础学习:3、数组
1.三种声明方式: // 创建一个double数据类型的数组,长度为5 double array[] = new double[5]; // 创建int数据类型数组,长度为6 int age[] = ...
- 碧血剑—新修版<随笔+剧情大纲>
明末,袁崇焕含冤而死,其子袁承志为部下相救,称为山宗,其时10岁左右,机缘巧合之下救下杨鹏举和张朝唐一行.随后山宗大会,明军来攻,在朱国治,孙仲寿等人保护下逃走,学得伏虎拳.遇到安大娘,安小惠和哑巴, ...
- web测试:test过程中接口报错 "Object reference not set to an instance of an object."
"Object reference not set to an instance of an object." 对象引用未设置为对象的实例 可能原因: 1.参数类型传错,或少传参数 ...
- 【LeetCode - 1055】形成字符串的最短路径
1.题目描述 代码: #include <iostream> #include <string> using namespace std; const int MAX_LETT ...
- 在 Rime 上对输入法进行定制
Rime Rime是什么?忘了!但是在用.而且很好用. 了解Rime历史,还是去官网吧! 定制 Rime有两个目录: 1. 程序目录 2. 用户目录 Rime 的程序目录 Windows 上 要看你安 ...
- openlayers-1 下载及安装使用
javascript - Import from in Openlayers - Geographic Information Systems Stack Exchange 在浏览器中运行开放层示例 ...
- nodejs 配置国内镜像
npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm.taobao.or ...
- PLC入门笔记8
梯形图基础电路 起保停电路 多点起保停电路 互锁控制电路 周期闪烁电路 这应该是等价的!! 定时器的接力电路 同 延时接通,延时断开电路 同 保持信号变脉冲信号电路 定时器TON 接通延时变断开延时电 ...
- ffmpeg安装教程
1 下载所需要的软件 mkdir /usr/local/soft cd /usr/local/soft wget https://www.ffmpeg.org/releases/ffmpeg-snap ...
- 判断MP4 文件
public class CheckResult { public bool IsMp4 { get; set; } public bool SupportStrea ...