所以我有一个简单的代码,可将值填充到数据库中
try {
for(int indexRow = 1; indexRow < numberOfRecords; indexRow++) {
record = new String[noOfColumns];
for(int indexColumn = 0;indexColumn < noOfColumns; indexColumn++) {
indexError = indexColumn;
String value = "";
XSSFRow row = sheet.getRow(indexRow);
if(row != null) {
XSSFCell cell = sheet.getRow(indexRow).getCell(indexColumn);
if(cell != null) {
value = fmt.formatCellValue(cell);
}
record[indexColumn] = value;
}
}
records.add(record);
}
}
现在我也已经遍历了源代码,但是我找不到一种可以设置默认DataFormatter的方式,该方式可以更改DecimalFormat来适应额外的更改。 任何帮助将不胜感激 。 例如:在Excel中,我有 -5.57055337362326 但是通过代码它将其写入db -5.5705533736
答案 0 :(得分:1)
重要:DataFormatter.formatCellValue()
方法的目的是按照 Excel 文档中显示的方式返回单元格的值。
假设您要在 Excel 中定义数字格式以显示4个小数位,并且文档看起来像这样:
您的代码示例将返回-5,5706
;如果您将数字格式更改为显示8位小数-结果将为-5,57055337
。
Excel 中的默认数字格式基于10位数字(在 Apache POI 中,请检查ExcelGeneralNumberFormat.decimalFormat
常量),看起来它是用于您基于输出的文档。
@samabcde提到过(添加我的答案以解决他的答案中的几个问题并提供其他详细信息),解决方案是改用cell.getNumericCellValue()
:
DecimalFormat decimalFormat = new DecimalFormat("#.###############");
String cellValue = decimalFormat.format(cell.getNumericCellValue());
在这里,我们使用"#.###############"
格式的15位数字,因为它是maximum precision for Excel >>
请注意本文:When reading Excel with POI, beware of floating points
根据DataFromatter
的配置,您可以使用DataFormatter#setDefaultNumberFormat(Format format)
设置默认数字格式,并且在您呼叫format.formatCellValue(cell)
时将使用它,但仅在使用时使用 Excel 文档中未知/无效的格式。
从您的评论中并不能完全清楚您要涵盖的所有情况,假设DataFormatter
在所有情况下都适用于您,数字值除外,DecimalFormat
的模式为"#.###############"
在这种情况下为您工作。无论如何,如果您需要更具体的逻辑,只需检查其他条件即可。
请找到在这种情况下可以使用的实用方法:
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###############");
private static final DataFormatter DATA_FORMATTER = new DataFormatter();
public static String formatCellValue(HSSFCell cell) {
if (cell != null && cell.getCellTypeEnum() == CellType.NUMERIC
&& !DateUtil.isCellDateFormatted(cell)) {
return DECIMAL_FORMAT.format(cell.getNumericCellValue());
} else {
return DATA_FORMATTER.formatCellValue(cell);
}
}
对于以下 Excel 文件:
28,9999999999999
-5.5
28,9999999999999
上面的实用程序方法将在此处返回实数值,即:28,9999999999999
,-5.5
和28,9999999999999
DataFormatter.formatCellValue()
将返回其在 Excel 中的外观值,即:29,0000
,-5,5000
和29
。
答案 1 :(得分:0)
以下代码来自POI版本3.14,对于带有数字单元格的DataFormatter.formatCellValue
方法,它将最终调用getFormattedNumberString
方法。该代码为
private String getFormattedNumberString(Cell cell, ConditionalFormattingEvaluator
cfEvaluator) {
Format numberFormat = getFormat(cell, cfEvaluator);
double d = cell.getNumericCellValue();
if (numberFormat == null) {
return String.valueOf(d);
}
String formatted = numberFormat.format(new Double(d));
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
}
numberFormat
默认为DecimalFormat
,具有10个小数位,假设您尚未设置任何格式,则值为'-5.57055337362326'的单元格将按预期返回'-5.5705533736'。< / p>
如果仅需要确切的值,则使用cell.getNumericValue
方法并创建DecimalFormat
可以解决此问题。如果还需要更改Excel中的显示,那么我们需要创建一个自定义DataFormatter
。以下示例说明了这两种解决方案:
import java.io.IOException;
import java.text.DecimalFormat;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TestDataFormatter {
public static void main(String[] args) throws IOException {
Double testValue = Double.valueOf("-5.57055337362326");
System.out.println("test value:\t\t" + testValue.toString());
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(testValue);
// 10 decimal place shown by default
DataFormatter dataFormatter = new DataFormatter();
String defaultFormatted = dataFormatter.formatCellValue(cell);
System.out.println("default formatted:\t" + defaultFormatted);
// Create custom format
XSSFCellStyle style = workbook.createCellStyle();
DataFormat customDataFormat = workbook.createDataFormat();
int dataFormatIndex = customDataFormat.getFormat("0.00000000000000");
style.setDataFormat(dataFormatIndex);
cell.setCellStyle(style);
String customFormatted = dataFormatter.formatCellValue(cell);
System.out.println("custom formatted:\t" + customFormatted);
// Get numeric value and then format by DecimalFormat
System.out.println("get numeric:\t\t" + cell.getNumericCellValue());
System.out.println(
"format numeric:\t\t" + new DecimalFormat("0.00000000000000").format(cell.getNumericCellValue()));
workbook.close();
}
}