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文件介绍如何使 ...
随机推荐
- pip install 报错
问题描述,在使用pip安装django相关软件包时,提示错误如下: [root@test4 install]# pip install django==1.6 Downloading/unpackin ...
- Vue Router滚动行为 scrollBehavior
滚动行为 使用前端路由,当切换到新路由时,想要页面滚动到顶部或者是保持原先的滚动位置,就像重新加载页面那样. vue-router能做到,而且更好,它让你可以自定义路由切换时页面如何滚动. 注意:这个 ...
- 我的Java之旅 第六课 JAVA WEB 请求与响应
一.有关URL编码 1.在URL的规范中定义了一些保留字符,如:: / ? & = @ % 等,在URI中有它的作用.如果要在URI中包含这些字符,必须转码,即%字符后跟十六进 ...
- Tomcat 8默认工具manager管理页面访问配置
Tomcat 8默认工具manager管理页面访问配置 1. 分配相关的角色权限 需要配置的配置文件是${catalina.home}/conf/tomcat-users.xml先给Tomcat访问相 ...
- 导入数据到MongoDB中
import sys import json import pymongo import datetime from pymongo import MongoClient client = Mongo ...
- 云卡门禁安卓SDK_BLEDOOR_SDK_ANDROID_2016_12_15
package com.bosk.bledoor.sdk; //sdk包的开门服务类,AndroidManifest.xml 必须注册 //<service //android:name=&qu ...
- 浅谈Java多线程同步机制之同步块(方法)——synchronized
在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: package com.jikexueyuan.t ...
- The packaging and installation process of Android programs
D:\android\adt-bundle-windows-x86-20131019\sdk\platform-tools工具的路径. 安卓工程经过eclipse编译然后通过aapt工具打包生成一个. ...
- [IDEA] IntelliJ IDEA 安装教程
原文地址:https://www.cnblogs.com/memento/p/9147477.html 下载地址:https://www.jetbrains.com/idea/ 本文以 64 位的 U ...
- 利用python实现简单词频统计、构建词云
1.利用jieba分词,排除停用词stopword之后,对文章中的词进行词频统计,并用matplotlib进行直方图展示 # coding: utf-8 import codecs import ma ...