java - 在工作表中添加大量 ValidationData 时,POI 写入损坏的 .xlsx
问题描述
我想.xlsx
在 JAVA 中使用 POI 编写一个大文件(50K 行)。我希望每一行都包含多个下拉单元格。当行数小于 30K 时,代码可以正常工作,但如果行数超过 35K,则会写入损坏的文件。
我试过了SXSSFWorkbook
,XSSFWorkbook
但没有一个对我有用。
这是代码:
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
SXSSFSheet sheet = workbook.createSheet();
String[] optionsArray = new String[] {"1000.00","2000.00"};
int no_of_rows = 35000;
for(int i=0;i<=no_of_rows;i++) {
SXSSFRow row1 = sheet.createRow(i);
SXSSFCell r1c1 = row1.createCell(0);
DataValidationConstraint constraint1 = sheet.getDataValidationHelper().createExplicitListConstraint(optionsArray);
CellRangeAddressList addressList1 = new CellRangeAddressList(i, i, 0, 0);
DataValidation dataValidation1 = sheet.getDataValidationHelper().createValidation(constraint1, addressList1);
sheet.addValidationData(dataValidation1);
r1c1.setCellValue("1000.00");
SXSSFCell r1c2 = row1.createCell(1);
DataValidationConstraint constraint2 = sheet.getDataValidationHelper().createExplicitListConstraint(optionsArray);
CellRangeAddressList addressList2 = new CellRangeAddressList(i, i, 1, 1);
DataValidation dataValidation2 = sheet.getDataValidationHelper().createValidation(constraint2, addressList2);
sheet.addValidationData(dataValidation2);
r1c2.setCellValue("2000.00");
}
FileOutputStream fos =new FileOutputStream(new File("c:\\data\\testout.xlsx"));
workbook.write(fos);
workbook.close();
fos.close();
我希望 POI 至少可以很好地处理 50K 行此类数据。
解决方案
不要DataValidation
为每个单元格创建一个。相反,只创建两个所需的数据验证,一个用于A1:A50001
,第二个用于B1:B50001
. 为此,CellRangeAddressList
s 可以包含整个列范围:
CellRangeAddressList addressList1 = new CellRangeAddressList(0, no_of_rows, 0, 0);
和
CellRangeAddressList addressList1 = new CellRangeAddressList(0, no_of_rows, 1, 1);
你的例子:
import java.io.File;
import java.io.FileOutputStream;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.*;
class CreateSXSSFWorkbookDataValidations {
public static void main(String[] args) throws Exception {
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
SXSSFSheet sheet = workbook.createSheet();
String[] optionsArray = new String[] {"1000.00","2000.00"};
int no_of_rows = 50000;
for(int i=0;i<=no_of_rows;i++) {
SXSSFRow row1 = sheet.createRow(i);
SXSSFCell r1c1 = row1.createCell(0);
r1c1.setCellValue("1000.00");
SXSSFCell r1c2 = row1.createCell(1);
r1c2.setCellValue("2000.00");
}
DataValidationConstraint constraint1 = sheet.getDataValidationHelper().createExplicitListConstraint(optionsArray);
CellRangeAddressList addressList1 = new CellRangeAddressList(0, no_of_rows, 0, 0);
DataValidation dataValidation1 = sheet.getDataValidationHelper().createValidation(constraint1, addressList1);
sheet.addValidationData(dataValidation1);
DataValidationConstraint constraint2 = sheet.getDataValidationHelper().createExplicitListConstraint(optionsArray);
CellRangeAddressList addressList2 = new CellRangeAddressList(0, no_of_rows, 1, 1);
DataValidation dataValidation2 = sheet.getDataValidationHelper().createValidation(constraint2, addressList2);
sheet.addValidationData(dataValidation2);
FileOutputStream fos = new FileOutputStream(new File("testout.xlsx"));
workbook.write(fos);
workbook.close();
fos.close();
}
}
当不同的唯一数据验证的计数超过限制时,不可能对每个单个单元格进行不同的唯一数据验证。这个限制是一个Excel
限制,而不是一个限制apache poi
。
Excel 规范和限制中未记录此数据验证的特殊限制。但这可能与独特单元格格式/单元格样式的限制(64,000)或工作表中超链接的限制(66,530)有关。
推荐阅读
- c# - SSRS LocalReport 渲染非常慢
- javascript - 如何修复提交按钮激活错误?
- java - springboot可以将组件初始化为线程吗?
- c# - Excel文件导出没有任何错误
- javascript - Firefox 下载标签超链接不起作用
- python - Python threading.Condition.notify_all() 未触发下一个线程
- node.js - 无法使用 multer 获取临时文件路径
- javascript - 数据表按钮展开/折叠行 JQuery
- c++ - C++中读取txt数据,展开成行或列并排序
- swift - 如何修复“无法转换类型的值 '(CGFloat) -> 数据?' 此代码上的预期参数类型“数据”错误?