EasyExcel 导入导出Excel文件

文章目录

  • 写在前面
    • 1、maven依赖
    • 2、导入Excel文件
      • 2.1、读取实例
      • 2.2、多个sheet表格
      • 2.3、监听器封装(也可不封装)
      • 2.4、读取数据格式化
    • 3、导出Excel文件
      • 3.1、导出表格格式

写在前面

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。
github文档: https://github.com/alibaba/easyexcel

1、maven依赖

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>easyexcelartifactId>
    <version>2.2.3version>
dependency>

2、导入Excel文件

常用如下两种读取方式

EasyExcel.read(文件名/文件流,数据实体类.class,监听器).sheet().doRead();
EasyExcel.read(文件名/文件流,数据实体类.class,监听器).build();

2.1、读取实例

实例1:
(这里假设已有实体类User)

public void test1() {
    EasyExcel.read("D:\\file\\1.xlsx", User.class, new AnalysisEventListener<User>() {
        // 每解析一行数据,该方法会被调用一次
        @Override
        public void invoke(User user, AnalysisContext analysisContext) {
            System.out.println("解析数据为:" + user.toString());
        }
        
        // 全部解析完成被调用
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("解析完成...");
            // 保存到数据库
        }
    }).sheet().doRead();
}

实例2:
(这里假设已有实体类User)

// springboot 接口
@PostMapping("/importUser")
public void importUser(@RequestParam("file") MultipartFile file) 
    ExcelReader excelReader = EasyExcel.read(file.getInputStream(), User.class, new AnalysisEventListener<DemoData>() {
        @Override
        public void invoke(User user, AnalysisContext analysisContext) {
            System.out.println("解析数据为:" + user.toString());
        }
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("解析完成...");
            // 保存到数据库
        }
    }).build();
    
    ReadSheet sheet = EasyExcel.readSheet(0).build();    // 创建sheet对象,读取Excel的第一个sheet, 也可以根据sheet名称获取
    excelReader.read(sheet);                             // 读取sheet表格数据,可以读取多个sheet
    excelReader.finish();                                // 这里必须手动关闭
}

2.2、多个sheet表格

读取多个sheet表格

// 方式1
EasyExcel.read(...)
//         .sheet(0).doRead();
           .doReadAll(); // 读取全部sheet


// 方式2
ExcelReader excelReader = EasyExcel.read(...) .build();
ReadSheet sheet = EasyExcel.readSheet(0).build();
//excelReader.read(sheet);
excelReader.readAll(); // 读所有sheet
excelReader.finish();


// 读指定的多个sheet
ExcelReader excelReader = EasyExcel.read(...) .build();
ReadSheet sheet = EasyExcel.readSheet(0).build();
// 读取sheet,有几个就构建几个sheet进行读取
excelReader.read(sheet0);
excelReader.finish();

2.3、监听器封装(也可不封装)

每次调用 EasyExcel.read() 都需要 new 一个 AnalysisEventListener 对象,我们可以将AnalysisEventListener封装为一个对象,方便重复调用

public class EasyExcelUtils<T> {

    /**
     * 获取读取Excel的监听器对象
     * @param consumer 处理解析数据的函数, 一般可以是数据入库逻辑的函数
     * @param threshold 阈值,达到阈值就处理一次存储的数据
     * @param  数据模型泛型
     * @return 返回监听器
     */
    public static <T> AnalysisEventListener<T> getReadListener(Consumer<List<T>> consumer, int threshold) {

        return new AnalysisEventListener<T>() {
        
           // ArrayList 查询更快
           // List dataList = new ArrayList<>(threshold);
           // LinkedList 插入和删除更快
            List<T> dataList = new LinkedList<>(); 

            /**
             * 每解析一行调用, 订阅者1
             * @param data 解析的每行数据
             * @param context
             */
            @Override
            public void invoke(T data, AnalysisContext context) {
                dataList.add(data);
                // 达到阈值就处理一次存储的数据
                if (dataList.size() >= threshold) {
                    consumer.accept(dataList);
                    dataList.clear();
                }
            }

            /**
             * excel文件解析完成后,事件调度中心会通知到该方法, 订阅者2
             * @param context
             */
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // 最后阈值外的数据做处理
                if (dataList.size() > 0) {
                    consumer.accept(dataList);
                }
            }
        };

    }

    /**
     * 获取读取Excel的监听器对象, 不指定阈值, 默认阈值为 2000
     */
    public static <T> AnalysisEventListener<T> getReadListener(Consumer<List<T>> consumer) {
        return getReadListener(consumer, 2000);
    }
}

使用示例

// 读取excel文件
public void test() {
    EasyExcel.read("user.xlsx", User.class,EasyExcelUtils.getReadListener(dataProcess())).doReadAll();
}

// 处理数据
public Consumer<List<User>> dataProcess() {
    return users -> users.forEach(System.out::println);
}

2.4、读取数据格式化

在实体类中加入注解可以格式化数据,
与lombok结合使用。

@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {

    @ExcelProperty(value = "字符串标题", index = 0)
    private String name;
    
    @ExcelProperty(value = "日期标题", index = 1)
    @DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒")  // 格式化日期类型数据
    private Date hireDate;
    
    @ExcelProperty(value = "数字标题", index = 2)
    @NumberFormat(value = "###.#")  // 格式化数字类型数据,保留一位小数,@NumberFormat不能用在Double类型中
    private String salary;
}

3、导出Excel文件

// 1、根据实体对象导出文件
EasyExcel.write(response.getOutputStream(), 实体.class).sheet().doWrite(list<实体>);

// 2、根据List>导出文件
EasyExcel.write(response.getOutputStream()).head(表头list对象).sheet().doWrite(数据list对象);

// 3、根据模板文件
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(new ClassPathResource("模板.xlsx").getInputStream()).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(list实体对象, writeSheet);  // 填充数据1
excelWriter.fill(map对象, writeSheet);       // 填充数据2
excelWriter.finish();                        // 关闭流

3.1、导出表格格式

在实体类中定义

@Data
@NoArgsConstructor
//@ContentRowHeight(50)//内容单元格高度
//@HeadRowHeight(50)//表头单元格高度
//@ColumnWidth(50)//单元格宽度
public class User {
	
    @ExcelProperty(value = {"导出台账","序号"})
    private Integer no;
    
    @ExcelProperty(value = {"导出台账","编号"})
    private  String  code;
}

你可能感兴趣的:(java系列,java,spring,boot,excel)