使用apache poi 3.7多次写入xlsx文档时出现exception

尝试使用Apache POI编写.xlsx文件时出现以下exception: org.apache.xmlbeans.impl.values.XmlValueDisconnectedException

这似乎是第二次使用方法write()的问题。 当处理这个问题的HSSFWorkbook不会出现。

代码如下:

 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); } } 

这很可能是一个错误。

https://issues.apache.org/bugzilla/show_bug.cgi?id=49940

我build议你订阅那张票,以获得有关当前改进/备选scheme的通知。

如果我find解决办法,我会让你知道。

今天我也有同样的问题。 我注意到许多人在很多不同的论坛上都提出了同样的问题,但是我没有在任何地方看到答案。 所以,这就是我想出来的。 这是远远不够理想的(我可以想到至less有两个情况,这可能是一个坏主意),并不能满足所有需求,但它的工作!

在工作簿对象是属性的类内的每个保存操作之后,我从我刚刚保存到的文件中重新加载工作簿。

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

 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")); } 

我在我的代码中testing了这个,并很好地解决了这个问题。 只要确保您从保存的相同文件中读取,而不是更早或不同的版本。

我find的解决scheme,我一直在寻找一段时间,是确保你不打开你的Workbook与你用来打开FileOutputStream保存Workbook 。 而是使用FileInputStream来打开Workbook

像这样的东西将完美地工作

  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); 

不要忘记closures每个打开的stream和OPCPackage

只有当我们尝试多次写入同一个文件时,才会发生这种情况,对于.xlsx文件也是如此。 我来到相同的问题,并得到了解决..

  1. 以前我在写两遍
  2. 现在删除了第一个写入电话
  3. 将相同的工作簿实例传递给该方法,并将值设置为新的单元格
  4. 最后通过编写更多的列和单元格对工作簿做了一些更改
  5. 然后使用文件输出stream写入。

它正在工作

当我使用apache poi 3.10时,我也面临同样的问题。 但添加最新的Apache poi jar文件后,它为我工作。 请在将jar子更新到最新之后再尝试。

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

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

出来的方法(诠释我),然后在主要的方法,我们可以使用:

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

那么,workbook.write只能用于一次。 此外,数据可能会被修改几次。

这似乎确实是XSSFSheet.createRow(int index)中的一个错误。 只要错误不是固定的,使用这个类作为解决方法应该做的伎俩:

 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; } } 

使用 :

 PoiHacks.createRow(sheet, 0);