Apache POI 4.1.2中#.##0,00自定义数字格式失效问题咨询
解决Apache POI设置自定义数字格式(#.##0,00)失效的问题
嘿,我来帮你理清这个问题——你完全没必要用#.##0,00这个格式,恰恰是它不符合Excel和Apache POI的格式规则,才导致失效的。
为什么你的#.##0,00格式不生效?
Excel的数字格式语法是和系统区域设置绑定的:
- 内置格式(比如你用的
#,##0.00)是通用标准,Excel会根据打开时的系统区域自动转换分隔符显示; - 自定义格式如果用了非标准语法(比如
#.##0,00),Excel根本无法正确解析它,自然就失效了。
你手动修改Excel的分隔符后#,##0.00能正常显示,就是因为Excel根据新的区域设置,把格式里的逗号(千位分隔符)和点(小数分隔符)自动转换成了对应的显示符号(点当千位,逗号当小数)。
修正后的代码方案
根据你的需求,我给你两个可靠的解决办法:
方案1:依赖Excel区域自动转换(推荐)
不管cDecimalSepString是什么,统一用标准的#,##0.00内置格式就行。如果需要强制生成的Excel用逗号当小数分隔符(不管用户的系统默认设置),可以给单元格指定对应的区域属性(仅XSSF格式支持,POI 4.1.2可用):
CellStyle numStyle = workbook.createCellStyle(); // 统一使用标准内置格式#,##0.00 short format = (short)BuiltinFormats.getBuiltinFormat("#,##0.00"); numStyle.setDataFormat(format); String value = "1000.43"; double dValue = Double.parseDouble(value); Cell cell = workbook.createSheet().createRow(0).createCell(0); cell.setCellValue(dValue); cell.setCellStyle(numStyle); // 如果需要强制用逗号作为小数分隔符,设置单元格区域为德语区(示例) if (cDecimalSepString != null && cDecimalSepString.equals(",")) { if (cell instanceof XSSFCell) { ((XSSFCell)cell).getCTCell().addNewS().setVal("de-DE"); } }
这样生成的Excel,在德语区域设置下会自动显示为1.000,43,在默认区域下显示为1,000.43,完美匹配你的需求。
方案2:强制显示特定分隔符(不依赖系统区域)
如果你想完全忽略系统区域,强制显示千位点、小数逗号,可以用包含文本分隔符的自定义格式(注意:这种方式兼容性稍差,不同Excel版本可能表现不同):
CellStyle numStyle = null; if (cDecimalSepString != null && cDecimalSepString.equals(".")) { numStyle = workbook.createCellStyle(); short format = (short)BuiltinFormats.getBuiltinFormat("#,##0.00"); numStyle.setDataFormat(format); } else { DataFormat dataFormat = workbook.createDataFormat(); numStyle = workbook.createCellStyle(); // 用转义的文本分隔符强制显示格式 numStyle.setDataFormat(dataFormat.getFormat("#\"\"##0\"\"00")); } String value = "1000.43"; double dValue = Double.parseDouble(value); Cell cell = workbook.createSheet().createRow(0).createCell(0); cell.setCellValue(dValue); cell.setCellStyle(numStyle);
最后再明确你的问题
生成Excel文件时不需要使用#.##0,00格式,这个格式不符合POI和Excel的标准语法,才会失效。用上面的方案就能完美解决你的需求。
内容的提问来源于stack exchange,提问作者satyakumar putcha




