处理excel,开源的javaApI提供了两种,一种是jxl,一种是poi。poi提供的功能较多,所以我用的是poi。

  poi有两种模式,一个是用户模式(HSSFworkbook:支持Excel2003,XSSFworkbook:支持Excel2007),这个操作数量上万的时候会造成out of memory 的情况。另一个是事件驱动模,解析的Excel数据上万的时候用这个,这里拿Excel2007来说明,Excel2007的底层其实就是xml形式的,其实也就是解析xml。

  底层xml格式:

<sheetData>//代表一个shet
- <row r="1" spans="1:33">//代表一个行
- <c r="A1" t="s">//代表一个单元格 r是坐标
<v>0</v> //代表相应的值,这里的0不是真正的值
</c>
- <c r="B1" t="s">
<v>1</v>
</c>
- <c r="C1" t="s">
<v>2</v>
</c>
</row>
</sheetData>

  所需jar包:poi.jar,poi-excelant,poi-ooxml.jar,poi-ooxml-schemas.jar,poi-    scratchpad.jar,dom4j.jar,xmlbeans.jar,xerces.jar

  代码:空值问题待解决

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
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; //Default是sax解析xml的处理类
public class TestExcel2007Util{
public static void main(String[] args) throws IOException, OpenXML4JException, SAXException {
Excel2007Util excel2007Util=new Excel2007Util();
excel2007Util.process("C:/Users/sime/Desktop/XXX.xlsx"); }
}
class Excel2007Util extends DefaultHandler{
//共享字符串表
private ReadOnlySharedStringsTable sst;
//单元格
private StylesTable stylesTable; private String lastContents; private boolean nextIsString; private List<String> rowlist=new ArrayList<String>();
//当前页
private int sheetIndex;
//当前行
private int curRow =0;
//当前单元格
private int curCol =0;
private boolean cellNull; /**
* excel记录行操作方法,rowlist是一行记录,这里可以进行你的逻辑处理
*/
public void optRows(int sheetIndex,int curRow,List<String> rowlist){
System.out.println(rowlist.toString());
} /**
* 遍历工作簿中所有的电子表格
* @throws OpenXML4JException
* @throws IOException
* @throws SAXException
*/
public void process (String filename) throws IOException, OpenXML4JException, SAXException{
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader xssfReader = new XSSFReader(pkg);
sst = new ReadOnlySharedStringsTable(pkg);
XMLReader parser=this.fetchSheetParser(sst);
Iterator<InputStream> sheets = xssfReader.getSheetsData();
while (sheets.hasNext()) {
curRow = 0;
sheetIndex++;
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
}
pkg.close();
}
public XMLReader fetchSheetParser(ReadOnlySharedStringsTable sst) throws SAXException {
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");

         parser.setContentHandler(this);
return parser;
} /**
* 解析器在 XML 文档中的每个元素的开始调用此方法
* uri:名称空间 URI
* localName:本地名称
* name:限定名
* attributes:连接到元素上的属性
*/
public void startElement(String uri, String localName, String name, Attributes attributes){
if (name.equals("c")) {
// 如果下一个元素是 SST 的索引,则将nextIsString标记为true
String cellType = attributes.getValue("t");
// System.out.println("cellType : " + cellType);
if (cellType != null && cellType.equals("s")) {
nextIsString = true;
cellNull = false;
} else {
nextIsString = false;
cellNull = true;
}
}
lastContents = "";
}
// 根据SST的索引值的到单元格的真正要存储的字符串
// 这时characters()方法可能会被调用多次
public void characters(char[] ch, int start, int length) throws SAXException {
//得到单元格内容的值
lastContents += new String(ch, start, length); } public void endElement (String uri, String localName, String name){
if (nextIsString) {
try {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
} catch (Exception e) { }
} // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
if (name.equals("v") || "t".equals(name)) {
String value = lastContents.trim();
rowlist.add(curCol, value);
curCol++;
cellNull = false;
}else if("c".equals(name)){
rowlist.add(curCol, "");
curCol++;
cellNull = false;
}else {
//如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
if (name.equals("row")) {
optRows(sheetIndex,curRow,rowlist);
rowlist.clear();
curRow++;
curCol = 0;
}
}
} }

这是个人网上百度后总结的方法,比较简洁,可以直接拿去用,但是空值的问题尚未解决,如有不对的地方请指出。

  

org.apache.xerces.parsers.SAXParser

poi解析Excel2007海量数据的更多相关文章

  1. POI Sax 事件驱动解析Excel2007文件

    Excel2007版本的代码如下,本文主要是用于POI解析大文件Excel容易出现内存溢出的现象而提出解决方案,故此解决了大数据量的Excel文件解析的难度,在此拿出来贡献给大家,谢谢! 里面用到的相 ...

  2. POI以SAX方式解析Excel2007大文件(包含空单元格的处理) Java生成CSV文件实例详解

    http://blog.csdn.net/l081307114/article/details/46009015 http://www.cnblogs.com/dreammyle/p/5458280. ...

  3. java 使用 poi 解析excel

    背景: web应用经常需要上传文件,有时候需要解析出excel中的数据,如果excel的格式没有问题,那就可以直接解析数据入库. 工具选择: 目前jxl和poi可以解析excel,jxl很早就停止维护 ...

  4. poi解析excel

    一.遇见的问题: 当单元格设置为日期类型时,cell.getCellStyle().getDataFormat()返回的值都为176. poi jar包3.14以上不支持用cell.getCellTy ...

  5. poi解析Excel文件版本问题

    poi解析Excel文件时有两种格式: HSSFWorkbook格式用来解析Excel2003(xls)的文件 XSSFWorkbook格式用来解析Excel2007(xlsx)的文件 如果用HSSF ...

  6. SpringMVC文件上传 Excle文件 Poi解析 验证 去重 并批量导入 MYSQL数据库

    SpringMVC文件上传 Excle文件 Poi解析并批量导入 MYSQL数据库  /** * 业务需求说明: * 1 批量导入成员 并且 自主创建账号 * 2 校验数据格式 且 重复导入提示 已被 ...

  7. Apache POI解析excel文件

    这里需要用到poi.jar和poi-ooxml.jar  没有的可以去http://mvnrepository.com/下载 import org.apache.poi.POIXMLDocument; ...

  8. java读写excel文件( POI解析Excel)

    package com.zhx.base.utils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi ...

  9. 使用POI解析Excel时,出现org.xml.sax.SAXParseException: duplicate attribute 'o:relid'的解决办法

    1.使用org.apache.poi解析excle,.xlsx类型文件InputStream is = new FileInputStream(strFileName);XSSFWorkbook wb ...

  10. poi解析excel出现格式不正确

    后缀为xlsx的excel做系统导入时出现bug: Strict OOXML isn't currently supported, please see bug #57699 为了同时兼容03.07及 ...

随机推荐

  1. windows 2012 打补丁升级后不能启动处理

    如果可以进入WinRE这个修复的高级选项,选择安全模式,是否可以进入,卸载最近安装的补丁,再重启看一下. 如果无法进入安全模式的话,那么选择cmd模式,使用下方命令.这通常会回退pending的upd ...

  2. 第三周day2

    第三周day2,星期二 所花时间:1h 代码量:60 博客量:2 了解知识点:按钮属性,文本属性.帧布局.表格布局.约束布局.

  3. 项目开发中的ORM框架使用mybatis还是mybatis-plus

    mybatis支持xml配置文件和注解 mybaits-plus也支持xml配置文件和注解,多了baseMapper,将基础的CRUD操作单独拿出来进行了封装 mybatis是一款优秀的持久层框架,它 ...

  4. 学习-Vue2-Vue实例-数据与方法-Object.freeze()

    Object.freeze(),会阻止修改现有的property,意味着响应系统无法再追踪变化 代码示例: <!DOCTYPE html> <html lang="en&q ...

  5. Oracle重建索引

    创建表 create table student( student_id number, name varchar2(240) ) tablespace school_data; 创建索引 creat ...

  6. uniapp记录

    1.uniapp获取imei imsi 型号 厂商 https://blog.csdn.net/qq_35620498/article/details/112172115

  7. nginx转发端口路由器再转发

    场景 nginx 转发端口 路由器二次转发了,端口不一样 (shiro 或者其他一些权限控制架构会自动跳转,导致的端口不对.) proxy_set_header Host $host:$proxy_p ...

  8. css 选择器再学一遍记录一下*1

    1 <!DOCTYPE html> 2 <html> 3 <HEAD> 4 5 <style> 6 *{font-size: 12px; padding ...

  9. yestoday once more

    夏日的光为百叶窗所驯服,褪去了令人刺痛的热烈.yestoday once more~ 耳机里传来那熟悉的旋律,恍惚间仿佛回到了十五年前的那个午后,老式收音机里放着同样的歌曲,对面办公桌旁某个少年正惶恐 ...

  10. wrf-python离线安装

    由于客户环境不能联网,python的插件库只能离线安装,wrf库的安装中踩了不少坑,特此记录. 1.官方插件库pypi.org只有压缩包,没有提供wheel,在线安装没有问题. 2.下载压缩包解压后, ...