Apache POI 官网:http://poi.apache.org/
POI 是什么?
POI 是 Apache 软件基金会开源的项目,根据官网的解释,POI提供了操作Office Open XML (OOXML)标准和微软 OLE 2 Compound Document (OLE2)格式文档的接口。OLE2 文件包括微软office 中的 xls、doc、ppt 文件,ooxml格式是新的格式标准,包含 xlsx、docx、pptx 文件。
简单来说,POI 让你能用 java 读/写 Excel、Word、PPT文件。
POI 的组件:
组件名
应用 类型
POIFS
OLE2 文件系统
HPSF
OLE2 属性集
HSSF
Excel xls
HSLF
PowerPoint ppt
HWPF
Word doc
HDGF
Visio vsd
HPBF
Publisher pub
HSMF
Outlook msg
DDF
埃舍尔通用图纸
HWMF
WMF图纸
OpenXML4j
OOXML
XSSF
Excel xlsx
XSLF
PowerPoint pptx
XWPF
Word docx
XDGF
Visio vsdx
Common SL
PowerPoint ppt和pptx
Common SS
Excel xls和xlsx
参考地址:http://poi.apache.org/overview.html
POI 能做什么?
POI 被设计来用 java 处理 office 文件,处理 Excel 文件非常好用,处理 word 和 ppt 文件的功能相对差一点。此外,POI还对 Outlook、Visio、TNEF、Publisher 文件提供支持。
POI 多被用于文本抽取应用,如网络爬虫、索引构建和内容管理系统。
如果你需要用 java 来读写 OLE2 文件,POI是至今最完整和正确的实现方式。POI 提供最简单的接口来操作各种 Excel 文件,而且拥有高级接口实现(SXSSF)可以优化内存来写很大的 Excel 文件。
同类产品有什么?
使用 POI 操作 Excel 文件
使用 POI 读、写 Excel 文件的流程
获得工作簿对象(HSSFWorkBook),可以创建新的,也可以从输入流打开
获得工作表(HSSFSheet),可以通过工作簿对象创建或获取
获得行(HSSFRow),通过工作表创建或获取
获得列(HSSFCell),通过行创建或获取
设置、获取表格中的数据
在 maven 项目使用 POI 读写 Excel 文件
创建maven项目
创建好 maven 项目,导入 Apache POI 的依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > xyz.wqf31415</groupId > <artifactId > poi-demo</artifactId > <version > 1.0-SNAPSHOT</version > <dependencies > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 3.17</version > </dependency > </dependencies > </project >
将数据写入到 Excel 文件(createExcelFile)、从 Excel 文件中读取数据(readExcelFile)
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 public class PoiDemoApp { public static void main (String[] args) { createExcelFile(); readExcelFile(); } public static void createExcelFile () { HSSFWorkbook workbook = new HSSFWorkbook (); HSSFSheet sheet = workbook.createSheet("名单" ); HSSFRow row0 = sheet.createRow(0 ); row0.createCell(0 ).setCellValue("姓名" ); row0.createCell(1 ).setCellValue("性别" ); row0.createCell(2 ).setCellValue("年龄" ); HSSFRow row1 = sheet.createRow(1 ); row1.createCell(0 ).setCellValue("张三" ); row1.createCell(1 ).setCellValue("男" ); row1.createCell(2 ).setCellValue(18 ); HSSFRow row2 = sheet.createRow(2 ); row2.createCell(0 ).setCellValue("李四" ); row2.createCell(1 ).setCellValue("女" ); row2.createCell(2 ).setCellValue(17 ); File excelFile = new File ("F:\\list.xls" ); try { FileOutputStream outPutStream = new FileOutputStream (excelFile); workbook.write(outPutStream); outPutStream.flush(); outPutStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void readExcelFile () { File excelFile = new File ("F:\\list.xls" ); try { FileInputStream inputStream = new FileInputStream (excelFile); HSSFWorkbook workbook = new HSSFWorkbook (inputStream); HSSFSheet sheet = workbook.getSheet("名单" ); HSSFRow row0 = sheet.getRow(0 ); System.out.print(row0.getCell(0 )+"\t" ); System.out.print(row0.getCell(1 )+"\t" ); System.out.print(row0.getCell(2 )+"\n" ); HSSFRow row1 = sheet.getRow(1 ); System.out.print(row1.getCell(0 )+"\t" ); System.out.print(row1.getCell(1 )+"\t" ); System.out.print(row1.getCell(2 )+"\n" ); HSSFRow row2 = sheet.getRow(2 ); System.out.print(row2.getCell(0 )+"\t" ); System.out.print(row2.getCell(1 )+"\t" ); System.out.print(row2.getCell(2 )+"\n" ); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
运行之后将在 F 盘根目录创建 list.xls
文件,并在控制台打出从 list.xls
文件中获取的数据。
在 java 项目中使用 POI
到 Apache 官网下载 POI 的 jar 包并导入项目中即可使用。
在 SpringBoot 项目中使用 POI
创建 SpringBoot web 项目,并在依赖中添加 POI 的依赖
demo 项目的 git 地址:https://git.coding.net/wqf31415/spring-boot-poi.git
创建 SpringBoot 项目的过程不再赘述,可参考《创建SpringBoot项目》 ,项目 pom.xml 如下所示:
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 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > xyz.wqf31415</groupId > <artifactId > spring-boot-poi</artifactId > <version > 0.0.1-SNAPSHOT</version > <packaging > jar</packaging > <name > spring-boot-poi</name > <description > Demo project for Spring Boot</description > <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 1.5.10.RELEASE</version > <relativePath /> </parent > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <project.reporting.outputEncoding > UTF-8</project.reporting.outputEncoding > <java.version > 1.8</java.version > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 3.17</version > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > </build > </project >
下载 Excel 文件的 Controller 类
用 POI 创建并生成 Excel 工作簿,添加表格内容,使用工作簿对象的 write(OutPutStream stream)
方法将内容写到 http 响应的输出流中。
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 @RestController @RequestMapping("/excel") public class ExcelController { @RequestMapping("/download") public void download (HttpServletResponse response) { HSSFWorkbook workbook = new HSSFWorkbook (); HSSFSheet sheet = workbook.createSheet("sheet0" ); HSSFRow row0 = sheet.createRow(0 ); row0.createCell(0 ).setCellValue("姓名" ); row0.createCell(1 ).setCellValue("年龄" ); row0.createCell(2 ).setCellValue("性别" ); row0.createCell(3 ).setCellValue("电话" ); HSSFRow row1 = sheet.createRow(1 ); row1.createCell(0 ).setCellValue("张三" ); row1.createCell(1 ).setCellValue(18 ); row1.createCell(2 ).setCellValue("男" ); row1.createCell(3 ).setCellValue("87878787" ); String excelFileName = "details.xls" ; try { ServletOutputStream out = response.getOutputStream(); response.reset(); response.setHeader("Content-disposition" , "attachment; filename=" + excelFileName); response.setContentType("application/msexcel" ); workbook.write(out); out.close(); } catch (IOException e) { e.printStackTrace(); } } }
访问:http://localhost:8080/excel/download 即可下载 Excel文档。
注意事项
工作表名的命名
Excel 表格的工作表(sheet)名称 长度不能超过31个字符 ,不能包含 0x000 0x003 : \ * / ? : [ ]
可以用 POI 提供的工具类创建正确的工作表名,非法字符将被替换成空格,以下代码将返回 s h e e t 1
1 String sheetName = WorkbookUtil.createSafeSheetName("[s/h*e:e?t\\1]" );
表格数据类型
可插入单元格(Cell)的数据类型
单元格(Cell)中支持的数据类型有 Double 、Date 、Calendar 、String 、Boolean 、RichTextString 。
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 Workbook workbook = new HSSFWorkbook ();CreationHelper helper = workbook.getCreationHelper(); Sheet sheet = workbook.createSheet(); Row row_0 = sheet.createRow(0 ); row_0.createCell(0 ).setCellValue("Double" ); row_0.createCell(1 ).setCellValue("Date" ); row_0.createCell(2 ).setCellValue("Calendar" ); row_0.createCell(3 ).setCellValue("String" ); row_0.createCell(4 ).setCellValue("Boolean" ); row_0.createCell(5 ).setCellValue("RichTextString" ); Row row_1 = sheet.createRow(1 );Cell cell_1_0 = row_1.createCell(0 );Double d = 3.14 ;cell_1_0.setCellValue(d); Cell cell_1_1 = row_1.createCell(1 );Date date = new Date ();cell_1_1.setCellValue(date); Cell cell_1_2 = row_1.createCell(2 );Calendar calendar = Calendar.getInstance();cell_1_2.setCellValue(calendar); Cell cell_1_3 = row_1.createCell(3 );String str = "String" ;cell_1_3.setCellValue(str); Cell cell_1_4 = row_1.createCell(4 );boolean b = true ;cell_1_4.setCellValue(b); Cell cell_1_5 = row_1.createCell(5 );RichTextString richTextString = helper.createRichTextString("富文本" );cell_1_5.setCellValue(richTextString);
从单元格(Cell)中获取的数据格式
从已有的 Excel 文件中获取的单元格数据类型有:String (字符串)、Numric (数字类型,包括数字和日期数据)、boolean (布尔型)、Formula (公式)、Blank (空值),获取方式如下:
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 DataFormatter formatter = new DataFormatter ();String text = formatter.formatCellValue(cell);CellType cellType = cell.getCellTypeEnum();switch (cellType) { case NUMERIC: if (DateUtil.isCellDateFormatted(cell)){ Date date = cell.getDateCellValue(); }else { Double d = cell.getNumericCellValue(); } break ; case STRING: String str = cell.getStringCellValue(); break ; case BOOLEAN: boolean b = cell.getBooleanCellValue(); break ; case FORMULA: String formula = cell.getCellFormula(); break ; case BLANK: break ; default : }
创建 .xls 或 .xlsx 文件
我们知道 .xls 是 Excel 03版的文件扩展名,.xlsx 是 07版的,我们可以分别通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来新建或打开。
其中,使用 XSSFWorkbook 需要导入 poi-ooxml
依赖:
1 2 3 4 5 6 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi-ooxml</artifactId > <version > 3.17</version > </dependency >
创建或打开 Excel 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 Workbook workbook1 = new HSSFWorkbook ();InputStream stream1 = new FileInputStream ("D:\\test.xls" );Workbook workbook2 = new HSSFWorkbook (stream1);Workbook workbook3 = new XSSFWorkbook ();InputStream stream2 = new FileInputStream ("D:\\test.xlsx" );Workbook workbook4 = new HSSFWorkbook (stream2);
设置单元格对齐方式
通过设置单元格(Cell)的样式(CellStyle)中的水平对齐(HorizontalAlignment)和垂直对齐(VerticalAlignment)来控制内容的对齐方式。
水平对齐方式包括:GENERAL (常规)、LEFT (左对齐)、CENTER (居中对齐)、RIGHT (右对齐)、FILL (填充)、JUSTIFY (两端对齐)、CENTER_SELECTION (居中选择)、DISTRIBUTED (分散对齐)
垂直对齐方式包括:TOP (顶部对齐)、CENTER (垂直居中)、BOTTOM (底部对齐)、JUSTIFY (两端对齐)、DISTRIBUTED (分散对齐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Workbook workbook = new XSSFWorkbook ();Sheet sheet = workbook.createSheet("alignSheet" );Row row_0 = sheet.createRow(0 );Cell cell_0_0 = row_0.createCell(0 );CellStyle cellStyle0 = workbook.createCellStyle();cellStyle0.setAlignment(HorizontalAlignment.LEFT); cellStyle0.setVerticalAlignment(VerticalAlignment.TOP); cell_0_0.setCellStyle(cellStyle0); cell_0_0.setCellValue("左上" ); Cell cell_0_1 = row_0.createCell(1 );CellStyle cellStyle1 = workbook.createCellStyle();cellStyle1.setAlignment(HorizontalAlignment.CENTER); cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER); cell_0_1.setCellStyle(cellStyle1); cell_0_1.setCellValue("中间" ); Cell cell_0_2 = row_0.createCell(2 );CellStyle cellStyle2 = workbook.createCellStyle();cellStyle2.setAlignment(HorizontalAlignment.RIGHT); cellStyle2.setVerticalAlignment(VerticalAlignment.BOTTOM); cell_0_2.setCellStyle(cellStyle2); cell_0_2.setCellValue("右下" );
设置边框
创建单元格样式(CellStyle),可设置单元格边框类型和颜色。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Workbook workbook = new HSSFWorkbook ();Sheet sheet = workbook.createSheet("border" );Row row = sheet.createRow(1 );Cell cell = row.createCell(1 );cell.setCellValue("边框" ); CellStyle cellStyle = workbook.createCellStyle();cellStyle.setBorderTop(BorderStyle.DOUBLE); cellStyle.setTopBorderColor(IndexedColors.BLUE.getIndex()); cellStyle.setBorderRight(BorderStyle.DASH_DOT); cellStyle.setRightBorderColor(IndexedColors.RED.getIndex()); cellStyle.setBorderBottom(BorderStyle.DOTTED); cellStyle.setBottomBorderColor(IndexedColors.GREEN.getIndex()); cellStyle.setBorderLeft(BorderStyle.DASH_DOT_DOT); cellStyle.setLeftBorderColor(IndexedColors.YELLOW.getIndex()); cell.setCellStyle(cellStyle);
大量数据导出
在 Excel 2003 中每个 sheet 最多支持 65536 行数据,对应 POI 中的 HSSF 对象,可以用来处理较少的数据量,如果需要处理大量数据,可以添加多个 sheet。
Excel 2007 以上版本中,每个 sheet 最多支持 1048576 行数据,对应 POI 中 XSSF 对象,这时就可以在一个表格页中导出 100 万条数据了,但要小心堆溢出。
在 POI 3.8 之后版本中新增了 SXSSFWorkbook ,它可以控制 excel 数据占用的内存,通过控制内存中的行数来实现资源管理,当创建对象超过了设定的行数,会自动刷新内存,将数据写入文件。这样占用 CPU 和内存较少。
完结鞠躬