我正在使用 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。
我回答这个问题是为了说明为什么建议始终使用最新版本的 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
的源代码,然后使用其新编译版本。但为什么?为什么不使用已修复该错误的当前版本?