1

POI を使用して、Excel ファイルの読み取り、編集、書き込みを行っています。私のプロセス フローは、Excel を書き、読み、また書き出すようなものです。

次に、Java アプリがまだ実行されている間に通常のデスクトップ Excel アプリケーションを使用してファイルを編集しようとすると、Excel を保存できません。一部のプロセスが Excel を保持していると表示され、すべてのファイル ハンドルを適切に閉じています。

この問題を解決する方法を教えてください。

SXSSFWorkbook wb = new SXSSFWorkbook(WINDOW_SIZE);
Sheet sheet = getCurrentSheet();//stores the current sheet in a instance variable
for (int rowNum = 0; rowNum < data.size(); rowNum++) {
    if (rowNum > RECORDS_PER_SHEET) {
        if (rowNum % (RECORDS_PER_SHEET * numberOfSheets) == 1) {
            numberOfSheets++;
            setCurrentSheet(wb.getXSSFWorkbook().createSheet());
            sheet = getCurrentSheet();
        }
    }
    final Row row = sheet.createRow(effectiveRowCnt);
    for (int columnCount = 0; columnCount < data.get(rowNum).size(); columnCount++) {
        final Object value = data.get(rowNum).get(columnCount);
        final Cell cell = row.createCell(columnCount);
        //This method creates the row and cell at the given loc and adds value
        createContent(value, cell, effectiveRowCnt, columnCount, false, false);
    }
}

public void closeFile(boolean toOpen) {
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(getFileName());
        wb.write(out);            
    }
    finally {
        try {
            if (out != null) {
                out.close();
                out = null;
                if(toOpen){
                    // Open the file for user with default program
                    final Desktop dt = Desktop.getDesktop();
                    dt.open(new File(getFileName()));
                }
            }
        }

    }

}
4

3 に答える 3

2

私はすべてのオプションを試しました。よく調べてみると、問題は Event User モデルにあるようです。データを読み取るために以下のコードを使用しています。

    final OPCPackage pkg = OPCPackage.open(getFileName());
    final XSSFReader r = new XSSFReader(pkg);
    final SharedStringsTable sst = r.getSharedStringsTable();

    final XMLReader parser = fetchSheetParser(sst);

    final Iterator<InputStream> sheets = r.getSheetsData();

    while (sheets.hasNext()) {
        final InputStream sheet = sheets.next();
        final InputSource sheetSource = new InputSource(sheet);
        parser.parse(sheetSource);
        sheet.close();
    }

私は、Excelが何らかの理由でこのプロセスによってしばらくの間保持されていると思います。このコードを削除して以下のコードを使用すると:

    final File file = new File(getFileName());
    final FileInputStream fis = new FileInputStream(file);
    final XSSFWorkbook xWb = new XSSFWorkbook(fis);

プロセスは正常に機能し、Excel はロックされたままになりません。

于 2013-09-10T06:15:18.430 に答える
2

コードは正しいようです。の後out.close();、ロックが残っていないはずです。

まだ起こり得ること:

  1. 別の Java プロセスがあります (デバッガーでハングしているなど)。新しいプロセスがファイルを書き込もうとして失敗し (プロセス 1 が原因で) finally、同じ問題が発生する Excel を開こうとします。で発生するすべての例外を必ずログに記録してください。wb.write(out);

    注: 上記のコードはout != null、Java がファイルを開くことができる場合にのみ Excel を起動するため、この点では正しいように見えます。

  2. ファイルが完全に書き込まれていない可能性があります (つまり、実行中に例外が発生しましたwrite())。Excel は破損したファイルを開こうとし、間違ったエラー メッセージを表示します。

  3. Process Explorerなどのツールを使用して、ファイルをロックしているプロセスを見つけます。

于 2013-09-06T13:44:48.437 に答える
0

私は実際にそれを理解しました。非常に単純な行が必要でしたが、何らかの理由で新しいハロウィーン ドキュメント ( http://poi.apache.org/spreadsheet/how-to.html#sxssf )で説明されていませんでした。

Busy Developer's Guide を確認したところ、解決策が見つかりました。追加する必要がありました

pkg.close(); //OPCPackage を閉じるには

これにより、私のコードは、同じ Excel ファイルに対する任意の数の読み取りと書き込みで正常に動作することが追加されました。

于 2013-09-10T08:11:37.177 に答える