POI:如果公式 returns 为空则输出空白
POI: output blank if formula returns blank
我在 Excel 中有这样的公式:
=IF(A1="foo";"";"0")
如果公式 returns 是空白值,我不希望在 POI 创建的结果 csv 文件中有任何值。如果公式 returns a 0
我想在我的 csv 文件中有一个 0
。
这是我的代码的一部分(问题一直是将代码剥离多少):
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
boolean isFirst = true;
for (int cn = 0; cn < row.getLastCellNum(); cn++) {
Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
if (!isFirst) {
buffer.write(delimiter.getBytes(charset));
} else {
isFirst = false;
}
// Numeric Cell type (0)
// String Cell type (1)
// Formula Cell type (2)
// Blank Cell type (3)
// Boolean Cell type (4)
// Error Cell type (5)
if (cell.getCellType() == 0 || cell.getCellType() == 2) {
try {
if (DateUtil.isCellDateFormatted(cell)) {
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
Date value = cell.getDateCellValue();
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
if (cell.getNumericCellValue() < 1) {
sdf.applyPattern("HH:mm:ss");
}
buffer.write(sdf.format(value).getBytes(charset));
} else {
double valueDouble = cell.getNumericCellValue();
if (valueDouble == Math.ceil(valueDouble)) {
buffer.write(String.format("%d", (long) valueDouble).getBytes(charset));
} else {
valueDouble = round(valueDouble, roundingPlaces);
String value = String.valueOf(valueDouble).replace(".", ",");
buffer.write(value.getBytes(charset));
}
}
} catch (Exception e) {
// Formula returns a string
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
}
} else {
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
}
}
buffer.write("\r\n".getBytes(charset));
}
此代码在每种情况下都会在 csv 文件中生成 0
。它来自行
double valueDouble = cell.getNumericCellValue();
documentation在这一点上说得很清楚了:
double getNumericCellValue()
Get the value of the cell as a number.
For strings we throw an exception. For blank cells we return a 0. For
formulas or error cells we return the precalculated value;
如果单元格包含 NULL 值,我该如何分析?
我认为您的问题是公式 returns 是字符“”或“0”,但您将其视为数字。
cell.getCellType() == Cell.CELL_TYPE_BLANK
对于空白 Cell
应该为真,否则为假。
编辑:我忘了你有一个公式单元格。在这种情况下,扩充为:cell.getCellType() == Cell.CELL_TYPE_FORMULA ? Cell.getCachedFormulaResultType() == Cell.CELL_TYPE_BLANK : cell.getCellType() == Cell.CELL_TYPE_BLANK
此外,您可能不应该过滤空白单元格,而是过滤非数字单元格。
@llogiq 让我走上正轨!
我在if
语句之前添加了以下代码:
if (cell.getCellType() == 2 && cell.getCachedFormulaResultType() == 1) {
logger.log(Level.DEBUG, "Formula returns a string. (1)");
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
} else if (cell.getCellType() == 0 || cell.getCellType() == 2) {
现在公式在我的 csv 文件中生成一个空白字段!我什至可以摆脱讨厌的 try catch
块。当然现在我还要美化代码...
我在 Excel 中有这样的公式:
=IF(A1="foo";"";"0")
如果公式 returns 是空白值,我不希望在 POI 创建的结果 csv 文件中有任何值。如果公式 returns a 0
我想在我的 csv 文件中有一个 0
。
这是我的代码的一部分(问题一直是将代码剥离多少):
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
boolean isFirst = true;
for (int cn = 0; cn < row.getLastCellNum(); cn++) {
Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
if (!isFirst) {
buffer.write(delimiter.getBytes(charset));
} else {
isFirst = false;
}
// Numeric Cell type (0)
// String Cell type (1)
// Formula Cell type (2)
// Blank Cell type (3)
// Boolean Cell type (4)
// Error Cell type (5)
if (cell.getCellType() == 0 || cell.getCellType() == 2) {
try {
if (DateUtil.isCellDateFormatted(cell)) {
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
Date value = cell.getDateCellValue();
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
if (cell.getNumericCellValue() < 1) {
sdf.applyPattern("HH:mm:ss");
}
buffer.write(sdf.format(value).getBytes(charset));
} else {
double valueDouble = cell.getNumericCellValue();
if (valueDouble == Math.ceil(valueDouble)) {
buffer.write(String.format("%d", (long) valueDouble).getBytes(charset));
} else {
valueDouble = round(valueDouble, roundingPlaces);
String value = String.valueOf(valueDouble).replace(".", ",");
buffer.write(value.getBytes(charset));
}
}
} catch (Exception e) {
// Formula returns a string
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
}
} else {
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
}
}
buffer.write("\r\n".getBytes(charset));
}
此代码在每种情况下都会在 csv 文件中生成 0
。它来自行
double valueDouble = cell.getNumericCellValue();
documentation在这一点上说得很清楚了:
double getNumericCellValue()
Get the value of the cell as a number.
For strings we throw an exception. For blank cells we return a 0. For formulas or error cells we return the precalculated value;
如果单元格包含 NULL 值,我该如何分析?
我认为您的问题是公式 returns 是字符“”或“0”,但您将其视为数字。
cell.getCellType() == Cell.CELL_TYPE_BLANK
对于空白 Cell
应该为真,否则为假。
编辑:我忘了你有一个公式单元格。在这种情况下,扩充为:cell.getCellType() == Cell.CELL_TYPE_FORMULA ? Cell.getCachedFormulaResultType() == Cell.CELL_TYPE_BLANK : cell.getCellType() == Cell.CELL_TYPE_BLANK
此外,您可能不应该过滤空白单元格,而是过滤非数字单元格。
@llogiq 让我走上正轨!
我在if
语句之前添加了以下代码:
if (cell.getCellType() == 2 && cell.getCachedFormulaResultType() == 1) {
logger.log(Level.DEBUG, "Formula returns a string. (1)");
cell.setCellType(Cell.CELL_TYPE_STRING);
String value = cell.getStringCellValue();
buffer.write(value.getBytes(charset));
} else if (cell.getCellType() == 0 || cell.getCellType() == 2) {
现在公式在我的 csv 文件中生成一个空白字段!我什至可以摆脱讨厌的 try catch
块。当然现在我还要美化代码...