Java读Exlcel表格数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java读Exlcel表格数据相关的知识,希望对你有一定的参考价值。

1.    了解Excel相关概念

  • Excel文件有两种格式,文件后缀为.xls的为excel2003及以前版本,文件后缀为.xlsx的为excel2007及以后版本。不同的版本,所使用的API不一样。
  • 一个Excel文件对应一个工作簿(Workbook),一个workbook可以有多个工作表(Sheet)组成,一个sheet由多个单元格(cell)组成。这些单元格分成M行(row)、N列(Column)组成。列用大写英文字母表示,从A开始到Z共26列,然后再从AA到AZ又26列,再从BA到BZ再26列以此类推。行则使用数字表示,例如;A3 表示第三行第一列,E5表示第五行第五列。
  • 工作簿里的工作表(sheet)从0开始编号。比如一个excel文件有3个sheet,则这三个sheet的序号分别是0,1,2。

 技术分享

 

2.    Java操作Excel的方法

Java操作Excel需要用到第三方工具包。在搜索引擎中搜索“Java excel 操作“,查阅相关资料后可以知道:

JAVA中操作Excel的有两种比较主流的工具包:JXL和POI。jxl 只能操作Excel 95, 97, 2000,即以.xls为后缀的excel。而poi可以操作Excel 95及以后的版本,即可操作后缀为.xls和.xlsx两种格式的excel。

POI全称 Poor Obfuscation Implementation,直译为“可怜的模糊实现”,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能。官网:http://poi.apache.org,POI支持office的所有版本,所以这里选择POI进行讲解。

a)         下载工具包

打开POI官网,在左侧导航栏处点击“Download

技术分享

第一步:打开官网

 技术分享

第二步:下载3.14版

选中下载3.14最新稳定版。下载文件分为二进制文件(容量小)和源码文件(容量大)两种,我们直接使用二进制文件即可。如果网站打不开或者开速度慢,大家也可以搜索其它网站下载其它版本,因为我们程序只需要处理简单的excel,没有其它特殊要求,所以一些较早版本(如3.9)也可以使用。3.9版本下载地址:http://pan.baidu.com/s/1slIf2Zb

3.14版下载后,会看到根目录、lib目录、ooxml-lib下有一些后缀为jar的文件,这些就是我们要使用的jar包。docs目录下的文件是帮助文档。

b)        添加jar包到项目中

软件包需要先导入到我们的项目中,我们的程序才可以使用poi。下载的jar包比较多,包括处理excel、word、ppt、visio、outlook等多种格式的office文档。我们的项目只需要处理excel,所以不必将所有jar包都导入进项目。我们可以通过下面方法来决定具体导入哪些:

在poi官网上左侧导航栏处点击“Components”菜单项,会看到与excel相关的组件:

技术分享 

从表中看出与excel操作相关的组件是poi和poi-ooxml。继续查看官网Components下面的说明,得知poi-ooxml包还需依赖poi-ooxml-schemas,而poi-ooxml-schemas包又依赖xmlbeans包(依赖是指一个工具包需要有另一个工具包才能够正常运行)。所以我们需要在项目中添加下图所示的4个jar包。添加方法是:

在MyEclipse的工作空间中,选中项目,点击右键,选择Properties菜单,弹出如下窗口:

 技术分享

按上图顺序就可将poi包导入进工程中。

c)         使用poi读写excel

了解POI的用法有两种方式,一种是阅读官网提供的文档。这种方法要求大家具有一定英文文档阅读能力。通常,很多有价值的第三方工具包都是国外发布的,作为程序员英语阅读能力是最基本的要求。官方文档一般会提供软件包的使用方法、api文档介绍、演示实例等。要想全面了解工具包的用法,阅读官方文档是最直接有效的途径。

第二种方法是查找对应的中文资料。这要求具有较强的互联网信息获取能力。

下面看一下Apache POI的基本用法。

Apache POI处理excel的类有两种前缀:

l  HSSF:以此为前缀的API用来处理Excel 2003及以前的文档。

l  XSSF:以此为前缀的API用来处理Excel 2007及以后的文档。

使用POI进行Excel文档处理之前还需要了解以下概念:

l  Workbook:Excel工作簿的接口(interface),xls工作簿HSSFWorkbook类和xlsx工作簿XSSFWorkbook类都是Workbook的具体实现(implement)。

l  Sheet:Excel工作表的接口,典型的实现类是HSSFSheet and XSSFSheet。

l  Row:工作表的行接口。HSSFRow和XSSFRow是具体的实现类。

l  Cell:工作表的列接口。HSSFCell和XSSFCell是具体的实现类。

让我们看看实际的读excel文件的例子:

简单读Excel文件的例子

假设要读一个如下内容的excel文件(见book.xlsx):

技术分享 表中三列信息分表图书名称、作者和价格。一共有4行图书数据。

ExcelReaderDemo.java示例代码

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.Iterator;

 

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.xssf.usermodel.XSSFWorkbook;

 

 

public class ExcelReaderDemo {

    public static  void main(String[] args) throws IOException{

         String excelFilePath = "E:/book.xlsx";

            FileInputStream inputStream = new FileInputStream(new File(excelFilePath));

            

            Workbook workbook = new XSSFWorkbook(inputStream);

            Sheet firstSheet = workbook.getSheetAt(0);

            Iterator<Row> iterator = firstSheet.iterator();

            

            while (iterator.hasNext()) {

                Row nextRow = iterator.next();

                Iterator<Cell> cellIterator = nextRow.cellIterator();

                

                while (cellIterator.hasNext()) {

                    Cell cell = cellIterator.next();

                    

                    switch (cell.getCellType()) {

                        case Cell.CELL_TYPE_STRING:

                            System.out.print(cell.getStringCellValue());

                            break;

                        case Cell.CELL_TYPE_BOOLEAN:

                            System.out.print(cell.getBooleanCellValue());

                            break;

                        case Cell.CELL_TYPE_NUMERIC:

                            System.out.print(cell.getNumericCellValue());

                            break;

                    }

                    System.out.print("  ");

                }

                System.out.println();

            }

            

            workbook.close();

            inputStream.close();  

    }

}

 

输出结果:

 技术分享

一个面向对象的例子

这个例子是读上面的book.xlsx文件,将每行数据转换成对象。先在项目中添加一个模型类(Book.java),类代码如下:

Book.java代码

public class Book {

    private String title;

    private String author;

    private double price;

 

    public Book() {

    }

 

    public String toString() {

        return String.format("%s - %s - %f", title, author, price);

    }  

    public String getAuthor() {

        return author;

    }

    public String getTitle() {

        return title;

    }

    public double getPrice() {

        return price;

    }

    public void setAuthor(String author) {

        this.author = author;

    }

    public void setPrice(double price) {

        this.price = price;

    }

    public void setTitle(String title) {

        this.title = title;

    }

}

 

Excel表中每一行数据需要转换成一个Book对象。转换过程由一个专门的类ExcelReadUtil完成。在项目中添加ExcelReadUtil类,列代码如下:

ExcelReadUtil.java代码

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

 

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.xssf.usermodel.XSSFWorkbook;

 

public class ExcelReaderUtil {

         private Object getCellValue(Cell cell) {

                   switch (cell.getCellType()) {

                   case Cell.CELL_TYPE_STRING:

                            return cell.getStringCellValue();

 

                   case Cell.CELL_TYPE_BOOLEAN:

                            return cell.getBooleanCellValue();

 

                   case Cell.CELL_TYPE_NUMERIC:

                            return cell.getNumericCellValue();

                   }

                   return null;

         }

         public List<Book> readBooksFromExcelFile(String excelFilePath) throws IOException {

             List<Book> listBooks = new ArrayList<>();

             FileInputStream inputStream = new FileInputStream(new File(excelFilePath));

          

             Workbook workbook = new XSSFWorkbook(inputStream);

             Sheet firstSheet = workbook.getSheetAt(0);

             Iterator<Row> iterator = firstSheet.iterator();

          

             while (iterator.hasNext()) {

                 Row nextRow = iterator.next();

                 Iterator<Cell> cellIterator = nextRow.cellIterator();

                 Book aBook = new Book();

          

                 while (cellIterator.hasNext()) {

                     Cell nextCell = cellIterator.next();

                     int columnIndex = nextCell.getColumnIndex();

          

                     switch (columnIndex) {

                     case 1:

                         aBook.setTitle((String) getCellValue(nextCell));

                         break;

                     case 2:

                         aBook.setAuthor((String) getCellValue(nextCell));

                         break;

                     case 3:

                         aBook.setPrice((double) getCellValue(nextCell));

                         break;

                     } 

                 }

                 listBooks.add(aBook);

             }

          

             workbook.close();

             inputStream.close();

          

             return listBooks;

         }

 

    public static  void main(String[] args) throws IOException{

        String excelFilePath = "E:/book.xlsx";

        ExcelReaderUtil reader = new ExcelReaderUtil();

        List<Book> listBooks = reader.readBooksFromExcelFile(excelFilePath);

        System.out.println(listBooks);

    }

}

 

 

getCellValue方法用来将Cell表格中的字符串、布尔值、数值数据转换成对应类型的java类型数据。

readBooksFromExcelFile方法用来读取指定的excel文件,并将excel文件中的数据转换成相应的Book对象,将得到的所有Book对象存放在List<Book>链表中返回给调用者。

main是测试代码(你也可以将main方法放在一个单独的入口类中),main中实例化了一个ExcelReaderUtil对象reader,调用readerreadBooksFromExcelFile方法,得到一个存放4个Book对象的链表,然后将此链表输出。

输出结果:

 技术分享

 

让程序既可以读Excel 2003,也可以读Excel 2007

通过阅读POI的API文档,我们知道读Excel 2003和Excel 2007所使用的API是不同的,一个是HSSFXXX,一个是XSSFXXX(XXX表示Workbook、Sheet、Row、Cell等)。其实,所有的HSSFWorkbook和XSSFWorkbook都是继承自Workbook,HSSFSheet和XSSFSheet都是继承自Sheet,HSSFRow和XSSFRow都是继承自Row,…,正式这种继承关系,我们就可以使用面向对象中的多态,对代码进行少许改动就能达到同时支持Excel 2003和Excel 2007。

在ExcelReaderUtil中添加如下getWorkbook方法:

    private Workbook getWorkbook(FileInputStream inputStream,String excelFilePath) throws IOException {                

        Workbook workbook = null;

     

        if (excelFilePath.endsWith("xlsx")) {

            workbook = new XSSFWorkbook(inputStream);

        } else if (excelFilePath.endsWith("xls")) {

            workbook = new HSSFWorkbook(inputStream);

        } else {

            thrownewIllegalArgumentException("The specified file is not Excel file");

        }

     

        return workbook;

    }

 

这样,在readBooksFromExcelFile方法中直接调用此方法就可以获取excel文件的Workbook对象了,而不用考虑是xls文件还是xlsx文件:

 

 

读Excel文件的其它信息

l  获取指定工作表

Sheet thirdSheet = workbook.getSheetAt(2);

l  获取工作表名称

String sheetName = sheet.getSheetName();

l  获取工作簿中工作表的总数

int numberOfSheets = workbook.getNumberOfSheets();

l  获取工作簿中所有工作表的名称

 技术分享

 

要获取其它更多信息,请查看API文档中WorkbookSheetRow 和 Cell 接口的getXXX()方法。

 

3. 实训任务一解析

编写代码,读取“附件1201320152016学年度第一学期教材计划.xlsx”文档中的内容,将每行数据转换成一个课程类对象和两个教材类对象(主教材对应一个教材对象,辅教材也对应一个教材对象)

类关系图:

 技术分享

 

 

以上是关于Java读Exlcel表格数据的主要内容,如果未能解决你的问题,请参考以下文章

java中ReentrantReadWriteLock读写锁的使用

Excel--03--读Excel生成java代码

用java的poi类读取一个excel表格的内容后再写入到一个新excel表格中的完整代码

android片段表格布局

java中如何读取excel表格中的日期

如何用Java实现将word里的表格数据写入到excel中去