POI Sax 事件驱动解析Excel2003文件
POI事件驱动解析Excel文件
package com.boguan.bte.util.excel; import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import com.boguan.bte.service.common.IExcelRowReader; /**
* 名称: ExcelXlsReader.java<br>
* 描述: <br>
* 类型: JAVA<br>
* 最近修改时间:2016年7月5日 上午10:00:32<br>
*
* @since 2016年7月5日
* @author “”
*/
public class ExcelXlsReader implements HSSFListener { private int minColumns = -1; private POIFSFileSystem fs; private int lastRowNumber; private int lastColumnNumber; /** Should we output the formula, or the value it has? */
private boolean outputFormulaValues = true; /** For parsing Formulas */
private SheetRecordCollectingListener workbookBuildingListener; // excel2003工作薄
private HSSFWorkbook stubWorkbook; // Records we pick up as we process
private SSTRecord sstRecord; private FormatTrackingHSSFListener formatListener; // 表索引
private int sheetIndex = -1; private BoundSheetRecord[] orderedBSRs; @SuppressWarnings("unchecked")
private ArrayList boundSheetRecords = new ArrayList(); // For handling formulas with string results
private int nextRow; private int nextColumn; private boolean outputNextStringRecord; // 当前行
private int curRow = 0; // 存储行记录的容器
private List<String> rowlist = new ArrayList<String>();; @SuppressWarnings("unused")
private String sheetName; private IExcelRowReader rowReader; public void setRowReader(IExcelRowReader rowReader) {
this.rowReader = rowReader;
} /**
* 遍历excel下所有的sheet
*
* @throws IOException
*/
public void process(String fileName) throws IOException {
this.fs = new POIFSFileSystem(new FileInputStream(fileName));
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
formatListener = new FormatTrackingHSSFListener(listener);
HSSFEventFactory factory = new HSSFEventFactory();
HSSFRequest request = new HSSFRequest();
if (outputFormulaValues) {
request.addListenerForAllRecords(formatListener);
} else {
workbookBuildingListener = new SheetRecordCollectingListener(formatListener);
request.addListenerForAllRecords(workbookBuildingListener);
}
factory.processWorkbookEvents(request, fs);
} /**
* HSSFListener 监听方法,处理 Record
*/
@SuppressWarnings("unchecked")
public void processRecord(Record record) {
int thisRow = -1;
int thisColumn = -1;
String thisStr = null;
String value = null;
switch (record.getSid()) {
case BoundSheetRecord.sid:
boundSheetRecords.add(record);
break;
case BOFRecord.sid:
BOFRecord br = (BOFRecord) record;
if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
// 如果有需要,则建立子工作薄
if (workbookBuildingListener != null && stubWorkbook == null) {
stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
} sheetIndex++;
if (orderedBSRs == null) {
orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
sheetName = orderedBSRs[sheetIndex].getSheetname();
}
break; case SSTRecord.sid:
sstRecord = (SSTRecord) record;
break; case BlankRecord.sid:
BlankRecord brec = (BlankRecord) record;
thisRow = brec.getRow();
thisColumn = brec.getColumn();
thisStr = "";
rowlist.add(thisColumn, thisStr);
break;
case BoolErrRecord.sid: // 单元格为布尔类型
BoolErrRecord berec = (BoolErrRecord) record;
thisRow = berec.getRow();
thisColumn = berec.getColumn();
thisStr = berec.getBooleanValue() + "";
rowlist.add(thisColumn, thisStr);
break; case FormulaRecord.sid: // 单元格为公式类型
FormulaRecord frec = (FormulaRecord) record;
thisRow = frec.getRow();
thisColumn = frec.getColumn();
if (outputFormulaValues) {
if (Double.isNaN(frec.getValue())) {
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
nextRow = frec.getRow();
nextColumn = frec.getColumn();
} else {
thisStr = formatListener.formatNumberDateCell(frec);
}
} else {
thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';
}
rowlist.add(thisColumn, thisStr);
break;
case StringRecord.sid:// 单元格中公式的字符串
if (outputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord) record;
thisStr = srec.getString();
thisRow = nextRow;
thisColumn = nextColumn;
outputNextStringRecord = false;
}
break;
case LabelRecord.sid:
LabelRecord lrec = (LabelRecord) record;
curRow = thisRow = lrec.getRow();
thisColumn = lrec.getColumn();
value = lrec.getValue().trim();
value = value.equals("") ? " " : value;
this.rowlist.add(thisColumn, value);
break;
case LabelSSTRecord.sid: // 单元格为字符串类型
LabelSSTRecord lsrec = (LabelSSTRecord) record;
curRow = thisRow = lsrec.getRow();
thisColumn = lsrec.getColumn();
if (sstRecord == null) {
rowlist.add(thisColumn, " ");
} else {
value = sstRecord.getString(lsrec.getSSTIndex()).toString().trim();
value = value.equals("") ? " " : value;
rowlist.add(thisColumn, value);
}
break;
case NumberRecord.sid: // 单元格为数字类型
NumberRecord numrec = (NumberRecord) record;
curRow = thisRow = numrec.getRow();
thisColumn = numrec.getColumn();
value = formatListener.formatNumberDateCell(numrec).trim();
value = value.equals("") ? " " : value;
// 向容器加入列值
rowlist.add(thisColumn, value);
break;
default:
break;
} // 遇到新行的操作
if (thisRow != -1 && thisRow != lastRowNumber) {
lastColumnNumber = -1;
} // 空值的操作
if (record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
curRow = thisRow = mc.getRow();
thisColumn = mc.getColumn();
rowlist.add(thisColumn, " ");
} // 更新行和列的值
if (thisRow > -1)
lastRowNumber = thisRow;
if (thisColumn > -1)
lastColumnNumber = thisColumn; // 行结束时的操作
if (record instanceof LastCellOfRowDummyRecord) {
if (minColumns > 0) {
// 列值重新置空
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
}
}
lastColumnNumber = -1; // 每行结束时, 调用getRows() 方法
rowReader.getRows(sheetIndex, curRow, rowlist);
// 清空容器
rowlist.clear();
}
}
public static void main(String[] args) {
IExcelRowReader rowReader = new ExcelRowReader();
try {
// ExcelReaderUtil.readExcel(rowReader,
// "E://2016-07-04-011940a.xls");
System.out.println("**********************************************");
ExcelReaderUtil.readExcel(rowReader, "E://test.xlsx");
} catch (Exception e) {
e.printStackTrace();
}
}
}
辅助类ExcelReaderUtil:
package com.boguan.bte.util.excel; import com.boguan.bte.service.common.IExcelRowReader;
import com.boguan.bte.service.common.impl.ExcelRowReader; /**
* 名称: ExcelReaderUtil.java<br>
* 描述: <br>
* 类型: JAVA<br>
* 最近修改时间:2016年7月5日 上午10:10:20<br>
*
* @since 2016年7月5日
* @author “”
*/
public class ExcelReaderUtil {
// excel2003扩展名
public static final String EXCEL03_EXTENSION = ".xls";
// excel2007扩展名
public static final String EXCEL07_EXTENSION = ".xlsx"; /**
* 读取Excel文件,可能是03也可能是07版本
*
* @param excel03
* @param excel07
* @param fileName
* @throws Exception
*/
public static void readExcel(IExcelRowReader reader, String fileName) throws Exception {
// 处理excel2003文件
if (fileName.endsWith(EXCEL03_EXTENSION)) {
ExcelXlsReader exceXls = new ExcelXlsReader();
exceXls.setRowReader(reader);
exceXls.process(fileName);
// 处理excel2007文件
} else if (fileName.endsWith(EXCEL07_EXTENSION)) {
ExcelXlsxReader exceXlsx = new ExcelXlsxReader();
exceXlsx.setRowReader(reader);
exceXlsx.process(fileName);
} else {
throw new Exception("文件格式错误,fileName的扩展名只能是xls或xlsx。");
}
} /**
* 测试
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
IExcelRowReader rowReader = new ExcelRowReader();
ExcelReaderUtil.readExcel(rowReader, "E://test.xls");
}
}
package com.boguan.bte.service.common; import java.util.List; /**
* 名称: IRowReader.java<br>
* 描述: <br>
* 类型: JAVA<br>
* 最近修改时间:2016年7月5日 上午10:28:06<br>
*
* @since 2016年7月5日
* @author “”
*/
public interface IExcelRowReader {
/**
* 业务逻辑实现方法
*
* @param sheetIndex
* @param curRow
* @param rowlist
*/
void getRows(int sheetIndex, int curRow, List<String> rowlist);
}
package com.boguan.bte.service.common.impl; import java.util.List; import com.boguan.bte.service.common.IExcelRowReader; /**
* 名称: ExcelRowReader.java<br>
* 描述: <br>
* 类型: JAVA<br>
* 最近修改时间:2016年7月5日 上午10:30:11<br>
*
* @since 2016年7月5日
* @author “”
*/
public class ExcelRowReader implements IExcelRowReader { @Override
public void getRows(int sheetIndex, int curRow, List<String> rowlist) {
System.out.print(curRow+" ");
for (int i = 0; i < rowlist.size(); i++) {
System.out.print(rowlist.get(i)==""?"*":rowlist.get(i) + " ");
}
System.out.println();
} }
POI Sax 事件驱动解析Excel2003文件的更多相关文章
- POI Sax 事件驱动解析Excel2007文件
Excel2007版本的代码如下,本文主要是用于POI解析大文件Excel容易出现内存溢出的现象而提出解决方案,故此解决了大数据量的Excel文件解析的难度,在此拿出来贡献给大家,谢谢! 里面用到的相 ...
- 用JAXP的SAX方式解析XML文件
简单用JAXP的SAX方式(事件驱动)解析XML文件: 文件(1.XML) <?xml version="1.0" encoding="UTF-8" st ...
- SAX方式解析XML文件实例
books.XML文件: 书籍book.java实体类: public class Book { private String id; private String name; private Str ...
- 【Java】使用Apache POI生成和解析Excel文件
概述 Excel是我们平时工作中比较常用的用于存储二维表数据的,JAVA也可以直接对Excel进行操作,分别有jxl和poi,2种方式. HSSF is the POI Project's pure ...
- 【Java POI】POI基于事件驱动解析大数据量2007版本Excel,空值导致列错位问题
1.目前测试了20M的文件,可以读取. 2.支持单个工作表1万+的数据行数,耗时如图. 3.以下是关键地方处理的代码 //Accepts objects needed while parsing. / ...
- 使用(POI)SAX处理Excel大文件,防止内存溢出
POISAXReader h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-chi ...
- Java&Xml教程(五)使用SAX方式解析XML文件
Java SAX解析机制为我们提供了一系列的API来处理XML文件,SAX解析和DOM解析方式不太一样,它并不是將XML文件内容一次性全部加载,而是连续的部分加载. javax.xml.parsers ...
- 使用SAX方式解析XML文件
package com.pingyijinren.test; import android.util.Log; import org.xml.sax.Attributes; import org.xm ...
- JAVA使用SAX解析XML文件
在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...
随机推荐
- springcloud 入门 10 (eureka高可用)
eureka高可用: 说白了,就是加一个实例作为原实例的备份,然后一起对外提供服务.这样可以保证在一台机器宕机的时候,整个系统不会死掉.保证其继续对外服务. eureka的集群化: 服务注册中心Eur ...
- lombok的简单介绍(1)
一.项目背景 在写Java程序的时候经常会遇到如下情形: 新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法 lombok项目的产生就是为了省 ...
- sql server系统表和视图相关的语句
一.系统表 数据字典的详细信息请查SQL SERVER BOL,这里仅列出一部分. 1.1.sysservers 1.查看所有本地服务器及链接服务器 select * from master..sys ...
- linux查找某段时间修改的文件的总大小
1.统计 2017-10-25 16:30:00 至 2017-10-25 19:30:00 修改的文件的总大小 b= for i in `find -type f \( -newermt '2017 ...
- Go语言学习笔记(一)Let's 干吧
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 简介 Go是Google开发的一种 静态强类型.编译型,并发型,并具有垃圾回收功能的编程语言.为了方便搜索 ...
- ubuntu16.04系统彻底卸载mysql,并源码免编译重装MySQL的步骤
今天的总结 ubuntu上彻底卸载MySQL或重新安装 https://www.jianshu.com/p/974b33873bca #查看是否存在mysql服务 service mysql stat ...
- 04LaTeX学习系列之---overleafz在线编辑平台的使用
目录 目录 前言 (一)overleaf的认识 1.由来: 2.优点: 3.界面: (二)编译与查看 1.选择编译器 2.编译 (三)基本的设置与操作 1.基本设置 2.基本操作 目录 本系列是有关L ...
- Linux 小知识翻译 - 「架构 续」(arch)
上次,从「计算机的内部构造」的角度解释了架构这个术语.这次,介绍下架构中经常提到的「i386架构」及之后的「i486」,「i586」. 安装Linux的时候,很多人即使不了解但也会经常听到i386架构 ...
- January 25th, 2018 Week 04th Thursday
What made something precious? Losing it and finding it. 一件东西怎样才会变得珍贵无比?先弄丢了它,然后又找到了. A short time ag ...
- Alpha版本 - 展示博客
Alpha版本 - 展示博客 S.W.S.D 成员简介 演示动态图 注册 登录 新建记录 分享记录 修改主页时间查看记录 文章模块 流星模块 修改用户信息(以头像为例) 用户使用概况 预期的典型用户 ...