Java 进阶 & 通过poi、poi-ooxml框架读取不同格式excel

有时候,excel的同一个sheet中会存储多种类型的数据。如:登录、数据添加、其他数据添加,要通过sheet工作表来控制并随意读取。
本类主要是读取后缀为xlsx或xls的excel操作。
需要导入包

  <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ExcelCommon {
    private XSSFSheet ExcelWSheet;
    private XSSFWorkbook ExcelWBook;
    private XSSFCell Cell;
    private XSSFRow row;
    private String filePath;

    //设定要操作的Excel 的文件路径和Excel 文件中的sheet名称
    //在读写excel的时候,均需要先调用此方法,设定要操作的excel 文件路径和要操作的sheet名称
    //构造函数初始化
    public ExcelCommon(String Path, String SheetName) throws Exception{ 
        FileInputStream ExcelFile;

        try{
            //实例化excel 文件的FileInputStream 对象
            ExcelFile = new FileInputStream(Path);
            //实例化excel 文件的XSSFWorkbook 对象
            ExcelWBook = new XSSFWorkbook(ExcelFile);
            //实例化ExcelWSheet 对象,指定excel 文件中的sheet 名称,后续用于sheet 中行、列和单元格的操作
            ExcelWSheet = ExcelWBook.getSheet(SheetName);
        }catch (Exception e){
            throw (e);
        }
        filePath = Path;
    }

   //读取指定单元格的数据。需要传入行数、列数
    public String getCellData(int RowNum,int ColNum) throws Exception{
        try{
            Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
            String CellData = "";
            if(Cell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                CellData = Cell.getStringCellValue();
            }else if(Cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC){
                DecimalFormat df = new DecimalFormat("0");
                CellData=df.format(Cell.getNumericCellValue());
            }
            return CellData;
        }catch (Exception e){
            e.printStackTrace();
            return  "";
        }
    }
   //读取指定单元格的数据且值为字符串。需要传入行数、列数
    public String getCellStrData_value(int RowNum, int ColNum) throws Exception{
        try{
            Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
            if (Cell!=null){
                String CellData = Cell.getStringCellValue();
                return CellData;
            }
            else {
                return"";
            }
        }catch (Exception e){
            return"";
        }
    }
   //读取指定单元格的数据且值为数字。需要传入行数、列数
    public String getCellNumData_value(int RowNum, int ColNum) throws Exception{
        String cellValue = "";
        DecimalFormat df = new DecimalFormat("#");
        try{
            Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
            if (Cell!=null){
                if (Cell.getCellType()==1){
                    cellValue= Cell.getStringCellValue();
                }else {
                    cellValue=  String.valueOf( Cell.getNumericCellValue());
                    if(cellValue.endsWith(".0")){
                        cellValue = cellValue.substring(0, cellValue.length() - 2);
                    }
                }
            }
            return cellValue;
        }catch (Exception e){
            return"";
        }
    }

    // 在excel 文件的执行单元格中写入数据,此函数只支持后缀为xlsx的excel 文件写入
    public void setCellData(int RowNum,int ColNum,String Result) throws Exception{
        try{
            // 获取excel文件中的行对象
            row = ExcelWSheet.getRow(RowNum);
            // 如果单元格为空,则返回Null
            Cell = row.getCell(ColNum, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);

            if(Cell == null){
                // 当单元格对象是null 的时候,则创建单元格
                // 如果单元格为空,无法直接调用单元格对象的setCellValue 方法设定单元格的值
                Cell = row.createCell(ColNum);
                // 创建单元格后可以调用单元格对象的setCellValue 方法设定单元格的值
                Cell.setCellValue(Result);
            }else{
                // 单元格中有内容,则可以直接调用单元格对象的s方法设定单元格的值etCellValue
                Cell.setCellValue(Result);
                System.out.println("执行完成");
            }
            // 实例化写入 excel 文件的文件输出流对象
            FileOutputStream fileOut = new FileOutputStream(filePath);
            // 将内容写入excel 文件中
            ExcelWBook.write(fileOut);
            // 调用flush方法强制刷新写入文件
            fileOut.flush();
            // 关闭文件输出流对象
            fileOut.close();
        }catch (Exception e){
            e.printStackTrace();
            throw (e);
        }
    }
    // 从excel 文件获取测试数据的静态方法
    public static Object[][] getTestData(String execlFilePath,String sheetName) throws IOException{
        // 根据参数传入的数据文件路径和文件名称,组合出excel 数据文件的绝对路径
        // 声明一个file 文件对象
        File file = new File(execlFilePath);

        // 创建FileInputStream 对象用于读取excel 文件
        FileInputStream inputStream = new FileInputStream(file);


        // 声明Workbook 对象
        Workbook Workbook = null;

        // 获取文件名参数的后缀名,判断xlsx文件还是xls文件
        String fileExtensionName = execlFilePath.substring(execlFilePath.indexOf("."));

        // 判断文件类型如果是xlsx,则使用XSSFWorkbook 对象进行实例化
        // 判断文件类型如果是xls,则使用HSSFWorkbook 对象进行实例化
        if(fileExtensionName.equals(".xlsx")){
            //如果是2007的,也就是.xlsx, 让Workbook = new XSSFWorkbook(inputStream);
            Workbook = new XSSFWorkbook(inputStream);
        }else if (fileExtensionName.equals(".xls")){
            //如果是2003的,也就是.xls, 让Workbook = new HSSFWorkbook(inputStream);
            Workbook = new HSSFWorkbook(inputStream);
        }

        // 通过sheetName参数,生成sheet 对象
        Sheet Sheet = Workbook.getSheet(sheetName);

        // 获取excel 数据文件中sheet1中数据的行数,getLastRowNum 方法获取数据的最后行号
        // getFirstRowNum 方法获取数据的第一行行号,相减之后算出数据的行数
        // 注意:excel 文件的行号和列号都是从0开始
        int rowCount = Sheet.getLastRowNum() - Sheet.getFirstRowNum();
        // 创建名为records 的list 对象来存储从excel数据文件读取的数据
        List<Object[]> records = new ArrayList<Object[]>();
        // 使用2个for 循环遍历excel 数据文件的所有数据(除了第一行,第一行是数据列名称)
        // 所以i 从1开始,而不是从0
        for (int i=1;i<rowCount + 1;i++){
            // 使用getRow 方法获取行对象
            Row row = Sheet.getRow(i);

            String fields[] = new String[row.getLastCellNum() - 1];

            if(row.getCell(row.getLastCellNum()-1).getStringCellValue().equals("y")){
                for(int j=0;j<row.getLastCellNum()-1;j++){
                    //判断excel 的单元格字段是数字还是字符,字符串格式调用getStringCellValue 方法获取
                    // 数字格式调用getNumericCellValue 方法获取
                    // fields[j-1]=(String) row.getCell(j).getCellType()==;
                  try {
                      if (row.getCell(j).getCellType() == XSSFCell.CELL_TYPE_STRING) {
                          fields[j] = row.getCell(j).getStringCellValue();
                      } else if (row.getCell(j).getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
                          DecimalFormat df = new DecimalFormat("0");
                          fields[j] = df.format(row.getCell(j).getNumericCellValue());
                      } else {
                          System.out.println("格式错误");
                      }
                  }catch (Exception e){
                      fields[j] ="";
                  }

                }
                // fields 的数据对象存储到records的list中
                records.add(fields);
            }
        }
        // 定义函数返回值,即Object[][]
        // 将存储测试数据的list 转换为一个Object 的二维数组
        Object[][] results = new Object[records.size()][];
        // 设置二维数组每行的值,每行是个object对象
        for(int i=0;i<records.size();i++){
            results[i] = records.get(i);
            //LogUtil.logInfo(results[i]);
        }
       // LogUtil.logInfo(results);
        // 关闭excel 文件
        return results;
    }

    public int getLastCellNum(){
        // 返回数据文件的最后一列的列号,如果有12列,则结果返回11
        return ExcelWSheet.getRow(0).getLastCellNum()-1;
    }

测试类

    public static void main(String[] args) throws Exception{
         String filePath =System.getProperty("user.dir")+File.separator+"testdata"+File.separator+"apitest.xlsx";
         Object[][] results = ExcelCommon.getTestData(filePath,"test");
        for (int i=0;i<results.length;i++){
            for(int j=0;j<results[i].length;j++) {
                System.out.print(results[i][j]+"\t");
            }
            System.out.println();
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 最近由于工作需要,需要写一个工具,实现搜索功能,数据来源为excel表格。目前主要实现方式为两种,一种是基于jxl...
    依静轩阅读 6,563评论 1 9
  • POI操作Excel Excel简介一个excel文件就是一个工作簿workbook,一个工作簿中可以创建多张工作...
    灰气球阅读 4,705评论 2 48
  • xls与xlsx的区别: .xls是03版Office Microsoft Office Excel 工作表的格式...
    请叫我张懂阅读 11,641评论 2 15
  • 手把手教你搭建数据驱动测试框架 (一)# 前言 在自动化测试框架中,数据驱动的意思指定的是测试用例或者说测试套件是...
    zhaozhiwen阅读 6,358评论 4 30
  • 同样的年纪,不同的我们——题记 窗外刚下过一场暴雨,短暂得十来分钟不到,天边露出了亮光,水洗过的天空,湛蓝非常,飘...
    蒋大力阅读 215评论 0 2