excel文件导入,采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题

这篇博客介绍了如何通过采用SAX事件驱动模式来读取XLSX文件,以此解决POI用户模式下可能出现的内存溢出问题。博主详细列出了所需导入的包和针对不同版本Excel的读取类,强调了这种模式是POI官方推荐处理大数据的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POI读取excel有两种模式,一种是用户模式,一种是事件驱动模式
采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题,该模式是POI官方推荐的读取大数据的模式

需要导入的包:
 <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
      <version>2.11.0</version>
      </dependency>
    <dependency>
<dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.8.1</version>
    </dependency>
读取文件类:

import java.util.List;

/**
 *  读取excel文件类,采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题;
 *
 * @author
 * @create
 * @desc
 **/
public class ExcelReaderUtil {
    //excel2003扩展名
    public static final String EXCEL03_EXTENSION = ".xls";
    //excel2007扩展名
    public static final String EXCEL07_EXTENSION = ".xlsx";


    /**
     * 每获取一条记录,即打印
     * 在flume里每获取一条记录即发送,而不必缓存起来,可以大大减少内存的消耗,这里主要是针对flume读取大数据量excel来说的
     * @param filePath  访问文件所处路径
     * @param sheetName  当前页名称
     * @param sheetIndex  当前是第几页
     * @param curRow     第多少行
     * @param cellList   当前行的单元格数组
     */
    public static void sendRows(String filePath, String sheetName, int sheetIndex, int curRow, List<String> cellList) {
        StringBuffer oneLineSb = new StringBuffer();
        oneLineSb.append(filePath);
        oneLineSb.append("--");
        oneLineSb.append("sheet" + sheetIndex);
        oneLineSb.append("::" + sheetName);//加上sheet名
        oneLineSb.append("--");
        oneLineSb.append("row" + curRow);
        oneLineSb.append("::");

       // map.put(cellList.get(9),cellList.get(0)) ;

        for (String cell : cellList) {
            oneLineSb.append(cell.trim());
            oneLineSb.append("|");
        }
        String oneLine = oneLineSb.toString();
        if (oneLine.endsWith("|")) {
            oneLine = oneLine.substring(0, oneLine.lastIndexOf("|"));
        }// 去除最后一个分隔符

        System.out.println(oneLine);
    }

    /**
     * 读取excel文件路径
     * @param fileName 文件路径
     * @throws Exception
     */
    public static void readExcel(String fileName) throws Exception {
        int totalRows =0;
        if (fileName.endsWith(EXCEL03_EXTENSION)) { //处理excel2003文件
            ExcelXlsxReader excelXls=new ExcelXlsxReader();
            totalRows =excelXls.process(fileName);
        } else if (fileName.endsWith(EXCEL07_EXTENSION)) {//处理excel2007文件
            ExcelXlsxReader excelXlsxReader = new ExcelXlsxReader();
            totalRows = excelXlsxReader.process(fileName);
            System.out.println("******"+excelXlsxReader.map.size());
            System.out.println("******"+excelXlsxReader.map.get(""));
        } else {
            throw new Exception("文件格式错误,fileName的扩展名只能是xls或xlsx。");
        }
        System.out.println("发送的总行数:" + totalRows);
    }

    public static void main(String[] args) throws Exception {
        String path="E:/resource/2.xlsx";
        ExcelReaderUtil.readExcel(path);
        //System.out.println(excelReaderUtil.map.size());
    }
}

xlsx2007版本:

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author y
 * @create 2018-01-18 14:28
 * @desc POI读取excel有两种模式,一种是用户模式,一种是事件驱动模式
 * 采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题,
 * 该模式是POI官方推荐的读取大数据的模式,
 * 在用户模式下,数据量较大,Sheet较多,或者是有很多无用的空行的情况下,容易出现内存溢出
 * <p>
     * 用于解决.xlsx2007版本大数据量问题
 **/
public class ExcelXlsxReader extends DefaultHandler {

    /**
     * 自定义获取表格某些信息
     */
    public Map map = new TreeMap<String,String>();
    /**
     * 单元格中的数据可能的数据类型
     */
    enum CellDataType {
        BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL
    }

    /**
     * 共享字符串表
     */
    private SharedStringsTable sst;

    /**
     * 上一次的索引值
     */
    private String lastIndex;

    /**
     * 文件的绝对路径
     */
    private String filePath = "";

    /**
     * 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值