一、POI操作Excel
1、Excel简介
一个excel文件就是一个工作簿workbook,一个工作簿中可以创建多张工作表sheet,而一个工作表中包含多个单元格Cell,这些单元格都是由列(Column)行(Row)组成,列用大写英文字母表示,从A开始到Z共26列,然后再从AA到AZ又26列,再从BA到BZ再26列以此类推。行则使用数字表示,例如;A3 表示第三行第一列,E5表示第五行第五列。
2、POI工具包
JAVA中操作Excel的有两种比较主流的工具包: JXL 和 POI 。
① JXL只能操作Excel 95, 97, 2000也即以.xls为后缀的excel
② POI可以操作Excel 95及以后的版本,即可操作后缀为 .xls 和 .xlsx两种格式的excel
3、POI全称 Poor Obfuscation Implementation,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能。
① 官网:http://poi.apache.org ,
② POI支持office的所有版本,并且在接下来的演示中需要从前端页面导入用户上传的版本不确定的excel文件,所以选择POI来讲解。
4、在官网下载完后,打开“poi-bin-3.10.1-20140818”获取操作excel需要的jar包,并将这些jar包复制到项目中。
对于只操作2003 及以前版本的excel,只需要poi-3.10.1-20140818.jar
,如果需要同时对2007及以后版本进行操作则需要复制poi-ooxml-3.10.1-20140818.jar
,poi-ooxml-schemas-3.10.1-20140818.jar
,以及复制在ooxml-lib目录下的xmlbeans-2.6.0.jar
,dom4j-1.6.1.jar
5、POI 简单操作
在POI包中有如下几个主要对象和Excel的几个对象对应
POI | Excel |
---|---|
HSSFWorkbook、XSSFWorkbook | Excel 工作簿workbook |
HSSFSheet、XSSFSheet | Excel 工作表 sheet |
HSSFRow、XSSFRow | Excel 行 |
HSSFCell、XSSFCell | Excel 单元格 |
public class TestPOI2Excel {
@Test
// 写入数据到Excel03
public void testWrite03Excel() throws Exception {
//1、创建工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
//2、创建工作表
HSSFSheet sheet = workbook.createSheet("hello world");//指定工作表名
//3、创建行;创建第3行
HSSFRow row = sheet.createRow(2);
//4、创建单元格;创建第3行第3列
HSSFCell cell = row.createCell(2);
cell.setCellValue("Hello World");
//输出到硬盘
FileOutputStream outputStream = new FileOutputStream("D:\\itcast\\测试.xls");
//把excel输出到具体的地址
workbook.write(outputStream);
workbook.close();
outputStream.close();
}
@Test
// 写入数据到Excel07
public void testWrite07Excel() throws Exception {
//1、创建工作簿
XSSFWorkbook workbook = new XSSFWorkbook();
//2、创建工作表
XSSFSheet sheet = workbook.createSheet("hello world");//指定工作表名
//3、创建行;创建第3行
XSSFRow row = sheet.createRow(2);
//4、创建单元格;创建第3行第3列
XSSFCell cell = row.createCell(2);
cell.setCellValue("Hello World");
//输出到硬盘
FileOutputStream outputStream = new FileOutputStream("D:\\itcast\\测试.xlsx");
//把excel输出到具体的地址
workbook.write(outputStream);
workbook.close();
outputStream.close();
}
@Test
// 从Excel03读取数据
public void testRead03Excel() throws Exception {
FileInputStream inputStream = new FileInputStream("D:\\itcast\\测试.xls");
//1、读取工作簿
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
//2、读取第一个工作表
HSSFSheet sheet = workbook.getSheetAt(0);
//3、读取行;读取第3行
HSSFRow row = sheet.getRow(2);
//4、读取单元格;读取第3行第3列
HSSFCell cell = row.getCell(2);
System.out.println("第3行第3列单元格的内容为:" + cell.getStringCellValue());
workbook.close();
inputStream.close();
}
@Test
// 从Excel07读取数据
public void testRead07Excel() throws Exception {
FileInputStream inputStream = new FileInputStream("D:\\itcast\\测试.xlsx");
//1、读取工作簿
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
//2、读取第一个工作表
XSSFSheet sheet = workbook.getSheetAt(0);
//3、读取行;读取第3行
XSSFRow row = sheet.getRow(2);
//4、读取单元格;读取第3行第3列
XSSFCell cell = row.getCell(2);
System.out.println("第3行第3列单元格的内容为:" + cell.getStringCellValue());
workbook.close();
inputStream.close();
}
@Test
// 从Excel03或07读取数据
public void testRead03And07Excel() throws Exception {
String fileName = "D:\\itcast\\测试.xlsx";
if(fileName.matches("^.+\\.(?i)((xls)|(xlsx))$")){//判断是否excel文档
boolean is03Excel = fileName.matches("^.+\\.(?i)(xls)$");
FileInputStream inputStream = new FileInputStream(fileName);
//1、读取工作簿
Workbook workbook = is03Excel ?new HSSFWorkbook(inputStream):new XSSFWorkbook(inputStream);
//2、读取第一个工作表
Sheet sheet = workbook.getSheetAt(0);
//3、读取行;读取第3行
Row row = sheet.getRow(2);
//4、读取单元格;读取第3行第3列
Cell cell = row.getCell(2);
System.out.println("第3行第3列单元格的内容为:" + cell.getStringCellValue());
workbook.close();
inputStream.close();
}
}
}
从POI-API文档中我们了解到:
① HSSFWorkbook 和 XSSFWorkbook 都实现了Workbook接口;
② HSSFSheet 和 XSSFSheet 实现了Sheet接口;
③ HSSFRow 和 XSSFRow 实现了Row接口;
④ HSSFCell 和 XSSFCell 实现了Cell接口。
因为这两类处理对象共同实现了对应的同一接口,届时将大大方便和简化了同时处理不同格式的excel文件的编码工作。如:在处理03和07版本的excel文件时利用统一的接口就可以做到分析两个版本的excel数据。
6、格式化Excel
在POI中可以利用格式化对象来格式化excel文档,也即设置excel内容的样式。POI中主要的格式化对象常用的有合并单元格、设置单元格字体、边框,背景颜色等。
① 合并单元格
在POI中有一个CellRangeAddress对象,中文直译是【单元格范围地址】,主要用于在单元格的合并上,这个对象的构造方法CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
有4个参数,分别表示(起始行号,终止行号, 起始列号,终止列号)
, 设置这个对象中要合并的单元格范围后,工作表对象sheet调用方法addMergedRegion(CellRangeAddress region)
,将上述设置的CellRangeAddress对象作为参数传入即可合并单元格。
【注意】合并单元格后,单元格的名称是第一个单元格,即上面中合并了第二行的第二列到第五列,合并后的单元格叫B2,而其它被合并的单元格已经无效了,不能对无效单元格设置值,如果进行了设置将不显示
② 设置单元格样式
首先要设置单元格样式则要先初始化POI中的单元格样式对象HSSFCellStyle,然后在样式对象中设置不同的样式(内容位置、字体、背景、颜色、边框等)。单元格样式是由工作簿workbook创建的,一个工作簿可以创建多个样式。
◇ 设置单元格内容位置;设置水平位置 setAlignment(short align)
,设置垂直位置setVerticalAlignment(short align)
◇ 设置单元格字体;POI中的字体对象为HSSFFont,字体是由工作簿创建,可以用于多个单元格上。
◇ 设置单元格背景色。
@Test
public void testExcelStyle() throws Exception {
//1、创建工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
//1.1、创建合并单元格对象;合并第3行的第3列到第5列
CellRangeAddress cellRangeAddress = new CellRangeAddress(2, 2, 2, 4);//起始行号,结束行号,起始列号,结束列号
//1.2、创建单元格样式
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
//1.3、创建字体
HSSFFont font = workbook.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//加粗字体
font.setFontHeightInPoints((short) 16);//设置字体大小
//加载字体
style.setFont(font);
//单元格背景
//设置背景填充模式
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//设置填充背景色
style.setFillBackgroundColor(HSSFColor.YELLOW.index);
//设置填充前景色
style.setFillForegroundColor(HSSFColor.RED.index);
//2、创建工作表
HSSFSheet sheet = workbook.createSheet("Hello World");//指定工作表名
//2.1、加载合并单元格对象
sheet.addMergedRegion(cellRangeAddress);
//3、创建行;创建第3行
HSSFRow row = sheet.createRow(2);
//4、创建单元格;创建第3行第3列
HSSFCell cell = row.createCell(2);
//加载样式
cell.setCellStyle(style);
cell.setCellValue("Hello World!");
//输出到硬盘
FileOutputStream outputStream = new FileOutputStream("D:\\itcast\\测试.xls");
//把excel输出到具体的地址
workbook.write(outputStream);
workbook.close();
outputStream.close();
}
7、POI应用案例
【需求1】在项目数据库中,有一张用户表user,里面有系统的用户数据;现在需要将这个用户表的数据导出到excel中提供用户下载。要求excel要有个一个主标题,各个列名称。
【分析】① 从数据库中读取用户数据;② 创建excel并写入数据; ③ 将excel输出到浏览器提供用户下载。
【编码】利用POI中的HSSFWorkbook创建一个excel,再利用 HSSFSheet 创建一个sheet,HSSFRow/HSSFCell创建行/列。创建的excel第一行标题(CellRangeAddress合并单元格),第二行列名,第三行开始是具体用户数据。
【注意】在输出excel时,要设定要好respone的头部ContentType为application/octet-stream或者application/x-excel,Header的Content-Disposition要正确设置下载文件名称编码,以便可以在各大浏览器中都能够正确输出中文的下载文件名称。
【需求2】将一张有用户数据的Excel导入到数据库中并展示在页面。
【分析】① 获取excel数据;② 解析excel 数据;③ 插入数据到数据库。
【编码】使用正则表达式^.+\\.(?i)((xls)|(xlsx))$
判断用户上传的excel是什么版本,使用HSSFWorkbook来读取2003以前版本,使用XSSFWorkbook来读取2007及以后版本。逐个遍历sheet,row,cell获取每个单元格对应数据并将数据转换为用户对象插入数据库中,当导入完毕后返回列表页面。