web-dev-qa-db-ja.com

Apache POISXSSFおよびXSSF

一つ質問があります。 xssfコンストラクターを介して作成されたワークブックがある場合、コンストラクターをsxssfワークブックに変更するだけで十分です(引数としてxssf wbを渡します) stream modeで機能させるには?あなたの答えをたくさんありがとう。

解決策:それはすべて、ストリーミングに使用するクラスによって異なります。クラスが保持できるよりも多くのストリームバッファを収集する場合、これは機能しません。そうでなければそれは

6
Stepan Pogosyan

はい、あなたが正しい。これら2つの実装の違いは、ストリームバージョンがデータをストリームに直接書き込み、最大で指定された行数をメモリに格納することです(デフォルト値は100で、SXSSFWorkbook.DEFAULT_WINDOW_SIZEに格納されます)。そのため、出力ストリームに書き込んだ後、一部の行データを取得できなくなります。ストリーム実装を使用することの大きな利点は、メモリ使用量が少ないことです。大量のデータをエクスポートする必要がある場合は、SXSSFWorkbookを使用してください。

例:

public static void main(String[] args) throws IOException {
        FileOutputStream inMemoryOut = new FileOutputStream(new File("inMemoryWorkbook.xlsx"));
        XSSFWorkbook workbook = new XSSFWorkbook();
        WorkbookExample example = new WorkbookExample(workbook, inMemoryOut);
        example.export();

        FileOutputStream streamOut = new FileOutputStream(new File("streamWorkbook.xlsx"));
        SXSSFWorkbook streamWorkbook = new SXSSFWorkbook();
        WorkbookExample streamExample = new WorkbookExample(streamWorkbook, streamOut);
        streamExample.export();
    }

public class WorkbookExample {

    private Logger logger = Logger.getLogger(WorkbookExample.class.getName());
    private Workbook workbook;
    private OutputStream out;

    public WorkbookExample(Workbook workbook, OutputStream out) {
        this.workbook = workbook;
        this.out = out;
    }

    public void export() throws IOException {
        logger.info("export start for " + workbook.getClass().getName());

        List<Person> persons = new ArrayList<Person>();
        for (int i = 0; i < 1000; i++) {
            persons.add(new Person(String.valueOf("user_" + i)));
        }

        Sheet sheet = workbook.createSheet();
        for (int i = 0; i < persons.size(); i++) {
            Person p = persons.get(i);
            Row row = sheet.createRow(i);
            Cell cell = row.createCell(0);
            cell.setCellValue(p.getName());
        }
        workbook.write(out);
        logger.info("Is row 1 accessible after writing to output stream? " + String.valueOf(sheet.getRow(1) != null));
        out.close();
        workbook.close();

        logger.info("export finished for " + workbook.getClass().getName());
    }

    public static class Person {

        private String name;

        public Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

}

出力:

kwi 21, 2015 7:56:14 PM pepuch.html2pdf.WorkbookExample export
    INFO: export start for org.Apache.poi.xssf.usermodel.XSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
    INFO: Is row 1 accessible after writing to output stream? true
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
    INFO: export finished for org.Apache.poi.xssf.usermodel.XSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
    INFO: export start for org.Apache.poi.xssf.streaming.SXSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
    INFO: Is row 1 accessible after writing to output stream? false
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
    INFO: export finished for org.Apache.poi.xssf.streaming.SXSSFWorkbook

ご覧のとおり、SXSSFWorkbookを使用して出力ストリームに書き込んだ後、行1にアクセスできなくなります。

11
pepuch