【问题标题】:Excel corrput due to creation of dropdown list with apache-poi libraryExcel corrput 由于使用 apache-poi 库创建下拉列表
【发布时间】:2020-03-06 07:19:45
【问题描述】:

需要说明

我需要在 Excel 中使用Apache POI 创建一个下拉列表。此列表应包含字符串。

代码

XSSFSheet sheet = workbook.getSheet(fieldName.getTabName());
XSSFDataValidationHelper helper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) helper.createExplicitListConstraint(myarray);
CellRangeAddressList addressList = new CellRangeAddressList(3, 10, 5, 5);
XSSFDataValidation validation = (XSSFDataValidation) helper.createValidation(dvConstraint, addressList);
validation.setEmptyCellAllowed(false);
validation.setShowErrorBox(true);
sheet.addValidationData(validation);

错误

对于某些内容,它运行良好。但是如果数组myarray 包含一些值,例如STUDENT 或HOUSE, DEF,当我想打开 Excel 时就会出错:

我们发现“file.xlsx”中的某些内容存在问题。你想让我们尽可能多地恢复吗?如果您信任工作簿的来源,请单击“是”。

其他信息

my array 是 List<WebElement>。我得到了这份清单:

Select select = new Select(By.xpath("myxpath"));
List<WebElement> opt = select.getOptions();
myarray = new String[opt.size()];
for(int i = 0; i < opt.size(); i++) 
    myarray[i] = opt.get(i).getText();

但我认为这段代码不是问题,因为我可以获得所有带有相关文本的选项。就是当我把这个内容放到createExplicitListConstraint 时,奇怪的事情发生了。

当我打印myarray的内容时,所有值都正确显示在控制台中。

【问题讨论】:

    标签: java excel apache-poi


    【解决方案1】:

    显式数据验证列表的公式长度存在限制。最大长度为 255。如果显式数据验证列表的公式超过 255 的长度,则 Excel 在打开时会失败,并出现错误 We found a problem with some content in ...。如果你点击Yes,Excel 会告诉你它已经修复了/xl/worksheet/sheet*.xml 部分。之后数据验证列表不起作用。

    重现示例:

    import java.io.FileOutputStream;
    
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.util.CellRangeAddressList;
    
    class CreateExcelDataValidationExplicitList {
    
     public static void main(String[] args) throws Exception {
    
      int arrSize = 50;
      String[] myarray = new String[arrSize+1];
    
      for (int i = 0; i < arrSize; i++) {
       myarray[i] = "abcd";
      }
    
      myarray[arrSize] = "abcde"; // this works
      //myarray[arrSize] = "abcdef"; // this fails
    
      String arrayFormula = String.join(",", myarray);
    System.out.println(arrayFormula.length()); // up to 255 works, bigger lengths fail
    
      //Workbook workbook = new HSSFWorkbook();
      Workbook workbook = new XSSFWorkbook();
    
      Sheet sheet = workbook.createSheet();
    
      DataValidationHelper dvHelper = sheet.getDataValidationHelper();
      CellRangeAddressList addressList = new CellRangeAddressList(3, 10, 5, 5);
      DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(myarray);
    
      DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);
      validation.setEmptyCellAllowed(false);
      if (workbook instanceof XSSFWorkbook) validation.setShowErrorBox(true);
    
      sheet.addValidationData(validation);
    
      FileOutputStream out = null;
      if (workbook instanceof HSSFWorkbook) {
       out = new FileOutputStream("CreateExcelDataValidationExplicitList.xls");
      } else if (workbook instanceof XSSFWorkbook) {
       out = new FileOutputStream("CreateExcelDataValidationExplicitList.xlsx");
      }
      workbook.write(out);
      workbook.close();
      out.close();
    
     }
    }
    

    唯一的解决方案是将列表项放在单独工作表的单元格中,然后使用createFormulaListConstraint 而不是createExplicitListConstraint。我在这里展示了这个:Apache POI Double Values in ComboBox。

    【讨论】:

    • 会很困难...用apache-poi有什么办法可以查看Excel日志吗?确实,我准确地确定了问题发生的时间。但我需要更多信息,因为值似乎没问题(它是基本字符串)。因为代码是完全执行的,所以 Excel 创建工作正常。问题是我什么时候想打开它...
    • @Royce:正如我所说,我的完整示例在Excel 中没有任何错误。所以使用String[] myarray = new String[]{"STUDENT", "HOUSE", "DEF"};作为数据验证列表是没有问题的。如果您在We found a problem with some content in 'file.xlsx'... 消息之后单击Yes,Excel 应该会告诉您工作簿的哪些部分已被删除。这是哪些部分?
    • Excel 不会告诉我删除了什么。但它是下拉列表。实际上,单击Yes 后不会显示下拉菜单。我检查了哪些值可能有问题。它是Baron 或Divorced 或SELF EMPLOYED DIRECTOR 或Professional。在相应的验证列表中添加这些值之前,Excel 将毫无问题地打开。但它是基本字符串,这就是我理解问题的原因......对于其他一些文件,相同的代码工作正常。
    • @Royce:我有一个怀疑。公式长度有限制。那么当String arrayFormula = String.join(",", myarray); System.out.println(arrayFormula.length()); 在Excel 中失败时,你能从String arrayFormula = String.join(",", myarray); System.out.println(arrayFormula.length()); 得到什么长度呢?
    • @Royce:290 对于显式数据验证列表的公式来说太长了。现在看看我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多