POI和easyExcel
常用信息
-
将用户信息导出Excel表格(导出数据)
-
将Excel表中的信息录入到网站数据库(习题上传),大大减轻网站的录入量
-
介绍
Apache POI是
-
基本功能
HSSF - 提供读写Microsoft Excel格式档案的功能。(03版本,最多支持行数65535行,后缀名.xls) XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。(07版本,无限制,后缀名.xlsx) HWPF - 提供读写Microsoft Word格式档案的功能。 HSLF - 提供读写Microsoft PowerPoint格式档案的功能。 HDGF - 提供读写Microsoft Visio格式档案的功能。
EasyExcel
官方文档:https://www.yuque.com/easyexcel/doc/easyexcel
easyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节约内存著称。
EasyExcel能够大大减少占用内存的主要原因是在解析excel时没有将文件数据一次性全部加载到内存中,而是从磁盘里一行行读取数据,逐个解析。
POI
-
使用说明
创建一个工作簿-->workbook
一个工作簿中有多个表 -->sheet
表中的每一行 -->row
表中的每一列 -->column
行与列组成了单元格 -->cell
-
使用的依赖
org.apache.poi - poi - 3.9
org.apache.poi - poi-ooxml - 3.9
POI-Excel写
03 | 07
03版本
public void testExport() throws Exception {
//表头部分
//1.创建工作簿
HSSFWorkbook hwb = new HSSFWorkbook();
//2.创建一张表
HSSFSheet userSheet = hwb.createSheet("userInfo");
//3.创建三行row
HSSFRow row1 = userSheet.createRow(0);
//4.创建单元格
HSSFCell row1Cell1 = row1.createCell(0);
HSSFCell row1Cell2 = row1.createCell(1);
//5.合并单元格
userSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1));
//6.插入数据
row1Cell1.setCellValue("学生信息");
//列名部分
HSSFRow row2 = userSheet.createRow(1);
HSSFCell row2Cell1 = row2.createCell(0);
HSSFCell row2Cell2 = row2.createCell(1);
row2Cell1.setCellValue("姓名");
row2Cell2.setCellValue("年龄");
//表数据部分
HSSFRow row3 = userSheet.createRow(2);
HSSFCell row3Cell1 = row3.createCell(0);
HSSFCell row3Cell2 = row3.createCell(1);
row3Cell1.setCellValue("张三");
row3Cell2.setCellValue(23);
HSSFRow row4 = userSheet.createRow(3);
HSSFCell row4Cell1 = row4.createCell(0);
HSSFCell row4Cell2 = row4.createCell(1);
row4Cell1.setCellValue("李四");
row4Cell2.setCellValue(24);
HSSFRow row5 = userSheet.createRow(4);
HSSFCell row5Cell1 = row5.createCell(0);
HSSFCell row5Cell2 = row5.createCell(1);
row5Cell1.setCellValue("王五");
row5Cell2.setCellValue(25);
//把数据导入到服务器指定的位置中去
File file = new File("C:\\Users\\zxc98\\Desktop\\user.xls");
FileOutputStream fos = new FileOutputStream(file);
hwb.write(fos);
}
07版本
public void testWrite07() throws IOException {
// 创建新的Excel 工作簿, 只有对象变了
Workbook workbook = new XSSFWorkbook();
// 如要新建一名为"user"的工作表,其语句为:
Sheet sheet = workbook.createSheet("user");
// 创建行(row 1)
Row row1 = sheet.createRow(0);
// 创建单元格(col 1-1)
Cell cell11 = row1.createCell(0);
cell11.setCellValue("今日新增关注");
// 创建单元格(col 1-2)
Cell cell12 = row1.createCell(1);
cell12.setCellValue(666);
// 创建行(row 2)
Row row2 = sheet.createRow(1);
// 创建单元格(col 2-1)
Cell cell21 = row2.createCell(0);
cell21.setCellValue("统计时间");
//创建单元格(第三列)
Cell cell22 = row2.createCell(1);
String dateTime = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell22.setCellValue(dateTime);
// 新建一输出文件流(注意:要先创建文件夹)
FileOutputStream out = new FileOutputStream(path + "user统计表07.xlsx");
// 把相应的Excel 工作簿存盘
workbook.write(out);
// 操作结束,关闭文件
out.close();
System.out.println("文件生成成功");
}
区别:创建的对象不一样,生成的文件的后缀名不一样
大文件写-HSSF(03版)
缺点:最多只能处理65536.否则会抛出异常
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快
大文件写-XSSF(07版)
缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出
优点:可以写较大的数据量
大文件写-SXSSF(07版的优化)
优点:可以写非常大的数据量,如百万条甚至更多,写数据速度非常的快,占用更少的内存
注意:
-
过程中会产生临时文件,需要清理
-
默认由100条记录被保存在内存中,如果超过这个数量,则最前面的数据被写入临时文件
-
如果想自定义内存中数据的量,可以使用
new SXSSFWorkbook(数量)
public void testWrite07BigDataFast() throws IOException {
//记录开始时间
long begin = System.currentTimeMillis();
//创建一个SXSSFWorkbook
Workbook workbook = new SXSSFWorkbook();
//创建一个sheet
Sheet sheet = workbook.createSheet();
//xls文件最大支持65536行
for (int rowNum = 0; rowNum < 100000; rowNum++) {
//创建一个行
Row row = sheet.createRow(rowNum);
for (int cellNum = 0; cellNum < 10; cellNum++) {//创建单元格
Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
}
System.out.println("done");
FileOutputStream out = new FileOutputStream(path + "bigdata07-fast.xlsx");
workbook.write(out);
// 操作结束,关闭文件
out.close();
//清除临时文件
((SXSSFWorkbook) workbook).dispose();
//记录结束时间
long end = System.currentTimeMillis();
System.out.println((double) (end - begin) / 1000);
}
}
POI-Excel读
03 | 07
03版本
public void testImport() throws Exception {
//从指定文件路径获取文件
File file = new File("C:\\Users\\zxc98\\Desktop\\user.xls");
FileInputStream fis = new FileInputStream(file);
//1.创建工作簿
HSSFWorkbook hwb = new HSSFWorkbook(fis);
//2.从工作簿中读取第一页数据
//2.1 根据表名读取
//HSSFSheet userInfo = hwb.getSheet("userInfo");
//2.2 根据索引读取
HSSFSheet userSheet = hwb.getSheetAt(0);
//3.从表里面读取行数据
//3.1 创建一个存储空间
List<User> users = new ArrayList<>();
for (Row row : userSheet) {
int rowNum = row.getRowNum();
if (rowNum < 2) {
continue;
}
//成行读取
String username = row.getCell(0).getStringCellValue();
int age = (int) row.getCell(1).getNumericCellValue();
users.add(new User(username, age));
}
for (User user : users) {
System.out.println(user);
}
}
07版本
public void testRead07() throws Exception {
InputStream is = new FileInputStream(path + "user.xlsx");
Workbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
// 读取第一行第一列
Row row = sheet.getRow(0);
Cell cell = row.getCell(0);
// 输出单元内容
System.out.println(cell.getStringCellValue());
// 操作结束,关闭文件
is.close();
}
读取不同的数据类型
public void testCellType() throws Exception {
InputStream is = new FileInputStream(path + "会员消费商品明细表.xls");
Workbook workbook = new HSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
// 读取标题所有内容
Row rowTitle = sheet.getRow(0);
if (rowTitle != null) {// 行不为空
// 读取cell,获取当前行的所有单元格
int cellCount = rowTitle.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cellCount; cellNum++) {
Cell cell = rowTitle.getCell(cellNum);
if (cell != null) {
int cellType = cell.getCellType();
String cellValue = cell.getStringCellValue();
System.out.print(cellValue + "|");
}
}
System.out.println();
}
// 读取商品列表数据
int rowCount = sheet.getPhysicalNumberOfRows();
for (int rowNum = 1; rowNum < rowCount; rowNum++) {
Row rowData = sheet.getRow(rowNum);
if (rowData != null) {// 行不为空
// 读取cell
int cellCount = rowTitle.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cellCount; cellNum++) {
System.out.print("【" + (rowNum + 1) + "-" + (cellNum + 1) + "】");
Cell cell = rowData.getCell(cellNum);
if (cell != null) {
int cellType = cell.getCellType();
//判断单元格数据类型
String cellValue = "";
switch (cellType) {
case HSSFCell.CELL_TYPE_STRING://字符串
System.out.print("【STRING】");
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN://布尔
System.out.print("【BOOLEAN】");