Spring Boot Excel导出二

425 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前言

上一篇给大家介绍了Spring Boot 集成jxls导出excel,不熟悉的朋友可以参考:juejin.cn/post/708236…, 今天给大家介绍下另外一种excel导出神器easyExcel。

简介

EasyExcel 是阿里巴巴开源的一个Java操作Excel的技术,和EasyPoi一样是封装Poi的工具类。但是不同的地方在于,在EasyExcel中解决了Poi技术读取大批量数据耗费内存的问题。当然了,也封装了很多常用的Excel操作

  • 最基本的导入导出
  • 图片的导入导出
  • 大批量数据的导入导出
  • 模板的导出

官方地址:alibaba-easyexcel.github.io/quickstart/…

引入jar包

   <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.4</version>
        </dependency>

无对象数据导出

 // 生成Excel路径
        String fileName = "E:\\easyExcel\\test.xlsx";
              EasyExcel.write(fileName).head(head()).sheet("模板").doWrite(dataList());
     
    private static List<List<String>> head() 
    {
        List<List<String>> list = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("姓名");
        List<String> head1 = new ArrayList<>();
        head1.add("年龄");
        List<String> head2 = new ArrayList<>();
        head2.add("生日");
        list.add(head0);
        list.add(head1);
        list.add(head2);
        return list;
    }
    
      private static  List<List<Object>> dataList() 
      {
          List<List<Object>> list = new ArrayList<>();
          for (int i = 0; i < 10; i++) {
              List<Object> data = new ArrayList<>();
              data.add("张三");
              data.add(25);
              data.add(new Date());
              list.add(data);
          }
          return list;
      }   
              

核心代码:

    EasyExcel.write(fileName).head(head()).sheet("模板").doWrite(dataList());

head()指定excel头部数据,dataList则为导出每行数据

效果图:

图片.png

对象导出数据

定义对象

 //忽略该字段
    @ExcelIgnore 
    private int oid;
    
    @ColumnWidth(50)
    @ExcelProperty(value = "姓名", index = 0)
    private String name;
    
    @ExcelIgnore
    private String pwd;
    
    @ColumnWidth(50)
    @ExcelProperty(value = "性别", index = 2)
    private String sex;
    
    @ColumnWidth(50)
    @ExcelProperty(value = "年龄", index = 1)
    private int age;
    
    @ColumnWidth(50)
    @ExcelProperty(value = "邮箱", index = 3)
    private String email;
    
    @ColumnWidth(100)
    @ExcelProperty(value = "地址", index = 4)
    private String address;
    
    省略getset方法
    

@ExcelIgnore :导出时忽略此字段 @ExcelProperty:value:指定导出列的名称,index:指定导出列的顺序。 @ColumnWidth:指定列的宽度。 @ContentLoopMerge(eachRow = 2,columnExtend = 4): 合并单元格

导出核心代码:

 private static List<TUser> getList() 
  {
      List<TUser> userList = new ArrayList<>();
      for (int i = 1; i <= 10; i++) 
      {
          TUser user = new TUser();
          user.setName("张三" + i);
          user.setSex("男");
          user.setAge(i);
          user.setEmail("1234@163.com");
          user.setAddress("广东省");
          userList.add(user);
      }
      return userList;
  } 
  
  // 生成Excel路径
  String fileName = "E:\\easyExcel\\test1.xlsx";
              EasyExcel.write(fileName,TUser.class).sheet("模板").doWrite(getList()); 
                        

EasyExcel.write:需要指定文件的路径和实体类对象。

导出数据到指定模板

excel模板已经存在了,需要将数据导出到此模板

  //模板名称
        String templateFile="E:\\easyExcel\\template.xlsx";
        // 生成Excel路径
        String fileName = "E:\\easyExcel\\test3.xlsx";
              EasyExcel.write(fileName).withTemplate(templateFile).sheet("模板").doWrite(getList()); 

注意点:

  • 只需要传入导出文件的路径和模板的文件路径即可,无需指定导出对象。
  • 导出的数据到新的excel文件中,而不是在指定的模板文件中添加数据。

Excel模板填充导出

定义模板文件

图片.png

实体对象

public class WorkHistory implements Serializable
{
    private static final long serialVersionUID = 1094291755828460204L;
    
    private String workStarTime;
    
    private String  workEndTime;
    
    private String workUnit;
    
    private String  workDesc;
 }

核心代码

public static void exportFillTemplate() 
 {
          // 生成Excel路径
          String filePath = "E:\\easyExcel\\模板填充测试.xlsx";
          String templatePath = "E:\\easyExcel\\templatefill.xlsx";
          ExcelWriter excelWriter = EasyExcel.write(filePath).withTemplate(templatePath).build();
          WriteSheet writeSheet = EasyExcel.writerSheet().build();
          FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
          // 填充数据
          Map<String, Object> map = new HashMap<>(64);
          map.put("name", "张三");
          map.put("sex", "男");
          map.put("age", "30");
          map.put("phone", "13123456789");
          map.put("email", "123@163.com");
          map.put("address", "广东省");
          map.put("shcool", "北京大学");
          map.put("major", "计算机与科学");
          map.put("education", "硕士");
          excelWriter.fill(map, writeSheet);
          excelWriter.fill(new FillWrapper("data", getWorkWorkHistoryList()), fillConfig, writeSheet);
          // 别忘记关闭流
          excelWriter.finish();
      }
   
      private static List<WorkHistory> getWorkWorkHistoryList() 
      {
          List<WorkHistory> list = new ArrayList<>();
          WorkHistory workHistory;
          for (int i = 1; i <= 10; i++) 
          {
              workHistory = new WorkHistory();
              workHistory.setWorkStarTime("2008/09/01");
              workHistory.setWorkEndTime("2018/09/01");
              workHistory.setWorkUnit("华为有限公司");
              workHistory.setWorkDesc("软件工程师");
              list.add(workHistory);
          }
          return list;
      }

填充数据主要是下面两行代码:

 excelWriter.fill(map, writeSheet);
 //集合对象
 excelWriter.fill(new FillWrapper("data", getWorkWorkHistoryList()), fillConfig, writeSheet);

注意:其中map定义导出集合,字段名称需要与模板定义的名称一样 下面是填充我们的表格,注意这里data的名字要和模板里面的名字一样。

 FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

代表表格每次都会重新生成新的一行,而不是使用下面的空行。

导出效果图:

图片.png

Web 方式导出

@GetMapping("/exportUser")
    public void exportUser(HttpServletRequest request,HttpServletResponse response)
    {
        ExcelWriter excelWriter =null;
        
        try
        {
            String fileName = URLEncoder.encode("web测导出", "UTF-8").replaceAll("\\+", "%20");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            excelWriter= EasyExcel.write(response.getOutputStream(),TUser.class).excelType(ExcelTypeEnum.XLSX).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(1, "模板").build();
            excelWriter.write(getUserPagedList(), writeSheet);
        }
        catch (Exception e)
        {
            logger.error("exportUser error",e);
        }
        finally
        {
            if(excelWriter!=null)
            {
                excelWriter.finish();
            }
        }
    }

代码与前面的导出基本一致,只是参数需要传入输出流。

结语

EasyExcel导出excel很好的解决了导出内存溢出的问题,至此easyexcel导出excel基本功能已经讲解完了,如果需要了解更多的特性,可以查询官网。