处理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

最新文章

  1. linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程
  2. BZOJ 3594 方伯伯的玉米田
  3. GCC、Makefile编程学习
  4. ASP.NET的一般处理程序对图片文件的基本操作
  5. 2.里氏替换原则(Liskov Substitution Principle)
  6. acmer -- 最美的情书
  7. rac安装中遇到的问题
  8. 注册表检测office版本
  9. 【分享】几篇关于Repository 相关的讨论、提问、文章
  10. 解决OS睡眠功能中,移动鼠标就会唤醒
  11. Python3+PyCharm+Django+Django REST framework开发教程
  12. python开发购物车
  13. AdminLTE用django部署
  14. Go Example--错误处理
  15. kolla-ansible部署多节点OpenStack-Pike
  16. Opencv 视频保存为图像
  17. 安装beanstalkd
  18. 图形数据库 Neo4j 开发实战
  19. HDU 5645 DZY Loves Balls 水题
  20. 【cocos2d-x制作别踩白块儿】第九期:游戏计时功能(附源代码)

热门文章

  1. Winfrom ComboBox中的性能探索
  2. vue-cli3配置打包后的文件加上版本号
  3. tensorflow-gpu安装遇到的坑
  4. Go语言格式化金额为3个一组隔开
  5. git的基本操作(一)
  6. 远程ubuntu虚拟机(VirtualBox)
  7. SAP物料状态
  8. Accelerated molecular dynamics simulation of Silicon Crystals on TaihuLight using OpenACC 阅读
  9. MySQL之中文数据问题
  10. rust crm 镜像源管理