使用POI操作Excel

使用POIExcel进行读、写操作

   Apache POI官网:https://poi.apache.org/

 什么是POI

 

 基本功能?

 

  1. POI-Excel

 

 

 

 

主要步骤:①创建工作簿; ②创建工作表; ③创建行; ④创建列

 

(1) 在项目中引入pom依赖

<!--xls(03)-->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.9</version>
</dependency>

<!--xlsx(07)-->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.9</version>
</dependency>

<!--日期格式化工具-->
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
  <groupId>joda-time</groupId>
  <artifactId>joda-time</artifactId>
  <version>2.10.1</version>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>

 

 

03版本:

//构建路径
String PATH="E:\\workpaceid\\Excel_test\\poi_test";

/*测试Excel03版本*/
@Test
public void testWrite03() throws Exception {
    //1.创建一个工作簿
    Workbook workbook = new HSSFWorkbook();
    //2.创建一个工作表
    Sheet sheet=workbook.createSheet("信息表");
    //3.创建一个行
    Row row1=sheet.createRow(0);
    //4.创建一个单元格 (构成了 A,1 这个单元格)
    Cell cellA1 = row1.createCell(0);
    //5.向单元格中填写数据
     cellA1.setCellValue("姓名");
        //(构成 A,2 坐标)
    Cell cellB1 = row1.createCell(1);
    cellB1.setCellValue("时间");
        //创建第二行 并传入数据
     Row row2 =sheet.createRow(1);
     Cell cellA2 = row2.createCell(0);
     cellA2.setCellValue("张三");
     Cell cellB2 = row2.createCell(1);
     String time= new DateTime().toString("yyyy-MM-DD");
     cellB2.setCellValue(time);

    //6.生成一张表(IO 流) 03版本后缀名使用xls
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "信息表03.xls");
    //通过流输出输出
    workbook.write(fileOutputStream);
    //关闭流
    fileOutputStream.close();
    System.out.println("信息表03生成完毕!");
}

 

 

07版本(生成方法和03版本一样 )

   区别在于 对象的不同   文件后缀名的不同

/*测试Excel07版本*/
@Test
public void testWrite07() throws Exception {
    //1.创建一个工作簿 使用excel操作的 workBook都能操作
    Workbook workbook = new XSSFWorkbook();
    //2.创建一个工作表 表中的设置
    Sheet sheet=workbook.createSheet("信息表");
    //3.创建一个行
    Row row1=sheet.createRow(0);
    //4.创建一个单元格 (构成了 A,1 这个单元格)
    Cell cellA1 = row1.createCell(0);
    //5.向单元格中填写数据
    cellA1.setCellValue("姓名");
    //(构成 A,2 坐标)
    Cell cellB1 = row1.createCell(1);
    cellB1.setCellValue("时间");
    //创建第二行 并传入数据
    Row row2 =sheet.createRow(1);
    Cell cellA2 = row2.createCell(0);
    cellA2.setCellValue("李四");
    Cell cellB2 = row2.createCell(1);
    String time= new DateTime().toString("yyyy-MM-DD");
    cellB2.setCellValue(time);

    //6.生成一张表(IO 流) 03版本后缀名使用xls
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "信息表07.xlsx");
    //通过流输出输出
    workbook.write(fileOutputStream);
    //关闭流
    fileOutputStream.close();
    System.out.println("信息表07生成完毕!");
}

 

 

大文件写HSSF03版)

优点:过程中写入缓存,不操作磁盘,最后一次写入磁盘,速度快

缺点:最多下入65536行,否则会抛出异常


/**
 *测试03版本大数据写入
 * 优点:过程中写入缓存,不操作磁盘,最后一次写入磁盘,速度快
 * 缺点:最多写入65536行,否则抛出异常
 */
@Test
public void testWrite03BigData() throws Exception {
    //计算时间 开始时间
    long begin=System.currentTimeMillis();
    //创建工作薄
    Workbook workbook=new HSSFWorkbook();
    //创建表
    Sheet sheet = workbook.createSheet();
    //写入数据
    for (int RowNum=0;RowNum<65536;RowNum++){        //RowNum 行数
        Row row = sheet.createRow(RowNum);          //每一行
        for ( int CellNum=0;CellNum<10;CellNum++){
            Cell cell = row.createCell(CellNum);     //每一个单元格
            cell.setCellValue(CellNum+1);
        }
    }
    System.out.println("over!");
    //生成一张表
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "bigData03.xls");
    //输出
    workbook.write(fileOutputStream);
    //关流
    fileOutputStream.close();
    //结束时间
    long end=System.currentTimeMillis();
    System.out.println((double)(end-begin)/1000);
}

 

 

大文件写XSSF07版)

优点:可以写入大量的数据

缺点:写数据的速度慢,消耗内存,如超过100万条数据,也会发生内存溢出现象

/**
 *测试07版本大数据写入
 * 优点:可以写入较大的数据量
 * 缺点:写数据的速度慢,消耗内存,如超过100万条数据,也会发生内存溢出现象
 */
@Test
public void testWrite07BigData() throws Exception {
    //计算时间 开始时间
    long begin=System.currentTimeMillis();
    //创建工作薄
    Workbook workbook=new XSSFWorkbook();
    //创建表
    Sheet sheet = workbook.createSheet();
    //写入数据
    for (int RowNum=0;RowNum<65537;RowNum++){        //RowNum 行数
        Row row = sheet.createRow(RowNum);          //每一行
        for ( int CellNum=0;CellNum<10;CellNum++){
            Cell cell = row.createCell(CellNum);     //每一个单元格
            cell.setCellValue(CellNum+1);
        }
    }
    System.out.println("over!");
    //生成一张表
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "bigData07.xlsx");
    //输出
    workbook.write(fileOutputStream);
    //关流
    fileOutputStream.close();
    //结束时间
    long end=System.currentTimeMillis();
    System.out.println((double)(end-begin)/1000);

}

 

 

 

大文件写SXSSF

优点:可以写入非常大的数据,如100万条甚至更多,写数据速度快,占用更少的内存

注意:过程中会产生临时文件,需要清理临时文件;

      默认有100条数据会被存入内存中,如果超过这个数量,则最前面的数据会被写入临时文件;

      自定义内存中的数量,可以使用new SXSSFWorkBook(数量)。

/**
 *测试大文件写SXSSF
 *优点:可以写入非常大的数据量,如100万条甚至更多,写数据数据快,占用更少内存
 * 注意:过程中会产生临时文件,需要清理临时文件
 *       默认有100条数据被存入内存中,如果超过这个数量,则最前面的数据被写入临时文件
 *       自定义内存中的数量,可以使用new SXXFWorkBook(数量)
 */
@Test
public void testWrite07BigDatas() throws Exception {
    //计算时间 开始时间
    long begin=System.currentTimeMillis();
    //创建工作薄
    Workbook workbook=new SXSSFWorkbook();
    //创建表
    Sheet sheet = workbook.createSheet();
    //写入数据
    for (int RowNum=0;RowNum<65535;RowNum++){        //RowNum 行数
        Row row = sheet.createRow(RowNum);          //每一行
        for ( int CellNum=0;CellNum<10;CellNum++){
            Cell cell = row.createCell(CellNum);     //每一个单元格
            cell.setCellValue(CellNum+1);
        }
    }
    System.out.println("over!");
    //生成一张表
    FileOutputStream fileOutputStream = new FileOutputStream(PATH + "bigData07S.xlsx");
    //输出
    workbook.write(fileOutputStream);
    //关流
    fileOutputStream.close();
    //清除临时文件
    ((SXSSFWorkbook)workbook).dispose();
    //结束时间
    long end=System.currentTimeMillis();
    System.out.println((double)(end-begin)/1000);
}

 

 

 

  1. POI-Excel

03版本读

在读取Excel中的数据是需要注意获取值的类型

/*测试03版本读取*/
@Test
public void TestRead03() throws Exception {

    //1.获取文件流
    FileInputStream fileInputStream = new FileInputStream(PATH+"poi_test信息表03.xls");
    //2.读取工作簿中的内容
    Workbook workbook=new HSSFWorkbook(fileInputStream);
    //3.获取工作中的表
    Sheet sheetAt = workbook.getSheetAt(0); //根据下标获取 也可根据表名查找
    //4.获取表中的行
    Row row1 = sheetAt.getRow(0);
    //5.获取单元格
    Cell cellA1 = row1.getCell(0);
    //6.取出单元格中的值
    // 读取值的时候需要注意表中数据的类型
    System.out.println(cellA1.getStringCellValue());   //getStringCellValue() 获取的是制字符串类型
    //关闭流
    fileInputStream.close();
}

 

 

 07版本读

/*测试07版本读取*/
@Test
public void TestRead07() throws Exception {

    //1.获取文件流
    FileInputStream fileInputStream = new FileInputStream(PATH+"poi_test信息表07.xlsx");

    //2.读取工作簿中的内容
    Workbook workbook=new XSSFWorkbook(fileInputStream);

    //3.获取工作簿中的表
    Sheet sheetAt = workbook.getSheetAt(0);

    //4.获取表中的行
    Row row2 = sheetAt.getRow(1);

    //5.获取单元格
    Cell cellB2 = row2.getCell(1);

    //6.取出单元格中的值
    System.out.println(cellB2.getStringCellValue());   //getStringCellValue() 获取的是制字符串类型

    //关闭流
    fileInputStream.close();
}

 

 

获取Excel中不同类型的值

/*读取不同类型的数据*/
@Test
public void testCellType() throws Exception {
    //1.获取文件流
    FileInputStream fileInputStream = new FileInputStream(PATH+"明细表.xls");
    //2.读取工作簿中的内容
    Workbook workbook=new HSSFWorkbook(fileInputStream);
    //3.获取工作簿中的表
    Sheet sheetAt = workbook.getSheetAt(0);
    //4.获取标题内容
    Row rowTitle = sheetAt.getRow(0);    //第一行 标题
    // 判断标题内容是否为空
    if(rowTitle!=null){
        //得到第一行标题的个数 (获取所有列数)
        int cellCount = rowTitle.getPhysicalNumberOfCells();
        for (int cellNum=0;cellNum<cellCount;cellNum++){
            Cell cell = rowTitle.getCell(cellNum);
            if (cell!=null){
                //获取类型
                int cellType = cell.getCellType();
                String cellValue = cell.getStringCellValue();
                System.out.print(cellValue+" | ");
            }
        }
        System.out.println();
    }
    //5.获取表中的内容
        //获取所有行数
    int rowCount= sheetAt.getPhysicalNumberOfRows();
    for(int rowNum=1;rowNum<rowCount;rowNum++){
        //获取行
        Row rowData = sheetAt.getRow(rowNum);
        //判断获取到每一行是否为空
        if(rowData!=null){
            //读取列
            int cellCount = rowTitle.getPhysicalNumberOfCells();
            for(int cellNum=0;cellNum<cellCount;cellNum++){
                System.out.print("["+(rowNum+1)+","+(cellNum+1)+"]");
                //获取列 获取单元格
                Cell cell = rowData.getCell(cellNum);
                /**
                 * 拿到单元格后并不能知道单元格的类型
                 * 需要去匹配数据类型
                 */
                 if(cell!=null){
                     //获取列类型
                     int cellType = cell.getCellType();
                     String cellVaule="";
                     switch (cellType){
                         case HSSFCell.CELL_TYPE_STRING:   //为字符串类型
                             System.out.print("[String]");
                             //获取值
                              cellVaule = cell.getStringCellValue();
                              break;
                         case HSSFCell.CELL_TYPE_BOOLEAN:   //为布尔类型
                             System.out.print("[Boolean]");
                             //获取值
                             cellVaule = String.valueOf(cell.getBooleanCellValue());
                             break;
                         case HSSFCell.CELL_TYPE_BLANK:   //为空
                             System.out.print("[Blank]");
                             break;
                         case HSSFCell.CELL_TYPE_NUMERIC:   //为数字 (日期和普通数字)
                             System.out.print("[NUMERIC]");
                             //再次判断数字为日期还是普通数字
                             if(HSSFDateUtil.isCellDateFormatted(cell)){    //日期
                                 System.out.print("[日期]");
                                 Date date = cell.getDateCellValue();
                                 cellVaule = new DateTime(date).toString("yyyy-MM-dd");
                             }else{                                               //为普通数字
                                 //如果不是日期,防止数字过长(科学计数法),转换成字符串输出
                                 System.out.print("[数字]");
                                 cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                                 cellVaule=cell.toString();
                             }
                             break;
                         case HSSFCell.CELL_TYPE_ERROR:   //数据类型错误
                             System.out.print("[数据类型错误]");
                             break;
                     }
                     System.out.println(cellVaule);
                 }
            }
        }
    }
    //关流
    fileInputStream.close();
}

 

 

  1. POI-Excel 计算公式

public class TestFormula {
   //路径变量
    String PATH="E:\\workpaceid\\Excel_test\\poi_test\\";
    /*测试计算公式*/
    @Test
    public void testFormula() throws Exception {

        //1.创建流
        FileInputStream fileInputStream = new FileInputStream(PATH+"计算公式.xls");
        //2.获取工作簿
        Workbook Workbook = new HSSFWorkbook(fileInputStream);
        //3.获取表
        Sheet sheetAt = Workbook.getSheetAt(0);
        //4.获取计算公式的单元格
        Row row = sheetAt.getRow(5);
        Cell cell = row.getCell(0);
        //5.拿到计算公式eval
        FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook)Workbook);
        //6.输出单元格的公式
            //获取类型
        int cellType = cell.getCellType();
            //判断
        switch (cellType){
            case Cell.CELL_TYPE_FORMULA:   //公式
                String cellFormula = cell.getCellFormula();
                //进行计算
                CellValue evaluate = formulaEvaluator.evaluate(cell);
                //得到计算结果的值
                String value = evaluate.formatAsString();
                System.out.println(value);
                break;
        }
    }
}

 

posted @ 2020-08-12 11:06  宋雨航哎  阅读(371)  评论(0编辑  收藏  举报