目标:读取execl的第一个sheet,并传入不需要读取的表头的行数,返回该execl里所有数据的list

解析共有2种:1、DOM      2、SAX

 import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
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.ContentHandler;
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; /**
* 基于XSSF and SAX (Event API)
* 读取excel的第一个Sheet的内容
* @author yzl
*
*/
public class ReadExcelUtils {
private int headCount = 0;
private List<List<String>> list = new ArrayList<List<String>>();
private static final Log log = LogFactory.getLog(ReadExcelUtils.class); /**
* 通过文件流构建DOM进行解析
* @param ins
* @param headRowCount 跳过读取的表头的行数
* @return
* @throws InvalidFormatException
* @throws IOException
*/
public List<List<String>> processDOMReadSheet(InputStream ins,int headRowCount) throws InvalidFormatException, IOException {
Workbook workbook = WorkbookFactory.create(ins);
return this.processDOMRead(workbook, headRowCount);
} /**
* 采用DOM的形式进行解析
* @param filename
* @param headRowCount 跳过读取的表头的行数
* @return
* @throws IOException
* @throws InvalidFormatException
* @throws Exception
*/
public List<List<String>> processDOMReadSheet(String filename,int headRowCount) throws InvalidFormatException, IOException {
Workbook workbook = WorkbookFactory.create(new File(filename));
return this.processDOMRead(workbook, headRowCount);
} /**
* 采用SAX进行解析
* @param filename
* @param headRowCount
* @return
* @throws OpenXML4JException
* @throws IOException
* @throws SAXException
* @throws Exception
*/
public List<List<String>> processSAXReadSheet(String filename,int headRowCount) throws IOException, OpenXML4JException, SAXException {
headCount = headRowCount; OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst); Iterator<InputStream> sheets = r.getSheetsData();
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close(); log.debug("时间:"+DateUtils.getNowTime()+",共读取了execl的记录数为 :"+list.size()); return list;
} private XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser"
);
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;
} /**
* SAX 解析excel
*/
private class SheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private boolean isNullCell;
//读取行的索引
private int rowIndex = 0;
//是否重新开始了一行
private boolean curRow = false;
private List<String> rowContent; private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
} public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
//节点的类型
//System.out.println("---------begin:" + name);
if(name.equals("row")){
rowIndex++;
}
//表头的行直接跳过
if(rowIndex > headCount){
curRow = true;
// c => cell
if(name.equals("c")) {
String cellType = attributes.getValue("t");
if(null == cellType){
isNullCell = true;
}else{
if(cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
isNullCell = false;
}
}
// Clear contents cache
lastContents = "";
}
} public void endElement(String uri, String localName, String name)
throws SAXException {
//System.out.println("-------end:"+name);
if(rowIndex > headCount){
if(nextIsString) {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
nextIsString = false;
}
if(name.equals("v")) {
//System.out.println(lastContents);
if(curRow){
//是新行则new一行的对象来保存一行的值
if(null==rowContent){
rowContent = new ArrayList<String>();
}
rowContent.add(lastContents);
}
}else if(name.equals("c") && isNullCell){
if(curRow){
//是新行则new一行的对象来保存一行的值
if(null==rowContent){
rowContent = new ArrayList<String>();
}
rowContent.add(null);
}
} isNullCell = false; if("row".equals(name)){
list.add(rowContent);
curRow = false;
rowContent = null;
}
} } public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
}
} /**
* DOM的形式解析execl
* @param workbook
* @param headRowCount
* @return
* @throws InvalidFormatException
* @throws IOException
*/
private List<List<String>> processDOMRead(Workbook workbook,int headRowCount) throws InvalidFormatException, IOException {
headCount = headRowCount; Sheet sheet = workbook.getSheetAt(0);
//行数
int endRowIndex = sheet.getLastRowNum(); Row row = null;
List<String> rowList = null; for(int i=headCount; i<=endRowIndex; i++){
rowList = new ArrayList<String>();
row = sheet.getRow(i);
for(int j=0; j<row.getLastCellNum();j++){
if(null==row.getCell(j)){
rowList.add(null);
continue;
}
int dataType = row.getCell(j).getCellType();
if(dataType == Cell.CELL_TYPE_NUMERIC){
DecimalFormat df = new DecimalFormat("0.####################");
rowList.add(df.format(row.getCell(j).getNumericCellValue()));
}else if(dataType == Cell.CELL_TYPE_BLANK){
rowList.add(null);
}else if(dataType == Cell.CELL_TYPE_ERROR){
rowList.add(null);
}else{
//这里的去空格根据自己的情况判断
String valString = row.getCell(j).getStringCellValue();
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(valString);
valString = m.replaceAll("");
//去掉狗日的不知道是啥东西的空格
if(valString.indexOf(" ")!=-1){
valString = valString.substring(0, valString.indexOf(" "));
} rowList.add(valString);
}
} list.add(rowList);
}
log.debug("时间:"+DateUtils.getNowTime()+",共读取了execl的记录数为 :"+list.size()); return list;
} @SuppressWarnings("unused")
public static void main(String[] args) throws Exception {
ReadExcelUtils howto = new ReadExcelUtils();
String fileName = "f:/test.xlsx";
List<List<String>> list = howto.processSAXReadSheet(fileName,2); ReadExcelUtils h = new ReadExcelUtils();
String fileName1 = "f:/test.xls";
List<List<String>> result = h.processDOMReadSheet(fileName1,2);
}
}

自己写的一个读取execl的帮助类的更多相关文章

  1. 自己写了一个mysql连接的工具类【java】

    要用的话,包名自己可以改一下: package com.usa3v.dreamcenter.util; import java.sql.Connection; import java.sql.Driv ...

  2. Java读取Execl表格数据

    在前面提到用java代码新建一个Execl 表格并添加数据到表格中, 这次写了一个读取Execl表格数据并添加导数据库中的案列 给定对方一个Execl模板表格,如果导入的Execl表格和预订的表格不相 ...

  3. 我写的一个ExcelHelper通用类,可用于读取或生成数据

    读取或生成EXCEL数据的方法有很多,一般常见的有: 1.通过OFFICE EXCEL组件,优点:读取与生成EXCEL文件方便,缺点:服务器上必须安装OFFICE软件,且进程无法及时释放 2.通过第三 ...

  4. 读取Execl表 导入数据库

    不知不觉博客园园林都两年多了,我是今年毕业的应届生,最近公司项目需要改动,很多的数据需要导入,很多的实体类需要些.考虑到这些问题自己写了两个winform版的小工具,一个是读取Execl数据导入数据库 ...

  5. C# winfrom 写的一个搜索助手,可以按照标题和内容搜索,支持doc,xls,ppt,pdf,txt等格式的文件搜索

    C# winfrom 写的一个搜索助手,可以按照标题和内容搜索,指定目录后,遍历搜索文件和子目,现在只写了支持.DOC.DOCX.XLS.XLSX.PPT.PPTX.PDF.HTML.HTM.TXT等 ...

  6. 读取Execl表数据 导入数据库

    不知不觉博客园园林都两年多了,我是今年毕业的应届生,最近公司项目需要改动,很多的数据需要导入,很多的实体类需要些.考虑到这些问题自己写了两个winform版的小工具,一个是读取Execl数据导入数据库 ...

  7. 51单片机实现对24C02进行页写、顺序读取并显示验证

    //************************************************************************************* //**程序名称:51单 ...

  8. 师兄写的一个JAVA播放器的源代码(转)

    师兄写的一个JAVA播放器的源代码 MediaPlayer.java------------------------------------------------------------------ ...

  9. 实现一个最简单的VIM文本编辑器(可能有bug,随便写了一个)

    简单的写了一个文本编辑器,功能很简单,但足以把文件IO相关的操作熟悉了,可能功能或者分配的大小还不够完善.请参考参考: #include <stdio.h> #include <co ...

随机推荐

  1. JavaScript对于函数的调用及原理

    <js> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...

  2. LDAP 总结

    LDAP入门 首先要先理解什么是LDAP,当时我看了很多解释,也是云里雾里,弄不清楚.在这里给大家稍微捋一捋. 首先LDAP是一种通讯协议,LDAP支持TCP/IP.协议就是标准,并且是抽象的.在这套 ...

  3. Android图片加载框架最全解析(一),Glide的基本用法

    现在Android上的图片加载框架非常成熟,从最早的老牌图片加载框架UniversalImageLoader,到后来Google推出的Volley,再到后来的新兴军Glide和Picasso,当然还有 ...

  4. Action过滤器使用实例(一)

    1.实例一 /// <summary> /// 需要用户登陆的 action,执行提前验证 /// </summary> public class LoginFilterAtt ...

  5. JConsole详解

    一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运行.您可以轻松地使用 JCons ...

  6. Zabbix iostat 监控配置

    ## zabbix iostat 监控模板安装与配置 配置定时任务,用于生成iostat的统计数据 crontab -e * * * * * /usr/local/zabbix327/bin/iost ...

  7. HDU4183 起点到终点再到起点 除起点每点仅经过一次 网络流

    题意: T个测试数据 n个圆 下面 fre x y r 表示圆的频率 坐标和半径 要求: 从频率为400(最小的) 圆 走到频率为789(最大)的圆,再走回来,除起点每个点只能经过一次 问这样的路径是 ...

  8. UVA 156 (13.08.04)

     Ananagrams  Most crossword puzzle fans are used to anagrams--groupsof words with the same letters i ...

  9. iOS开发-Quartz2D初识

    Quartz2D如果单独的从Quartz,那么会发现Quartz是一个开源的Java作业调度框架,单独从英文翻译的角度来看的话Quartz的英文是石英,如果有的时候不小心搜索会发现手表推荐.本文中介绍 ...

  10. 基于jQuery的Cookie操作插件--简单而又没有兼容性问题!

    在网页客户端,我们经常会遇到读取或者设置cookie的情况,如果用纯生的js我们可能会遇到一些兼容性带来的麻烦,这里给大家介绍一个比较实用jquery操作cookie的插件,插件的源代码如下: 1 2 ...