excel解析内存溢出

03版本excel 与07版本excel 区别比较大,07版本excel最多能存储1048576行数据,如果用之前的方式解析可能会导致内存溢出,采用逐行方式读取能够解决内存问题

package excelReadUtil;



import org.apache.poi.openxml4j.opc.OPCPackage;

import org.apache.poi.xssf.eventusermodel.XSSFReader;

import org.apache.poi.xssf.model.SharedStringsTable;

import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import org.xml.sax.*;

import org.xml.sax.helpers.XMLReaderFactory;



import java.io.InputStream;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import org.xml.sax.helpers.DefaultHandler;



/**

 * Created by Administrator on 2016/11/2.

 */

public class ExcelReadUtil extends DefaultHandler {

    private SharedStringsTable sst;

    private String lastContents;

    private boolean nextIsString;

    private int sheetIndex = -1;

    private List<String> rowlist = new ArrayList<String>();

    private int curRow = 0;

    private int curCol = 0;



    /**

     * 读取第一个工作簿的入口方法

     * @param path

     */

    public void readFistSheet(String path) throws Exception {

        sheetIndex=0;

        OPCPackage pkg = OPCPackage.open(path);

        XSSFReader r = new XSSFReader(pkg);

        SharedStringsTable sst = r.getSharedStringsTable();

        XMLReader parser = fetchSheetParser(sst);

        InputStream sheet = r.getSheet("rId1");

        InputSource sheetSource = new InputSource(sheet);

        parser.parse(sheetSource);

        sheet.close();

    }

    /**

     * 读取所有工作簿的入口方法

     * @param path

     * @throws Exception

     */

    public void readAllSheet(String path) throws Exception {

        OPCPackage pkg = OPCPackage.open(path);

        XSSFReader r = new XSSFReader(pkg);

        SharedStringsTable sst = r.getSharedStringsTable();

        XMLReader parser = fetchSheetParser(sst);

        Iterator<InputStream> sheets = r.getSheetsData();

        while (sheets.hasNext()) {

            curRow = 0;

            sheetIndex++;

            InputStream sheet = sheets.next();

            InputSource sheetSource = new InputSource(sheet);

            parser.parse(sheetSource);

            sheet.close();

        }

    }



    /**

     * 该方法自动被调用,每读一行调用一次,在方法中写自己的业务逻辑即可

     * @param sheetIndex 工作簿序号

     * @param curRow 处理到第几行

     * @param rowList 当前数据行的数据集合

     */

    //int i=0;



    public void readOneRow(int sheetIndex, int curRow, List<String> rowList) {

        String temp = "";

        for(String str : rowList) {

            temp += str + "_";

        }

        System.out.println(temp);

    }





    public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {

        XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");

        this.sst = sst;

        parser.setContentHandler(this);

        return parser;

    }

    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {

        if (name.equals("c")) {// c => 单元格

            // 如果下一个元素是 SST 的索引,则将nextIsString标记为true

            String cellType = attributes.getValue("t");

            if (cellType != null && cellType.equals("s")) {

                nextIsString = true;

            } else {

                nextIsString = false;

            }

        }

        lastContents = "";// 置空

    }

    public void endElement(String uri, String localName, String name) throws SAXException {

        // 根据SST的索引值的到单元格的真正要存储的字符串

        // 这时characters()方法可能会被调用多次

        if (nextIsString) {

            try {

                int idx = Integer.parseInt(lastContents);

                lastContents = new XSSFRichTextString(sst.getEntryAt(idx))

                        .toString();

            } catch (Exception e) {



            }

        }

        // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引

        // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符

        if (name.equals("v")) {

            String value = lastContents.trim();

            value = value.equals("") ? " " : value;

            rowlist.add(curCol, value);

            curCol++;

        } else {

            // 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法

            if (name.equals("row")) {

                readOneRow(sheetIndex, curRow, rowlist);

                rowlist.clear();

                curRow++;

                curCol = 0;

            }

        }

    }

    public void characters(char[] ch, int start, int length)

            throws SAXException {

        // 得到单元格内容的值

        lastContents += new String(ch, start, length);

    }

}

pom.xml 依赖配置


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>



    <groupId>test</groupId>

    <artifactId>test</artifactId>

    <version>1.0-SNAPSHOT</version>



<dependencies>

    <!-- https://mvnrepository.com/artifact/xerces/xercesImpl -->

    <dependency>

        <groupId>xerces</groupId>

        <artifactId>xercesImpl</artifactId>

        <version>2.11.0</version>

    </dependency>



    <!--poi -->

    <dependency>

        <groupId>org.apache.poi</groupId>

        <artifactId>poi</artifactId>

        <version>3.10.1</version>

    </dependency>

    <dependency>

        <groupId>org.apache.poi</groupId>

        <artifactId>poi-ooxml</artifactId>

        <version>3.10.1</version>

    </dependency>

    <dependency>

        <groupId>junit</groupId>

        <artifactId>junit</artifactId>

        <version>4.11</version>

    </dependency>

</dependencies>

</project>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值