HSSF [1] - 提供读写Microsoft Excel -- XLS格式档案的功能。
XSSF [1] - 提供读写Microsoft Excel OOXML -- XLSX格式档案的功能。
HWPF [1] - 提供读写Microsoft Word -- DOC格式档案的功能。
HSLF [1] - 提供读写Microsoft -- PowerPoint格式档案的功能。
HDGF [1] - 提供读Microsoft -- Visio格式档案的功能。
HPBF [1] - 提供读Microsoft -- Publisher格式档案的功能。
HSMF [1] - 提供读Microsoft -- Outlook格式档案的功能。
1、将用户信息导出为excel表格(导出数据…)
2、将Excel表中的信息录入到网站数据库(习题上传…)大大减轻网站录入量!开发中经常会设计到excel的处理,如导出Excel,导入Excel到数据库中!
操作Excel目前比较流行的就是Apache POI和阿里巴巴的easyExcel !
图片来自 EasyExcel 文档
POI 是将excel中的数据一次性全部放入内存中
优点︰过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快
<dependencies>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>3.9version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.9version>
dependency>
<dependency>
<groupId>joda-timegroupId>
<artifactId>joda-timeartifactId>
<version>2.10.1version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
dependencies>
我们需要知道excel有多少个对象【万物皆对象】我们需要有面向对象的思想,整张表、sheet 、行、列都是对象
我们需要知道excel有03【.xls】版本和07【.xlsx】版本
实现遍历65535行账号和密码, 具体实现类是HSSFWorkbook ,记得修改文件输出的路径
private static String path = System.getProperty("user.dir");
public static void main(String[] args) throws Exception {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("账户密码信息");
//第一行
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("账户");
Cell cell1 = row.createCell(1);
cell1.setCellValue("密码");
for (int i = 1; i < 65535; i++) {
Row row2 = sheet.createRow(i);
Cell cell2 = row2.createCell(0);
cell2.setCellValue(12345678+i);
Cell cell22 = row2.createCell(1);
cell22.setCellValue(123456+i);
}
FileOutputStream fileOutputStream = new FileOutputStream(path + "\\旧版本账户表.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
System.out.println("完成");
}
执行完成后会生成.xls文件
打开.xls文件展示:最多有65536行
以.xls结尾的excel不能超过65536行,超过会报java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
我们是面向接口编程的,所有只需要修改Workbook 的具体实现类 XSSFWorkbook ,文件输出的位置和名称需要更改是 .xlsx结尾
private static String path = System.getProperty("user.dir");
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("账户密码信息2");
//第一行
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("账户");
Cell cell1 = row.createCell(1);
cell1.setCellValue("密码");
for (int i = 1; i < 65536; i++) {
Row row2 = sheet.createRow(i);
Cell cell2 = row2.createCell(0);
cell2.setCellValue(12345678+i);
Cell cell22 = row2.createCell(1);
cell22.setCellValue(123456+i);
}
FileOutputStream fileOutputStream = new FileOutputStream(path + "\\新版本账户表.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
System.out.println("完成");
}
执行完成后会创建.xlsx文件
打开文件可以看到xlsx07对行数没有限制
缺点︰写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条
优点:可以写较大的数据量,如20万条
@Test
public static void testWriter03BigData() throws Exception{
long begin = System.currentTimeMillis();
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
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);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(path + "\\测试大文件.xlsx");
workbook.write(fileOutputStream);
System.out.println("写完成");
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println("07版本写大文件耗时:"+(double) (end - begin)/1000);
}
写大文件
SXSSF写大文件 优点:可以写非常大的数据量,如100万条甚至更多条,韦数据速度快占用更少的内存
注意∶
过程中会产生临时文件,需要清理临时文件
默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook(数量)
使用实体SXSSFWorkbook对象的dispose方法来清除缓存可以解决 07版本写大文件耗时的问题
((SXSSFWorkbook)workbook).dispose();
public static void testWriter03BigData2() throws Exception{
long begin = System.currentTimeMillis();
Workbook workbook = new SXSSFWorkbook();
Sheet sheet = workbook.createSheet();
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);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(path + "\\测试大文件解决耗时.xlsx");
workbook.write(fileOutputStream);
System.out.println("写完成");
fileOutputStream.close();
//清除缓存
((SXSSFWorkbook)workbook).dispose();
long end = System.currentTimeMillis();
System.out.println("07版本写大文件耗时:"+(double) (end - begin)/1000);
}
运行速度大大提高了
SXSSFWorkbook来至官方的解释:实现"BigGridDemo"策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。
请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注和…当然只存储在内存中,因此如果广泛使用,可能需要大量内存。
注意获取类型
public void testReader() throws Exception{
// 获取文件流
FileInputStream fis = new FileInputStream(path + "\\新版本账户表.xlsx");
// 1、创建一个工作簿 ,
Workbook workbook = new XSSFWorkbook(fis);
// 2、得到表
Sheet sheet = workbook.getSheetAt(0);
// 3、的到行
Row row = sheet.getRow(1);
// 4、得到列
Cell cell1 = row.getCell(0);
Cell cell2 = row.getCell(1);
//读取值的时候,注意类型
System.out.println("账户 = "+cell1.getNumericCellValue());
System.out.println("密码 = "+cell2.getNumericCellValue());
System.out.println("读完成");
fis.close();
}
直接 ‘码’ 上
public void testReader2() throws Exception{
// 获取文件流
FileInputStream fis = new FileInputStream(path + "\\data.xlsx");
// 1、创建一个工作簿 ,
Workbook workbook = new XSSFWorkbook(fis);
// 2、得到表
Sheet sheet = workbook.getSheetAt(0);
// 3、获取标题内容
Row rowTitle = sheet.getRow(0);
//判断是否非空 , 重点
if(rowTitle != null){
//获取列的数量
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){
//读取全部的列
int cellCount = rowData.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("【Bealean】");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK: // 空
System.out.print("【BLANK】");
break;
case HSSFCell.CELL_TYPE_NUMERIC: //数字 包含[日期、普通数字]
System.out.print("【NUMERIC】");
if(HSSFDateUtil.isCellDateFormatted(cell)){ //如果是日期
System.out.print("【日期】");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
}else {
//不是日期格式, 防止数字过长 转换成字符串输出
System.out.print("【转换为字符串输出】");
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cellValue = cell.toString();
}
break;
case HSSFCell.CELL_TYPE_ERROR:// 数据类型错误
System.out.println("【数据类型错误】");
break;
}
System.out.println(cellValue);
}
}
}
}
System.out.println("读完成");
fis.close();
}
执行结果展示
直接 "码"上了
public void testFormula() throws Exception{
// 获取文件流
FileInputStream fis = new FileInputStream(path + "\\公式demo.xlsx");
// 1、创建一个工作簿 , HSSFWorkbook 03版本
Workbook workbook = new XSSFWorkbook(fis);
// 2、得到表
Sheet sheet = workbook.getSheetAt(0);
// 3、获取行 求和 在第四行
Row row = sheet.getRow(4);
Cell cell = row.getCell(0);
//拿到计算公司 eval
FormulaEvaluator formulaEvaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
// 输出单元格的内容
int cellType = cell.getCellType();
switch (cellType){
case Cell.CELL_TYPE_FORMULA://公式
String formula = cell.getCellFormula();
System.out.println("formula = " + formula);
//计算
CellValue evaluate = formulaEvaluator.evaluate(cell);
String cellValue = evaluate.formatAsString();
System.out.println("cellValue = " + cellValue);
break;
}
}
展示执行结果
copy 官网
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便
它就是 alibaba 的 EasyExcel 官方文档
其实文档写很清楚,但是我也看了很久【我木】我自己也写了一个简单的文档,有手就可以。。。可以看看这篇=>EasyExcel 简单使用操作
好习惯就是不会忘了提供视频学习地址=> 狂神说