Java 通过POI技术实现对Excel中大量数据的读和写操作

最近在学习POI技术,觉得一个不错的视频讲解,分享一下:

视频(讲的很详细):https://www.bilibili.com/video/BV1Ua4y1x7BK

1、使用场景

将Excel表中的信息录入到网站数据库(习题上传、数据上传等),在开发中我们经常会涉及到excel的处理,如导出Excel,导入Excel到数据库中! 操作Excel目前比较流行的就是Apache POI和阿里巴巴的easyExcel !

2、xls(03)和xlsx(07)

xls和xlsx的1区别:
1、就是对象不同,方法一样

2、最大行列得数量不同:

xls最大只有65536行、256列
xlsx可以有1048576行、16384列

3、数据量较小时

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Date;

public class ExcelWrite {

    String PATH = "G:\\狂\\POIStudy\\xy-poi";

    /**
     * 写工作簿 03版本
     */
    @Test
    public void Write03() throws Exception {
        //1.创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        //2.创建 一个工作表
        Sheet sheet = workbook.createSheet("闲言粉丝统计表");
        //3.创建一行
        Row row1 = sheet.createRow(0);
        //4.创建一个单元格
        //(1,1)
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("今日新增观众");
        //(1,2)
        Cell cell2 = row1.createCell(1);
        cell2.setCellValue(666);

        //创建第二行
        Row row2 = sheet.createRow(1);
        //(2,1)
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("统计时间");
        //(2,2)
        Cell cell22 = row2.createCell(1);
        String datetime = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(datetime);

        //生成一张表(IO流),03版本就是使用xls结尾
        FileOutputStream fos = new FileOutputStream(PATH + "闲言观众统计表03.xls");
        //输出
        workbook.write(fos);
        //关闭流
        fos.close();
        System.out.println("文件生成完毕");
    }

    /**
     * 写工作簿 07版本
     */
    @Test
    public void Write07() throws Exception {
        //1.创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        //2.创建 一个工作表
        Sheet sheet = workbook.createSheet("闲言粉丝统计表");
        //3.创建一行
        Row row1 = sheet.createRow(0);
        //4.创建一个单元格
        //(1,1)
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("今日新增观众");
        //(1,2)
        Cell cell2 = row1.createCell(1);
        cell2.setCellValue(666);

        //创建第二行
        Row row2 = sheet.createRow(1);
        //(2,1)
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("统计时间");
        //(2,2)
        Cell cell22 = row2.createCell(1);
        String datetime = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(datetime);

        //生成一张表(IO流),03版本就是使用xlsx结尾
        FileOutputStream fos = new FileOutputStream(PATH + "闲言观众统计表07.xlsx");
        //输出
        workbook.write(fos);
        //关闭流
        fos.close();
        System.out.println("文件生成完毕");
    }
}

4、数据量较大

4.1 HSSF处理方法(03版)

public void Write_03_BigData() throws Exception{

    //时间
    long begin = System.currentTimeMillis();
    //1.创建一个工作簿
   Workbook workbook = new HSSFWorkbook();
    //2.创建一个表
    Sheet sheet = workbook.createSheet("第一页");
    //写入数据
    for (int rowNum = 0;rowNum<65536;rowNum++){
        //3.创建行
        Row row = sheet.createRow(rowNum);
       for (int CellNum = 0;CellNum<10;CellNum++){
           Cell cell = row.createCell(CellNum);
           cell.setCellValue(CellNum);
       }
    }
    System.out.println("over");
    //获取io流
    FileOutputStream fos = new FileOutputStream(PATH+"Write03BigData.xls");
    //生成一张表
    workbook.write(fos);
    fos.close();
    long end = System.currentTimeMillis();
    System.out.println("耗时:"+(end-begin));
}

HSSF的优缺点

优点:过程中写入缓存,不操作磁盘,最后一次性吸入磁盘,速度快
缺点:最多只能处理65536行,否则会抛异常

4.2 XSSF处理方法(07版)
public void Write07BigData() throws Exception{

    //时间
    long begin = System.currentTimeMillis();
    //1.创建一个工作簿
    Workbook workbook = new XSSFWorkbook();
    //2.创建一个表
    Sheet sheet = workbook.createSheet("第一页");
    //写入数据
    for (int rowNum = 0;rowNum<65537;rowNum++){
        //3.创建行
        Row row = sheet.createRow(rowNum);
        for (int CellNum = 0;CellNum<10;CellNum++){
            Cell cell = row.createCell(CellNum);
            cell.setCellValue(CellNum);
        }
    }
    System.out.println("over");
    //获取io流
    FileOutputStream fos = new FileOutputStream(PATH+"Write03BigData.xlsx");
    //生成一张表
    workbook.write(fos);
    fos.close();
    long end = System.currentTimeMillis();
    System.out.println("耗时:"+(end-begin));
}

XSSF的优缺点

优点:可以写较大数据量,比如20万条
缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条数据时可能发生内存溢出。

4.3 SXSSF处理方法

SXSSF方法可加快写数据速度,减少内存占用

public void Write07BigDataS() throws Exception{

    //时间
    long begin = System.currentTimeMillis();
    //1.创建一个工作簿
    Workbook workbook = new SXSSFWorkbook();
    //2.创建一个表
    Sheet sheet = workbook.createSheet("第一页");
    //写入数据
    for (int rowNum = 0;rowNum<100000;rowNum++){
        //3.创建行
        Row row = sheet.createRow(rowNum);
        for (int CellNum = 0;CellNum<10;CellNum++){
            Cell cell = row.createCell(CellNum);
            cell.setCellValue(CellNum);
        }
    }
    System.out.println("over");
    //获取io流
    FileOutputStream fos = new FileOutputStream(PATH+"Write03BigDataS.xlsx");
    //生成一张表
    workbook.write(fos);
    fos.close();
    //清除临时文件
    ((SXSSFWorkbook) workbook).dispose();
    long end = System.currentTimeMillis();
    System.out.println("耗时:"+(end-begin));
}

SXSSF的优点

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

1、 sxssf处理过程中会产生临时文件,需要清理临时文件
2、 默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件
3、如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook(数量)

5、读取Excel中的数据

03版本读取Excel表格内容

 public void CellType03() throws Exception{
     //获取文件流
     FileInputStream fis = new FileInputStream(PATH+"明显表.xls");
     //获取一个工作簿
     Workbook workbook = new HSSFWorkbook(fis);
     //获取一个工作表
     Sheet sheet = workbook.getSheetAt(0);
     //获取第一行内容
     Row row = sheet.getRow(0);
     if (row != null){
         //获取所有的列
         int Cells = row.getPhysicalNumberOfCells();
         for (int col = 0;col < Cells;col++){
             //获取当前列
             Cell cell = row.getCell(col);
             if (cell != null){
                 //获取当前行的第 col 列的值
                 String cellValue = cell.getStringCellValue();
                 System.out.print(cellValue+" | ");
             }
         }
     }
     //获取标准的内容
     //获取有多少行
     int rowCount = sheet.getPhysicalNumberOfRows();
     //从1开始,第一行是标题
     for (int rowNum = 1;rowNum < rowCount;rowNum++){
         Row rowData = sheet.getRow(rowNum);
         if (rowData != null){
             //获取当前行的列数
             int cellCount = rowData.getPhysicalNumberOfCells();
             System.out.println();
             for (int col = 0;col < cellCount;col++){
                 //获取当前列的值
                 Cell cellData = rowData.getCell(col);
                 //打印当前行当前列的值
                 System.out.print("["+(rowNum+1)+"-"+(col+1)+"]");
                 //匹配列的类型
                 if (cellData != null){
                     //获取列的类型
                     int cellType = cellData.getCellType();
                     String cellValue = "";
                     switch (cellType){
                         case  Cell.CELL_TYPE_STRING://字符串
                             System.out.print("[string]");
                             cellValue = cellData.getStringCellValue();
                             break;
                         case  Cell.CELL_TYPE_BOOLEAN://布尔
                             System.out.print("[boolean]");
                             cellValue = String.valueOf(cellData.getBooleanCellValue());
                             break;
                         case  Cell.CELL_TYPE_BLANK://System.out.print("[blank]");
                             break;
                         case  Cell.CELL_TYPE_NUMERIC://数字(日期、普通数字)
                             System.out.print("[numeric]");
                             if (HSSFDateUtil.isCellDateFormatted(cellData)){
                                 //如果是日期
                                 System.out.print("[日期] ");
                                 Date date = cellData.getDateCellValue();
                                 cellValue = new  DateTime(date).toString("yyyy-MM-dd HH:mm:ss");
                             }else {
                                 //不是日期格式,防止数字过长
                                 System.out.print("[转换字符串输出] ");
                                 //转为字符串
                                 cellData.setCellType(HSSFCell.CELL_TYPE_STRING);
                                 cellValue = cellData.toString();
                             }
                             break;
                         case  Cell.CELL_TYPE_ERROR://错误
                             System.out.print("[error]");
                             break;
                     }
                     System.out.print("["+cellValue+"]\n");
                 }
             }
         }
     }
     System.out.println("over");
     fis.close();
 }

如果是07版本的Excel ,只需要将HSSFWorkbook类修改为XSSFWorkbook类,将xls文件修改为xlsx文件。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值