如何使用Apache POI(SXSSF)为特定单元格设置数据(数字)格式区域设置?

时间:2017-09-12 15:59:44

标签: java excel apache-poi locale

问题非常具体:使用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)

1 个答案:

答案 0 :(得分:2)

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

在Excel中,这看起来像:

enter image description here

如您所见,只能对货币符号进行本地化。

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

"#\\ ###\\ ##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电子表格格式中可用的本地化货币格式不同。这看起来像:

enter image description here

如您所见,货币符号和整个格式的语言都可以进行本地化。

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

OpenOffice / Libreoffice的“语言”组合框的设置无法存储在*.xlsx中,也不能存储在OpenOffice / Libreoffice中。在OpenOffice / Libreoffice中设置除默认值之外的其他内容,将文件保存为*.xlsx,关闭OpenOffice / Libreoffice,再次打开OpenOffice / Libreoffice中存储的*.xlsx文件。您将看到“语言”重置为默认值。