【Java】轻量级自动化组件POI

POI

​ 今天向大家介绍一个轻量级的自动化处理Microsoft Office格式文件的Java组件POI。

​ 在工作中打交道最多的就是Excel数据表了,遇到一些重复性的而又不得不做的事务的时候POI组件就可以根据你的想法完成各种各样的任务。

进入正题,首先向大家介绍一下POI中对Excel操作常用的两个类分别是

HSSFWorkbook Hw = new HSSFWorkbook();
XSSFWorkbook Xw = new XSSFWorkbook();

​ 以上两个对象的区别就是随着Excel的发展来划分的,众所周知Excel有代表性的版本分别是03版本和07版本,这两个版本最显著的区别就是03版本所容纳的数据行只有65536行,而07版本则是可以容纳无限数据的。

​ 以上各两个对象也是为了兼容新版和旧版Excel来划分的,HSSFWorkbook适用于旧版,XSSFWorkbook适用于新版。在使用过程中没有区别,只是对象名称不同。

Maven中的POI依赖

<!--    03版本的POI依赖-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.9</version>
    </dependency>

<!--    07版本的POI依赖-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.9</version>
    </dependency>

<!--    非常好用的时间格式化依赖-->
    <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>2.10.1</version>
    </dependency>

POI写操作

​ 这个操作过程可以使用流水账来形容,顺滑的逻辑思想,下面来简单的过一遍吧

  • 创建对Excel的操作对象,工作簿

    Workbook Work = new XSSFWorkbook();  //面向接口编程,对象变了,接口不变
    
  • 创建工作表

    有了工作簿之后,使用工作簿对象创建工作表

    Sheet sheet = Work.createSheet();
    
  • 创建第一行数据

    使用上面的工作表对象,调用创建数据行方法

    方法内的参数就是Excel中的行数,索引为0,表示常规工作表中的第一行

    Row row = sheet.createRow(0);
    
  • 创建第一列数据

    使用上面的第一行对象,调用创建第一列数据的方法

    方法内的参数为0,就表示创建了第一行中的第一列的数据

    Cell cell = row.createCell(0);
    

​ 执行完上述操作之后,就相当于选中了一个工作表中的第一行中的第一列数据,接下来就可以往当前选中的单元格填充数据了!

  • 填充字符串格式的数据

    cell.setCellValue("卡特琳娜")
    

​ 之后就可将,创建的Excel表输出到本地来查看我们的执行结果啦

  • 输出Excel文档

    //FileOutputStream中参数就是当前本地输出的地址
    FileOutputStream fileOutputStream = new FileOutputStream(PATH+"mmd.xlsx");
    //调用work工作簿对象,就可以将文件输出到本地
    Work.write(fileOutputStream);
    

POI读操作

​ 既然要读取本地的Excel文件,那么就要存在本地文件并且创建文件的输入流

  • 创建本地文件输入流,并转交给工作簿操作对象

    //创建文件的数据流
    FileInputStream file = new FileInputStream(PATH + "07.xlsx");
    
    //将文件流引入POI操作对象
    Workbook Work = new XSSFWorkbook(file);
    
  • 获取工作表

    现在已经有了工作簿的操作对象,现在我们就要选择工作簿中具体的工作表来进行下一步操作,这里介绍两种方法。

    Sheet sheet1 = Work.getSheetAt(0);		//根据索引选择第一张工作表
    Sheet sheet2 = Work.getSheet("one");	//根据工作表的名称选择工作表
    
  • 获取第一行

    将指针定位到第一行

    Row row = sheet1.getRow(0);		//获取第一行
    
  • 获取具体的单元格

    使用定位到上一行的对象,定位具体的第N列数据

    Cell cell = row.getCell(0);		//获取第一行中第一列的数据
    
  • 获取单元格数据

    cell.getStringCellValue()		//获取String的值
    
  • 以工作表对象为基点,获取工作表中有效行的总行数(自动化读取数据的时候使用)

    //获取工作表中可用的数据总行数,说白了就是有多少有效数据行,就返回多大的数字
    int Lines = sheet.getPhysicalNumberOfRows();
    
  • 以行对象为基点,获取行单位下有效列的总列数

    //这个跟上面内个方法没啥大区别,这个是获取当前选中行中有效的数据列数
    int Cells = line.getPhysicalNumberOfCells();
    

​ 到这里其实已经掌握了怎样从Excel中读数据和写数据,其实向Excel中写数据好说,读数据这里有一个很显著的坑,那就是你永远不知道你选择的单元格中的数据类型是啥,所以上面演示的读数据是读出来的String类型的数据。

接下来就补充一下在读数据的时候,为了应对各种情况进行的安全性判断吧。

				/*
                int CELL_TYPE_NUMERIC = 0;      数字类型(普通数字,日期)
                int CELL_TYPE_STRING = 1;       字符串类型
                int CELL_TYPE_FORMULA = 2;      公式类型
                int CELL_TYPE_BLANK = 3;        空白类型
                int CELL_TYPE_BOOLEAN = 4;      Boolean类型
                int CELL_TYPE_ERROR = 5;        错误类型
                 */

实例演示

个人演示的实例,贴在这里,需要者自取,已经封装为工具类,可以直接使用!!!

/**
     * 该方法为自动适配单元格中的各种类型,进行读取Excel中的数据并显示在控制台中
     * 可以进一步进化,封装为工具类使用
     * @throws Exception
     */
    public static void AutoRead07() throws Exception{

        //创建文件的数据流(本地实际存在的文件)
        FileInputStream file = new FileInputStream(PATH + "07.xlsx");

        //将文件流引入POI操作对象
        Workbook Work = new XSSFWorkbook(file);

        //跟上边一样都是先获取位于工作簿中的第一个工作表
        Sheet sheet = Work.getSheetAt(0);

        //获取工作表中可用的数据总行数,说白了就是有多少有效数据行,就返回多大的数字
        int Lines = sheet.getPhysicalNumberOfRows();
        for (int i = 0; i < Lines; i++) {
            //选中第 N 行
            Row line = sheet.getRow(i);

            //这个跟上面内个方法没啥大区别,这个是获取当前选中行中有效的数据列数
            int Cells = line.getPhysicalNumberOfCells();

            for (int j = 0; j < Cells; j++) {
                //获取具体的列
                Cell cell = line.getCell(j);
                //接下来就是打印了,首先经过我们以上的操作,已经定位到了具体单元格,就差获取单元格中的数据了,但是我们并不知道单元格中的数据类型,所以我们不能直接获取
                //不同类型返回不同的值
                if(cell != null){
                    int cellType = cell.getCellType();

                /*
                int CELL_TYPE_NUMERIC = 0;      数字类型(普通数字,日期)
                int CELL_TYPE_STRING = 1;       字符串类型
                int CELL_TYPE_FORMULA = 2;      公式类型
                int CELL_TYPE_BLANK = 3;        空白类型
                int CELL_TYPE_BOOLEAN = 4;      Boolean类型
                int CELL_TYPE_ERROR = 5;        错误类型
                 */

                    String Cellvalue = "";
                    switch (cellType){
                        case Cell.CELL_TYPE_NUMERIC:    //数字类型(普通数字,日期)
                            //HSSFDateUtil.isCellDateFormatted为判断当前数字是否为日期
                            if(HSSFDateUtil.isCellDateFormatted(cell)){
                                Date dateCellValue = cell.getDateCellValue();
                                Cellvalue = new DateTime(dateCellValue).toString("YYYY-MM-dd");
                            }else{
                                Cellvalue = String.valueOf(cell.getNumericCellValue());
                            }
                            break;
                        case Cell.CELL_TYPE_STRING:
                            Cellvalue = cell.getStringCellValue();
                            break;
                        case Cell.CELL_TYPE_FORMULA:
                            Cellvalue = cell.getCellFormula();
                            break;
                        case Cell.CELL_TYPE_BOOLEAN:
                            Cellvalue = String.valueOf(cell.getBooleanCellValue());
                            break;
                        case Cell.CELL_TYPE_ERROR:
                            Cellvalue = String.valueOf(cell.getErrorCellValue());
                            break;
                    }
                    System.out.print(Cellvalue+"  |  ");
                }
            }
            //显示完一行之后自动回车一下
            System.out.println();
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡特霖娜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值