使用Apache poi将excel转换为XSSFWorkbook需要很长时间

时间:2017-09-09 14:27:51

标签: java excel apache-poi performance-testing fileinputstream

我正在尝试将excel文件转换为XSSFWorkbook,我有大约7000行和大约145列。在我的代码中,将该excel文件转换为第2行的XSSFWorkbook需要大约15分钟: -

> function updateResultTableColumns(){
>         $('#tblqresult').colResizable({ disable : true });
> 
>         $('table#tblqresult tbody').empty();
>         $('#tblqresult').find('th').remove();
> 
>         //Adding columns as per select list in that order
>         $('#' + selectULiD + ' li').each(function(){
>             if( $(this).text() != 'Drop Columns here...'){
>               var th1 = $("<th></th>").text($(this).text());
>               $('table#tblqresult tr:first').append(th1);
>             }
>         });
>         setResultTableColresizable(); }
> 
> 
> function setResultTableColresizable(){  
> $("#tblqresult").colResizable({
>     fixed:false,
>     liveDrag:true,
>     gripInnerHtml:"<div class='grip2'></div>", 
>     draggingClass:"dragging"    }); }

我只想在第2行转换时向XFFSWorkbook添加30行,而不是向XFFSWorkbook添加7000行?

如果没有,我怎样才能减少将Excel转换为XSSFWorkbook所需的时间?

2 个答案:

答案 0 :(得分:1)

*.xlsx文件是ZIP存档,其中包含具有不同Excel文件的目录结构中的XML数据。

例如有

  • /xl/workbook.xml描述了基本的工作簿结构,
  • /xl/worksheets/sheet1.xml/xl/worksheets/sheet2.xml,... /xl/worksheets/sheetN.xml拥有工作表数据 - 这是行 并且直接存储单元格但不是单元格内的所有数据 那里。细胞样式也不直接存储在那里。 - ,
  • /xl/styles.xml包含单元格样式
  • /xl/sharedStrings.xml,其中包含所有单元格的字符串内容 所有床单。这是为了避免多次存储相同的字符串 如果在单元格中多次使用此字符串,则为次。

因此,如果您想阅读*.xlsx ZIP存档,则需要解压缩ZIP存档,然后至少解析上面提到的四个XML文件以获取XSSFWorkbook的数据。这是apache poiXSSFWorkbook wb = new XSSFWorkbook(fileinputstream);时所做的事情。

因此,如果您确实需要XSSFWorkbook作为结果,则无法绕过此过程。如果你不怀疑apache poi编写了明确的延迟例程,那么就不可能减少这个过程的时间。

您的方法只是读取比存储在工作表中更少的行,可能会节省时间。但是,您的结果将是XSSFWorkbook,其中包含所有样式和所有字符串内容,但只包含与这些样式和字符串数据相关的一些工作表数据。因此,它会导致部分损坏XSSFWorkbook。这就是为什么没有人真正考虑过这种方法。

只有当要求只是从/xl/worksheets/sheetN.xml 之一读取未加格式的数据而没有创建XSSFWorkbook时,您才需要解压缩ZIP归档然后只解析所需的/xl/worksheets/sheetN.xml/xl/sharedStrings.xml来获取单元格的字符串内容。这可能在比上述整个过程更短的时间内完成。

答案 1 :(得分:1)

要在非常大的文件上略微提高性能,只需将文件直接传递到工作簿而不是流。

从此link

  

打开工作簿时,可以是.xls HSSFWorkbook,也可以是.xlsx   XSSFWorkbook,可以从文件或文件加载工作簿   的InputStream。使用File对象可以降低内存消耗,   而InputStream需要更多内存,因为它必须缓冲   整个文件。

XSSFWorkbook wb = new 
XSSFWorkbook(new File (filename));           // (2)
XSSFSheet sheet = wb.getSheetAt(0);

此外,使用WorkBookFactory更清晰,因为它抽象了您正在使用的excel文件的类型:

Workbook workbook = WorkbookFactory.create(new File(filename));