英文:
Facing an issue while opening .xlsx using MS-Excel in which APACHE POI XSSFDataValidationHelper is used for numeric and date validation
问题
我使用了 Apache POI 3.17,在 Java 中使用 XSSFDataValidationHelper 来为 .xlsx 文件中的日期和数值等数据添加验证。但每当我使用 MS-Excel 打开文件时,它显示:
“我们发现了<Excel_filename>中的一些内容问题。您是否希望我们尽量恢复文件?如果您信任此工作簿的来源,请点击“是”。
当我查找此错误时,我得知,当文件部分损坏或完全损坏时,就会发生此问题。
这个问题只会出现在那些使用了上述任何类型数据验证的 .xlsx 文件中,但如果我在 Linux 环境中打开该 .xlsx 文件,则不会出现此问题。
附注:我在最后关闭了工作簿和FileOutputStream,至少在工作簿下创建了一个工作表(显然)
以下是用于数据验证的代码片段:
`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);`
英文:
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 :-
`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
得分: 1
以下是翻译好的内容:
无法在Excel数据验证中使用Double.MIN_VALUE
和Double.MAX_VALUE
。Excel对数字单元格值有更严格的限制。您无法在Excel单元格中存储1.7976931348623157E308
,也无法存储4.9E-324
。在Excel单元格中只能存储15个有效数字。因此,您可以存储的最小数字是-9.99999999999999E307
,最大数字是9.99999999999999E307
。因此,您必须使用这些数字来限制可能数字的范围。
DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
DataValidationConstraint.ValidationType.DECIMAL,
DataValidationConstraint.OperatorType.BETWEEN,
"-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();
}
}
英文:
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.
DataValidationConstraint numberValidationConstraint = dataValidationHelper.createNumericConstraint(
DataValidationConstraint.ValidationType.DECIMAL,
DataValidationConstraint.OperatorType.BETWEEN,
//String.valueOf(Double.MIN_VALUE),
//String.valueOf(Double.MAX_VALUE)
"-9.99999999999999E307",
"9.99999999999999E307"
);
But I suspect the goal is allowing only numeric values. This also can be achieved using a custom formula constraint having the formula
=ISNUMBER(OFFSET($A$1,ROW()-1,COLUMN()-1))
Complete example:
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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论