10

私は、Excel ワークブックを読み取る必要があるプロジェクトに取り組んでおり、必要な Web サービスを呼び出し、Web サービスからの応答を受け取り、その情報を読み取った同じ Excel ワークブックに入力します。

Excel ワークブックに書き込もうとしたときに表示されるエラーは次のとおりです。

Exception in thread "main" org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:141)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:177)
at ext.ExcelProcessor.main(ExcelProcessor.java:197)
Caused by: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
    at org.apache.poi.openxml4j.opc.PackagePart.getInputStream(PackagePart.java:500)
    at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:75)
    at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:139)
    ... 2 more

ファイルを開く/読み取るための私のコードは次のとおりです。

pkg = OPCPackage.open(xslFile);
    theWorkbook = new XSSFWorkbook(pkg);

この後、各行を読み取り、各セル値を抽出します。

これが完了したら、成功メッセージと結果メッセージのヘッダーの下にセルを作成し、次の操作を行います。

String sessionData = sessionKey[1];
                String[] cellValCurrRow = rowCellVals.get(r-1);
                String attachmentData[] = WQSServices.uploadAttachment(sessionData, cellValCurrRow);

                XSSFCell cell = xslRows[r].getCell(7);

                if(cell == null)
                {
                    cell = xslRows[r].createCell(7);
                }

                System.out.println("The Cell: "+cell.getStringCellValue());

                XSSFCell cell2 = xslRows[r].getCell(8);

                if(cell2 == null)
                {
                    cell2 = xslRows[r].createCell(8);
                }

                System.out.println("The Cell: "+cell2.getStringCellValue());

                cell.setCellType(Cell.CELL_TYPE_STRING);
                cell2.setCellType(Cell.CELL_TYPE_STRING);
                cell.setCellValue(attachmentData[0]);
                cell2.setCellValue(attachmentData[1]);

                System.out.println("New Cell Data: 1-"+cell.getStringCellValue()+" 2-"+cell2.getStringCellValue());

                FileOutputStream fos = new FileOutputStream(xslFile);
                theWorkbook.write(fos);
                fos.close();

誰かが同様の問題に遭遇しましたか?

4

6 に答える 6

14

同じエラー メッセージが表示されましたが、別のクラスを使用していました。私が使用している現在の poi バージョンは poi-ooxml 3.9 ですが、まだ問題があります。これで問題は解決しました。最初に Workbook インスタンスを取得するときにこの問題が発生すると思います。

ファイルにデータを書き込むときは、次のようにします (例外とクローズの実践規則を使用):

    FileOutputStream fos = new FileOutputStream(filePath);
    wb.write(fos);
    fos.close();

次のように Workbook インスタンスを取得すると、「/docProps/app.xml から入力ストリームを取得できません」というエラー メッセージが表示されます。

    Workbook wb = WorkbookFactory.create(new File(filePath));

問題を修正したところ、変更されたコードは

    Workbook wb = WorkbookFactory.create(new FileInputStream(filePath));

私の場合、同じファイルを開いて読み書きするか、あるファイルから読み込んでから別のファイルに書き込むかは問題ではありません。poi のソース コードを読むと、私が使用したファクトリ メソッドが OPCPackage クラスの open() メソッドを呼び出している可能性があることがわかります。引数として InputStream を取得するメソッドを使用してみてください。

于 2014-02-06T16:22:25.910 に答える
1

ここでの問題は、ファイルを開いて保存するために同じfilePathを使用していることだと思いxslFileます。

ファイルを開く、

pkg = OPCPackage.open(xslFile);
    theWorkbook = new XSSFWorkbook(pkg);

ファイルを保存し、

FileOutputStream fos = new FileOutputStream(xslFile);
theWorkbook.write(fos);
fos.close();

ファイルを読み取って操作するにはInputStreamが必要ですが、同じパスとファイル名でOutputStreamを作成すると、このストリームにアクセスできなくなります。

于 2013-01-02T06:15:44.660 に答える
1

リストされている現在の問題は、2010 年から発生しているバグであり、@ https://issues.apache.org/bugzilla/show_bug.cgi?id=49940で見つけることができます。

以下のスタックオーバーフローのリストでは、ファイルに別の書き込みを行う前にブックを閉じて再度開くと、問題なく動作するという回避策が見つかりました。これは決して効率的ではありませんが、Apache-POI 開発チームが問題を解決するまで問題を修正します。

https://stackoverflow.com/a/9792406/1231715

于 2013-01-03T20:12:25.253 に答える
1

前に閉じる前に、同じファイルが再度開かれていることを確認してください。

FileInputStream file1 = new FileInputStream("file.xlsx");
FileOutputStream file2 = new FileOutputStream("file.xlsx");
file2.close();
file1.close();

このコードは、このエラーをスローします。

解決:

FileInputStream file1 = new FileInputStream("file.xlsx");
file1.close();
FileOutputStream file2 = new FileOutputStream("file.xlsx");
file2.close();
于 2021-06-04T06:21:22.810 に答える