EasyExcel导出基本使用,及作用于通用报表导出

Posted San-gougou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EasyExcel导出基本使用,及作用于通用报表导出相关的知识,希望对你有一定的参考价值。

最近遇到了一个问题:大数据量导出的时候,性能会大大下降,需要优化excel通用报表导出(是的,没有听错,是通用的导出接口)

于是小编想到了阿里开源了一个excel处理框架,使用简单,节省内存。easyexcel其实去一行行去读数据,逐个去解析,大大减少了占用内存的资源。

 

这里附上官方文档(其实官方文档是很详细了记录了不同场景,建议先看官方文档了解下):EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel (alibaba.com)

关键的问题来了,怎么样去写成一个通用的呢,其实这个小编也是纠结了一小会儿,下面请见详细过程:

1.导入以下依赖

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

2.实体类Student

public class Student implements Serializable 

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    @ExcelProperty("自定义对应列的标题")
    //@ExcelProperty这个注解可以省略,可以通过head来添加列标题,但是要注意,属性的值要和列名相对应
    //如果需要值类型枚举转换,则需要写一个枚举转换类,注解中convertor指定,这里不过多赘述
    //@ExcelProperty(value = "性别(0:女,1:男)",convertor = 枚举转换.class)
    //private GenderType gender;或者是private Integer gender;
    private Integer id;

    @ExcelProperty("自定义对应列的标题")
    private String name;

    @ExcelProperty("自定义对应列的标题")
    private Integer age;

    @ExcelProperty("自定义对应列的标题")
    private String sex;

3.大数据导出接口(我的思路是:前端将查询的httpurl、className(全路径)、分页条件(可忽略)传递到后端接口)

分页的情况:按照分页每页去查询,循环外定义好sheet,循环的去使用httpclient查数据,给excel写入数据。注意:在循环外去finish,因为finish是一个excel的结束。(循环的条件当然是分页参数的totalPages啦)

不分页的情况:这个就比较简单了,可以直接参考下面代码,httpclient去调用前端传回的http接口获取到返回值,json进行转换后,写入即可

/**
     *
     * @param request
     * @param response
     * @param <T>
     * @return
     */
    @GetMapping("/bigData-export")
    public <T> String exportBigData(HttpServletRequest request,HttpServletResponse response) 
        try 
            //新建一个临时的file,指定名称和路径
            File excelFile;
            excelFile = new File(System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis() + ".xls");
            excelFile.createNewFile();
            
            //这里是用于显示我们想要的列名,不需要可以忽略
            List<List<String>> headList = new ArrayList();
            List<String> head1 = new ArrayList();
            head1.add("序列号");
            List<String> head2 = new ArrayList();
            head2.add("姓名");
            List<String> head3 = new ArrayList();
            head3.add("年龄");
            List<String> head4 = new ArrayList();
            head4.add("性别");
            headList.add(head1);
            headList.add(head2);
            headList.add(head3);
            headList.add(head4);

            //com.demo.Student权限定名,可以前端动态传递过来,这里先写成定值了
            Class entityClass = Class.forName(“com.demo.Student”);

            List<String> excluteNameList = new ArrayList<>();
            excluteNameList.add("name");
            ExcelWriter excelWriter = EasyExcel.write(excelFile)//传参是File,可以有两个参(File,class)指定了class类型
            .head(headList)//指定每列的标题
            .excludeColumnFiledNames(excluteNameList)//指定不想显示的列名称
            .build();
            WriteSheet writeSheet = EasyExcel.writerSheet(excelFile.getName()).build();

            List<Student> studentList = new ArrayList();
            //这里循环加4条数据
            for (int i = 0;i<4;i++)
                Student stu = new Student().setId(i).setName("张三" + i).setAge(i).setSex("女");
                studentList.add(stu);
            
            //这里是模仿了后端调用http请求,返回json串,所以进行了一个转换,可以忽略下面两步,直接传studentList
            //实际是前端传递一个url查询的路径,可以拼接查询条件
            //我们通过http调用去请求,如果有分页,可以传回分页参数,后端去循环给excel拼接数据
            String s = JSON.toJSONString(studentList);
            List list = JSON.parseArray(s,entityClass);

            excelWriter.write(list,writeSheet);
            excelWriter.finish();//finish代表我的excel写入完成了
            //下面是用response将excel刷到页面上
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + URLEncoder.encode(excelFile.getName(), "UTF-8"));
            response.flushBuffer();
            BufferedInputStream bis = null;
            try 
                bis = new BufferedInputStream(new FileInputStream(excelFile));
                OutputStream os = response.getOutputStream();
                byte[] buffer = new byte[1024];
                int j = bis.read(buffer);
                while (j != -1) 
                    os.write(buffer, 0, j);
                    j = bis.read(buffer);
                
             catch (Exception e) 
                e.printStackTrace();
             finally 

                if (bis != null) 
                    try 
                        bis.close();
                        excelFile.delete();
                     catch (IOException e) 
                        e.printStackTrace();
                    
                
            
            return "导出成功";
         catch (Exception busExcep) 
            return busExcep.toString();
        
    

到这里就结束啦,有疑问欢迎大家一起讨论学习,有错误我也会改正的!

以上是关于EasyExcel导出基本使用,及作用于通用报表导出的主要内容,如果未能解决你的问题,请参考以下文章

EasyExcel的基本使用及在项目中的应用

EasyExcel封装一个分页写数据的通用方法(保姆级),继上一篇easyExcel导出上线后的优化

EasyExcel太方便易用了,强烈推荐

EasyExcel太方便易用了,强烈推荐

Alibaba工具型技术系列「EasyExcel技术专题」摒除OOM!让你的Excel操作变

SpringBoot+EasyExcel导入导出加水印