Java 通过 POI 读取 Excel 文件数据

目录

术语

目的

技术

实现过程

实现的代码

验证程序


术语

术语

说明

工作簿

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,则默认设置为1;
  2. 判断文件路径是否正确或是不是 Excel 文件(以 .xls 或 .xlsx 结尾的文件),如果判断失败,程序结束;
  3. 如果判断成功,创建工作簿,根据文件输入流自动检测创建工作簿类型;
  4. 判断是否为指定工作表,如果是只读取指定工作表的数据,如果不是读取工作簿中所有工作表数据;
  5. 判断指定工作表位置在工作簿中是否存在,存在读取指定工作表的数据,不存在则读取工作簿最后一张工作表的数据;
  6. 工作表中添加工作表的名称;

如果工作表不止一行数据,工作表的总列数取第一行和第二行中最大的列数,注意:工作表中第一行或第二行的列数必须和工作表的总列数相同

实现的代码

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 文件中的数据:

城市邮编工作表的数据
城市区号工作表的数据

不指定工作表程序运行结果:

工作簿中的所有工作表数据

指定工作表程序运行结果:

城市邮编工作表数据

 

 

感谢您的阅读!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java使用POI库可以实现对Excel文件读取操作。具体的步骤如下: 1. 引用POI库。在Java项目中引入POI相关的jar包。 2. 创建文件输入流。使用FileInputStream类创建一个输入流对象,并指定要读取Excel文件路径。 3. 创建工作簿对象。使用HSSFWorkbook类创建一个工作簿对象,将输入流作为参数传入。 4. 获取工作表。使用getSheetAt方法获取指定的工作表,可以通过工作表的索引或名称进行获取。 5. 获取行。使用getRow方法获取指定行的对象,行号作为参数传递给该方法。 6. 获取单元格。使用getCell方法获取指定单元格的对象,行号和列号作为参数传递给该方法。 7. 获取单元格的值。使用getStringCellValue方法获取单元格的值,将其赋给一个字符串变量。 8. 输出结果。使用System.out.println方法将获取到的数据打印出来。 需要注意的是,在读取Excel文件时可能会出现FileNotFoundException和IOException异常,需要进行异常处理。同时,在读取完成后,需要关闭输入流。 下面是一个示例代码,用于演示Java使用POI读取Excel文件: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class ExcelReader { public static void poiRead() { FileInputStream xlsStream = null; try { // 创建文件输入流 xlsStream = new FileInputStream(new File("C:\\Users\\itour\\Desktop\\poiTest.xls")); // 创建工作簿对象 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(xlsStream); // 获取工作表 HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0); // 获取行 HSSFRow row = sheetAt.getRow(0); // 获取单元格 HSSFCell cell = row.getCell(0); // 获取单元格的值 String cellValue = cell.getStringCellValue(); System.out.println("获取到的数据是:" + cellValue); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (xlsStream != null) { try { xlsStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` 以上代码演示了如何使用POI读取Excel文件中第一个工作表的第一个单元格的值。你可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值