Java 使用apache poi 3.7多次写入xlsx文档时出现异常

Java 使用apache poi 3.7多次写入xlsx文档时出现异常,java,excel,apache-poi,Java,Excel,Apache Poi,我在尝试使用Apache POI编写.xlsx文件时遇到以下异常:org.Apache.xmlbeans.impl.values.XmlValueDisconnectedException 问题似乎是第二次使用write()方法。 使用HSSF工作手册时,不会出现此问题 代码如下: public class SomeClass{ XSSFWorkbook workbook; public SomeClass() throws IOException{ File excelFile =

我在尝试使用Apache POI编写
.xlsx
文件时遇到以下异常:
org.Apache.xmlbeans.impl.values.XmlValueDisconnectedException

问题似乎是第二次使用write()方法。 使用HSSF工作手册时,不会出现此问题

代码如下:

public class SomeClass{

XSSFWorkbook workbook;

public SomeClass() throws IOException{
    File excelFile = new File("workbook.xlsx");

    InputStream inp = new FileInputStream(excelFile);
    workbook = new XSSFWorkbook(inp);
    inp.close();
}

void method(int i) throws InvalidFormatException, IOException {

    XSSFSheet sheet = workbook.getSheetAt(0);
    XSSFRow row = sheet.getRow(i);
    if (row == null) {
        row = sheet.createRow(i);
    }
    XSSFCell cell = row.getCell(i);
    if (cell == null)
        cell = row.createCell(i);
    cell.setCellType(Cell.CELL_TYPE_STRING);
    cell.setCellValue("a test");

    // Write the output to a file
    FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
    workbook.write(fileOut);
    fileOut.close();

}

public static void main(String[] args) throws Exception {
    SomeClass sc = new SomeClass();

    sc.method(1);
    sc.method(2);
}
}

这很可能是一个bug

我建议您订阅该通知单,以获得有关当前改进/备选方案的通知


如果我找到解决办法,我会告诉你。

我今天也遇到了同样的问题。我注意到很多人在不同的论坛上问同样的问题,但我在任何地方都没有看到答案。这就是我的想法。它远不是理想的(我能想到至少两种情况,这可能是个坏主意),并且可能不适合所有的需要,但它可以工作

在工作簿对象是其属性的类中执行每次保存操作后,我都会从刚保存到的文件中重新加载工作簿

使用上面的代码示例,我将修改此方法,如下所示:

void method(int i) throws InvalidFormatException, IOException {
    ...

    // Write the output to a file
    FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
    workbook.write(fileOut);
    fileOut.close();

    // Reload the workbook, workaround for bug 49940
    // https://issues.apache.org/bugzilla/show_bug.cgi?id=49940
    workbook = new XSSFWorkbook(new FileInputStream("workbook.xlsx"));
}

我在代码中对此进行了测试,它很好地解决了这个问题。只需确保从保存该文件的同一文件中读回,而不是更早或不同的版本。

仅当我们尝试多次写入同一文件时才会发生这种情况,而.xlsx文件也是如此。我遇到了同样的问题,并通过

  • 以前我写过两次
  • 现在删除了第一个写调用
  • 将同一工作簿实例传递给该方法,并为新单元格设置值
  • 最后,通过编写更多的列和单元格,对工作簿进行了更多的更改
  • 然后使用文件输出流写入

  • 它正在工作

    这似乎确实是XSSFSheet.createRow(int index)中的一个bug。只要bug没有被修复,使用这个类作为解决方案应该可以做到:

    import java.util.Iterator;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    
    public class PoiHacks
    {
        // Fix of XSSFSheet.createRow(int index)
        public static Row createRow(Sheet sheet, int index) {
            Row row = sheet.getRow(index);
            if(row==null) return sheet.createRow(index);
    
            Iterator it = row.iterator();
            while(it.hasNext()) {
                it.next();
                it.remove();
            }
            return row;
        }
    }
    
    使用:


    我已经找到了解决方法,我已经寻找了一段时间,就是确保你没有用
    文件打开
    工作簿
    ,你用它打开
    文件输出流
    来保存
    工作簿
    。相反,请使用
    文件输入流
    打开
    工作簿

    像这样的东西可以完美地工作

            File inputFile = new File("Your-Path");
            this.inputStream = new FileInputStream(inputFile);
            this.opc = OPCPackage.open(this.inputStream);
            this.workbook = WorkbookFactory.create(opc);
    
    ...
    
            this.outputStream = new FileOutputStream(inputFile);
            this.workbook.write(this,outputStream);
    

    不要忘记关闭每个打开的流,在使用ApachePOI3.10时,
    OPCPackage

    我也面临同样的问题。 但是在添加了最新的ApachePOIJAR文件之后,它对我来说很有效。
    请将JAR更新到最新版本后再试。

    我也遇到了同样的问题。后来,我尝试了另一种方法,它解决了。
    在这种情况下,我们可以移动代码:

    FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
    workbook.write(fileOut);
    fileOut.close();
    
    在方法(int i)之外,然后在主方法中,我们可以使用:

     sc.method(1); 
     sc.method(2); 
     FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
     workbook.write(fileOut);
     fileOut.close();
    

    然后,workbook.write仅使用一次。数据也可以修改几次。

    如果某个善良的灵魂有时间处理这个bug,那就更好了:)斯科特,谢谢你的帮助。我自己也发布了一些关于OP的问题,并与您的工作相关。这可能不是您所说的最有效的方法,但在Apache POI团队决定修复此错误之前,这是一种解决问题的好方法。感谢您的解决方案。。。添加了一个
    新文件(“workbook.xlsx”).delete()
    ;广告结束清理。。。
     sc.method(1); 
     sc.method(2); 
     FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
     workbook.write(fileOut);
     fileOut.close();