【问题标题】:Apache POI SXSSF and XSSFApache POI SXSSF 和 XSSF
【发布时间】:2015-04-21 16:58:18
【问题描述】:

我有一个问题。我是否正确,如果我有一个通过xssf 构造函数创建的工作簿,那么将构造函数更改为sxssf 工作簿(xssf wb 作为参数传递)以使其在stream mode 中工作就足够了?非常感谢您的回答。

解决方案:这完全取决于您用于流式传输的类。如果你的类收集的流缓冲区比它可以容纳的多,这件事就行不通了。否则会

【问题讨论】:

    标签: java apache apache-poi xlsx


    【解决方案1】:

    是的,你是对的。这两种实现之间的区别在于流版本直接将数据写入流并在内存中最多存储指定数量的行(默认值为 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 行。

    【讨论】:

    • 感谢您的回复,但实际上我问的是完全不同的事情。我想知道如果我将开始使用 sxssfworkbook 类而不是 xssf 创建工作簿,那么使用工作簿作为创建 xlsx 文件的基础的现有实现能否成为流。
    • 正如我所写的,区别在于存储在工作簿中的行的可用性。如果您在写入输出后不需要获取行 steeam 可以使用它。
    • @pepuch 只有SXSSFWorkbook 有方法dispose(),用于删除临时文件。您将如何将其添加(或不添加)到 WorkbookExample 类中?投掷?实例?
    • 我可以知道什么时候应该避免使用 sxssf,因为它的好处很多,它的缺点是什么??
    • 据我了解,流式传输应该以增量方式将数据写入磁盘。但在本例中,您是在循环结束后写入磁盘。整个文件的数据将留在内存中,并立即写入磁盘。这违背了流媒体的目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多