EasyPOI与EasyExcel 实现导入和导出 | Eddie'Blog
EasyPOI与EasyExcel 实现导入和导出

EasyPOI与EasyExcel 实现导入和导出

eddie 803 2022-01-27

目录

1.0 准备工作

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>${easyexcel.version}</version>
</dependency>

Students.json

[
  {
    "id": "1",
    "username": "zhangsan",
    "password": "123456",
    "nickname": "xiaosan",
    "birthday": "2022-01-01",
    "mobile": "13800138000",
    "gender": "0"
  },
  {
    "id": "2",
    "username": "lisi",
    "password": "123456",
    "nickname": "xiaosi",
    "birthday": "2022-02-01",
    "mobile": "13800138001",
    "gender": "0"
  },
  {
    "id": "3",
    "username": "wangwu",
    "password": "123456",
    "nickname": "xiaowang",
    "birthday": "2022-03-01",
    "mobile": "13800138002",
    "gender": "1"
  },
  {
    "id": "4",
    "username": "chaoliu",
    "password": "123456",
    "nickname": "xiaoliu",
    "birthday": "2022-04-01",
    "mobile": "13800138003",
    "gender": "1"
  }
]

2.0 EasyExcel 导入和导出

2.0.1 利用 EasyExcel 进行导出

2.0.1.1 Student Entity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

  @ExcelProperty("ID")
  @ColumnWidth(10)
  private Long id;

  @ExcelProperty("用户名")
  @ColumnWidth(20)
  private String username;

  @ExcelIgnore
  private String password;

  @ExcelProperty("昵称")
  @ColumnWidth(20)
  private String nickname;

  @ExcelProperty("出生日期")
  @ColumnWidth(20)
  @DateTimeFormat("yyyy-MM-dd")
  @JsonFormat(pattern = "yyyy-MM-dd")
  private Date birthday;

  @ExcelProperty("手机号")
  @ColumnWidth(20)
  private String mobile;

  /** 0->男,1->女 **/
  @ExcelProperty(value = "性别", converter = GenderConverter.class)
  @ColumnWidth(10)
  private Integer gender;
}

2.0.1.2 Controller

/**
 * 导出会员列表Excel
 *
 * @param response
 */
@SneakyThrows(IOException.class)
@GetMapping("/exportStudentList")
public void exportStudentList(HttpServletResponse response) {
  String title = "学生列表";
  EasyExcelUtils.setExcelRespProp(response, title);
  List<Student> studentList = FileUtils.readJsonFile();
  // 写Excel
  EasyExcel.write(response.getOutputStream())
      .head(Student.class)
      .excelType(ExcelTypeEnum.XLSX)
      .sheet(title)
      .doWrite(studentList);
}

PostMan -> Send and Download

在这里插入图片描述

2.0.2 利用 EasyExcel 进行导入

/**
 * 从Excel导入会员列表
 *
 * @param file
 * @return
 */
@SneakyThrows(Exception.class)
@PostMapping("/importStudentList")
@ResponseBody
public List<Student> importStudentList(@RequestPart("file") MultipartFile file) {
  return EasyExcel.read(file.getInputStream())
      .head(Student.class)
      .sheet()
      .doReadSync();
}

在这里插入图片描述

3.0 EasyPOI导入和导出

3.0.1 利用 EasyPOI 进行导出

3.1.1.1 准备工作

<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-base</artifactId>
  <version>${easypoi.version}</version>
</dependency>
<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-web</artifactId>
  <version>${easypoi.version}</version>
</dependency>
<dependency>
  <groupId>cn.afterturn</groupId>
  <artifactId>easypoi-annotation</artifactId>
  <version>${easypoi.version}</version>
</dependency>

3.1.1.2 Entity

学校信息

@Data
@ExcelTarget("school")
public class School {

  @Excel(name = "编号", width = 30 , needMerge = true)
  private Integer id;

  @Excel(name = "教学科目", width = 30 , needMerge = true)
  private String subject;

  @ExcelCollection(name = "教师信息")
  private List<Teacher> teachers;

}

教师信息

@Data
@ExcelTarget("teacher")
public class Teacher {

  @Excel(name = "序号", width = 30, isColumnHidden = true)
  private Integer id;

  @Excel(name = "教师姓名", width = 30, groupName = "基本信息")
  private String empName;

  @Excel(name = "年龄", width = 30, type = 10, groupName = "基本信息")
  private Integer age;

  @Excel(name = "入职时间", width = 30, groupName = "工作信息", format = "yyyy/MM/dd HH:mm")
  private Date entryTime;

  @Excel(name = "薪酬", width = 30, type = 10, groupName = "工作信息")
  private BigDecimal salary;

}

groupName 合并表格导出好用,导入就需要留意

3.1.1.3 Service

@Service
public class SheetsServiceImpl implements SheetsService {

  @Override
  public List<Map<String, Object>> getEasypoiData() {

    Random random=new Random();

    List<School> exportList = new LinkedList<>();
    School school = new School();
    school.setId(1);
    school.setSubject("计算机科");

    List<Teacher> ll = new LinkedList<>();
    for (int i = 0; i < 10; i++) {
      if (i % 2 == 0) {
        Teacher teacher = new Teacher();
        teacher.setId(i);
        teacher.setAge(random.nextInt(90)+10);
        teacher.setEmpName("张三" + i);
        teacher.setSalary(BigDecimal.valueOf(random.nextInt(100)+100));
        teacher.setEntryTime(new Date());
        ll.add(teacher);
      } else {
        Teacher teacher2 = new Teacher();
        teacher2.setId(i);
        teacher2.setAge(random.nextInt(90)+10);
        teacher2.setEmpName("王五" + i);
        teacher2.setSalary(BigDecimal.valueOf(random.nextInt(100)+100));
        teacher2.setEntryTime(new Date());
        ll.add(teacher2);
      }
    }

    school.setTeachers(ll);
    exportList.add(school);
    ExportParams exportParams = new ExportParams();
    // 设置sheet得名称
    exportParams.setSheetName("员工报表1");

    Map<String, Object> exportMap = new HashMap<>(16);
    // title的参数为ExportParams类型,目前仅仅在ExportParams中设置了sheetName
    exportMap.put("title", exportParams);
    // 模版导出对应得实体类型
    exportMap.put("entity", School.class);
    // sheet中要填充得数据
    exportMap.put("data", exportList);

    List<Map<String, Object>> sheetsList = new ArrayList<>();
    sheetsList.add(exportMap);
    return sheetsList;
  }

}

3.1.1.4 Controller

package com.edcode.easypoi.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.edcode.easypoi.entity.Teacher2;
import com.edcode.easypoi.service.SheetsService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author eddie.lee
 * @date 2022-01-26 17:16
 * @description https://easypoi.mydoc.io/#text_202979
 */
@Controller
@RequestMapping("/easyPoi")
@RequiredArgsConstructor
public class EasyPoiController {

  private final SheetsService sheetsService;

  @GetMapping("export")
  public void export(HttpServletResponse response) throws IOException {
    try {
      List<Map<String, Object>> sheetsList = sheetsService.getEasypoiData();
      setWorkbook(response, sheetsList);
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }

  private void setWorkbook(HttpServletResponse response, List<Map<String, Object>> sheetsList)
      throws IOException {
    // 导出显示文件名称
    String excelName = "excelName.xls";
    // 设置响应输出的头类型
    response.setHeader("content-Type", "application/vnd.ms-excel");
    // 下载文件的默认名称
    response.setHeader("Content-Disposition", "attachment;filename=" + excelName);
    // exportExcel 传 List<Map<String, Object>>
    Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
    ServletOutputStream outputStream = response.getOutputStream();
    workbook.write(outputStream);
    outputStream.flush();
    outputStream.close();
  }

  /**
   * 复杂导入使用
   * @param file
   * @return
   * @throws Exception
   */
  @PostMapping("/importExcel")
  @ResponseBody
  public List<Map<String, Object>> importExcel(@RequestParam("file") MultipartFile file) throws Exception {
    ImportParams params = new ImportParams();
    params.setTitleRows(0);
    params.setHeadRows(3);
    params.setNeedVerify(true);
    List<Map<String, Object>> list = ExcelImportUtil.importExcel(
        file.getInputStream(),
        Map.class,
        params);
    System.out.println(JSONUtil.toJsonStr(list));
    return list;
  }

  /**
   * 简单的表格导入
   * @param file
   * @return
   */
  @PostMapping("/importExcel2")
  @ResponseBody
  public List<Teacher2> importExcel2(@RequestParam("file") MultipartFile file) {
    ImportParams params = new ImportParams();
    params.setTitleRows(0);
    //头行忽略的行数
    params.setHeadRows(1);
    //是否开启校验
    params.setNeedVerify(true);
    try {
      ExcelImportResult<Teacher2> result = ExcelImportUtil.importExcelMore(
          file.getInputStream(),
          Teacher2.class,
          params);
      List<Teacher2> list = result.getList().stream().map(item -> {
        Teacher2 t2 = new Teacher2();
        BeanUtil.copyProperties(item, t2);
        return t2;
      }).collect(Collectors.toList());
      System.out.println(JSONUtil.toJsonStr(list));
      return list;
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return new ArrayList<>();
  }
}

3.1.1.4 PostMan

  • Excel 简单表格

在这里插入图片描述POST http://localhost:8081/easyPoi/importExcel2
在这里插入图片描述

  • Excel 复杂表格
    • 嵌套型导入

在这里插入图片描述

POST http://localhost:8081/easyPoi/importExcel
在这里插入图片描述

在上面我使用的是 Map去接收,而不是 School 实体类,至于为什么,看到 PostMan 截图你就会明白了。也不在过多解释!

4.0 总结

  • 简单表格而追求效率的使用 EasyExcel
  • 复杂表格而追求快捷开发使用 EasyPOI

示例源码:Github