使用事件模式(Event API)读取Excel2007(.xlsx)文件
2021-01-21 01:16
标签:定位 get 文本 erro uri printf 不能 set img POI的事件模式占用内存更小,它利用基础的XML数据进行处理,适用于愿意学习.xlsx文件结构以及在java中处理XML的开发人员;也能有效预防出现java.lang.OutOfMemoryError: GC overhead limit exceeded问题。 重点备注信息:如下图所示,所有的信息都是在 ```java public class POIEventModelUtil { } class Myhandler extends DefaultHandler { } POI事件模式指北(二)-Excel2007 使用事件模式(Event API)读取Excel2007(.xlsx)文件 标签:定位 get 文本 erro uri printf 不能 set img 原文地址:https://www.cnblogs.com/xiaoBlog2016/p/12114832.html1.了解下Excel文件的XML结构
1.1、了解文件结构之前先来看一下准备的文件,这个文件只有一个sheet页,结构也很简单。
1.2、Excel2007是用XMl格式储存,将要读取的文件后缀名改为.zip或者直接用解压缩工具打开,就可以看到这个Excel文件的结构
1.3、[Content_Types].xml文件描述了整个Excel文件的结构,也将根据这个文件组织后面的读取工作
1.4、xl文件夹包括了需要的数据和格式信息,是重点关注的对象
1.5、workbook.xml重点关注的就是sheets和sheet两个标签
重点备注信息:r:id="rId3"是获取数据关键
1.6、一般一个Excel文件有几个sheet页,就会有几个XML文件与之对应。其中sheet页和xml文件就是根据【新建 Microsoft Excel 工作表xl_relsworkbook.xml.rels】文件对应起来的
.读取.xlsx文件实例(java代码)
import com.inspur.evaluation.message.consume.receive.utils.StringHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.util.IOUtils;
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.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.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;public static void main(String[] args) throws Exception {
OPCPackage pkg = OPCPackage.open("E:/ceshi/广州市评价详情明细数据20191105.xlsx", PackageAccess.READ);
XSSFReader r = new XSSFReader(pkg);
//根据workbook.xml中r:id的值获得流
InputStream is = r.getSheet("rId3");
//debug 查看转换的xml原始文件,方便理解后面解析时的处理,
byte[] isBytes = IOUtils.toByteArray(is);
//读取流,查看文件内容
streamOut(new ByteArrayInputStream(isBytes));
//下面是SST 的索引会用到的
SharedStringsTable sst = r.getSharedStringsTable();
System.out.println("excel的共享字符表sst------------------start");
sst.writeTo(System.out);
System.out.println();
System.out.println("excel的共享字符表sst------------------end");
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
List
> container = new ArrayList();
parser.setContentHandler(new Myhandler(sst, container));
InputSource inputSource = new InputSource(new ByteArrayInputStream(isBytes));
parser.parse(inputSource);
is.close();
printContainer(container);
}
/**
* 输出获得excel内容
* @param container
*/
public static void printContainer(List
> container) {
System.out.println("excel内容------------- -start");
for (List
//取SST 的索引对应的值
private SharedStringsTable sst;
public void setSst(SharedStringsTable sst) {
this.sst = sst;
}
//解析结果保存
private List
> container;
public Myhandler(SharedStringsTable sst, List
> container) {
this.sst = sst;
this.container = container;
}
/**
* 存储cell标签下v标签包裹的字符文本内容
* 在v标签开始后,解析器自动调用characters()保存到 lastContents
* 【但】当cell标签的属性 s是 t时, 表示取到的lastContents是 SharedStringsTable 的index值
* 需要在v标签结束时根据 index(lastContents)获取一次真正的值
*/
private String lastContents;
//有效数据矩形区域,A1:Y2
private String dimension;
//根据dimension得出每行的数据长度
private int longest;
//上个有内容的单元格id,判断空单元格
private String lastCellid;
//上一行id, 判断空行
private String lastRowid;
// 判断单元格cell的c标签下是否有v,否则可能数据错位
private boolean hasV = false;
//行数据保存
private List
本文出自以下文章,
文章标题:使用事件模式(Event API)读取Excel2007(.xlsx)文件
文章链接:http://soscw.com/index.php/essay/44800.html