web-dev-qa-db-ja.com

Apache poi3.7を使用してxlsxドキュメントに数回書き込む場合の例外

ApachePOIを使用して.xlsxファイルを書き込もうとすると、次の例外が発生します:org.Apache.xmlbeans.impl.values.XmlValueDisconnectedException

問題は、メソッドwrite()を2回使用することであるようです。この問題の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);
}
}
19
Mihail

これはおそらくバグです。

https://issues.Apache.org/bugzilla/show_bug.cgi?id=4994

そのチケットを購読して、現在の改善/代替案に関する通知を受け取ることをお勧めします。

回避策が見つかった場合はお知らせします。

10
Ernani Joppert

今日も同じ問題がありました。多くの人が多くの異なるフォーラムで同じ質問をしているのに気づきましたが、どこにも答えがありません。だから、これが私が思いついたものです。これは理想からはほど遠いものであり(これが悪い考えである可能性がある少なくとも2つのシナリオを考えることができます)、すべてのニーズに合うとは限りませんが、機能します。

ワークブックオブジェクトがプロパティであるクラス内のすべての保存操作の後、保存したファイルからワークブックをリロードします。

上記のコード例を使用して、次のようにメソッドを変更します。

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

私は自分のコードでこれをテストしました、そしてそれは問題をうまく解決しました。以前のバージョンや異なるバージョンではなく、保存したのと同じファイルから読み戻すようにしてください。

11
Scott Offen

私がこれについて見つけ、しばらく探していた解決策は、Workbookを開くために使用するFileFileOutputStreamを開かないようにすることです。 [$ var] _ 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

これは、.xlsxファイルの場合と同じファイルに複数回書き込もうとした場合にのみ発生します。私は同じ問題に遭遇し、それを解決しました。

  1. 以前は2回書いていました
  2. 最初の書き込み呼び出しを削除しました
  3. 同じブックインスタンスをメソッドに渡し、新しいセルに値を設定しました
  4. 最後に、いくつかの列とセルを追加して、ブックにさらにいくつかの変更を加えました
  5. 次に、ファイル出力ストリームを使用して書き込みました。

それは働いていた

0
Sriram Ramani

Apache poi 3.10を使用しているときに、私も同じ問題に直面しました。しかし、最新のApache poi jarファイルを追加した後、それは私のために働きました。 jarファイルを最新のものに更新してからお試しください。

0
Ashok Pandian

私も同じ問題を抱えていました。その後、別の方法を試してみましたが、解決しました。
この場合、コードを移動できます。

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は1回だけ使用されます。また、データは数回変更される可能性があります。

0
Jing Wan