首先这篇博客可以告诉你什么?

  1. springboot中 如何用easypoi导出数据?
  2. 用ajax请求数据流,后台写入字节流无反应
  3. maven导入easypoi的 springboot版本后,报 ErrorWebMvc is registry 的错误
  4. easypoi的简单使用

在自己做的一个 SpringBoot 2.14Relese 版本的一个小系统中 有数据导出的需求。

以前是用 Apache的POI进行数据的导出, 但查到 有简单的封装插件 easypoi ,我决定用一下这个新东西。

首先介绍一下它的中文教程

http://easypoi.mydoc.io/

 

这个插件通过注解的方式来实现自动添加列

这个注解就是 @Excel 这是最核心的注解,其他的可以看它教程中的具体参数就好

Maven的引入

注意 这里就产生了一个问题 ,之前我是 用 easypoi-spring-boot-starter ,它与 导入上面的3个包的功能是一样的,但是 在 springboot 2.1以上的版本,SpringBoot关于 SpringMVC 的自动配置 中 存在 ErrorWebMvc等类的命名注册冲突,所以还是用回 上面的那3个jar包吧!! 

<!-- 集成easypoi组件 .导出excel http://easypoi.mydoc.io/ -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.2.0</version>
        </dependency>


        <!--  Excel 导出插件 但 与 springboot 2.1 版本冲突 -->
      <!--  <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>-->

 

我们需要导出的数据不一定要新建一个 pojo 类来 对应 列的关系数据

如果在现有的 bean中符合要求,可直接在现有的 bean 上添加 注解

需要导出那些字段上加上注解和相关参数

@EntityScan
public class Record {

    private String rid;

    @Excel(name = "修改人", width = 20)
    private String modify_username;
    @Excel(name = "工号", width = 20)
    private String emp_id;
    @Excel(name = "日期", width = 25,exportFormat = "yyyy-MM-dd HH:mm")
    private Date create_date;
    @Excel(name = "CAR号", width = 30)
    private String leasts;
    @Excel(name = "客户编码", width = 35)
    private String customercode;
    @Excel(name = "修改内容", width = 60)
    private String content;
    @Excel(name = "修改理由", width = 50)
    private String reason;

   // 省略get set
}

那么如果 是 存在一对多的关系咋办 ,比如 一个 班级 对应 一个老师,多个学生,导出班级的所有信息

springboo导出Exce springboot poi导出_springboo导出Exce

 

在 Class classes 这个类的字段中对于对象 和 集合添加 @ExcelEntity 和 @ExcelCollection即可

当然ID是对应的, Teacher这个类上也要加@ExcelTarget (“teacher”)对应关系

@ExcelTarget("classes")
 public class classes implements java.io.Serializable {

    private String        id;

    @Excel(name = "课程名称", orderNum = "1", width = 25)
    private String        name;

    @ExcelEntity(id = "teacher")
    private Teacher teacher;

    @ExcelCollection(name = "学生", orderNum = "4")
    private List<Student> students;
 }

Controller类中相关方法

@GetMapping("/export")
    public void complaintChangeRecordToExcel(@RequestParam("startdate") String startdate,
                                            @RequestParam("enddate") String enddate,
                                            HttpServletResponse response) throws  Exception {
       //  如果要使用 自己设计的模板,而不是让 插件给你自动创建就引入模板,写入字节流
       // TemplateExportParams params = new TemplateExportParams("com/suntak/eightdisciplines/doc/record.xlsx");
       // params.setSheetName("客诉修改明细");
        response.reset();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 由于传入的结束时间是 那天 的0点不符合实际需求,改为当天23:59分
        Date startday = sdf.parse(startdate);
        Date endday = sdf.parse(enddate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(endday);
        cal.add(Calendar.DAY_OF_MONTH,1);
        endday = cal.getTime();
        List<Record> list = recordService.getRecordByOptions(startday,endday,"");


        //ExcelExportUtil.exportExcel( new ExportParams("8D客诉修改记录明细","客诉修改明细"),Record.class, list)
        // 这种是帮你 自行创建 EXCEL表格
        // 告诉浏览器用什么软件可以打开此文件
        response.setHeader("content-Type", "application/vnd.ms-excel");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("8D修改数据明细表","UTF-8") + ".xls");
        //编码
        response.setCharacterEncoding("UTF-8");
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), Record.class, list);
        workbook.write(response.getOutputStream());
    }

前端当时我是用ajax请求的,发现不报错但是也没反应。这就引发了这个问题

用ajax请求数据流,后台写入字节流无反应?

为什么呢? 这是因为 ajax 是无法直接导出excel的, ajax返回的数据格式是字符流,而导出excel是后台往浏览器中写入二进制的字节流。

字节流是 1byte : 8 bit

字符流是 1 char : 2 byte : 16 bit

 

那我们该如何 请求呢? 

方法有很多,可以用一个内置表单来submit,也可以 window.open(),window.location.href

这里用 window.location.href

// 导出客诉修改EXCEL
    $("#exportBtn").click(function(){
        var start_day = $("#startdate").val();
        var end_day = $("#enddate").val();

        window.location.href = contextPath +"record/export?startdate="+start_day + "&enddate="+ end_day;
    });

这样请求,浏览器就会直接接受到 Excel的字节流 生成一个 xlsx 的文件。

这里说一下如果是自己设计的模板写入字节流时,模板该怎么写, 注意不要用别名, 直接用 t作为数据对象 {{fe:list t.username,t.password }}   ,让数据遍历每行就行。Controller类中的写法看中文文档。

springboo导出Exce springboot poi导出_springboo导出Exce_02