为什么在XSSFRow中使用copyRowFrom(...)时会出现IllegalArgumentException?

时间:2019-01-29 22:21:44

标签: java apache-poi apache-poi-4

我正在尝试使用copyRowFrom(...);将电子表格的第一行复制到新XSSFSheet的第一行,但是某些方法无法正常工作。 您可以在这里找到XSSFRow类和方法: https://github.com/apache/poi/blob/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java#L581

我从FormulaShifter.java得到IllegalArgumentException("amountToMove must not be zero")https://github.com/apache/poi/blob/trunk/src/java/org/apache/poi/ss/formula/FormulaShifter.java#L80

问题似乎出在XSSFRow的第623行,其中FormulaShifter.createForRowCopy(...)是用参数rowDifference = 0调用的,因为源行是0,目标行是0: https://github.com/apache/poi/blob/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java#L623

我不知道,也许是一个错误,但是当到达FormulaShifter.java的第80行时,参数rowDifference对应于为0的amountToMove,因此它抛出IllegalArgumentException。

我是否缺少某些东西,或者这是XSSFRow中copyRowFrom(...);方法的错误吗?

2 个答案:

答案 0 :(得分:1)

您是正确的。这是XSSFRow中的一个错误,因为即使目标行号与源行号相同也没有任何变化,它也会调用FormulaShifter.createForRowCopy。您可以将其作为错误提交给apache poi

但是随后需要创建一个可以在此处提供的测试用例。我为你做了。该代码还提供了一种解决方法。这是首先复制到错误的目标行,其中目标行号与源行号不同。然后它将错误的第一个目标行复制到真正需要的目标行。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

class ExcelCopyRowFrom {

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

  XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));
  XSSFSheet srcSheet = workbook.getSheetAt(0);
  XSSFRow srcRow = srcSheet.getRow(0);

  XSSFSheet destSheet = workbook.createSheet();
  //XSSFRow destRow = destSheet.createRow(0); //this fails because destination row number is the same as source row number

  XSSFRow destRow = destSheet.createRow(1); //this works 
  destRow.copyRowFrom(srcRow, new CellCopyPolicy());

  //workaround copy wrong first destination row to really needed destination row
  XSSFRow destRowNeeded = destSheet.createRow(0);
  destRowNeeded.copyRowFrom(destRow, new CellCopyPolicy());
  //the remove wrong first destination row
  destSheet.removeRow(destRow);

  FileOutputStream outputStream = new FileOutputStream("SAMPLENEW.xlsx");
  workbook.write(outputStream);
  outputStream.close();
  workbook.close();

 }
}

答案 1 :(得分:0)

//fix amountToMove must not be zero:srcRows index base destStartRow+1,avoid the same
int indexAdd1 = 1;
            for (Row row : failRowList) {
                row.setRowNum(indexAdd1);
                indexAdd1++;
            }
            failSheet.copyRows(failRowList,0, CellCopyPolicyFactory.newOnlyValue());