4

生成される Excel レポートがあります。ほとんどの場合、行数が約 2,000 までであれば問題なく動作します。

今朝、11,000 行のレポートを生成しようとしましたが、変更されていない同じコードに従っていたため、なぜハングするのかわかりませんでした。以下を参照してください。XLSTransformer が本当に遅い可能性があるという事実を除いて、私はまだそれを理解できませんか?

List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
    Map<String, Object> sheetData = null;
    for(EntityForecastWrapper wrapper : wrappers) {
        sheetName = Integer.toString(wrapper.getEntityId());
        sheetNames.add(sheetName);
        sheetData = new HashMap<String, Object>();
        sheetData.put("wrapper", wrapper);
        maps.add(sheetData);
    }
    Map<String, Object> beansMap = new HashMap<String, Object>();
    Workbook workbook = null;
    XLSTransformer transformer = new XLSTransformer();
    try {
        Logger.getLogger(getClass()).error("generating excel");
        InputStream is = getClass().getResourceAsStream(getReportTemplate().getLabel());
        workbook = transformer.transformMultipleSheetsList(is, maps, sheetNames, "map", beansMap, 0);
        Logger.getLogger(getClass()).error("generated excel");
        /*FileOutputStream fos = new FileOutputStream(new File(fileName));
        workbook.write(fos);
        fos.flush();
        fos.close();*/
    } catch(Exception e) {
        Logger.getLogger(getClass()).error("Error writing excel data: ", e);
    }

コードは基本的に次の行から戻ってくることはありません。

workbook = transformer.transformMultipleSheetsList(is, maps, sheetNames, "map", beansMap, 0);

行数がそれほど多くない場合 (例: 500 行から 1000 行) は非常に高速です。行の内容は変わらず、同じ列数...

何か案は?

ありがとう!

4

3 に答える 3

5

Jxls はドキュメント全体を一度に RAM に構築しようとします。コードをざっと見たところ、 jxlsが POI HSSFWorkbook を内部で使用していることがわかりました。大量のデータの処理に役立つストリームはありません。

うまくいく可能性のある解決策は、データを小さな部分 (私の場合は ~1000 エントリ) で処理し、jxls の出力を一時的にファイル システムに保存することです。すべてのデータが処理されたら、poi を使用してファイルをマージします。あまりきれいな解決策ではありません...

于 2012-10-03T06:43:48.977 に答える
1

この場合、これはJXLSテンプレートが動的列または他のタグを使用するときに発生します。プロパティアクセスだけの単純なテンプレートがある場合${name}、それは高速に実行されます。より複雑なレポートのために、ダイレクトPOIAPIに切り替えました。

更新:XL​​SXテンプレートの処理も、XLSテンプレートよりもはるかに多くのメモリと時間を消費します。

于 2013-01-22T15:47:08.113 に答える