目录
一、03版本和07版本excel区别
首先来说一下03版本与07版本excel的主要区别,包括以下两点:
①文件格式:03版本默认保存为.xls
格式(二进制文件);07版本的默认扩展名为.xlsx
(基于XML的压缩文件)。
②数据量:03版本单个工作表最多支持65536行*256列;07版本支持更大数据量:1,048,576行 × 16,384列。
二、添加依赖
要读写excel,首先需要在maven项目里添加依赖,你需要在pom.xml里添加以下依赖:
<!-- POI Core -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version> <!-- 替换为最新版本 -->
</dependency>
<!-- POI for OOXML (Excel) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
三、excel写入操作
1.基本语法
(1)创建工作簿workbook
03:HSSFWorkbook
07: XSSFWorkbook
(2)创建工作表sheet
(3)创建行row
(4)创建单元格cell
(5)写入数据
cell.setCellValue();xxx
(6)生成一张表-IO流
FileOutputStream OutputStream = new FileOutputStream("xxx.xls"); (07:xlsx)
workbook.write(OutputStream);
(7)关闭输出流
OutputStream.close();
以下为03版本的例子:
public void writeExcel03() throws Exception {
//1.创建工作簿
Workbook workbook = new HSSFWorkbook();
//2.创建工作表
Sheet sheet = workbook.createSheet("03Test");
//3.创建行(第一行)
Row row1 = sheet.createRow(0);
//4.创建单元格(1,1)
Cell cell11 = row1.createCell(0);
//5.写入数据
cell11.setCellValue("商品ID");
//6.写入数据(1,2)
Cell cell12 = row1.createCell(1);
cell12.setCellValue("商品名称");
//第二行
Row row2 = sheet.createRow(1);
Cell cell21 = row2.createCell(0);
cell21.setCellValue(1);
//(2,2)
Cell cell22 = row2.createCell(1);
cell22.setCellValue("鼠标");
//生成一张表-IO流
FileOutputStream OutputStream = new FileOutputStream("./03版本测试.xls");
workbook.write(OutputStream);
//关闭输出流
OutputStream.close();
System.out.println("表格输出完毕!");
}
如果是07版本的话,创建工作簿时,应该是
Workbook workbook = new XSSFWorkbook();
生成IO流的文件后缀改为.xlsx就可以。
2.批量数据写入
当需要批量写入数据时,在创建行、单元格和写入数据时只需要添加一个双重循环即可。
如下以03版本为例:
public void writeBatchData03() throws Exception {
//开始时间
long start = System.currentTimeMillis();
//创建工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
Sheet sheet = workbook.createSheet("03BatchTest");
//写入数据
for (int rowNum = 0; rowNum < 65536; rowNum++) {
Row row = sheet.createRow(rowNum);
for (int cellNum = 0; cellNum < 20; cellNum++) {
Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum+1);
}
}
//生成表
FileOutputStream outputStream = new FileOutputStream("./03BatchData.xls");
workbook.write(outputStream);
//关闭流
outputStream.close();
System.out.println("表格生成完毕");
//结束时间
long end = System.currentTimeMillis();
System.out.println((end-start)/1000);
}
3.大数据量的写入问题
在上面的例子中,添加了一个开始时间和结束时间,目的是为了测试当大数据量写入时需要耗费的时间。经过测试后,可以发现在大数据量写入时比较耗费时间,特别是对应07版本的excel来说。所有在这里提供了SXSSSF来解决大数据量写入问题。
只需要在创建工作簿时利用以下语法即可让时间大大简短:
Workbook workbook = new SXSSFWorkbook();
四、读取excel数据的操作
1.基本语法
(1)通过文件流去读Excel工作簿
(2)获取工作簿
(3)获取表(通过下标的方式来进行读取 或 可以采用表名来进行获取)
(4)获取行(通过下标的方式来进行读取 )
(5)获取单元格(通过下标的方式来进行读取 )
(6)读取数据
(7)关闭流
下面以03版本为例:
public void readExcel03() throws Exception {
//1.通过文件流去读Excel工作簿
FileInputStream inputSream = new FileInputStream("./03版本测试.XLS");
//2.获取工作簿
Workbook workbook = new HSSFWorkbook(inputSream);
//3.获取表(通过下标的方式来进行读取 或 可以采用表名来进行获取)
Sheet sheet = workbook.getSheetAt(0);
//4.获取行(通过下标的方式来进行读取 )
Row row = sheet.getRow(0);
//5.获取单元格(通过下标的方式来进行读取 )
Cell cell = row.getCell(1);
//6.读取数据
String data = cell.getStringCellValue();
System.out.println(data);
//7.关闭流
inputSream.close();
}
如果是07版本的话,通过文件流去读Excel工作簿,应该是把文件后缀改为.xlsx。
获取工作簿时,应该是
Workbook workbook = new XSSFWorkbook(inputSream);
2.数据的批量读取
(1)先读取标题
(2)再读取标题以下的数据
(3)这里需要注意的是每一列数据类型不同,需要根据不同的类型来读取数据
以下为批量读取数据的代码,以03版本为例:
//批量读取
public void readExcelCellType() throws Exception {
//1.通过文件流去读Excel工作簿
FileInputStream inputSream = new FileInputStream("./商品表.XLS");
//2.获取工作簿
Workbook workbook = new HSSFWorkbook(inputSream);
//3.获取表(通过下标的方式来进行读取 或 可以采用表名来进行获取)
Sheet sheet = workbook.getSheetAt(0);
//4.获取标题内容(第一行)
Row title = sheet.getRow(0);
//非空判断
if(title != null) {
//获取标题的单元格数量,用于遍历获取所有的单元格
int cellNum = title.getPhysicalNumberOfCells();
System.out.println(cellNum);
for (int i = 0; i < cellNum; i++) {
//获取所有单元格
Cell cell = title.getCell(i);
if(cell != null) {
//获取单元格中的数据
String value = cell.getStringCellValue();
System.out.println(value);
}
}
}
//获取标题以下的具体内容
//获取一共有多少行数据
int roeNum = sheet.getPhysicalNumberOfRows();
System.out.println(roeNum);
//跳过第一行标题数据,获得以下具体内容
for (int i = 1; i < roeNum; i++) {
Row row = sheet.getRow(i);
if(row != null) {
//获取每一行有多少单元格
int cellNum = row.getPhysicalNumberOfCells();
//遍历每一行单元格的数据
for (int j = 0; j < cellNum; j++) {
Cell cell = row.getCell(j);
if(cell != null) {
/**
* CellType中定义了不同的枚举类型,来作为表格数据的接收类型
* _NONE 未知类型
* NUMERIC 数值类型(整数、小数、日期)
* STRING 字符串
* FORMULA 公式
* BLANK 空字符串(没有值),但是有单元格样式
* BOOLEAN 布尔值
* ERROR 错误单元格
*/
//获取所有读取数据的类型
CellType cellType = cell.getCellType();
String cellVal = "";
//根据不同的类型来读取数据
switch (cellType) {
case STRING://字符串
cellVal = cell.getStringCellValue();
System.out.println("字符串类型");
break;
case NUMERIC://数值类型
//判断是否为日期类型
if(DateUtil.isCellDateFormatted(cell)) {
System.out.println("日期类型");
Date date = cell.getDateCellValue();
cellVal = new SimpleDateFormat("yyy-MM-dd").format(date);
} else {
cellVal = cell.toString();
System.out.println("数值类型");
}
break;
case BLANK://空字符串
System.out.println("空字符串");
break;
case BOOLEAN://布尔类型
cellVal = String.valueOf(cell.getBooleanCellValue());
System.out.println("布尔类型");
break;
case ERROR://错误类型
System.out.println("错误格式");
break;
}
System.out.println(cellVal);
}
}
}
}
inputSream.close();
}
五、总结与思考
1.总结
本文系统性地介绍了 Excel 2003 与 2007 版本的核心区别(`.xls` vs `.xlsx`、数据容量差异),并基于 Apache POI 库详细演示了 Java 读写 Excel 文件的完整流程,涵盖以下关键点:
(1)版本适配:针对不同 Excel 版本(03/07),需选择对应的 `HSSFWorkbook` 、`XSSFWorkbook` 类,并注意文件扩展名差异。
(2)性能优化:大数据量写入时,`SXSSFWorkbook` 通过流式处理显著提升效率,避免内存溢出。
(3)数据类型处理:读取时需根据 `CellType` 动态解析数据(如文本、数值、日期等),确保准确性。
(4)批量操作:通过循环结构实现批量读写,结合异常处理增强代码的健壮性。
2.思考
(1)实际开发中,若仅需处理 `.xlsx` 文件,可优先选用 `XSSFWorkbook` 或 `SXSSFWorkbook`(大数据场景)。
(2)对于更高性能需求,可探索 EasyExcel 等替代方案。
(3)务必注意资源释放(如关闭流),防止内存泄漏。
掌握这些技能后,可高效实现报表生成、数据导入导出等企业级需求,提升开发效率。