Facing an issue while opening .xlsx using MS-Excel in which APACHE POI XSSFDataValidationHelper is used for numeric and date validation

huangapple go评论132阅读模式
英文:

Facing an issue while opening .xlsx using MS-Excel in which APACHE POI XSSFDataValidationHelper is used for numeric and date validation

问题

  1. 我使用了 Apache POI 3.17,在 Java 中使用 XSSFDataValidationHelper 来为 .xlsx 文件中的日期和数值等数据添加验证。但每当我使用 MS-Excel 打开文件时,它显示:
  2. “我们发现了<Excel_filename>中的一些内容问题。您是否希望我们尽量恢复文件?如果您信任此工作簿的来源,请点击“是”。
  3. 当我查找此错误时,我得知,当文件部分损坏或完全损坏时,就会发生此问题。
  4. 这个问题只会出现在那些使用了上述任何类型数据验证的 .xlsx 文件中,但如果我在 Linux 环境中打开该 .xlsx 文件,则不会出现此问题。
  5. 附注:我在最后关闭了工作簿和FileOutputStream,至少在工作簿下创建了一个工作表(显然)
  6. 以下是用于数据验证的代码片段:
  7. `XSSFDataValidationHelper dataValidationHelper = new XSSFDataValidationHelper(sheet);
  8. XSSFDataValidationConstraint numberValidationConstraint =
  9. (XSSFDataValidationConstraint)
  10. dataValidationHelper.createNumericConstraint(
  11. XSSFDataValidationConstraint.ValidationType.DECIMAL,
  12. XSSFDataValidationConstraint.OperatorType.BETWEEN,
  13. String.valueOf(Double.MIN_VALUE),
  14. String.valueOf(Double.MAX_VALUE)
  15. );
  16. CellRangeAddressList addressList = new CellRangeAddressList(
  17. 2, 2000, columnCounter, columnCounter);
  18. XSSFDataValidation numberValidation = (XSSFDataValidation) dataValidationHelper.createValidation(
  19. numberValidationConstraint, addressList);
  20. numberValidation.setSuppressDropDownArrow(false);
  21. numberValidation.setShowErrorBox(true);
  22. numberValidation.createErrorBox("Invalid data", "Only numbers are allowed");
  23. sheet.addValidationData(numberValidation);`
英文:

I used Apache POI 3.17, XSSFDataValidationHelper in java to add validation for data like dates and numeric values in .xlsx file, but whenever I am opening the file using MS-Excel it shows

“We found a problem with some content in <Excel_filename>. Do you want us to try recovering the file as much as we can? If you trust the source of this workbook, then click Yes”

When i checked for this error, I got, this happens when the file is partially corrupted or completely corrupted.

This problem only appear on those .xlsx files where i used any sort of data validation like I mentioned above but also this problem won't happen if I open that .xlsx file in linux environment.

P.S : I am closing workbook and FileOutputStream at the end, have created atleast one sheet under the workbook (obviously)

PFB the code snippet for data validation :-

  1. `XSSFDataValidationHelper dataValidationHelper = new XSSFDataValidationHelper(sheet);
  2. XSSFDataValidationConstraint numberValidationConstraint =
  3. (XSSFDataValidationConstraint)
  4. dataValidationHelper.createNumericConstraint(
  5. XSSFDataValidationConstraint.ValidationType.DECIMAL,
  6. XSSFDataValidationConstraint.OperatorType.BETWEEN,
  7. String.valueOf(Double.MIN_VALUE),
  8. String.valueOf(Double.MAX_VALUE)
  9. );
  10. CellRangeAddressList addressList = new CellRangeAddressList(
  11. 2, 2000, columnCounter, columnCounter);
  12. XSSFDataValidation numberValidation =(XSSFDataValidation)dataValidationHelper.createValidation(
  13. numberValidationConstraint, addressList);
  14. numberValidation.setSuppressDropDownArrow(false);
  15. numberValidation.setShowErrorBox(true);
  16. numberValidation.createErrorBox(&quot;Invalid data&quot;,&quot;Only numbers are allowed&quot;);
  17. sheet.addValidationData(numberValidation);`

答案1

得分: 1

以下是翻译好的内容:

无法在Excel数据验证中使用Double.MIN_VALUEDouble.MAX_VALUE。Excel对数字单元格值有更严格的限制。您无法在Excel单元格中存储1.7976931348623157E308,也无法存储4.9E-324。在Excel单元格中只能存储15个有效数字。因此,您可以存储的最小数字是-9.99999999999999E307,最大数字是9.99999999999999E307。因此,您必须使用这些数字来限制可能数字的范围。

  1. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
  2. DataValidationConstraint.ValidationType.DECIMAL,
  3. DataValidationConstraint.OperatorType.BETWEEN,
  4. "-9.99999999999999E307",
  5. "9.99999999999999E307"
  6. );

但我怀疑目标是只允许数字值。这也可以通过使用自定义公式约束来实现,公式如下:

  1. =ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))

完整示例:

  1. import java.io.FileOutputStream;
  2. import org.apache.poi.ss.usermodel.*;
  3. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  4. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  5. import org.apache.poi.ss.util.CellRangeAddressList;
  6. class CreateExcelDataValidation {
  7. public static void main(String[] args) throws Exception {
  8. //Workbook workbook = new HSSFWorkbook();
  9. Workbook workbook = new XSSFWorkbook();
  10. Sheet sheet = workbook.createSheet();
  11. int columnCounter = 0;
  12. int fromRow = 2;
  13. int toRow = 2000;
  14. DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
  15. /*
  16. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
  17. DataValidationConstraint.ValidationType.DECIMAL,
  18. DataValidationConstraint.OperatorType.BETWEEN,
  19. //String.valueOf(Double.MIN_VALUE),
  20. //String.valueOf(Double.MAX_VALUE)
  21. "-9.99999999999999E307",
  22. "9.99999999999999E307"
  23. );
  24. */
  25. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createCustomConstraint(
  26. "ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))"
  27. );
  28. CellRangeAddressList addressList = new CellRangeAddressList(fromRow, toRow, columnCounter, columnCounter);
  29. DataValidation numberValidation = dataValidationHelper.createValidation(numberValidationConstraint, addressList);
  30. numberValidation.setShowErrorBox(true);
  31. numberValidation.createErrorBox("Invalid data","Only numbers are allowed");
  32. sheet.addValidationData(numberValidation);
  33. FileOutputStream out = null;
  34. if (workbook instanceof HSSFWorkbook) {
  35. out = new FileOutputStream("CreateExcelDataValidation.xls");
  36. } else if (workbook instanceof XSSFWorkbook) {
  37. out = new FileOutputStream("CreateExcelDataValidation.xlsx");
  38. }
  39. workbook.write(out);
  40. workbook.close();
  41. out.close();
  42. }
  43. }
英文:

You cannot use Double.MIN_VALUE and Double.MAX_VALUE in Excel data validation. Excel has more strict restrictions for numeric cell values. You cannot store 1.7976931348623157E308 in a Excel cell, nor you can store 4.9E-324. In Excel cells only 15 significant digits can be stored. So the smallest number you can store is -9.99999999999999E307 and the biggest number you can store is 9.99999999999999E307. So you would must use that numbers to limit the range of possible numbers.

  1. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
  2. DataValidationConstraint.ValidationType.DECIMAL,
  3. DataValidationConstraint.OperatorType.BETWEEN,
  4. //String.valueOf(Double.MIN_VALUE),
  5. //String.valueOf(Double.MAX_VALUE)
  6. &quot;-9.99999999999999E307&quot;,
  7. &quot;9.99999999999999E307&quot;
  8. );

But I suspect the goal is allowing only numeric values. This also can be achieved using a custom formula constraint having the formula

  1. =ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))

Complete example:

  1. import java.io.FileOutputStream;
  2. import org.apache.poi.ss.usermodel.*;
  3. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  4. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  5. import org.apache.poi.ss.util.CellRangeAddressList;
  6. class CreateExcelDataValidation {
  7. public static void main(String[] args) throws Exception {
  8. //Workbook workbook = new HSSFWorkbook();
  9. Workbook workbook = new XSSFWorkbook();
  10. Sheet sheet = workbook.createSheet();
  11. int columnCounter = 0;
  12. int fromRow = 2;
  13. int toRow = 2000;
  14. DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
  15. /*
  16. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
  17. DataValidationConstraint.ValidationType.DECIMAL,
  18. DataValidationConstraint.OperatorType.BETWEEN,
  19. //String.valueOf(Double.MIN_VALUE),
  20. //String.valueOf(Double.MAX_VALUE)
  21. &quot;-9.99999999999999E307&quot;,
  22. &quot;9.99999999999999E307&quot;
  23. );
  24. */
  25. DataValidationConstraint numberValidationConstraint = dataValidationHelper.createCustomConstraint(
  26. &quot;ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))&quot;
  27. );
  28. CellRangeAddressList addressList = new CellRangeAddressList(fromRow, toRow, columnCounter, columnCounter);
  29. DataValidation numberValidation = dataValidationHelper.createValidation(numberValidationConstraint, addressList);
  30. numberValidation.setShowErrorBox(true);
  31. numberValidation.createErrorBox(&quot;Invalid data&quot;,&quot;Only numbers are allowed&quot;);
  32. sheet.addValidationData(numberValidation);
  33. FileOutputStream out = null;
  34. if (workbook instanceof HSSFWorkbook) {
  35. out = new FileOutputStream(&quot;CreateExcelDataValidation.xls&quot;);
  36. } else if (workbook instanceof XSSFWorkbook) {
  37. out = new FileOutputStream(&quot;CreateExcelDataValidation.xlsx&quot;);
  38. }
  39. workbook.write(out);
  40. workbook.close();
  41. out.close();
  42. }
  43. }

huangapple
  • 本文由 发表于 2020年4月10日 19:04:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/61138970.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定