当前位置: 首页 > 知识库问答 >
问题:

使用 MS-Excel 打开.xlsx时遇到问题,其中 APACHE POI XSSF数据验证助手用于数字和日期验证

轩辕晔
2023-03-14

我使用java中的Apache POI 3.17、XSSFDataValidationHelper为.xlsx文件中的日期和数值等数据添加验证,但每当我使用MS Excel打开该文件时,它都会显示

我们发现中的某些内容有问题。是否希望我们尽量恢复该文件?如果您信任此工作簿的来源,请单击“是”

当我检查这个错误时,我得到,当文件部分损坏或完全损坏时会发生这种情况。

这个问题只出现在那些。xlsx文件,其中我使用了任何类型的数据验证,就像我上面提到的,但如果我打开它,这个问题就不会发生。linux环境下的xlsx文件

P.S:我正在关闭工作簿和文件输出流在最后,在工作簿下至少创建了一个工作表(显然)

PFB数据验证的代码段:-

`XSSFDataValidationHelper dataValidationHelper = new XSSFDataValidationHelper(sheet);

        XSSFDataValidationConstraint numberValidationConstraint =
                (XSSFDataValidationConstraint)
                        dataValidationHelper.createNumericConstraint(
                                XSSFDataValidationConstraint.ValidationType.DECIMAL,
                                XSSFDataValidationConstraint.OperatorType.BETWEEN,
                                String.valueOf(Double.MIN_VALUE),
                                String.valueOf(Double.MAX_VALUE)
                        );

        CellRangeAddressList addressList = new CellRangeAddressList(
                2, 2000, columnCounter, columnCounter);
        XSSFDataValidation numberValidation =(XSSFDataValidation)dataValidationHelper.createValidation(
                numberValidationConstraint, addressList);
        numberValidation.setSuppressDropDownArrow(false);
        numberValidation.setShowErrorBox(true);
        numberValidation.createErrorBox("Invalid data","Only numbers are allowed");
        sheet.addValidationData(numberValidation);`

共有1个答案

孔乐邦
2023-03-14

不能使用< code>Double。MIN_VALUE和< code>Double。< code>Excel数据验证中的MAX_VALUE。< code>Excel对数字单元格值有更严格的限制。您不能在< code>Excel单元格中存储< code > 1.7976931348623157 e308 ,也不能存储< code>4.9E-324。在< code>Excel单元格中,只能存储15位有效数字。因此,您可以存储的最小数字是< code >-9.999999999999 e307 ,最大数字是< code > 9.9999999999 e307 。所以你必须用这些数字来限制可能数字的范围。

DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
 DataValidationConstraint.ValidationType.DECIMAL,
 DataValidationConstraint.OperatorType.BETWEEN,
 //String.valueOf(Double.MIN_VALUE),
 //String.valueOf(Double.MAX_VALUE)
 "-9.99999999999999E307",
 "9.99999999999999E307"
);

但是我怀疑目标是只允许数值。这也可以使用具有以下公式的自定义公式约束来实现

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

完整示例:

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 CreateExcelDataValidation {

 public static void main(String[] args) throws Exception {

  //Workbook workbook = new HSSFWorkbook();
  Workbook workbook = new XSSFWorkbook();

  Sheet sheet = workbook.createSheet();

  int columnCounter = 0;
  int fromRow = 2;
  int toRow = 2000;

  DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();

/*
  DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
   DataValidationConstraint.ValidationType.DECIMAL,
   DataValidationConstraint.OperatorType.BETWEEN,
   //String.valueOf(Double.MIN_VALUE),
   //String.valueOf(Double.MAX_VALUE)
   "-9.99999999999999E307",
   "9.99999999999999E307"
  );
*/

  DataValidationConstraint numberValidationConstraint = dataValidationHelper.createCustomConstraint(
   "ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))"
  );

  CellRangeAddressList addressList = new CellRangeAddressList(fromRow, toRow, columnCounter, columnCounter);
  DataValidation numberValidation = dataValidationHelper.createValidation(numberValidationConstraint, addressList);
  numberValidation.setShowErrorBox(true);
  numberValidation.createErrorBox("Invalid data","Only numbers are allowed");
  sheet.addValidationData(numberValidation);

  FileOutputStream out = null;
  if (workbook instanceof HSSFWorkbook) {
   out = new FileOutputStream("CreateExcelDataValidation.xls");
  } else if (workbook instanceof XSSFWorkbook) {
   out = new FileOutputStream("CreateExcelDataValidation.xlsx");
  }
  workbook.write(out);
  workbook.close();
  out.close();

 }
}
 类似资料:
  • 问题内容: 我试图验证实际上是一个字符串的日期,尝试以格式打印它。这是代码。 输出为。我也想要验证。不知道如何进行。 问题答案: 默认情况下宽松。您需要在解析之前将其设置为非宽容。 与年份相比,这将导致提供无效的日期和/或月份。请注意,这并不能验证年份本身,因为基本上任何年份都是有效的。根据具体的功能要求,您可能希望对年份进行其他检查,例如,打开字符串,然后检查第一部分的长度是否为4。

  • 问题内容: 我正在使用python-dateutil从字符串中解析日期: 我期望的是引发异常,但它返回的是当前日期。如果在提供的字符串中找不到日期,有人可以告诉我如何避免获取当前日期吗? 提前致谢。 问题答案: 请参阅dateutil文档,特别是解析函数(强调我的): 此外,可以使用以下关键字参数: 默认值 如果给出,则它必须是日期时间实例。解析日期中缺少的任何字段都将从该实例复制。 默认值为当前

  • 我试图创建一个表达式验证方法,以确保传递到函数中的帐号是否有效。如果是,则返回true,如果为false,则返回false。 但是我正在经历一个错误: 我已经看了一些堆栈溢出问题,但我似乎无法弄清楚我在代码中做错了什么。 代码: 我从https://www.freeformatter.com/java-regex-tester.html#ad-output

  • 我正在尝试使用自定义Bean验证来验证应该大于零的数值,但问题是使用如下单个自定义验证器来验证任何数值:整数、浮点数、双......: 整数int; @PositiveNumber双倍双; 这可能吗?

  • 本文向大家介绍使用自定义函数在MySQL中验证日期,包括了使用自定义函数在MySQL中验证日期的使用技巧和注意事项,需要的朋友参考一下 让我们创建一个自定义函数来验证MySQL中的日期- 情况1- 当参数为空值时,即要检查的日期不是实际日期。使用SELECT语句调用函数- 这将产生以下输出,即不是日期- 情况2- 当parameter为实际日期值时。使用SELECT语句调用函数- 这将产生以下输出

  • 我似乎无法使用Excel::Writer::XLSX将超过85,000行导出到. xlsx文件。导出超过85,000行数据会导致5KB文件中没有数据。当导出85,000条记录或90,000条记录(约40秒)时,脚本运行所需的时间大致相同。 85000行的文件是7.9MB,但90000行的文件只有5KB。 使用top监视导出脚本,我的perl脚本只显示大约1%的内存使用率,几秒钟后就会消失。我不熟悉