使用sax解析大量的Excel数据

为什么要用sax解析excel文件呢?
先把其他几个简单的提一下,2003版的excel(.xls)文件咱们可以用HSSFWorkbook来读写。2007版的excel(.xlsx)文件咱们可以用XSSFWorkbook来读写。当然低内存高效写也可以使用SXSSF,SXSSF是内存中保留一定行数数据,超过行数,将索引最低的数据刷入硬盘。但是读文件时数据量级一提升,传统方式cpu消耗大而且容易内存溢出(OutOfMemoryError)。
这时候就需要咱们今天介绍的主角登场,基于事件驱动,SAX的方式解析excel,cup和内存消耗低(只读)。网上介绍原理和简单应用的博客有很多,随便看看其他博客就可以了解事件模式读取excel。我要说的是我在工作中运用遇到的问题以及对其他大佬博客当中一些介绍的更正。说到更正真的是火大,好几个博客都是大佬级别的排名,但是有些地方真不想说了,大家一定要养成看人家官方文档的习惯。
官方文档http://poi.apache.org/components/spreadsheet/how-to.html#XSSF+and+SAX+%28Event+API%29
可以看这个官方文档,也可以看其他人的博客,这一点有很多人讲(我今天要说的是比这个更完善的一版),实际上sax解析的核心就是自己写一个处理器。继承DefaultHandler 就行(DefaultHandler 实现的是ContentsHandler接口,等会儿提的完整版用到的处理器实现的是SheetContentsHandler接口),咱们写的处理器里面会依次调用startElement(),characters(),endElement。characters()方法要注意这个方法里面咱们new String(ch, start, length)得到的并不是单元格的值,得到的是得到单元格对应的索引值或是内容值,如果单元格类型是字符串、INLINESTR、数字、日期得到的是索引值,如果单元格类型是布尔值、错误、公式,则是内容值。得到索引值了再从SharedStringsTable(这个里面装的是所有sheet的字符串,共享的)里面根据索引取。SharedStringsTable这个在new咱们处理器的时候要传过去。但是要注意了这里面装了所有非数字的单元格。(重点说三遍非数字非数字非数字,啥子意思哇,就是咱们的处理器里面传了这个共享字符表,然后从里面取单元格值,但是数字给丢了,数字不在这个容器里面,言外之意咱们这一版只能处理非数字的excel文件,别抬杠你自己数字转字符串的不提,人家文档底下说的很清楚了,看我画出来的部分)在这里插入图片描述

数字也要能导入参考这篇官方文档https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java
当然小生不才,自己在工作中根据官方的代码稍作修改了点,为了贴合我的业务场景。以下就是我自己封装的工具类

package com.cqmc.cqiop.portal.autobusinessMg.util;


import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值