尝试使用Apache POI编写.xlsx
文件时出现以下异常: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);
}
}
答案 0 :(得分:11)
我今天遇到了同样的问题。我注意到很多人在很多不同的论坛上都提出同样的问题,但我没有在任何地方看到答案。所以,这就是我想出的。它远非理想(我可以想到至少有两种情况可能是一个坏主意),并且可能无法满足所有需求,但它有效!
在工作簿对象所属的类中的每个保存操作之后,我从刚刚保存到的文件中重新加载工作簿。
使用上面的代码示例,我会像这样修改方法:
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"));
}
我在我的代码中对此进行了测试,并且很好地解决了这个问题。只需确保您从保存它的同一文件中读回来,而不是早期版本或不同版本。
答案 1 :(得分:10)
这很可能是一个错误。
https://issues.apache.org/bugzilla/show_bug.cgi?id=49940
我建议您订阅该机票,以获得有关当前改进/替代方案的通知。
如果我找到解决方法,我会通知您。
答案 2 :(得分:3)
我为此找到的解决方案,我一直在寻找一段时间,是为了确保您没有使用Workbook
打开您的File
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);
不要忘记关闭每个打开的流和OPCPackage
。
答案 3 :(得分:0)
仅当我们尝试多次写入.xlsx文件的同一文件时才会发生这种情况。我遇到了同样的问题并通过......解决了。
它正在运作
答案 4 :(得分:0)
使用apache poi 3.10时我也遇到了同样的问题。 但是在添加最新的apache poi jar文件后,它对我有用。 请将罐子更新到最新版本后尝试。
答案 5 :(得分:0)
我也有同样的问题。后来,我尝试了另一种方法,它解决了
在这种情况下,我们可以移动代码:
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
workbook.write(fileOut);
fileOut.close();
出方法(int i),然后在main方法中,我们可以使用:
sc.method(1);
sc.method(2);
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
workbook.write(fileOut);
fileOut.close();
然后,workbook.write仅用于一次。此外,数据可以多次修改。
答案 6 :(得分:-1)
这似乎确实是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);