【问题标题】:How to set data (number) format locale for specific cell using Apache POI (SXSSF)?如何使用 Apache POI (SXSSF) 为特定单元格设置数据(数字)格式区域设置?
【发布时间】:2017-09-12 15:59:44
【问题描述】:

问题非常具体:使用 Apache POI,我想创建单元格(完成),为其分配数字格式(完成),并设置格式的语言环境(卡在这里)。

代码如下所示:

SXSSFWorkbook workbook = new SXSSFWorkbook(100);
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(1);
Cell cell = row.createCell(0);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(8); //currency with thousands separator and two decimal places after period
cell.setCellValue(123456.78);
//??? how to set custom locale for the cell's number format?

我试图用自定义语言环境解决的问题是自定义千位分隔符字符(法语的不间断空格对我来说是可以的)。

XLSX 工作簿允许这样的自定义(更新:我的意思是为每个单元格设置格式区域设置),这可以通过 MS Office 和 OpenOffice 实现。我想在代码中做同样的事情。

(Apache POI 3.12)

【问题讨论】:

  • 当我使用 Apache-poi 时,我不必处理语言环境,因为本地化的格式细节(例如,逗号或点)由显示数据的 Excel 确定,因此它总是正确的实际用户。这还不够吗?
  • “XLSX 工作簿允许这样的定制”:不,它没有。对于货币数字格式,只能本地化货币符号,但不能本地化小数分隔符。这来自 Windows 系统区域设置。千位分隔符也默认为 Windows 系统区域设置。但这可以使用格式字符串进行设置。所以格式字符串可以是"#\\ ##0.00\\ [$€-40C];[RED]\\-#\\ ##0.00\\ [$€-40C]"。这是你想要的吗?但这与可用于 Libreoffice OpenDocument 电子表格格式的本地化货币格式不同。
  • @ZsoltV 不幸的是,这还不够。我有客户要求说“空格作为分隔符”,但我无法让客户更改计算机的区域设置
  • @AxelRichter XLSX 工作簿允许为特定单元格设置区域设置。不过,Apache POI 似乎没有 API。但是像“# ### ### ###”这样的格式对我有用。如果您将其发布为答案,我会接受它
  • "XLSX 工作簿允许为特定单元格设置区域设置。"你能告诉我怎么做吗?

标签: java excel apache-poi locale


【解决方案1】:

在用于货币数字格式的 Offixe OpenXML (*.xlsx) 中,只能本地化货币符号,但不能本地化小数分隔符。小数点分隔符来自运行 Excel 的 Windows 系统的 Windows 系统区域设置。千位分隔符也默认为运行 Excel 的 Windows 系统的 Windows 系统区域设置。

在 Excel 中如下所示:

如您所见,只有货币符号可以本地化。

至少可以使用格式字符串设置千位分隔符。所以格式字符串可以是

"#\\ ###\\ ##0.00\\ [$€-40C];[RED]\\-#\\ ###\\ ##0.00\\ [$€-40C]"

这是一种货币数字格式,具有本地化的法国欧元货币符号和空格作为千​​位分隔符。因为我们伪造了千位分隔符,所以我们必须在格式字符串中提供尽可能多的数字。

小数点分隔符是默认值,这意味着它来自运行 Excel 的 Windows 系统的 Windows 系统区域设置。因此,格式字符串中的点. 并不意味着始终使用点作为十进制分隔符,而是使用来自运行 Excel 的 Windows 系统的 Windows 系统区域设置的十进制分隔符。如果我们在格式字符串中使用逗号, 作为千位分隔符,这也将使用来自运行 Excel 的 Windows 系统的 Windows 系统区域设置的千位分隔符。然后我们就不需要在格式字符串中提供这么多数字了,因为这样一来,千位分隔符设置就会每千位重复一次。所以

"#,##0.00\\ [$€-40C];[RED]\\-#,##0.00\\ [$€-40C]"

足够了。

例子:

import java.io.FileOutputStream;

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

import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.streaming.SXSSFSheet;

public class CreateExcelNumberFormat {

 public static void main(String[] args) throws Exception {
  SXSSFWorkbook workbook = new SXSSFWorkbook(100);

  DataFormat dataformat = workbook.createDataFormat();
  CellStyle cellStyleCurrency = workbook.createCellStyle();
  cellStyleCurrency.setDataFormat(dataformat.getFormat("#\\ ###\\ ##0.00\\ [$€-40C];[RED]\\-#\\ ###\\ ##0.00\\ [$€-40C]")); 

  Sheet sheet = workbook.createSheet();
  Row row = sheet.createRow(1);
  Cell cell = row.createCell(0);

  cell.setCellValue(123456.78);
  cell.setCellStyle(cellStyleCurrency);

  ((SXSSFSheet)sheet).trackColumnForAutoSizing(0);
  sheet.autoSizeColumn(0);

  workbook.write(new FileOutputStream("CreateExcelNumberFormat.xlsx"));
  workbook.close();
  workbook.dispose();
 }
}

但这与可用于 Libreoffice OpenDocument 电子表格格式的本地化货币格式不同。这看起来像:

正如您在此处看到的,货币符号和整个格式的语言都可以本地化。

但是Office OpenXML (*.xlsx) 无法存储本地化的货币数字格式。 OpenDocument Spreadsheet (*.ods) 是 OpenOffice/Libreoffice 的原生格式,可以保存本地化的货币数字格式,但是如果 Excel 会打开这样的文件,本地化就会丢失。

OpenOffice/Libreoffice 的“语言”组合框的设置不能存储在*.xlsx 中,也不能从 OpenOffice/Libreoffice 存储。在 OpenOffice/Libreoffice 中设置非默认值,将文件另存为 *.xlsx,关闭 OpenOffice/Libreoffice,再次在 OpenOffice/Libreoffice 中打开存储的 *.xlsx 文件。您将看到“语言”已重置为默认值。

【讨论】:

  • 我不太明白 Excel 和 OpenOffice 的格式字符串有什么区别。只是空间被转义了吗?
  • 我也怀疑 e。 G。 123456789 将正确显示为“123 456 789” - 而不是“123456 789”。所以完整的解决方案可能是“# ### ### ### ##0”(重复很多空格)
  • 如果两者都保存 Office OpenXML (*.xlsx),则 Excel 和 OpenOffice/Libreoffice 的格式字符串之间没有区别。就是 Office OpenXML (*.xlsx) 无法存储本地化的货币数字格式。 OpenDocument 电子表格 (*.ods) 可以保存本地化的货币数字格式,但如果 Excel 会打开这样的文件,本地化就会丢失。是的,你是对的,因为我们伪造了千位分隔符,所以我们必须在格式字符串中提供尽可能多的数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 2014-01-20
  • 2012-12-28
相关资源
最近更新 更多