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文件介绍如何使 ...
随机推荐
- 网页一键加入QQ群
三步简单实现功能:网页提供加入qq群按钮 让他人一键加入qq群 第一步:进入qq群官网:http://qun.qq.com/join.html 第二步:选择需要加入的群并生成网页代码 第三步:在网页 ...
- 编码最佳实践——Liskov替换原则
Liskov替换原则(Liskov Substitution Principle)是一组用于创建继承层次结构的指导原则.按照Liskov替换原则创建的继承层次结构中,客户端代码能够放心的使用它的任意类 ...
- 【已解决】gradle project refresh failed:connection refused
git上clone一个Gradle项目,使用AS的gradle sync报错如下: Error:Connection refused (Connection refused) 原因:本地gradle版 ...
- python第八十四天---十五周作业
后台管理页面: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- Java设计模式之四 ----- 适配器模式和桥接模式
前言 在上一篇中我们学习了创建型模式的建造者模式和原型模式.本篇则来学习下结构型模式的适配器模式和桥接模式. 适配器模式 简介 适配器模式是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型 ...
- Axios发送请求时params和data的区别
在使用axios时,注意到配置选项中包含params和data两者,以为他们是相同的,实则不然. 因为params是添加到url的请求字符串中的,用于get请求. 而data是添加到请求体(body) ...
- ModelForm 中选择框的数据 以及 instance 参数
ModelForm 中选择框的数据 print(list(self.fields['customer'].choices)) # [('', '---------'), (1, '张飞'), (2, ...
- centos7下安装docker(7docker base command 命令词典)
上一章中我总结了学习docker 镜像时所用过的命令,今天先来将docker base command 记录一下,参考:https://docs.docker.com/edge/engine/refe ...
- 「SNOI2019」字符串
题目 看起来非常一眼啊,我们完全可以\(std::sort\)来解决这歌问题 于是现在的问题转化成了比较函数怎么写 随便画一下就会发现前面的好几位是一样的,后面的好几位也是一样,只需要比较中间的一段子 ...
- solidity return data和revert/require的reason string的获得
前言: 在使用solidity写智能合约的时候,会使用到revert和require来进行断言,比如: require(tokenOwner[tokenId] == 0x0,'this is not ...