目录
术语
目的
技术
实现过程
实现的代码
验证程序
术语
术语 | 说明 |
工作簿 | Excel 文件 |
工作表 | Excel 文件中的 Sheet 表格 |
xls | xls 格式的Excel 文件,Excel 2003及以前使用的 Excel 文件格式 |
xlsx | xlsx 格式的 Excel 文件,Excel 2007 及以后使用的 Excel 文件格式 |
目的
根据 Excel 文件的路径获取到 Excel 文件中的数据。
技术
使用 Apache 组织下 POI 项目对 Excel 文件进行读取操作,本次主要使用到的接口和类如下表所示:
名称 | 类型 | 说明 |
WorkBookFactory | 类 | 创建合适的工作簿(HSSFWorkBook或XSSFWorkBook),根据文件输入流自动检测。 |
HSSFWorkBook | 类 | 创建xls 格式的工作簿,Excel 2003 及其以前使用的格式。 |
XSSFWorkBook | 类 | 创建 xlsx 格式的工作簿,Excel 2007 及其以后使用的格式。 |
WorkBook | 接口 | 工作簿接口 |
Sheet | 接口 | 工作表接口 |
Row | 接口 | 行接口 |
Cell | 接口 | 单元格接口 |
如需更多关于 POI 项目下的接口和类的详细文档,请参考官方文档:http://poi.apache.org/apidocs/index.html?overview-summary.html
读取 xls 格式文件需要用到的 jar 包:
读取 xls 格式文件时需要的 jar 文件
读取 xlsx 格式文件需要用到的 jar 包:
读取 xlsx 格式文件时需要的 jar 文件
POI 项目使用到的 jar 包官方下载地址:http://poi.apache.org/download.html
实现过程
- 如果指定的工作表位置小于1,则默认设置为1;
- 判断文件路径是否正确或是不是 Excel 文件(以 .xls 或 .xlsx 结尾的文件),如果判断失败,程序结束;
- 如果判断成功,创建工作簿,根据文件输入流自动检测创建工作簿类型;
- 判断是否为指定工作表,如果是只读取指定工作表的数据,如果不是读取工作簿中所有工作表数据;
- 判断指定工作表位置在工作簿中是否存在,存在读取指定工作表的数据,不存在则读取工作簿最后一张工作表的数据;
- 工作表中添加工作表的名称;
如果工作表不止一行数据,工作表的总列数取第一行和第二行中最大的列数,注意:工作表中第一行或第二行的列数必须和工作表的总列数相同。
实现的代码
package cn.bc.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
/**
*
* @ClassName: cn.bc.util.ExcelUtil
*
* @Description: 读取 Excel 工作表数据
* xls 格式是 Excel 2003及其以前版本使用的格式
* xlsx 格式是 Excel 2007及其以后版本使用的格式
* 工作簿表示整个 Excel 文件,工作表表示 Excel 文件中的 Sheet 表
* 注意: 1、Excel 文件中工作表的第一行不能为空;
* 2、如果 Excel 文件中工作表除第一行外还有其它数据时,第二行也不能为空;
* 3、Excel 文件中工作表的第一行或第二行的列数必须是整个工作表的总列数
*
* @author 17bc8
* @date: 2019年8月10日
*
* @Copyright: 2019 www.17bc8.cn
*/
public class ExcelUtil {
private static Log log = LogFactory.getLog(ExcelUtil.class);
/**
*
* @Title: validExxel
*
* @Description: 验证文件是不是 Excel 文件
*
* @param path 文件的路径
* @return 是:true;不是:false
*/
private static Boolean validExxel (String path) {
String xls = "^.+\\.(?i)(xls)$"; // 正则表达式判断是不是以 .xls 结尾的文件
String xlsx = "^.+\\.(?i)(xlsx)$"; // 正则表达式判断是不是以 .xlsx 结尾的文件
if (path == null || !(path.matches(xls) || path.matches(xlsx))) {
log.error("@!--------------------不是Excel文件!");
return false;
}
return true;
}
/**
*
* @Title: readExcel
*
* @Description: 读取 Excel 文件的数据
*
* @param path 文件的路径
* @param isSheetIndex 是否指定工作表(Sheet)
* @param sheetIndex 指定工作表在工作簿中的位置
* 1、如果 isSheetIndex 为 true 时,sheetIndex 为大于0的整数
* 1.1、如果 sheetIndex 小于等于 0,默认读取工作簿中的第一张工作表;
* 1.2、如果 sheetIndex 大于工作簿中工作表的总数,默认读取工作簿中最后一张工作表;
* 2、如果 isSheetIndex 为 false 时,sheetIndex 可以是任何整数,此时读取工作簿中所有工作表的数据
* @return Excel Excel 文件的数据集
*/
public static List<Object> readExcel (String path, Boolean isSheetIndex, Integer sheetIndex) {
// 指定工作表位置小于1时,默认读取第一张工作表的数据
if (sheetIndex < 1) {
sheetIndex = 1;
}
List<Object> dataList = new ArrayList<>();
InputStream is = null;
// 通过指定的文件路径创建文件对象
File file = new File (path);
if (file == null || !file.exists()) {
log.error("@!--------------------文件不存在!");
return null;
}
if (!validExxel(path)) {
log.error("@!--------------------此文件不是 Excel 文件!");
return null;
}
try {
is = new FileInputStream(file); // 获取文件的输入流
dataList = readFile (is, isSheetIndex, sheetIndex-1);
} catch (FileNotFoundException e) {
log.error("@!--------------------找不到该文件!");
} finally {
if (is != null) {
try {
is.close(); // 关闭文件输入流
} catch (IOException e) {
log.error("@!-----------------------------文件输入流关闭失败!");
}
}
}
return dataList;
}
/**
*
* @Title: readFile
*
* @Description: 读取输入流中的数据
*
* @param is 文件输入流
* @param isXls 是不是 xls 格式的文件
* @param isSheetIndex 是不是指定的工作表
* @param sheetIndex 工作表在工作簿中的位置
* @return 工作簿的数据
*/
private static List<Object> readFile (InputStream is, Boolean isSheetIndex, Integer sheetIndex) {
List<Object> dataList = new ArrayList<>();
Workbook wb = null;
try {
// 创建工作簿(HSSFWorkbook或XSSFWorkbook),根据文件输入流自动检测创建对象
wb = WorkbookFactory.create(is);
Integer sheetCount = wb.getNumberOfSheets(); // 工作簿中工作表的总数
List<Object> sheetList = new ArrayList<>();
if (isSheetIndex) { // 读取指定工作表
// 判断指定的位置是否在工作簿中有对应的工作表
if (sheetIndex < sheetCount) {
sheetList = readWorkBook (wb, sheetIndex);
} else {
// 没有找到对应的工作表时,读取工作簿的最后一张工作表
sheetList = readWorkBook (wb, sheetCount-1);
}
dataList.add(sheetList); // 添加工作表的数据到工作簿数据集中
} else {
// 读取工作簿的所有工作表
for (int i = 0; i < sheetCount; i++) {
sheetList = readWorkBook (wb, i);
dataList.add(sheetList); // 将工作簿中的每一张不为空的工作表添加到工作簿的数据集中
}
}
} catch (IOException e) {
log.error("@!------------------------------创建工作簿失败!");
}
return dataList;
}
/**
*
* @Title: readWorkBook
*
* @Description: 读取工作表中的数据
*
* @param wb 工作簿
* @param index 工作表在工作簿中的位置
* @return 工作表的数据
*/
private static List<Object> readWorkBook (Workbook wb, Integer index) {
List<Object> sheetList = new ArrayList<>();
Integer totalRows = 0;
Integer totalCells = 0;
Sheet sheet = wb.getSheetAt(index); // 获取工作表对象
sheetList.add(sheet.getSheetName()); // 添加工作表的名称到工作表中
totalRows = sheet.getPhysicalNumberOfRows(); // 获取工作表的总行数
if (totalRows > 0 && sheet.getRow(0) != null) {
// 获取工作表的总列数,第一行或第二行的列数必须是整张工作表的总列数
if (sheet.getRow(1) != null && sheet.getRow(0).getPhysicalNumberOfCells() < sheet.getRow(1).getPhysicalNumberOfCells()) {
totalCells = sheet.getRow(1).getPhysicalNumberOfCells();
} else {
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
}
List<Object> rowList = new ArrayList<>();
for (int i = 0; i < totalRows; i++) {
Row row = sheet.getRow(i); // 获取行对象
// 去除空行
if (row == null) {
continue;
}
List<Object> cellList = new ArrayList<Object>();
for (int j = 0; j < totalCells; j++) {
Cell cell = row.getCell(j); // 获取单元格对象
cellList.add(cell); // 将单元格中的数据添加到单元格数据集中
}
rowList.add(cellList); // 将单元格数据集天津爱到行数据集中
}
sheetList.add(rowList); // 将行数据集添加到工作表中
return sheetList;
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// List<Object> dataList = readExcel ("D:\\Desktop\\test.xlsx", false, 0);
List<Object> dataList = readExcel ("D:\\Desktop\\test.xlsx", true, 1);
if (dataList != null) {
for (int i = 0; i < dataList.size(); i++) {
// 获取工作表
List<Object> sheetList = (List<Object>) dataList.get(i);
String sheetName = (String) sheetList.get(0);
System.out.println("工作表的名称:" + sheetName);
System.out.println("工作表的数据:");
for (int j = 1; j < sheetList.size(); j++) {
// 获取工作表的每一行
List<Object> rowList = (List<Object>) sheetList.get(j);
for (int k = 0; k < rowList.size(); k++) {
// 获取工作表的每一列
List<Object> cellList = (List<Object>) rowList.get(k);
for (Object object : cellList) {
// 获取每一个单元格的数据
System.out.print(" "+object);
}
System.out.println();
}
}
}
}
}
}
验证程序
test.xlsx 文件中的数据:
城市邮编工作表的数据
城市区号工作表的数据
不指定工作表程序运行结果:
工作簿中的所有工作表数据
指定工作表程序运行结果:
城市邮编工作表数据
感谢您的阅读!