当前位置 : 首页 » 文章分类 :  开发  »  Apache-POI

Apache-POI

Apache POI 操作Excel表格笔记


SXSSFWorkbook 处理超大Excel

POI提供了SXSSF的方式可以流式的创建十分大的xlsx文件,SXSSF使用了window的概念,如果数据行已经超出window的范围,那么就无法修改其内容。
这个窗口的大小可以在构造函数中设定new SXSSFWorkbook(int windowSize) 也可以在sheet中设定SXSSFSheet#setRandomAccessWindowSize(int windowSize),其默认值为SXSSFWorkbook.DEFAULT_WINDOW_SIZE(100)。
还要注意SXSSF会创建一些临时文件这个需要在finally中显示地通过调用dispose方法清除,而且临时文件也占用一定硬盘,可以通过wb.setCompressTempFiles(true)设置workbook的临时文件使用压缩来减少硬盘占用。

POI-处理大EXCEL文件(XLSX写)
https://www.cnblogs.com/resentment/p/6414210.html


HSSFWorkbook/XSSFWorkbook/SXSSFWorkbook 区别

用JavaPOI导出Excel时,我们会考虑到Excel版本及数据量的问题。针对不同的Excel版本,要采用不同的工具类。

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;

XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx;

对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,会提示如下错误信息。
org.apache.poi.openxml4j.exceptions.InvalidOperationException
org.apache.poi.poifs.filesystem.OfficeXmlFileException

SXSSFWorkbook
从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的API——SXSSFWorkbook

当数据量超出65536条后,在使用HSSFWorkbook或XSSFWorkbook,程序会报OutOfMemoryError:Javaheap space;内存溢出错误。这时应该用 SXSSFWorkbook

Java基础——HSSFworkbook,XSSFworkbook,SXSSFworkbook区别简述
https://blog.csdn.net/qq_34869143/article/details/76512289


SXSSFSheet有数据但getLastRowNum值为0问题

问题:
SXSSFWorkbook 的 sheet[0] 中第一行有标题行数据,但是用getRow()方法取到的Row却为null,或者sheet.getLastRowNum()返回0

原因:
不能使用SXSSFWorkbook读取excel数据,要用XSSFWorkbook读取数据!
SXSSFWorkBook is write only, it doesn’t support reading

SXSSF可以解决写大文件的问题,但是无法进行修改文件原有的内容,也不支持读源文件。如果需要,可以结合之前的读大文件,然后将读到的内容通过SXSSF写入新的文件,来达到类似修改的操作。

Sheet sheet = wb.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum(); // 结果是 0
Row row = sheet.getRow(0); // 结果是 null

官方文档在 SXSSFWorkbook 的构造方法中明确说了 不支持访问和修改已有的行
public SXSSFWorkbook(XSSFWorkbook workbook)
Construct a workbook from a template.

There are three use-cases to use SXSSFWorkbook(XSSFWorkbook) :

  • Append new sheets to existing workbooks. You can open existing workbook from a file or create on the fly with XSSF.
  • Append rows to existing sheets. The row number MUST be greater than max(rownum) in the template sheet.
  • Use existing workbook as a template and re-use global objects such as cell styles, formats, images, etc.

All three use cases can work in a combination.

What is not supported:

  • Access initial cells and rows in the template. After constructing all internal windows are empty and SXSSFSheet.getRow(int) and SXSSFRow.getCell(int) return null.
  • Override existing cells and rows. The API silently allows that but the output file is invalid and Excel cannot read it.

https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/streaming/SXSSFWorkbook.html#SXSSFWorkbook-org.apache.poi.xssf.usermodel.XSSFWorkbook-

之前我想写一个这样的方法,将rows写入一个已存在的 SXSSFWorkbook ,方法里面先调用 getLastRowNum() 来获取表格中已有的行数,好多情况下获取不到或不准,现在知道了不能这样写,应该用一个全局变量保存已写入的行数。

/**
 * 将行数据写入Workbook
 * @param wb
 * @param rows
 * @return
 */
private void writeToWorkbook(Workbook wb, List<List<String>> rows) {
    // 获取sheet
    Sheet sheet = wb.getSheetAt(0);
    int lastRowNum = sheet.getLastRowNum(); //经常为0

    // 写入excel
    for (int i = 0, rowCount = rows.size(); i < rowCount; i++) {
        Row row = sheet.createRow(lastRowNum++);
        List<String> rowData = rows.get(i);
        for (int j = 0, colCount = rowData.size(); j < colCount; j++) {
            logger.info(rowData.get(j));
            row.createCell(j).setCellValue(rowData.get(j));
        }
    }
}

改成下面这样写就好了,多一个起始行数参数:

/**
 * 将行数据写入Workbook
 * @param wb
 * @param lastRowNum wb中已有行数
 * @param rows
 */
private int writeToWorkbook(Workbook wb, int lastRowNum, List<List<String>> rows) {
    // 获取sheet
    Sheet sheet = wb.getSheetAt(0);

    // 写入excel
    for (int i = 0, rowCount = rows.size(); i < rowCount; i++) {
        Row row = sheet.createRow(lastRowNum++);
        List<String> rowData = rows.get(i);
        for (int j = 0, colCount = rowData.size(); j < colCount; j++) {
            logger.info(rowData.get(j));
            row.createCell(j).setCellValue(rowData.get(j));
        }
    }
    return lastRowNum;
}

POI-处理大EXCEL文件(XLSX写)
https://www.cnblogs.com/resentment/p/6414210.html

Read xlsx file with POI (SXSSFWorkbook)
https://stackoverflow.com/questions/13873489/read-xlsx-file-with-poi-sxssfworkbook

Reading data from xlsx with Apache POI’s SXSSFSheet
https://stackoverflow.com/questions/12513981/reading-data-from-xlsx-with-apache-pois-sxssfsheet

Apache POI getRow() returns null and .createRow fails
https://stackoverflow.com/questions/30868325/apache-poi-getrow-returns-null-and-createrow-fails

SXSSFWorkbook XSSFWorkbook 我所遇到的坑大集合,希望能帮助更多的人。
https://blog.csdn.net/qq_31615049/article/details/82228812

使用poi读取excel时,getRow()方法返回null
https://www.cnblogs.com/study-room/p/5459363.html

SXSSFSheet对象调用getLastRowNum的问题
https://blog.csdn.net/zc123456zzc/article/details/47301461


常用类

Class XSSFWorkbook
https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFWorkbook.html

Class SXSSFWorkbook
https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/streaming/SXSSFWorkbook.html

Class SXSSFSheet
https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/streaming/SXSSFSheet.html


上一篇 Java-File

下一篇 Apache-Curator

阅读
1,200
阅读预计6分钟
创建日期 2019-01-02
修改日期 2019-01-05
类别
百度推荐