使用poi读取Excel文件数据

除分数被转换为小数存储外,其他数据经本人测试无问题,如发现问题请留言,方便及时更新

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
 *
 */

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);
                /**
                 * 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);
                        }
                        sheetObjects.add(rowValues);
                    }
                }
                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;
    }

    private static int getFirstColNum(Sheet sheet, int lastRowNum) {
        if(sheet == null || lastRowNum == 0){
            return 0;
        }
        // 初始值设置为一个较大的值
        int firstCol = 100;
        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 || rowNum == 0){
            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){
            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;
    }
}

原文地址:https://www.cnblogs.com/TheKiteRunner/p/8890924.html

时间: 2024-10-23 18:41:09

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

使用Apache POI 读取Excel文件

生活中用到用到Excel文件的情况很多,什么商品进货单,产品维修单,餐厅的营业额等等.作为程序员,我们该如何读取Excel文件,获取我们想要的资源呢.本篇将讲解如何使用Apache POI读取Excel文件. 准备工作: 1)Apache POI 开发jar包 2)Excel资源文件,包括Excel2003,Excel2007这两种版本分别对应xls.xlsx文件. 本篇已经为您做好准备工作,请点击此处,下载资源文件,你也可以浏览Apace POI官网了解更多详细信息. 简要流程: 获取Work

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

使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10 [问题点数:40分,结帖人xieyongqiu] 不显示删除回复             显示所有回复             显示星级回复             显示得分回复             只显示楼主           收藏 关注 xieyongqiu maobingxixi 本版等级: 结帖率:71.43% 楼主发表于: 2010-09-13 17:33:03 使用POI 读取 Excel 

VC6.0读取Excel文件数据

啰嗦一下:本人所在公司从事碟式斯特林太阳能发电设备的研发与销售.单台设备图如下: 工作原理如下:整个设备大致可分为五个部分, 1.服务器,负责气象.发电等数据存取,电.网连接等处理: 2.气象站,通过光感应器实时获取气象数据,传送至服务器 3.碟型镜面,反射阳光热量,均匀聚焦到350mm直径的圆形范围内--发动机热头大小: 4.斯特林发动机,吸收镜面反射热量,通过内部气体膨胀.收缩带动发动机发电: 5.通信线,连接系统各个部分,使其运行正常. 对于这样一台设备,要使其高效发电,出气象条件要好之外

使用jxl,poi读取excel文件

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

java利用poi读取Excel文件

java读取Excel文件,笔者认为:从结构上来看,Excel文件是由一个一个的单元格组成的,有点像细胞cell,逐行的排列.那么我们读的时候也应该逐行逐行的读,从左到右的寻找每一个cell.一.实例代码: 只是实现了一种方式,因为依照读取内容的不同,读取的后想要的操作不同,因此不能苟同全部,只是方法是相通的.说道Excel文件的结构,这货从数学的角度来说,绝对是一个二维数组,因此我就拿字符串二维数组接受读取后的内容,并每个单元格每个单元格的打印.当然也可以返回三维数组(包含该单元格的位置坐标)

使用poi读取excel文件 Cannot get a text value from a numeric cell

我这样转换得到一个excel文本域的值 Cell cell = row.getCell(c); cell.setCellType(Cell.CELL_TYPE_STRING); String parkName = cell.getStringCellValue(); 某些时候,读取 excel 文件会出现如下错误 java.lang.IllegalStateException: Cannot get a text value from a numeric cell at org.apache.p

java poi读取excel文件

poi-3.9-20121203.jar poi-ooxml-3.9-20121203.jar poi-ooxml-schemas-3.9-20121203.jar stax-api-1.0.1.jar xmlbeans-2.3.0.jar 上面几个jar包缺一不可,有时候会出现ClassNotFound之类的错误,是因为jar缺少或不兼容的原因,上面jar包已经过测试,可以使用. 读取excel文件代码如下: public class ExcelUtils {// 对外提供读取excel文件的

POI 读取Excel文件,将Excel数据导入数据库

/** * 读取Excel单元格所显示的字符串(显示什么就返回什么) * 创建人:minlorry * 创建日期:2015-07-31 * 更新日期:2015-07-31 * 更新说明:生硬地处理了数值单元格的处理,日期单元格未作处理. * @param cell Excel单元格 * @return String 单元格显示的字符串 */ public static String getStringValue(Cell cell) { String stringValue = "";

poi读取Excel文件图片位置

下载最新的poi包poi-bin-3.12-20150511.zip,里面有读取xlsx图片的新方法! 上个星期开始鼓捣导入Excel,下载了最新的poi包,结果Excel文件里有图片.处理图片还真是个难事,网上搜索一开始发现了HSSFSheet类处理图片的例子,但不是xlsx文件能用的,其中对一个方HSSFSheet.getDrawingEscherAggregate()有印象. 转帖处:贴子1:http://www.cnblogs.com/shwen99/archive/2010/09/13