POI POI介绍
Apache POI 简介是用 Java 编写的免费开源的跨平台的 Java API,Apache POI 提供 API 给 Java 程式对 Microsoft Office(Excel、WORD、PowerPoint、Visio 等)格式档案读和写的功能。POI 为“Poor Obfuscation Implementation”的首字母缩写。
官网以及参考的文档地址:
POI常用的类和接口 Apache POI 包含类和方法,来将 MS Office 所有 OLE 2 文档复合。此 API 组件的列表如下:
HSSF 提供读写 Microsoft Excel XLS 格式档案的功能
XSSF 提供读写 Microsoft Excel OOXML XLSX 格式档案的功能
HWPF 提供读写 Microsoft Word DOC 格式档案的功能
HSLF 提供读写 Microsoft PowerPoint 格式档案的功能
HDGF 提供读 Microsoft Visio 格式档案的功能
……
POI 很强大,不单单可以操作 Excle 还可以操作 PPT、Word……但是我们在实际开发中百分之九十都是操作 Excel 的,使用 POI 操作 Excel 的话无非两种情况一张使用操作 2003 版本的 Excel,一种是操作 2007 版本的 Excel。
POI常用类和方法 使用 POI 操作 Excel 的话无非两种情况一种是操作 2003+ 版本的 Excel,使用的接口对象是(HSSF)开头的对象,另一种是操作 2007+ 版本的 Excel,接口对象是(XSSF)开头。
Excel 中的工作簿、工作表、行、单元格中的关系:
一个 Excel 文件对应于一个 workbook(HSSFWorkbook、XSSFWorkbook)
一个 workbook 可以有多个 sheet(HSSFSheet、XSSFSheet)组成
一个 sheet 是由多个 row(HSSFRow、XSSFRow)组成
一个 row 是由多个 cell(HSSFCell、XSSFCell)组成
2003 版本常用类和方法 HSSFWorkbook:工作簿 工作簿,代表一个 Excel 的整个文档。
1 2 3 4 5 6 7 8 9 10 11 HSSFWorkbook(); HSSFWorkbook(InputStream inputStream); HSSFSheet createSheet (String sheetname) ; HSSFSheet getSheet (String sheetName) ; HSSFSheet getSheetAt (int index) ; HSSFCellStyle createCellStyle () ; int getNumberOfSheets () ; setActiveSheet(int index); write(); write(File newFile); write(OutputStream stream);
HSSFSheet:工作表 1 2 3 4 5 6 7 HSSFRow createRow (int rownum) ; HSSFRow getRow (int index) ; int addMergedRegion (CellRangeAddress region) ; CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol); autoSizeColumn(int column); getLastRowNum(); setColumnWidth(int columnIndex, int width);
HSSFRow:行 1 2 3 4 5 6 HSSFCell createCell (int column) ; HSSFCell setCell (shot index) ;HSSFCell getCell (shot index) ;setRowStyle(HSSFCellStyle style); short getLastCellNum () ; setHeightInPoints(float height);
HSSFCell:单元格 1 2 3 4 5 6 setCellValue(String value); setCellType(); setCellStyle(); String getStringCellValue () ; setCellStyle(HSSFCellStyle style); setCellFormula(String formula);
2007 版本常用类和方法 XSSFWorkbook:工作簿 1 2 3 4 5 6 7 8 9 10 11 XSSF Workbook () ; XSSF Workbook (InputStream inputStream) ; XSSF Sheet createSheet (String sheetname) ; XSSF Sheet getSheet (String sheetName) ; XSSF Sheet getSheetAt (int index) ; XSSF CellStyle createCellStyle () ; int getNumberOfSheets () ; setActiveSheet(int index); write(); write(File newFile); write(OutputStream stream);
XSSFSheet:工作表 1 2 3 4 5 6 7 XSSF Row createRow (int rownum) ; XSSF Row getRow (int index) ; int addMergedRegion (CellRangeAddress region) ; CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol); autoSizeColumn(int column); getLastRowNum(); setColumnWidth(int columnIndex, int width);
XSSFRow :行 1 2 3 4 5 6 XSSF Cell createCell (int column) ; XSSF Cell setCell (shot index) ;XSSF Cell getCell (shot index) ;setRowStyle(XSSF CellStyle style); short getLastCellNum () ; setHeightInPoints(float height);
XSSFCell:单元格 1 2 3 4 5 6 setCellValue(String value); setCellType(); setCellStyle(); String getStringCellValue () ; setCellStyle(XSSF CellStyle style); setCellFormula(String formula);
POI 中 Excel 组成和步骤 组成 Excel 的文件的组成形式:
一个 Excel 文件对应于一个 workbook(XSSFWorkbook,工作薄)
一个 workbook 可以有多个 sheet(XSSFSheet,工作表)组成
一个 sheet 是由多个 row(Row,工作行)组成
一个 row 是由多个 cell(Cell,工作单元格)组成
操作步骤 基于以上几条,如果想对 Excel 文件进行读写的话就要需要执行下面这几个步骤:
用 Workbook 打开或者创建一个 Excel 文件的对象
用上一步的 Excel 对象创建或者获取到一个 Sheet 对象
用 Sheet 对象创建或获取一个 Row 对象
用 Row 对象创建或获取一个 Cell 对象
对 Cell 对象读写
2003 版本和 2007 版本 操作 Excel 文件区分版本如下。
2003+版本(包含 2003)文件的扩展名为 .xls 需要用 HSSFWorkbook 类操作:
2007+ 版本(包含 2007)文件的扩展名为 .xlsx 需要用 XSSFWorkbook 类操作:
需要注意:2003 版本和 2007 版本存在兼容性的问题!2003 最多只有 65536 行!2007 最多是 1048576。
2007 版及以上的其实也是有限制的,最大是 1048576。
实战案例:POI操作案例 注意:poi的引入,从版本 4.0.1 开始,POI 需要 Java 8 或更高版本,目前官网,稳定说的 4.1.2 是最新稳定版本
创建maven工具,并引入依赖
1 2 3 4 5 6 7 8 9 10 11 12 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 4.1.2</version > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi-ooxml</artifactId > <version > 4.1.2</version > </dependency >
写Excel
从上面的接口对于Excel抽取出几个核心对象:
工作薄(Workbook)
工作表(Sheet)
行(行是由单元格组成)(Row)
单元格(Cell)
关系简单来说就是:
一个工作薄中可以有很多个工作表
一个工作中表可以有很多个工作行
一个工作行中可以有很多个工作单元格
03 版本的 POI 操作写 Excel(案例)Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 package com.poi.demo;import org.apache.poi.hssf.usermodel.HSSFWorkbook;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 java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class WriteExcelFor03 { public static void main (String[] args) { String path = "/Users/apple/JavaProject/operation-excel/" ; Workbook workbook = new HSSFWorkbook(); Sheet sheet = workbook.createSheet("excel write test" ); Row row1 = sheet.createRow(0 ); Cell cell1 = row1.createCell(0 ); cell1.setCellValue("name:Jack" ); Cell cell2 = row1.createCell(1 ); cell2.setCellValue("age:20" ); Row row2 = sheet.createRow(1 ); Cell cell21 = row2.createCell(0 ); cell21.setCellValue("name:May" ); Cell cell22 = row2.createCell(1 ); cell22.setCellValue("age:16" ); FileOutputStream fileOutputStream = null ; try { fileOutputStream = new FileOutputStream(path + "excel2003.xls" ); try { ((HSSFWorkbook) workbook).write(fileOutputStream); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (fileOutputStream != null ) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("-----------POI 写入 Excel 成功" ); } }
执行结果:
打开excel:
07 版本的 POI 操作写 Excel(案例)Demo 查看Workbook是一个接口,Java也是面向接口编程的,对象变了接口不嫌,所以说只需把 03 版本的接口实现换为 07 版本的接口实现即可。(HSSFWorkbook 换为 XSSFWorkbook)和把 xxx.xls 结尾的后缀改为 xxx.xlsx。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 package com.poi.demo;import org.apache.poi.hssf.usermodel.HSSFWorkbook;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 java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class WriteExcelFor07 { public static void main (String[] args) { String path = "/Users/apple/JavaProject/operation-excel/" ; Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("excel write test" ); Row row1 = sheet.createRow(0 ); Cell cell1 = row1.createCell(0 ); cell1.setCellValue("name:Jack" ); Cell cell2 = row1.createCell(1 ); cell2.setCellValue("age:20" ); Row row2 = sheet.createRow(1 ); Cell cell21 = row2.createCell(0 ); cell21.setCellValue("name:May" ); Cell cell22 = row2.createCell(1 ); cell22.setCellValue("age:16" ); FileOutputStream fileOutputStream = null ; try { fileOutputStream = new FileOutputStream(path + "excel2007.xlsx" ); try { workbook.write(fileOutputStream); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (fileOutputStream != null ) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("-----------POI 写入 Excel 成功" ); } }
执行结果:
读Excel 03 版本的 POI 操作读 Excel(案例)Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.poi.demo;import org.apache.poi.hssf.usermodel.HSSFWorkbook;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 java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class ReadExcelFor03 { public static void main (String[] args) { String path = "/Users/apple/JavaProject/operation-excel/" ; FileInputStream fileInputStream = null ; try { fileInputStream = new FileInputStream(path + "excel2003.xls" ); Workbook workbook = new HSSFWorkbook(fileInputStream); Sheet sheet = workbook.getSheetAt(0 ); Row row1 = sheet.getRow(0 ); Cell cell1 = row1.getCell(0 ); System.out.println(cell1.getStringCellValue()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fileInputStream != null ) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
07 版本的 POI 操作读 Excel(案例)Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.poi.demo;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;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class ReadExcelFor07 { public static void main (String[] args) { String path = "/Users/apple/JavaProject/operation-excel/" ; FileInputStream fileInputStream = null ; try { fileInputStream = new FileInputStream(path + "excel2007.xlsx" ); Workbook workbook = new XSSFWorkbook(fileInputStream); Sheet sheet = workbook.getSheetAt(0 ); Row row1 = sheet.getRow(0 ); Cell cell1 = row1.getCell(0 ); System.out.println(cell1.getStringCellValue()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fileInputStream != null ) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
读取 Excel 时不同的数据类型怎样处理 Excel 中是可以给列设置数据类型的,那不同的类型数据,我们应该怎样获取?
注意,在读取单元格的值时需要先判断数据类型,不然获取数据会报数据类型错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 package com.poi.demo;import cn.hutool.core.date.DateTime;import org.apache.poi.ss.usermodel.*;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.util.Date;public class ExcelCellType { public static void main (String[] args) { String path = "/Users/apple/JavaProject/operation-excel/" ; FileInputStream fileInputStream = null ; try { fileInputStream = new FileInputStream(path + "type.xlsx" ); Workbook workbook = new XSSFWorkbook(fileInputStream); Sheet sheet = workbook.getSheetAt(0 ); Row rowTitle = sheet.getRow(0 ); if (null != rowTitle) { int cellCount = rowTitle.getPhysicalNumberOfCells(); for (int cellNumber = 0 ; cellNumber < cellCount; cellNumber++) { Cell cell = rowTitle.getCell(cellNumber); if (null != cell) { CellType cellType = cell.getCellType(); String cellValue = cell.getStringCellValue(); System.out.print(cellValue + "||" ); } } System.out.println(); } int rowCount = sheet.getPhysicalNumberOfRows(); for (int rowNumber = 1 ; rowNumber < rowCount; rowNumber++) { Row rowData = sheet.getRow(rowNumber); if (null != rowData) { int cellCount = rowTitle.getPhysicalNumberOfCells(); for (int cellNumber = 0 ; cellNumber < cellCount; cellNumber++) { Cell cell = rowData.getCell(cellNumber); if (null != cell) { CellType cellType = cell.getCellType(); String cellValue = "" ; switch (cellType) { case STRING: cellValue = cell.getStringCellValue(); break ; case BOOLEAN: cellValue = String.valueOf(cell.getStringCellValue()); break ; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { System.out.print("【日期】" ); Date date = cell.getDateCellValue(); cellValue = new DateTime(date).toString("yyyy-MM-dd" ); } else { System.out.print("【转换为字符串输出】" ); cell.setCellType(CellType.STRING); cellValue = cell.toString(); } break ; case BLANK: System.out.print("【BLANK】" ); break ; case ERROR: System.out.print("【数据类型错误】" ); break ; } System.out.println(cellValue); } } } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fileInputStream != null ) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }