Apache poi-3.17 在 Excel 工作表中创建额外的空列

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

我正在使用 Apache poi-3.17 创建 Excel 工作表。打开 Excel 工作表时,看起来不错,但在 MS Access 中打开时也是如此,最后会添加一个新的空白列。此行为仅在 poi-3.17 版本中观察到,在任何其他版本中均未观察到(已尝试使用 3.11、3.7、5.18、4.*)。有人可以帮我解决这个问题吗?

我使用的代码如下。

public static String createExcel(String test) {
    String encodedBase64 = "";
    try {
        System.out.println("Start of method : Test : " + test);
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder;

        docBuilder = docBuilderFactory.newDocumentBuilder();
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Data");
        XSSFRow row = sheet.createRow(0);

        XSSFCell cell = row.createCell(0);
        cell.setCellValue("TEST1");
        XSSFCell cell1 = row.createCell(1);
        cell1.setCellValue("TEST2");
        workbook.write(baos);

        try {
            byte[] bytes = baos.toByteArray();
            File file = new File("C:\\Files\\test.xlsx");

            OutputStream out = new FileOutputStream(file);
            out.write(baos.toByteArray());
            out.close();
       workbook.close();
            encodedBase64 = Base64.getEncoder().encodeToString(bytes).trim();
            System.out.println("encodedBase64 :" + encodedBase64);
           
        } catch (Exception e) {

            System.out.println("Message :" + e.getMessage());
        }<kbd>your text</kbd>

    } 
    return encodedBase64;
}

我还尝试使用 row.removeCell(getCell(2)) 只是为了看看它是否获取任何额外的列,但它给出了 nullPointerException。

java apache apache-poi
1个回答
0
投票

我回答这个问题是为了说明为什么建议始终使用最新版本的 Apache POI。

简短回答

这是 Apache POI 版本 3.17 中设置

XSSFSheet
的维度字段时的一个错误。它在 4.0.0 版本中已修复。但 Apache POI 不会修复先前版本代码中的错误。 3.17之前的版本没有这个bug,因为他们根本没有设置
XSSFSheet
的维度字段。

所以我的建议是:始终使用最新的 Apache POI 版本(目前为 5.2.3)。

问题

结果

*.xlsx
文件中
/xl/worksheets/sheet1.xml
的尺寸设置错误。它将一列的尺寸设置得太大。

示例:

import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.*;

class CreateXSSF {

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

  try (XSSFWorkbook workbook = new XSSFWorkbook(); 
       FileOutputStream fileout = new FileOutputStream("./Excel.xlsx") ) {

   XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Data");
   XSSFRow row = sheet.createRow(0);

   XSSFCell cell = row.createCell(0);
   cell.setCellValue("TEST1");
   XSSFCell cell1 = row.createCell(1);
   cell1.setCellValue("TEST2");
   
   workbook.write(fileout);   
  }
 }
}

使用 Apache POI 3.17:

<dimension ref="A1:C1"/>

一栏太大。

使用当前的 Apache POI 5.2.3:

<dimension ref="A1:B1"/>

原因

Apache POI 3.17 的代码 XSSFSheet.java 设置

maxCell = Math.max(maxCell, row.getLastCellNum())
,然后使用该
maxCell
设置尺寸参考。但是
Row.getLastCellNum
将获取该行中包含的最后一个单元格的索引 PLUS ONE

Apache POI 4.0.0 XSSFSheet.java的代码纠正了这个问题并执行

maxCell = Math.max(maxCell, row.getLastCellNum()-1)

Apache POI 3.17 有解决方法吗?

其实不然。

XSSFSheet
方法
protected void write(OutputStream out)
XSSFWorkbook.write
时被调用。因此,即使在写入之前在
XSSFSheet
XML 中设置正确的维度,写入时也会被覆盖。

可以更改 Apache POI 3.17 中

XSSFSheet.java
的源代码,然后使用其新编译版本。但为什么?为什么不使用已修复该错误的当前版本?

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