目标:读取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. Adding an instance to a MEF container

    How can you add an already created instance to a MEF container/cataloge to use when resolving Import ...

  2. 使用框架帮助Activity规范化

    摘要 本文原创,转载请注明地址:http://kymjs.com/code/2015/05/10/01 写给那些在用.想用.还没有用过KJFrame的朋友. KJFrameForAndroid总共分为 ...

  3. DWZ学习记录--关闭loading效果

    修改文件:jquery-1.7.1.js 查找内容:7142行 ajaxSettings: { 修改内容:global: true=>global: false修改目的:关闭loading效果

  4. SVN中的Trunk、Tag、Brance的用法

    在SVN中Branch/tag在一个功能选项中,在使用中也往往产生混淆.在实现上,branch和tag,对于svn都是使用copy实现的,所以他们在默认的权限上和一般的目录没有区别.至于何时用tag, ...

  5. 最小二乘法least square

    上研究生的时候接触的第一个Loss function就是least square.最近又研究了一下,做个总结吧. 定义看wiki就够了.公式如下 E(w)=12∑n=1N{y−xWT}2E(w)=12 ...

  6. 通过java读取HDFS的数据 (转)

    原文链接:通过java读取HDFS的数据 通过JAVA直接读取HDFS中的时候,一定会用到FSDataInputStream类,通过FSDataInputStream以流的形式从HDFS读数据代码如下 ...

  7. PreparedStatement 使用like 模糊查询

    PreparedStatement 使用like 在使用PreparedStatement进行模糊查询的时候废了一番周折,以前一直都没有注意这个问题. 一般情况下我们进行精确查询,sql语句类似:se ...

  8. oracle和mysql功能相同的函数

    wm_concat ---->mysql 的group_concat decode (两条件的)----->mysql 的 if decode (3个及以上条件的)---------> ...

  9. Depth of field --Circle of confusion 推导

    https://en.wikipedia.org/wiki/Circle_of_confusion https://developer.download.nvidia.com/books/HTML/g ...

  10. java.net.URI 简介 文档 API

    URI 简介 文档地址:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh public final class java.net.URI extend ...