解析xlsx文件---Java读取Excel2007
Posted y_keven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析xlsx文件---Java读取Excel2007相关的知识,希望对你有一定的参考价值。
关于Java读取Excel2007的文章在Google、百度上搜索一下,没有太好的例子,实现的也不算太好。查看了一下Poi,最新的 POI 3.5 beta 4 支持读写 Excel2007和PPT2007(XLSX and PPTX),自己来实现Java读取Excel2007了。
一、老版本案例,08年的poi.jar;下面案例只适用于与解析格式较小的文件,对于较大的文件会出现内存溢出情况。
1,下载 POI 3.5 beta 4 解压,把其中的jar包导入项目文件。以我的读取为例,导入了以下jar包。
没有配置 log4j,测试时报告警报信息,应该为加载顺序导致的初始化问题造成(暂时没有找原因)。
2,建立读取 Excel2007 方法
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = new XSSFWorkbook(path); //已过时,被废弃,使用会出错
XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
// 定义 row、cell
XSSFRow row;
String cell;
// 循环输出表格中的内容
for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++)
row = sheet.getRow(i);
for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++)
// 通过 row.getCell(j).toString() 获取单元格内容,
cell = row.getCell(j).toString();
System.out.print(cell + "\\t");
System.out.println("");
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = new XSSFWorkbook(strPath);
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
// 定义 row、cell
XSSFRow row;
String cell;
// 循环输出表格中的内容
for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++)
row = sheet.getRow(i);
for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++)
// 通过 row.getCell(j).toString() 获取单元格内容,
cell = row.getCell(j).toString();
System.out.print(cell + "\\t");
System.out.println("");
此过程直接传入文件所在路径,其他一些过程已经被自动实现。
3,测试,文件为8列3563行数据,以文本方式读取内容,
public static void main(String[] args)
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS");
TimeZone t = sdf.getTimeZone();
t.setRawOffset(0);
sdf.setTimeZone(t);
Long startTime = System.currentTimeMillis();
String fileName = "F:\\\\我的文档\\\\学生缴费代码.xlsx";
// 检测代码
try
PoiReadExcel er = new PoiReadExcel();
// 读取excel2007
er.testPoiExcel2007(fileName);
catch (Exception ex)
Logger.getLogger(FastexcelReadExcel.class.getName()).log(Level.SEVERE, null, ex);
Long endTime = System.currentTimeMillis();
System.out.println("用时:" + sdf.format(new Date(endTime - startTime)));
public static void main(String[] args)
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS");
TimeZone t = sdf.getTimeZone();
t.setRawOffset(0);
sdf.setTimeZone(t);
Long startTime = System.currentTimeMillis();
String fileName = "F:\\\\我的文档\\\\学生缴费代码.xlsx";
// 检测代码
try
PoiReadExcel er = new PoiReadExcel();
// 读取excel2007
er.testPoiExcel2007(fileName);
catch (Exception ex)
Logger.getLogger(FastexcelReadExcel.class.getName()).log(Level.SEVERE, null, ex);
Long endTime = System.currentTimeMillis();
System.out.println("用时:" + sdf.format(new Date(endTime - startTime)));
读取所用时间为:4.172秒。
二、java解析大数据分析
一. Apache POI 简介( http://poi.apache.org/)
使用Java程序读写Microsoft Office,提供了下面这几种类型:
HSSF-提供读写Microsoft Excel XLS格式档案的功能。
XSSF-提供读写Microsoft Excel OOXML XLSX格式档案的功能。
HWPF-提供读写Microsoft Word DOC格式档案的功能。
HSLF-供读写Microsoft PowerPoint格式档案的功能。
HDGF-提供读Microsoft Visio格式档案的功能。
HPBF-提供读Microsoft Publisher格式档案的功能。
二、POI操作Excel
1. 官方快速帮助:http://poi.apache.org/spreadsheet/quick-guide.html
2. 导入包:poi-3.6.jar
参考:
1. http://www.blogjava.net/vwpolo/archive/2009/09/16/295243.html
2. http://hacker-zxf.javaeye.com/blog/746546
3. http://zmx.javaeye.com/blog/622536
4. http://canfly2010.javaeye.com/blog/701726
[java] view plaincopyprint?
package excel.poi.input;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.POITextExtractor;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlException;
public class ReadExcel
/**
* 读取office 2003 xls
* @param filePath
*/
@SuppressWarnings( "unchecked", "deprecation" )
public void loadXls(String filePath)
try
InputStream input = new FileInputStream("D://test.xls");
POIFSFileSystem fs = new POIFSFileSystem(input);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
// Iterate over each row in the sheet
Iterator rows = sheet.rowIterator();
while (rows.hasNext())
HSSFRow row = (HSSFRow) rows.next();
System.out.println("Row #" + row.getRowNum());
// Iterate over each cell in the row and print out the cell"s
// content
Iterator cells = row.cellIterator();
while (cells.hasNext())
HSSFCell cell = (HSSFCell) cells.next();
System.out.println("Cell #" + cell.getCellNum());
switch (cell.getCellType())
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
System.out.println(cell.getCellFormula());
break;
default:
System.out.println("unsuported sell type");
break;
catch (IOException ex)
ex.printStackTrace();
/**
* 读取xlsx文本
* @param filePath
*/
public void loadXlsxText(String filePath)
File inputFile = new File("D://test.xlsx");
try
POITextExtractor extractor = ExtractorFactory.createExtractor(inputFile);
System.out.println(extractor.getText());
catch (InvalidFormatException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (OpenXML4JException e)
e.printStackTrace();
catch (XmlException e)
e.printStackTrace();
/**
* 读取office 2007 xlsx
* @param filePath
*/
public void loadXlsx(String filePath)
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = null;
try
xwb = new XSSFWorkbook("D://test.xlsx");
catch (IOException e)
System.out.println("读取文件出错");
e.printStackTrace();
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
xwb.getSheetAt(1);
// 定义 row、cell
XSSFRow row;
String cell;
// 循环输出表格中的内容
for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++)
row = sheet.getRow(i);
for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++)
// 通过 row.getCell(j).toString() 获取单元格内容,
cell = row.getCell(j).toString();
System.out.print(cell + "/t");
System.out.println("");
public static void main(String[] args)
ReadExcel readExcel =new ReadExcel();
readExcel.loadXlsx("");
package excel.poi.input;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.POITextExtractor;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlException;
public class ReadExcel
/**
* 读取office 2003 xls
* @param filePath
*/
@SuppressWarnings( "unchecked", "deprecation" )
public void loadXls(String filePath)
try
InputStream input = new FileInputStream("D://test.xls");
POIFSFileSystem fs = new POIFSFileSystem(input);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
// Iterate over each row in the sheet
Iterator rows = sheet.rowIterator();
while (rows.hasNext())
HSSFRow row = (HSSFRow) rows.next();
System.out.println("Row #" + row.getRowNum());
// Iterate over each cell in the row and print out the cell"s
// content
Iterator cells = row.cellIterator();
while (cells.hasNext())
HSSFCell cell = (HSSFCell) cells.next();
System.out.println("Cell #" + cell.getCellNum());
switch (cell.getCellType())
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
System.out.println(cell.getCellFormula());
break;
default:
System.out.println("unsuported sell type");
break;
catch (IOException ex)
ex.printStackTrace();
/**
* 读取xlsx文本
* @param filePath
*/
public void loadXlsxText(String filePath)
File inputFile = new File("D://test.xlsx");
try
POITextExtractor extractor = ExtractorFactory.createExtractor(inputFile);
System.out.println(extractor.getText());
catch (InvalidFormatException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (OpenXML4JException e)
e.printStackTrace();
catch (XmlException e)
e.printStackTrace();
/**
* 读取office 2007 xlsx
* @param filePath
*/
public void loadXlsx(String filePath)
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = null;
try
xwb = new XSSFWorkbook("D://test.xlsx");
catch (IOException e)
System.out.println("读取文件出错");
e.printStackTrace();
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
xwb.getSheetAt(1);
// 定义 row、cell
XSSFRow row;
String cell;
// 循环输出表格中的内容
for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++)
row = sheet.getRow(i);
for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++)
// 通过 row.getCell(j).toString() 获取单元格内容,
cell = row.getCell(j).toString();
System.out.print(cell + "/t");
System.out.println("");
public static void main(String[] args)
ReadExcel readExcel =new ReadExcel();
readExcel.loadXlsx("");
[java] view plaincopyprint?
<SPAN style="COLOR: #ff0000">但是:Workbook wb = WorkbookFactory.create(new FileInputStream(FILE_URL));</SPAN>
但是:Workbook wb = WorkbookFactory.create(new FileInputStream(FILE_URL));[java] view plaincopyprint?
<SPAN style="COLOR: #ff0000">查看Create函数的源代码:</SPAN>
三、java解析excel大数据;临时表的形式
此篇是紧接上篇《大数据量的excel文件读取——2003及之前版本》。
excel2007文件格式与之前版本不同,之前版本采用的是微软自己的存储格式。07版内容的存储采用XML格式,所以,理所当然的,对大数据量的xlsx文件的读取采用的也是XML的处理方式SAX。
同之前的版本一样,大数据量文件的读取采用的是事件模型eventusermodel。usermodel模式需要将文件一次性全部读到内存中,07版的既然采用的存储模式是xml,解析用的DOM方式也是如此,这种模式操作简单,容易上手,但是对于大量数据占用的内存也是相当可观,在Eclipse中经常出现内存溢出。
下面就是采用eventusermodel对07excel文件读取。
同上篇,我将当前行的单元格数据存储到List中,抽象出 optRows 方法,该方法会在每行末尾时调用,方法参数为当前行索引curRow(int型)及存有行内单元格数据的List。继承类只需实现该行级方法即可。
补充:今天发现读取2007的脚本存在存在一处问题,在遇到空单元格时会跳过该单元格,由于工作紧张没有时间去解决该问题,这里给出一个暂时的处理办法。打开文件,在开始菜单中选择"查找和选择","定位条件",选择"空值",确定,这时会找出所有的空单元格,直接按空格,然后Ctrl+enter,就会将所有空单元格填入一个空格,保存即可。
2010.6.10补充:空单元格的问题已经解决,在2007的文档中空单元格是不存储的,单元格的r属性是单元格位置信息,格式为[A-Z]+[0-9]+。字母部分是列索引,数字部分是行索引。
抽象类:XxlsAbstract ,作用:遍历excel文件,提供行级操作方法 optRows
package com.gaosheng.util.xls;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.openxml4j.opc.OPCPackage;
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;
/**
* XSSF and SAX (Event API)
*/
public abstract class XxlsAbstract extends DefaultHandler
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private int sheetIndex = -1;
private List<String> rowlist = new ArrayList<String>();
private int curRow = 0; //当前行
private int curCol = 0; //当前列索引
private int preCol = 0; //上一列列索引
private int titleRow = 0; //标题行,一般情况下为0
private int rowsize = 0; //列数
//excel记录行操作方法,以行索引和行元素列表为参数,对一行元素进行操作,元素为String类型
// public abstract void optRows(int curRow, List<String> rowlist) throws SQLException ;
//excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型
public abstract void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException;
//只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3
public void processOneSheet(String filename,int sheetId) throws Exception
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
// rId2 found by processing the Workbook
// 根据 rId# 或 rSheet# 查找sheet
InputStream sheet2 = r.getSheet("rId"+sheetId);
sheetIndex++;
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
/**
* 遍历 excel 文件
*/
public void process(String filename) throws Exception
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while (sheets.hasNext())
curRow = 0;
sheetIndex++;
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
public XMLReader fetchSheetParser(SharedStringsTable sst)
throws SAXException
XMLReader parser = XMLReaderFactory
.createXMLReader("org.apache.xerces.parsers.SAXParser");
this.sst = sst;
parser.setContentHandler(this);
return parser;
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException
// c => 单元格
if (name.equals("c"))
// 如果下一个元素是 SST 的索引,则将nextIsString标记为true
String cellType = attributes.getValue("t");
String rowStr = attributes.getValue("r");
curCol = this.getRowIndex(rowStr);
if (cellType != null && cellType.equals("s"))
nextIsString = true;
else
nextIsString = false;
// 置空
lastContents = "";
public void endElement(String uri, String localName, String name)
throws SAXException
Java对Excel解析(求助)
JS-XLS/X读取和解析Excel表格文件(xls/xlsx)的JavaScript插件