Java Apache POI XSSFWorkbook如何将价格列设为数值格式而非文本?
解决Apache POI生成Excel时价格列文本格式转数值格式的问题
你当前的代码通过value.toString()将所有字段统一以字符串形式写入Excel单元格,这直接导致价格列被识别为文本格式——即便后续设置了数值样式,Excel也不会将字符串自动转换为数值,所以样式设置无效。
核心解决思路是区分数据类型写入单元格,而非统一转成字符串。针对价格列,先将获取到的值转换为数值类型,再调用对应类型的setCellValue方法,同时为该列应用数值样式。
修改后的代码示例:
public static void generateExcel(List<Results> results, String outputPath) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Workbook workbook = new XSSFWorkbook(); var sheet = workbook.createSheet("Report"); String[] headerValues = {"Name", "Type", "Price"}; // 预先创建数值样式 DataFormat fmt = workbook.createDataFormat(); CellStyle numericStyle = workbook.createCellStyle(); numericStyle.setDataFormat(fmt.getFormat("0.00")); Row headerRow = sheet.createRow(0); for (int i = 0; i < headerValues.length; i++) { headerRow.createCell(i).setCellValue(headerValues[i]); } for (var i = 0; i < results.size(); i++) { var row = sheet.createRow(i + 1); Results summary = results.get(i); int colNum = 0; for (var header : headerValues) { String propertyName = "get" + header; Method method = Results.class.getMethod(propertyName); Object value = method.invoke(summary); if (value != null) { if ("Price".equals(header)) { // 单独处理价格列:写入数值类型并应用样式 if (value instanceof Number) { double priceValue = ((Number) value).doubleValue(); Cell cell = row.createCell(colNum); cell.setCellValue(priceValue); cell.setCellStyle(numericStyle); } else { // 若Price返回字符串,尝试解析为数值(根据实际情况调整异常处理) try { double priceValue = Double.parseDouble(value.toString()); Cell cell = row.createCell(colNum); cell.setCellValue(priceValue); cell.setCellStyle(numericStyle); } catch (NumberFormatException e) { row.createCell(colNum).setCellValue(""); } } } else { // 其他列按原逻辑写入字符串 row.createCell(colNum).setCellValue(value.toString()); } } else { row.createCell(colNum).setCellValue(""); } colNum++; } } for (var i = 0; i < headerValues.length; i++) { sheet.autoSizeColumn(i); } String path = Objects.requireNonNullElse(outputPath, "report.xlsx"); writeToFile(workbook, path, LOG); }
补充说明:
- 之前的
sheet.setDefaultColumnStyle(15, numericStyle)无效,一是列索引错误(Price列是第2列,索引从0开始应为2),二是单元格存储的是字符串,样式无法覆盖数据类型的本质问题。 - 若
Results类的getPrice()返回BigDecimal、Double等数值类型,直接用((Number)value).doubleValue()即可;若返回字符串,需额外处理解析异常。
内容的提问来源于stack exchange,提问作者eazy
相关产品推荐
相关产品推荐

