package com.haiyisoft.iecp.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
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.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
* excel读取数据
*
* @author 白亚龙
*
* <p>
* 2018-04-19 白亚龙 新建
* </p>
*/

public class ReadExceTool {

/**
* 导出Excel文件的信息 形式为:List<List<Object>> 支持格式为 : xlsx,xls
* 第一层list为文件sheet信息 第二层list为一个sheet页面的信息 第三层为sheet内容某一行的信息
* 文件信息由上自下由左自右查找
* 分数数据暂时只能读取成小数保存
* @param File 输入文件
* @param String 文件后缀
* @return List<List<Object>> (最内层object为一个List<Object>数组)
*/
public List<List<Object>> readExcel(File file, String extension) {
List<List<Object>> fileObject = new java.util.ArrayList<List<Object>>();
Workbook wb = null;
// 读取文件格式判断,如果是excel文件则返回Workbook实例
wb = readFile(file, extension);
if(wb != null){
// 循环sheet页面,添加第一层list
for(int numSheet = 0; numSheet < wb.getNumberOfSheets(); numSheet++){
Sheet sheet = wb.getSheetAt(numSheet);
if(sheet == null){
continue;
}
/**
* column: sheet页面最大列数;
* 根据 sheet页最大行,最大列对页面进行循环处理
*/
List<Object> sheetObjects = new ArrayList<Object>();
// 获取数据最小列数
int startColumn = getFirstColNum(sheet, sheet.getLastRowNum());
// 获取数据最大列数
int endColumn = getLastColNum(sheet, sheet.getLastRowNum());
// 根据最大行数进行循环,将行数据数据放入第二层list
for(int i =0; i <= sheet.getLastRowNum(); i++){
Row row = sheet.getRow(i);
List<Object> rowValues = new ArrayList<Object>();
// 空行忽略
if(row == null){
continue;
}else {
// 每行内根据最大列数循环,将单元数据数据放入第三层list
for(int j = startColumn; j < endColumn; j++){
Cell cell = row.getCell(j);
// 空单元忽略
String cellValue = null;
if(cell == null) continue;
// 判断是否为合并单元格
if(isMergedRegion(sheet, i, j)){
// 合并单元格取值(所有单元格取第一个单元格的值,跨列合并单元格 只取第一个数据)
cellValue = getMergedValue(sheet, i, j);
}else{
// 单元格取值
cellValue = getValue(cell);
}
// 如果是跨列合并单元格 只取第一个数据
if(cellValue != null && cellValue.equals("ignoredData"))continue;
else rowValues.add(cellValue);
}
if (rowValues.size()>0) {
sheetObjects.add(rowValues);
}
}
}
if (sheetObjects.size()>0) {
fileObject.add(sheetObjects);
}
}
/*//遍历解析出来的list (数据验证)
for (List<Object> sheetObjects : fileObject) {
for (Object rowObjects : sheetObjects) {
List<Object> cellValues = (List<Object>) rowObjects;
for (int i = 0; i < cellValues.size(); i++) {
System.out.print(cellValues.get(i) + ",");
}
System.out.println();
}
System.out.println();
}*/
}
return fileObject;
}

/**
* 求Excel某一工作簿0~某行内的最小列数
* @param sheet 工作簿
* @param rowNum 行数
* @return
*/
private static int getFirstColNum(Sheet sheet, int lastRowNum) {
if(sheet == null){
return 0;
}
// 初始值设置为一个较大的值
int firstCol = 1000;
Row row = null;
// 根据行循环,取第一个非空值的最小下标
for(int i = 0; i <= lastRowNum; i++){
row = sheet.getRow(i);
if(row != null){
for(int j = 0; j < row.getLastCellNum(); j++){
if(row.getCell(j) != null){
if(firstCol > j){
firstCol = j;
break;
}
}
}
}
}
return firstCol;
}

/**
* 求Excel某一工作簿0~某行内的最大列数
* @param sheet 工作簿
* @param rowNum 行数
* @return
*/
private static int getLastColNum(Sheet sheet, int rowNum) {
if(sheet == null ){
return 0;
}
int lastCol = 0;
Row row = null;
for(int i = 0; i <= rowNum; i++){
row = sheet.getRow(i);
if(row != null){
int temp = row.getLastCellNum();
if(temp > lastCol){
lastCol = temp;
}
}
}
return lastCol;
}

/**
* 获取合并单元格的值
* @param sheet 工作簿
* @param rowNum 单元行
* @param columnIndex 单元列
* @return Object 单元值
*/
private static String getMergedValue(Sheet sheet, int rowNum,
int columnIndex) {
// 获取合并单元格个数
int mergeNum = sheet.getNumMergedRegions();
String value = null;
// 循环判断单元格所在合并单元格,合并单元格内所有单元格赋相同的值
for(int i = 0; i < mergeNum; i++){
CellRangeAddress range = sheet.getMergedRegion(i);
// 数据依次为合并单元格的第一列、最后一列、第一行、最后一行
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
// 判断是否在次单元格区间内
if(rowNum >= firstRow && rowNum <= lastRow){
// 所有单元格取第一个单元格的值,跨列合并单元格 只取第一个数据
if(columnIndex == firstColumn){
value = getValue(sheet.getRow(firstRow).getCell(firstColumn));
}else if(columnIndex > firstColumn && columnIndex <= lastColumn){
value = "ignoredData";
}
}
}
return value;
}

/**
* 判断是不是合并单元格
* @param sheet Excel工作簿
* @param rowNum 单元格行下标
* @param columnIndex 单元格列下标
* @return
*/
private static boolean isMergedRegion(Sheet sheet, int rowNum,
int columnIndex) {
// 获取合并单元格个数
int sheetMergedNum = sheet.getNumMergedRegions();
for(int i = 0; i < sheetMergedNum; i++){
CellRangeAddress range = sheet.getMergedRegion(i);
// 数据依次为合并单元格的第一列、最后一列、第一行、最后一行
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
// 判断是否在次单元格区间内,如果是则返回true
if(rowNum >= firstRow && rowNum <= lastRow){
if(columnIndex >= firstColumn && columnIndex <= lastColumn){
return true;
}
}
}
// 如果不在所有的合并单元格内则返回false
return false;
}

/**
* 读取文件类型,如果是excel则返回对象实例, 如果不是则返回null
* @param filePath 文件路径
* @return Workbook实例
*/
private static Workbook readFile(File file, String extension) {
Workbook wb = null;
if(file != null && extension != null && !extension.equals("")){
try {
InputStream inputStream = null;
inputStream = new FileInputStream(file);
if(extension.equals("xls")){
wb = new HSSFWorkbook(inputStream);
}else if(extension.equals("xlsx")){
wb = new XSSFWorkbook(inputStream);
}else{
wb = null;
}
} catch (FileNotFoundException e) {
System.out.println("未找到文件位置!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("文件类型不正确,请重新选择!");
e.printStackTrace();
}
}
return wb;
}

/**
* 获取单元格的值,并格式化 日期格式不变 其他格式转换为字符串类型
* @param cell 单元格
* @return
*/
private static String getValue(Cell cell){
String cellValue = null;
// 格式化数据对象
DecimalFormat df = new DecimalFormat("0.######");
if(cell != null){
// 获取单元格数据类型
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
DateFormat formater = null;
Date d = cell.getDateCellValue();
if(cell.getCellStyle().getDataFormat() == 31){
formater = new SimpleDateFormat("yyyy年MM月dd日");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 58){
formater = new SimpleDateFormat("MM月dd日");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 14){
formater = new SimpleDateFormat("yyyy-MM-dd");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 57){
formater = new SimpleDateFormat("yyyy年MM月");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 20){
formater = new SimpleDateFormat("HH:mm");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 32){
formater = new SimpleDateFormat("HH时mm分");
cellValue = formater.format(d);
}else if(cell.getCellStyle().getDataFormat() == 9){
cellValue = df.format(cell.getNumericCellValue()*100) + "%";
}else if(DateUtil.isCellDateFormatted(cell)){
formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
cellValue = formater.format(d);
}else{
cellValue = df.format(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_FORMULA:
try {
cellValue = df.format(cell.getNumericCellValue());
} catch (Exception e) {
cellValue = cell.getCellFormula();
}
break;
case Cell.CELL_TYPE_STRING:
cellValue = cell.getRichStringCellValue().getString();
break;
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_ERROR:
break;
default:
cellValue = "";
break;
}
}
return cellValue;
}
}

使用poi读取Excel文件数据的更多相关文章

  1. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  2. JAVA使用POI读取EXCEL文件的简单model

    一.JAVA使用POI读取EXCEL文件的简单model 1.所需要的jar commons-codec-1.10.jarcommons-logging-1.2.jarjunit-4.12.jarlo ...

  3. 上传读取Excel文件数据

    /// <summary> /// 上传读取Excel文件数据 /// 来自http://www.cnblogs.com/cielwater /// </summary> // ...

  4. 使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10

    使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10 [问题点数:40分,结帖人xieyongqiu]             不显示删除回复             ...

  5. 使用POI读取excel文件内容

    1.前言 项目中要求读取excel文件内容,并将其转化为xml格式.常见读取excel文档一般使用POI和JExcelAPI这两个工具.这里我们介绍使用POI实现读取excel文档. 2.代码实例: ...

  6. Java实现POI读取Excel文件,兼容后缀名xls和xlsx

    1.引入所需的jar包: maven管理项目的话直接添加以下坐标即可: <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -- ...

  7. spring boot 使用 POI 读取Excel文件

    内容简介 本文主要介绍使用POI进行Excel文件的相关操作,涉及读取文件,获取sheet表格,对单元格内容进行读写操作,以及合并单元格的操作. Excel文件目录 Excel模板文件存了resour ...

  8. 使用jxl,poi读取excel文件

    作用:在java后台添加一个方法,读取导入的excel内容,根据需要返回相应的sql语句,以完成对临时表的插入操作. 使用jxl读取excel文件 package com.sixthf.bi.sapp ...

  9. VC6.0读取Excel文件数据

    啰嗦一下:本人所在公司从事碟式斯特林太阳能发电设备的研发与销售.单台设备图如下: 工作原理如下:整个设备大致可分为五个部分, 1.服务器,负责气象.发电等数据存取,电.网连接等处理: 2.气象站,通过 ...

随机推荐

  1. 【python系列】--Python变量和数据类型

    python数据类型 一.整数 Python可以处理任意大小的整数,当然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等. 计算机由于使用 ...

  2. Day04.a(对象类型的转换,多态)

    对象类型的转换 Dog dog = new Dog(); 通常情况下,对象(new Dog())类型和引用(dog)类型是相同的,当引用类型和对象类型不一致时,就需要类型转换. 向上转型:将较具体的类 ...

  3. 2、阿里云ECS发送邮件到腾讯企业邮箱(ECS默认不开启25端口)

    阿里云ECS默认禁用25端口导致发邮件失败. 方法一: 使用shell脚本发送邮件,需要配置mailx 1.安装软件 yum install mailx 2.配置 vim /etc/mail.rc在文 ...

  4. 公司外网测试服务器 redis 被攻击复盘

    最近 公司外网的测试的 redis 服务器被攻击,最开始是用 docker 搭建的 直接裸奔在外网,任何域名都可以通过 ip+6379来访问,最开始想的是测试服务器也没有啥,后面直接就被人登陆进去改了 ...

  5. .Net Framework 下运行项目提示.dll类库程序集未能加载

     咨询个问题..项目可以生成成功,运行时总提示未能加载程序集,而且这个程序集就是当前webApi项目的dll,这是怎么回事.. 还一个奇怪的现象,刚开始报缺失xxx.dll, 那个dll是本解决方案里 ...

  6. ArcMap中获取要素的Extent值

    新建xmax,xmin,ymax,ymin4个字段,右键,在[字段计算器]中选择Python,分别输入!shape.extent.XMax!.!shape.extent.XMin!.!shape.ex ...

  7. Jmeter性能测试报告扩展

    自动收集采集结果:运行完毕后,自动出结果:

  8. 关于hadoop的运行的一些指标监控(非cdh平台的)

    在hadoop-env.sh中添加: # 在配置namenode和datanode时都会有用到JMX_OPTS的代码,是为了减少重复提取出的公共代码 export JMX_OPTS="-Dc ...

  9. python 配置文件__ConfigParser

    基础读取配置文件 -read(filename)               直接读取文件内容 -sections()                      得到所有的section,并以列表的形 ...

  10. css实现图片等比例缩放

    <div class="box"> <img src="01.jpg"/> </div> .box{ } //只要给图片设置 ...