Excel的导入及导出

Excel的导入及导出

作用:

  1. 大量数据的导入以及导出
  2. 将Excel表中的数据录入网站上(习题上传…)数据库回填

Apache POI

在这里插入图片描述

问题:将100w数据先加载到内存中(OOM内存溢出),再写入文件

EasyExcel

在这里插入图片描述

EasyExcel是一行一行读取,POI是直接读取全部内容

Excel单行数据导入

  • 导入依赖
<!--xls(03)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

<!--xlsx(07)-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

<!--日期格式化工具-->
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.10.6</version>
</dependency>

<!--单元测试-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>compile</scope>
</dependency>

注意:两个版本都是3.17,一样的才行,不然07.xlsx就会报错

  • 存储路径
// 文件存储路径
static String PATH ="C:\\Users\\XXX\\Excel\\";
  • Excel(03)导入
	/**
     * o3版本Excel的导出
     */
    public static void Xls03() throws Exception {
        // 1、创建一个工作薄
        Workbook workbook = new HSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet1 = workbook.createSheet("廖述幸03学习表");
        // 3、创建第一行
        Row row1 = sheet1.createRow(0);
        // 4、创建一个单元格 (1,1坐标的单元格)
        Cell cell11 = row1.createCell(0);
        // 5、写入一个数据
        cell11.setCellValue("今日新增学习任务");

        // (1,2坐标的单元格)
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("2个");

        // 6、创建第一行
        Row row2 = sheet1.createRow(1);
        Cell cell21 = row2.createCell(0);
        Cell cell22 = row2.createCell(1);
        cell21.setCellValue("统计时间");
        // 用到joda-time的依赖
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);

        // 7、生成一张Excel表(03版本 xls)
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "o3.xls");
        // 8、写出xls文件
        workbook.write(fileOutputStream);
        // 9、关闭流
        fileOutputStream.close();
        System.out.println("Excel(03版)生成完毕...");
    }
  • Excel(07)导入
/**
     * o7版本
     */
    public static void Xls07() throws Exception {
        // 1、创建一个工作薄
        Workbook workbook = new XSSFWorkbook();
        // 2、创建一个工作表
        Sheet sheet1 = workbook.createSheet("廖述幸07学习表");
        // 3、创建第一行
        Row row1 = sheet1.createRow(0);
        // 4、创建一个单元格 (1,1坐标的单元格)
        Cell cell11 = row1.createCell(0);
        // 5、写入一个数据
        cell11.setCellValue("今日新增学习任务");

        // (1,2坐标的单元格)
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue("统计时间");

        // 6、创建第一行
        Row row2 = sheet1.createRow(1);
        Cell cell21 = row2.createCell(0);
        Cell cell22 = row2.createCell(1);
        cell21.setCellValue("2个");
        // 用到joda-time的依赖
        String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
        cell22.setCellValue(time);

        // 7、生成一张Excel表(03版本 xls)
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "o7.xlsx");
        // 8、写出xls文件
        workbook.write(fileOutputStream);
        // 9、关闭流
        fileOutputStream.close();
        System.out.println("Excel(07版)生成完毕...");
    }

Excel大数据导入

大文件写HSSF(03版)

缺点:最多只能处理65536行,否则会抛出异常

java.lang.IllegalArgumentException:Invallid row number (65536) outside allowable range (0..65536)

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

大文件写XSSF(07)

缺点:写数据时候非常慢,非常消耗内存,也会发生内存溢出,入100w条数据

java.lang.OutOfMemoryError: Java heap space

优点:可写较大的数据量,如:20万条

大文件写SXSSF

优点:可以写非常庞大的数据

注意:

过程中会产生临时文件,需要清理临时文件

  • Excel(03)大数据导入 HSSFWorkbook
	public static void Excel03BigData() throws Exception {
        // 计算开始--->结束的时间差
        long begin = System.currentTimeMillis();

        // 创建薄
        Workbook workbook = new HSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet();
        // 写入数据
        for (int rowNum = 0; rowNum < 65536 ; rowNum++) {
            // 循环生成65536行
            Row row = sheet.createRow(rowNum);
            for (int cellNum=0;cellNum <10;cellNum++){
                // 循环生成10列
                Cell cell = row.createCell(cellNum);
                // 添加列的值
                cell.setCellValue(cellNum);
            }
        }
        // 将这个表写出
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "BigData03.xls");
        workbook.write(fileOutputStream);
        // 关闭流
        fileOutputStream.close();
        System.out.println("大数据Excel03版导入成功...");

        long end = System.currentTimeMillis();
        System.out.println("耗费的时间--->"+(double)(end-begin)/1000);
    }
  • Excel(07)导入 XSSFWorkbook
	public static void Excel07BigData() throws Exception {
        // 计算开始--->结束的时间差
        long begin = System.currentTimeMillis();

        // 创建薄
        Workbook workbook = new XSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet();
        // 写入数据
        for (int rowNum = 0; rowNum < 65536 ; rowNum++) {
            // 循环生成65536行
            Row row = sheet.createRow(rowNum);
            for (int cellNum=0;cellNum <10;cellNum++){
                // 循环生成10列
                Cell cell = row.createCell(cellNum);
                // 添加列的值
                cell.setCellValue(cellNum);
            }
        }
        // 将这个表写出
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "BigData07.xlsx");
        workbook.write(fileOutputStream);
        // 关闭流
        fileOutputStream.close();
        System.out.println("大数据Excel07版导入成功...");

        long end = System.currentTimeMillis();
        System.out.println("耗费的时间--->"+(double)(end-begin)/1000);
    }

java.lang.OutOfMemoryError 内存溢出OOM问题

  • Excel(07)升级版 SXSSFWorkbook
	public static void Excel07BigDataVip() throws Exception {
        // 计算开始--->结束的时间差
        long begin = System.currentTimeMillis();

        // 创建薄 SXSSFWorkbook
        Workbook workbook = new SXSSFWorkbook();
        // 创建表
        Sheet sheet = workbook.createSheet();
        // 写入数据
        for (int rowNum = 0; rowNum < 65536 ; rowNum++) {
            // 循环生成65536行
            Row row = sheet.createRow(rowNum);
            for (int cellNum=0;cellNum <10;cellNum++){
                // 循环生成10列
                Cell cell = row.createCell(cellNum);
                // 添加列的值
                cell.setCellValue(cellNum);
            }
        }
        // 将这个表写出
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "BigData07Vip.xlsx");
        workbook.write(fileOutputStream);
        // 关闭流
        fileOutputStream.close();
        // 清除临时文件
        ((SXSSFWorkbook)workbook).dispose();

        System.out.println("大数据Excel07升级版导入成功...");

        long end = System.currentTimeMillis();
        System.out.println("耗费的时间--->"+(double)(end-begin)/1000);
    }

Excel单行文件读取

// 文件读取路径
static String PATH ="C:\\Users\\XXX\\Excel\\";

public static void Xls03() throws Exception {

    // 1、获取文件输入流
    FileInputStream fileInputStream = new FileInputStream(PATH + "o3.xls");

    // 2、创建一个工作薄
    Workbook workbook = new HSSFWorkbook(fileInputStream);

    // 3、得到表(通过下标获取表)
    Sheet sheet = workbook.getSheetAt(0);

    // 3.1、得到行
    Row row1 = sheet.getRow(0);
    Row row2 = sheet.getRow(1);
    // 3.2 得到列
    Cell cell11 = row1.getCell(0);// 1行1列
    Cell cell12 = row1.getCell(1);// 1行2列
    Cell cell21 = row2.getCell(0);// 2行1列
    Cell cell22 = row2.getCell(1);// 2行2列

    // 3.3、关闭流
    fileInputStream.close();

    // 4、输出(注意获取值的类型)
    System.out.print(cell11.getStringCellValue()+"\t");
    System.out.println(cell12.getStringCellValue());
    System.out.print(cell21.getStringCellValue()+"\t");
    System.out.println(cell22.getStringCellValue());
}

public static void main(String[] args) throws Exception {
    Xls03();
}

07版本的.xlsx只需要同上面改成XSSFWorkbook即可

Excel数据遍历读取+数据类型判定

// 文件读取路径
static String PATH ="C:\\目录\\Excel\\";

public static void Xls03() throws Exception {
    // 1、获取文件输入流
    FileInputStream fileInputStream = new FileInputStream(PATH + "文件名.xls");

    // 2、得到工作薄
    Workbook workbook = new HSSFWorkbook(fileInputStream);
    // 2.1、获取第一个表
    Sheet sheet = workbook.getSheetAt(0);
    // 3、获取第一行(标题)
    Row rowTitle = sheet.getRow(0);
    // 3.1、读取标题内容
    if (rowTitle!=null){
        // 3.2、获取这一行头标题数量
        int cellNum = rowTitle.getPhysicalNumberOfCells();
        // 3.3、循环打印头标题
        System.out.print("|");
        for (int i = 0; i < cellNum; i++) {
            Cell cell = rowTitle.getCell(i);
            // 3.4、判断内容不为空
            if (cell!=null){
                // 3.5、标题都是String类型的
                System.out.print(cell.getStringCellValue());
                System.out.print("|");
            }
        }
        System.out.println();
        System.out.println("=================================");
    }

    // 4、获取除头标题外所有行的内容
    // 4.1、读取行
    int rowNum = sheet.getPhysicalNumberOfRows();
    for (int i = 1; i < rowNum; i++) {
        Row rowData = sheet.getRow(i);
        if (rowData!=null){
            // 4.2、读取列
            int cellNum = rowData.getPhysicalNumberOfCells();
            for (int j = 0; j < cellNum; j++) {
                Cell cell = rowData.getCell(j);
                // 4.3、匹配列的数据类型
                if (cell!=null){
                    CellType cellType = cell.getCellTypeEnum();
                    String cellValue = "";
                    switch (cellType){
                        case STRING://字符串类型
                            System.out.print("【String】");
                            cellValue = cell.getStringCellValue();
                            break;
                        case BOOLEAN:// boolean类型
                            System.out.print("【BOOLEAN】");
                            cellValue = String.valueOf(cell.getBooleanCellValue());
                            break;
                        case NUMERIC:// 数字类型(日期、普通数字)
                            System.out.print("【NUMERIC】");
                            if (HSSFDateUtil.isCellDateFormatted(cell)){
                                System.out.print("【日期类型】");
                                // 日期的转换+格式显示
                                Date date = cell.getDateCellValue();
                                cellValue = new DateTime(date).toString("yyyy-MM-dd");
                            }else {
                                // 不是日期,防止数字过长,转化为String类型
                                cell.setCellType(CellType.STRING);
                                System.out.print("【数字】");
                                cellValue = cell.toString();
                            }
                            break;
                        case BLANK:// 空白
                            System.out.print("【BLANK】");
                            break;
                        case ERROR:// 错误
                            System.out.println("【数据类型错误】");
                            break;
                    }
                    System.out.println(cellValue);

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

public static void main(String[] args) throws Exception {
    Xls03();
}

在这里插入图片描述

EasyExcel的使用

官方文档:https://www.yuque.com/easyexcel/doc/easyexcel

  • 导入依赖
<!--EasyExcel依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

<!--单元测试-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>compile</scope>
</dependency>
    
<!--fastjson依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.73</version>
</dependency>

导入依赖

<!--EasyExcel依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

<!--单元测试-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>compile</scope>
</dependency>
    
<!--fastjson依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.73</version>
</dependency>

EasyExcel依赖中包含了 POI和poi-ooxml,为了防止依赖冲突只导入EasyExcel的依赖就行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值