解析xlsx文件---Java读取Excel2007

Posted y_keven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析xlsx文件---Java读取Excel2007相关的知识,希望对你有一定的参考价值。

关于Java读取Excel2007的文章在Google、百度上搜索一下,没有太好的例子,实现的也不算太好。查看了一下Poi,最新的 POI 3.5 beta 4 支持读写 Excel2007PPT2007(XLSX and PPTX),自己来实现Java读取Excel2007了。

一、老版本案例,08年的poi.jar;下面案例只适用于与解析格式较小的文件,对于较大的文件会出现内存溢出情况。

1,下载 POI 3.5 beta 4 解压,把其中的jar包导入项目文件。以我的读取为例,导入了以下jar包。


没有配置 log4j,测试时报告警报信息,应该为加载顺序导致的初始化问题造成(暂时没有找原因)

2,建立读取 Excel2007 方法

Java代码

// 构造 XSSFWorkbook 对象,strPath 传入文件路径

XSSFWorkbook xwb = new XSSFWorkbook(path);  //已过时,被废弃,使用会出错

XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));

// 读取第一章表格内容

XSSFSheet sheet = xwb.getSheetAt(0);

// 定义 rowcell

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);

        // 定义 rowcell

        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,测试,文件为83563行数据,以文本方式读取内容,

Java代码

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); 

    // 定义 rowcell     

     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);

       // 定义 rowcell  

        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

同之前的版本一样,大数据量文件的读取采用的是事件模型eventusermodelusermodel模式需要将文件一次性全部读到内存中,07版的既然采用的存储模式是xml,解析用的DOM方式也是如此,这种模式操作简单,容易上手,但是对于大量数据占用的内存也是相当可观,在Eclipse中经常出现内存溢出。

下面就是采用eventusermodel07excel文件读取。

同上篇,我将当前行的单元格数据存储到List中,抽象出 optRows 方法,该方法会在每行末尾时调用,方法参数为当前行索引curRow(int)及存有行内单元格数据的List。继承类只需实现该行级方法即可。

 

补充:今天发现读取2007的脚本存在存在一处问题,在遇到空单元格时会跳过该单元格,由于工作紧张没有时间去解决该问题,这里给出一个暂时的处理办法。打开文件,在开始菜单中选择"查找和选择""定位条件",选择"空值",确定,这时会找出所有的空单元格,直接按空格,然后Ctrl+enter,就会将所有空单元格填入一个空格,保存即可。

2010.6.10补充:空单元格的问题已经解决,在2007的文档中空单元格是不存储的,单元格的r属性是单元格位置信息,格式为[A-Z]+[0-9]+。字母部分是列索引,数字部分是行索引。

抽象类:XxlsAbstract ,作用:遍历excel文件,提供行级操作方法 optRows

Java代码

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解析excel表格

JS-XLS/X读取和解析Excel表格文件(xls/xlsx)的JavaScript插件

为啥java读不了.xlsx的excel文件只能读.xls的,难道是因为我的jxl.jar包太久了?

java如何读取一个加密后的.xls文件

关于jquery读取excel文件内容 xls xlsx格式