Java 在工作表中添加大量ValidationData时,POI会写入损坏的.xlsx

Java 在工作表中添加大量ValidationData时,POI会写入损坏的.xlsx,java,excel,apache-poi,Java,Excel,Apache Poi,我想用JAVA中的POI编写一个大的.xlsx文件50k行。我希望每行包含多个下拉单元格。当行数小于30K时,代码可以正常工作,但如果行数超过35K,则会写入损坏的文件 我试过SXSSFWorkbook和XSSFWorkbook,但都不适合我 代码如下: SXSSFWorkbook workbook = new SXSSFWorkbook(100); SXSSFSheet sheet = workbook.createSheet(); String

我想用JAVA中的POI编写一个大的.xlsx文件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行这样的数据。

不要为每个单元格创建数据验证。相反,只创建两个所需的数据验证,一个用于A1:A50001,另一个用于B1:B50001。为此,CellRangeAddressList可以包含整个列范围:

CellRangeAddressList addressList1 = new CellRangeAddressList(0, no_of_rows, 0, 0);

你的例子是:

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限制


此数据验证的特殊限制未在中记录。但这可能与独特单元格格式/单元格样式64000的限制有关,或者与工作表66530中超链接的限制有关。

我猜一个工作簿中可以包含的数据验证数量是有限制的。到现在为止,您创建了70002个不同的数据验证,对吧!如果数据验证少于65500,则可以正常工作。我的要求是为每个单元格显示不同的下拉列表,因此对每个单元格使用不同的约束。@Rahul Saxena:当不同唯一数据验证的计数超过限制时,由于Excel的限制,这是不可能的。见我的补充答案。对!这应该是MS excel的限制。由于每张工作表都存在此限制,我想我必须拆分数据并根据每张工作表可以添加的验证数量编写多张工作表。谢谢分享你的想法。
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();


    }
}