Apache POI 在添加样式时生成无效的 Excel XML

问题描述 投票:0回答:1

我正在使用 Apache POI 并尝试将日期格式样式添加到电子表格中的数字字段。但是,当我向单元格添加样式时,它无法在 Excel 中打开(尝试修复文件)。

我的代码看起来很像这样:

DeferredSXSSFWorkbook wb = new DeferredSXSSFWorkbook(100);
DeferredSXSSFSheet sheet1 = wb.createSheet("Sheet1");
...
Row row = sheet.createRow(0);
CellStyle style = sheet.getWorkbook().createCellStyle();
CreationHelper createHelper = sheet.getWorkbook().getCreationHelper();
short format = createHelper.createDataFormat().getFormat("m/d/yy");
style.setDataFormat(format);
...
Cell cell = row.createCell(0);
cell.setCellStyle(style);
cell.setCellValue(new Date());

我能够解压缩 xlsx 文件并获取生成的sheet1.xml:

<?xml version="1.0" encoding="UTF-8"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <dimension ref="A1"/>
    <sheetViews>
        <sheetView tabSelected="true" workbookViewId="0"/>
    </sheetViews>
    <sheetFormatPr defaultRowHeight="15.0"/>
    <sheetData>
        <row r="2">
            <c r="A2" s="1" t="n">
                <v>45442.657083680555</v>
            </c>
        </row>
    </sheetData>
    <pageMargins bottom="0.75" footer="0.3" header="0.3" left="0.7" right="0.7" top="0.75"/>
</worksheet>

和 styles.xml:

<?xml version="1.0" encoding="UTF-8"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <numFmts count="0"/>
    <fonts count="1">
        <font>
            <sz val="11.0"/>
            <color indexed="8"/>
            <name val="Calibri"/>
            <family val="2"/>
            <scheme val="minor"/>
        </font>
    </fonts>
    <fills count="2">
        <fill>
            <patternFill patternType="none"/>
        </fill>
        <fill>
            <patternFill patternType="darkGray"/>
        </fill>
    </fills>
    <borders count="1">
        <border>
            <left/>
            <right/>
            <top/>
            <bottom/>
            <diagonal/>
        </border>
    </borders>
    <cellStyleXfs count="1">
        <xf borderId="0" fillId="0" fontId="0" numFmtId="0"/>
    </cellStyleXfs>
    <cellXfs count="1">
        <xf borderId="0" fillId="0" fontId="0" numFmtId="0" xfId="0"/>
    </cellXfs>
</styleSheet>

如果我理解这个问题,单元格上的

s="1"
应该引用日期格式样式?但是,我没有看到任何与我在
styles.xml
中创建的样式类似的样式。我应该期待
cellStyleXfs
里面有更多的东西,对吧?

我检查了很多示例和 Apache 文档,但我没有看到我做错了什么。有人遇到过这个或者有什么想法吗?

java apache-poi export-to-excel
1个回答
0
投票

看起来好像单元格样式没写。单元格样式位于工作簿级别,并在工作表中的单元格之间共享。因此,在将单元格流式传输到工作表时无法创建单元格样式。

参见示例 HSSF 和 XSSF 示例 -> 仅 XSSF 示例 -> DeferredGeneration.java:

... // 单元格样式应在行生成器外部创建 功能...

虽然您的代码不是完整的示例,但我怀疑您正在尝试在行生成器函数中生成单元格样式。这不会生成任何单元格样式,因为单元格样式位于工作簿级别,而不是行级别或单元格级别。单元格仅通过 s 属性引用单元格样式。

完整的示例,有效:

import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.streaming.*; import java.util.Date; class CreateExcelDateDeferredSXSSFWorkbook { public static void main(String[] args) throws Exception { try (DeferredSXSSFWorkbook workbook = new DeferredSXSSFWorkbook(100);) { // cell styles should be created outside the row generator function CellStyle cellStyle = workbook.createCellStyle(); CreationHelper createHelper = workbook.getCreationHelper(); short format = createHelper.createDataFormat().getFormat("m/d/yy"); cellStyle.setDataFormat(format); DeferredSXSSFSheet sheet = workbook.createSheet("Sheet1"); sheet.setRowGenerator((ssxSheet) -> { for (int i = 0; i < 1; i++) { Row row = ssxSheet.createRow(i); // Don't do this here! It will not be stored into styles. //CellStyle cellStyle = sheet.getWorkbook().createCellStyle(); //CreationHelper createHelper = sheet.getWorkbook().getCreationHelper(); //short format = createHelper.createDataFormat().getFormat("m/d/yy"); //cellStyle.setDataFormat(format); Cell cell = row.createCell(0); cell.setCellStyle(cellStyle); cell.setCellValue(new Date()); } }); try (FileOutputStream fileout = new FileOutputStream("./Excel.xlsx");) { workbook.write(fileout); } finally { workbook.dispose(); } } } }

	
© www.soinside.com 2019 - 2024. All rights reserved.