【问题标题】:Apache POI custom data format is modifiedApache POI自定义数据格式修改
【发布时间】:2020-04-01 18:13:38
【问题描述】:

我正在使用 Apache POI 更改 Excel 文件并将一些数据放入其中。 我尝试的大部分内容都很顺利。但是我的货币格式没有 100% 正确完成...

我想要的是我的货币格式像€ 1.000,43。所以左边是欧元符号,右边是金额,点作为千位分隔符,逗号作为小数分隔符,两位小数。

如果我在 Excel 中执行此操作并应用此自定义格式规则,它将起作用:"_ [$€-nl-BE] * #.##0,00_ ;_ [$€-nl-BE] * -#.##0,00_ ;_ [$€-nl-BE] * \"-\"??_ ;_ @_ "

所以我只是复制了该规则并通过 Apache POI 应用它:

XSSFDataFormat dataFormat = (XSSFDataFormat) workbook.createDataFormat();
cellStyle.setDataFormat(dataFormat.getFormat("_ [$€-nl-BE] * #.##0,00_ ;_ [$€-nl-BE] * -#.##0,00_ ;_ [$€-nl-BE] * \"-\"??_ ;_ @_ "));

但是,这会导致一些不同的结果:€ 1.000,4300。您可以看到它运行良好,除了小数点。有4个而不是2个... 当我在 Excel 中查看自定义格式时,它也略有不同(注意 4 个零):_ [$€-nl-BE] * #.##0,00000_ ;_ [$€-nl-BE] * -#.##0,00000_ ;_ [$€-nl-BE] * "-"?????_ ;_ @_

所以我想知道某个地方的某个人(Apache POI 或 Excel)确实输入了 4 个小数而不是我定义的 2 个小数,这可能有什么问题。请注意,如果我在 Excel 中将其更改回小数点后 2 位,则它再次显示正确。即使在保存并关闭并重新打开文档之后。

【问题讨论】:

  • 它是否适用于XSSFDataFormat dataFormat = workbook.getCreationHelper().createDataFormat(); 而不是XSSFDataFormat dataFormat = (XSSFDataFormat) workbook.createDataFormat();
  • @deHaar 不,没有任何区别...所以我将其更改为:XSSFDataFormat dataFormat1 = (XSSFDataFormat) workbook.getCreationHelper().createDataFormat(); cellStyle.setDataFormat(dataFormat1.getFormat("_ [$€-nl-BE] * #.##0,00_ ;_ [$€-nl-BE] * -#.##0,00_ ;_ [$€-nl-BE] * \"-\"??_ ;_ @_ "));
  • 那是否按预期工作?
  • 不,不是,同样的结果...

标签: java excel apache-poi


【解决方案1】:

Apache poi 创建*.xlsx 文件,因为Excel 将存储它。并且在存储中,数字格式永远不会被本地化,而是始终采用en_US 格式。只有 Excel GUI 然后本地化数字格式。

因此,对于存储,您的数字格式必须是

"_ [$€-nl-BE] * #,##0.00_ ;_ [$€-nl-BE] * -#,##0.00_ ;_ [$€-nl-BE] * \"-\"??_ ;_ @_ "

注意小数点分隔符是.,千位分隔符是,,因为en_US 区域设置。

如果在本地化 Excel GUI 打开,则会更改为特定于区域设置的小数分隔符和千位分隔符。

但 Excel 本身也不会以数字格式存储像 nl-BE 这样的语言标签。相反,它使用Windows Language Code Identifier (LCID)。这是813 代表nl-BE。所以使用[$€-813],和[$€-nl-BE]一样,会更好。

以下内容也适用于我的德语Excel

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;

class CreateExcelCustomNumberFormat {

 public static void main(String[] args) throws Exception {

  Workbook workbook = new XSSFWorkbook();
  DataFormat dataFormat = workbook.createDataFormat();
  CellStyle cellStyle = workbook.createCellStyle();
  cellStyle.setDataFormat(dataFormat.getFormat("_ [$€-813] * #,##0.00_ ;_ [$€-813] * -#,##0.00_ ;_ [$€-813] * \"-\"??_ ;_ @_ "));

  Cell cell = workbook.createSheet().createRow(0).createCell(0);
  cell.setCellValue(1000.43);
  cell.setCellStyle(cellStyle);

  FileOutputStream out = new FileOutputStream("Excel.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();
 }
}

此代码使用当前的apache poi 4.1.2Excel 2016 进行测试。

【讨论】:

  • 感谢您的输入,我确实更改了千位和小数点分隔符,但现在当我打开 Excel 时,它说存在一些数据问题,并且它想尝试从中恢复,当我这样做时我可以看到金额不再格式化......
  • @dirkvranckaert:我给了你一个完整的例子,它使用当前的apache poi 4.1.2Excel 2016 进行了测试。所以我无法重现你的问题。
  • @dirkvranckaert:你把空格放在格式代码最后一个下划线后面了吗?所以dataFormat.getFormat("...;_ @_ ")dataFormat.getFormat("...;_ @_") 会出错。
  • 这确实是我的问题!感谢您向我指出这一点! :-) 现在可以了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多