Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java POI性能_Java_Excel_Apache Poi - Fatal编程技术网

Java POI性能

Java POI性能,java,excel,apache-poi,Java,Excel,Apache Poi,我在J2EEWeb应用程序中使用POI生成工作簿。 但是,我发现POI创建一个包含25K行(每行大约15列)的工作簿大约需要3分钟。 这是POI性能问题,还是花费这么多时间是合理的? 是否还有其他API具有更好的性能?如果POI花那么多时间生成这样的文件,我会感到非常惊讶。我刚刚生成了一个大约18秒内包含30000行x10个单元格的工作表(公平地说,没有格式)。原因可能是以下原因之一: POI日志记录可能已打开,如前所述 您正在使用交换内存运行 您的VM可用堆可能非常低 我们在web应用程序中

我在J2EEWeb应用程序中使用POI生成工作簿。 但是,我发现POI创建一个包含25K行(每行大约15列)的工作簿大约需要3分钟。 这是POI性能问题,还是花费这么多时间是合理的?
是否还有其他API具有更好的性能?

如果POI花那么多时间生成这样的文件,我会感到非常惊讶。我刚刚生成了一个大约18秒内包含30000行x10个单元格的工作表(公平地说,没有格式)。原因可能是以下原因之一:

  • POI日志记录可能已打开,如前所述
  • 您正在使用交换内存运行
  • 您的VM可用堆可能非常低

我们在web应用程序中也使用POI,并且没有任何性能问题-尽管我们生成的文档比您的文档小得多。我会先检查一下POI是否是真正的问题。尝试在没有J2EE开销(单元测试)的情况下生成这些文档,并测量性能。您还可以监视J2EE服务器上的负载和内存使用情况,以查看问题是否来自某些次优的系统设置。

如果其他答案都不起作用,请查看Andy Khan的Jetcel是否会更好。我发现它在Java中处理Excel方面远远优于POI。

我比较了ApachePOI和JExcel库。JExcel似乎比Apache POI快4倍,但内存消耗似乎大致相同:

@Test
public void createJExcelWorkbook() throws Exception {
        WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls"));
        WritableSheet sheet = workbook.createSheet("sheet", 0); 
        for ( int i=0; i < 65535; i++) {
            for ( int j=0; j < 10; j++) {
                Label label = new Label(j, i, "some text " + i + " " + j);
                sheet.addCell(label);
            }
        }
        workbook.write();
        workbook.close();
}

@Test
public void createPoiWorkbook() throws Exception {
    Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("sheet");  
    for ( int i=0; i < 65535; i++) {
        Row row = sheet.createRow(i);
        for ( int j=0; j < 10; j++) {
            Cell cell = row.createCell(j);
             cell.setCellValue("some text " + i + " " + j);
        }
    }   
    FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls");
    wb.write(fileOut);
    fileOut.close();
}
@测试
public void createjexcel工作簿()引发异常{
WritableWorkbook=workbook.createWorkbook(新文件(“jexcel_workbook.xls”);
WritableSheet=workbook.createSheet(“工作表”,0);
对于(int i=0;i<65535;i++){
对于(int j=0;j<10;j++){
标签标签=新标签(j,i,“某些文本”+i+“”+j);
表。添加单元格(标签);
}
}
workbook.write();
workbook.close();
}
@试验
public void createPoiWorkbook()引发异常{
工作簿wb=新的HSSF工作簿();
工作表=wb.createSheet(“工作表”);
对于(int i=0;i<65535;i++){
Row Row=sheet.createRow(i);
对于(int j=0;j<10;j++){
Cell Cell=row.createCell(j);
cell.setCellValue(“某些文本”+i+“”+j);
}
}   
FileOutputStream fileOut=新的FileOutputStream(“poi_工作簿.xls”);
wb.写入(文件输出);
fileOut.close();
}
我已经用Jetcel2.6.12版和ApachePOI 3.7版对它进行了测试。您需要自己下载最新的库版本,并运行上面的简单测试以获得更准确的数字

<dependency org="org.apache.poi" name="poi" rev="3.7"/>
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/>


注意:Apache POI中每页有65535行的限制。

如果使用“流式”POI API而不是标准POI API,则使用POI编写大型文件的性能会大大降低。事实上,默认情况下,POI会将所有数据保存在内存中,然后在最后一次性写入所有数据。对于大文件来说,它的内存占用可能会大得离谱。相反,使用流式API,您可以控制内存的使用方式,并逐步将数据写入磁盘

要创建流式工作簿,请使用以下方法:

  SXSSFWorkbook book = new SXSSFWorkbook(); 
  book.setCompressTempFiles(true);

  SXSSFSheet sheet = (SXSSFSheet) book.createSheet();
  sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk
  // ...

使用国际字符会使处理速度变慢吗?还有一个问题,增加虚拟机内存如何提高性能?我不相信国际字符会使这种处理变得更慢:主要是数据量。至于VM可用堆,当所需的内存量接近可用堆时,垃圾收集器必须更频繁地启动:在极端情况下,大部分CPU时间用于垃圾收集。这是一种特殊情况:您不太可能受到它的显著影响。根据我的经验,POI有点慢,如果POI需要s*内存负载或需要关闭日志记录,那么它肯定**是一个POI问题。我们使用POI生成报告,一旦生成了多个电子表格,它就会变得非常缓慢。此外,30000行x10个单元对于每秒执行数十亿个周期的CPU来说,实际上是微不足道的数据量。所以,是的,POI是一个相当慢的API。@Gugussee:我想说,将30k行的持久性与CPU时钟进行比较有点误导。如果高效地使用大型电子表格是很容易的,那么这两个旗舰办公生产力套件就不会需要这么多工程师/年的时间来打破64k行的限制。@Gugusse,被接受的答案是阅读问题的人的一个指标,询问者认为什么是他/她的实际问题的正确答案。这是一条非常重要的信息。也就是说,你为什么不评论询问者需要提供一个显示所描述行为的最小代码片段呢?@Gugussee,他只是在猜测。实际原因可能是代码示例将立即显示的任何东西。建议您改进元警务是否合理?@Thorbjørn Ravn Andersen:建议您改进元警务是否合理?;)@Gugussee,我会考虑当你赶上我…行限制是Excel。XLS文件格式限制,而不是POI一。如果您使用.xlsx文件格式(使用ApachePOI中的XSSF),那么您可以创建更多的行。这对我的用例产生了巨大的影响。我有一个相对简单的表格,有45000行和20列,没有公式或奇特的格式。在我的生产虚拟机上运行时,最初需要不到2分钟的时间来生成。切换到流式工作簿后,时间缩短到6秒。哇!