用 Apache POI 读取 XLSX 数据
最近因为项目的原因,需要从一些 Microsoft Office Excel 文件读取数据并加载到数据库。
Google了一下方法,发现其实可以用的 Java 第三方库很多,最著名的是 Apache 的 POI 开源项目,其官网地址是 https://poi.apache.org
从首页的简介中我发现这个项目功能非常强大,不仅能处理 Excel,它还可以处理 Word、PowerPoint、Outlook、Visio,基本上囊括了 MS Office 的全部常用组件。目前 POI 更新到了 3.16 版本,可以从这个页面下载 https://poi.apache.org/download.html#POI-3.16
和所有的 Apache 开源项目一样,POI 下载页面同时提供源码和编译好的库文件下载,有时间的朋友建议下源码看看,写得非常好(编译用 ant 就行)。下载好库文件后(或者下载源文件自己编译好后),以 External Jars 的形式导入 Eclipse 项目中,就可以开始编程了。
读取 Excel 其实很简单,步骤如下:
1. 使用一个 java.io.FileInputStream 对象打开要访问的 Excel 文件获取一个输入流
2. 用这个文件流创建一个 org.apache.poi.xssf.usermodel.XSSFWorkbook 类的实例
3. 使用 XSSFWorkbook 类的 getSheetAt(int index) 方法读取指定的 sheet,其返回一个 org.apache.poi.xssf.usermodel.XSSFSheet 类的实例
4. 使用 XSSFSheet 类的 getRow(int index) 方法读取指定的 row(这里可以进行一个循环,详情请参阅下面的代码),其返回一个 org.apache.poi.xssf.usermodel.XSSFRow 类的实例
5. 使用 XSSFRow 类的 getCell(int index) 方法读取指定的 cell(同上,可以循环读取,参阅代码),其返回一个 org.apache.poi.xssf.usermodel.XSSFCell 类的实例
6. 根据返回的 Cell 的不同类型,分别处理:字符型数字型直接输出,日期型可以指定一个格式输出,表达式则需要使用 org.apache.poi.ss.usermodel.FormulaEvaluator 类的 evaluate(Cell arg0) 方法先得到表达式的值,然后再进行第二次类型判断后才能输出。
PS:因为目标数据的特性,我只需要把数据输出到标准输出即可。
完整程序如下:
package com.peisu.xlsx;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XLSXLoader {
//Define the variables
private static InputStream inputStream;
private static XSSFWorkbook xssfWorkbook;
private static FormulaEvaluator formulaEvaluator;
private static int maxCellCount = 0;
//args[0]: the path to the xlsx file
//args[1]: the sheet number to process, start from 0
//args[2]: the date format output to standard output, for example, yyyy-MM-dd
//args[3]: start from which line to read, if there is a header, start from line 1
public static void main(String[] args) {
try {
//Open the input stream from the file, initialize the workbook
inputStream = new FileInputStream(args[0]);
xssfWorkbook = new XSSFWorkbook(inputStream);
formulaEvaluator = xssfWorkbook.getCreationHelper().createFormulaEvaluator();
//Open the sheet
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(Integer.valueOf(args[1]));
if (xssfSheet != null){
//Get the first row of the sheet
XSSFRow firstXSSFRow = xssfSheet.getRow(0);
if (firstXSSFRow != null){
//Set the max cell count to be the last cell number of the first line
maxCellCount = firstXSSFRow.getLastCellNum();
//Loop to read the rows
for (int rowNum = Integer.valueOf(args[3]);rowNum <= xssfSheet.getLastRowNum();rowNum++) {
//Get the row
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if (xssfRow != null){
//Loop to read the cells
for (int cellNum = 0;cellNum < maxCellCount;cellNum++){
//Get the cell
XSSFCell xssfCell = xssfRow.getCell(cellNum);
if (xssfCell != null){
//Process the cell based on the cell type
switch (xssfCell.getCellTypeEnum()){
case STRING:
System.out.print(xssfCell.getStringCellValue());
break;
case NUMERIC:
//If the cell matches the date format, output the cell as a date
if (DateUtil.isCellDateFormatted(xssfCell)) {
SimpleDateFormat dateFormat = new SimpleDateFormat(args[2]);
System.out.print(dateFormat.format(xssfCell.getDateCellValue()));
}
else
System.out.print(xssfCell.getNumericCellValue());
break;
case BOOLEAN:
System.out.print(xssfCell.getBooleanCellValue());
break;
case FORMULA:
//For formula cell, evaluate the formula to get the result
CellValue cellValue = formulaEvaluator.evaluate(xssfCell);
//Process the formula cell based on the type of the result
switch(cellValue.getCellTypeEnum()){
case STRING:
System.out.print(xssfCell.getStringCellValue());
break;
case NUMERIC:
//If the result matches the date format, output the result as a date
if (DateUtil.isCellDateFormatted(xssfCell)) {
SimpleDateFormat dateFormat = new SimpleDateFormat(args[2]);
System.out.print(dateFormat.format(xssfCell.getDateCellValue()));
}
else
System.out.print(xssfCell.getNumericCellValue());
break;
case BOOLEAN:
System.out.print(xssfCell.getBooleanCellValue());
break;
default:
System.out.print(xssfCell.getRawValue());
}
break;
case ERROR:
//System.out.print(xssfCell.getErrorCellString());
System.out.print("");
break;
default:
System.out.print(xssfCell.getRawValue());
}
}
//Add a column delimiter between the output cells
if(cellNum < maxCellCount - 1)
System.out.print("\t");
}
}
//Add a row delimiter between the output rows
System.out.println("");
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
xssfWorkbook.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
用 Apache POI 读取 XLSX 数据的更多相关文章
- apache poi 读取xlsx并导出为json(没考虑xls)
		
1.用到的jar包:fastjson-1.2.9.poi(poi-3.15.poi-ooxml-3.15.poi-ooxml-schemas-3.15.xmlbeans-2.6.0.commons-c ...
 - 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据
		
1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...
 - Java开发小技巧(六):使用Apache POI读取Excel
		
前言 在数据仓库中,ETL最基础的步骤就是从数据源抽取所需的数据,这里所说的数据源并非仅仅是指数据库,还包括excel.csv.xml等各种类型的数据接口文件,而这些文件中的数据不一定是结构化存储的, ...
 - 使用poi读取excel数据示例
		
使用poi读取excel数据示例 分两种情况: 一种读取指定单元格的值 另一种是读取整行的值 依赖包: <dependency> <groupId>org.apache.poi ...
 - 使用poi读取xlsx中的数据
		
excel中的内容见下图: 详细代码: package dataprovider; import java.io.FileInputStream; import java.io.InputStream ...
 - 基于Apache POI 从xlsx读出数据
		
[0]写在前面 0.1) these codes are from 基于Apache POI 的从xlsx读出数据 0.2) this idea is from http://cwind.iteye. ...
 - 基于Apache POI 向xlsx写入数据
		
[0]写在前面 0.1) these codes are from 基于Apache POI 的向xlsx写入数据 0.2) this idea is from http://cwind.iteye. ...
 - Java POI读取Excel数据,将数据写入到Excel表格
		
1.准备 首先需要导入poi相应的jar包,包括: 下载地址:http://pan.baidu.com/s/1bpoxdz5 所需要的包的所在位置包括: 2.读取Excel数据代码 package S ...
 - POI读取Excel数据保存到数据库,并反馈给用户处理信息(导入带模板的数据)
		
今天遇到这么一个需求,将课程信息以Excel的形式导入数据库,并且课程编号再数据库中不能重复,也就是我们需要先读取Excel提取信息之后保存到数据库,并将处理的信息反馈给用户.于是想到了POI读取文件 ...
 
随机推荐
- CentOS 7下安装配置FTP
			
安装vsftpd yum install -y vsftpd 编辑ftp配置文件 vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO #anonymous_e ...
 - Java  NIO.2  使用Path接口来监听文件、文件夹变化
			
Java7对NIO进行了大的改进,新增了许多功能: 对文件系统的访问提供了全面的支持 提供了基于异步Channel的IO 这些新增的IO功能简称为 NIO.2,依然在java.nio包下. 早期的Ja ...
 - 【转】浅谈多核CPU、多线程、多进程
			
浅谈多核CPU.多线程.多进程 1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核3 ...
 - Linux下Shell文件内容替换(sed)(转)
			
sed -i 's/被替换的内容/要替换成的内容/g' file #-i为直接修改并保存 参考: http://blog.sina.com.cn/s/blog_7211cb9201019hgd.htm ...
 - git——简易指南
			
Git对于我来说,只知道是一个版本控制器,类似于乌龟的svn.其中也仅仅会几个常的命令,比如说“更新git pull”.“提交git push”等等,因为记得当初使用的时候,师傅告诉我,对于你不懂这个 ...
 - AutoCAD如何移动零件和缩放零件图
			
如下图所示,我想要把这个零件放大并移动到图纸的中央,先全部选中这个零件,方法是在左上角点一下,然后拖出一个矩形包围整个零件 然后点击右侧的缩放命令,底部的命令栏变成指定基点的时候,在这个图纸的右上 ...
 - 【小程序】微信小程序开发实践
			
帐号相关流程 注册范围 企业 政府 媒体 其他组织 换句话讲就是不让个人开发者注册. :) 填写企业信息 不能使用和之前的公众号账户相同的邮箱,也就是说小程序是和微信公众号一个层级的. 填写公司机构信 ...
 - 浅谈Generator和Promise原理及实现
			
Generator 熟悉ES6语法的同学们肯定对Generator(生成器)函数不陌生,这是一个化异步为同步的利器. 栗子: function* abc() { let count = 0; whil ...
 - robot framework selenium2library定位
			
进行页面元素操作,最麻烦的莫过于元素定位了,经常提示element is not visible 或者element is not exist 下面介绍常见的定位方法和定位中的问题 1 使用name和 ...
 - linux init->upstart->systemd
			
http://en.wikipedia.org/wiki/Init init From Wikipedia, the free encyclopedia This article is abo ...