使用Apache POI插入内容

介绍

大家都知道POI! 它是可用Java创建Excel文档的最佳库。 它真的很好,可以轻松地完成很多事情。 但是最近我想做些不那么简单的事情。 我想将现有的xlsx文件用作模板,并在某些位置将一些数据插入其中。 在这篇文章中,我将说明为什么版本4.0.0并不那么容易。

可用工具

为了在现有Excel文档的中间插入一些内容,必须将从插入点到最后一行的所有行向下移动n行,其中n是要插入的行数。 还最好保持要移动的行的格式。

实际上,POI具有一些API可以帮助解决这些问题。 的
工作表界面有方法
Sheet.shiftRows(int,int,int)可以这样使用:

sheet.shiftRows(insertPosition,sheet.getLastRowNum(),n);

有更高级的方法
Sheet.shiftRows(int,int,int,boolean,boolean),但是对于XSSF,布尔参数没有什么区别,正如我在代码中可以找到的那样。 对于HSSF,这些参数可能很重要。

因此,该方法应该可以解决问题! 有什么问题?

问题

当我尝试使用这种方法时,遇到了一个可怕的问题:“我们发现了一些内容问题……”

Apache POI

实际上,这非常令人沮丧。 我很快发现行以某种方式被错误地移动了。 LibreOffice至少能够打开文件,但是格式和插入的内容均错误。

这需要2-3个小时的勤奋挖掘:-)。 事实证明,即使在最新的4.0.0版本(甚至很可能是4.0.1版本)中,POI都有一个错误,无法正确移动行。 这是该错误的链接:

https://bz.apache.org/bugzilla/show_bug.cgi?id=57423

例如,该方法更新工作表xml中的行引用

<row r =” 139

但不会更新单元格引用

<cr =” A138 ” s =“ 1” /> –错误

在这种情况下,单元必须指向上一级行,如下所示:
<cr =” A139 ” s =“ 1” /> –对

(如果您解压缩xlsx文件,则可以查看工作表xml)

该错误显示了一种解决方法。 我创建了一个方法,该方法在一个方法中实现了移位和变通方法:

public static void xssfShiftRows(Sheet sh, int firstRow, int last    Row, int shiftN) {
    int firstShiftedRow = firstRow + shiftN;
    int lastShiftedRow = lastRow + shiftN;
    sh.shiftRows(firstRow, lastRow, shiftN, true, true);
    /*
     * This code is a workaround for the bug
     * https://bz.apache.org/bugzilla/show_bug.cgi?id=57423
     * In the sheet xml the row references are updated like this:
     * <row r="139"
     * but the cell references are incorrect
     * <c r="A138" s="1"/>
     *
     * The number in the row 139 must match the number in the cell A139.
     * This code manually updates these links.
     */
               for (int nRow = firstShiftedRow; nRow <= lastShiftedRow; nRow++)  {
    final Row row = sh.getRow(nRow);
    if (row != null) {
    String msg = "Row[rownum=" + row.getRowNum()
    + "] contains cell(s) included in a multi-cell array         formula.  "
    + "You cannot change part of an array.";
    for (Cell c : row) {
        ((XSSFCell) c).updateCellReferencesForShifting(msg);
    }
  }
}
}

翻译自: https://www.javacodegeeks.com/2019/03/insert-content-apache-poi.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值