导入导出笔记-二探EasyExcel(多sheet导出)

前言

多sheet导出也是我们日常工作经常会碰到的一个需求场景,它既可以是复杂内容的sheet排列展示,也可以是几个小部分的内容并列展示。
细心的朋友似乎已经通过上一篇博文发现了EasyExcel写数据的套路:打开sheet -> 执行写入。不要惊讶,确实就这两步!

  1. 打开sheet

先来看看我们昨天是怎么打开一个可写入的sheet,也就是返回一个com.alibaba.excel.write.builder.ExcelWriterSheetBuilder对象

很明显可以看到,API里面支持对sheetNo进行设置,所以我们可以利用起来。

2、执行写入

写入的时候我们可以看到有write方法和fill方法

  • write方法适合表格式逐行的写入
  • fill方法适合对于模板样式的数据填充

下面我们也要用同样的套路来实现我们今天的主题---多sheet导出

多sheet导出-表格式逐行写入(难度星级:☆☆☆☆)

需求:我们需要导出一个excel,除了学生基本信息,新增一个sheet为班级信息,具体如下

首先我们需要先定义数据对象,用来传递数据列表信息

@Data
public class Grate implements Serializable {

    @ExcelProperty("班级")
    private String grate;

    @ExcelProperty("班主任老师")
    private String teacher;

    @ExcelProperty("任课老师")
    private String instructor;

    @ExcelProperty("学科")
    private String subject;
}

假定数据已经定义好了,学生信息studentList、班级信息grateList,导出代码:

     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).build();
        WriteSheet studentSheet =
                EasyExcel.writerSheet(0, "学生信息").head(Student.class).build();
        WriteSheet grateSheet =
                EasyExcel.writerSheet(1, "班级信息").head(Grate.class).build();
        excelWriter.write(studentList, studentSheet)
                .write(grateList.get(), grateSheet);
        excelWriter.finish();

ps:页面导出直接下载代码

    private void downloadExcel(HttpServletResponse response, InputStream inputStream, String fileName)
        throws IOException {
        if (StringUtils.isBlank(fileName)) {
            fileName = this.getFileDefaultName();
        }
        if (!StringUtils.endsWith(fileName, XLSX)) {
            fileName += XLSX;
        }

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.ms-excel");

        int buffer = 1024 * 10;
        byte[] data = new byte[buffer];
        int read;
        while ((read = inputStream.read(data)) != -1) {
            response.getOutputStream().write(data, 0, read);
        }

        String fileNameEncode = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncode);
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }
  • HttpServletResponse:前端请求响应流,懂的人都懂
  • ByteArrayInputStream:new ByteArrayInputStream(outputStream.toByteArray()),定义IO输入到页面的数据流
  • fileName:文件名

至此,需求解决!相信可以满足产品一段时间了

隔天,我们那要命的产品又来跟我说,我想在"学生信息"页面看到昨天模板那个页面,不然就别下班了,卑微的我默默又开始干起来了

多sheet导出-模板写入(难度星级:☆☆☆☆)

有了上一篇博客的经验,我们直接上代码

      // 定义写入输出流(方便后续上传,主要用于异步导出)
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        File file = new File("/template/模板.xlsx");
        FileInputStream fileInputStream = new FileInputStream(file);
        // 以模板的方式打开写入门面类
        ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).withTemplate(new ByteArrayInputStream(copyStream(fileInputStream).toByteArray())).build();
        // 自定义数据
        StudentInfo.Student student = new StudentInfo.Student("高一","张三","男","17","88");
        StudentInfo studentInfo = new StudentInfo("第三中学", "李丽", Lists.list(student));
        Grate grate = new Grate("高一","李丽","张合","语文");
        // 自定义sheet
        WriteSheet studentInfoSheet = EasyExcel.writerSheet(0, "学生信息").build();
        WriteSheet grateSheet = EasyExcel.writerSheet(1, "班级信息").head(Grate.class).build();
        // 填充数据(fill填充模板数据|write填充表格数据)
        excelWriter.fill(studentInfo, studentInfoSheet).fill(studentInfo.getStudentList(),studentInfoSheet).write(Lists.newArrayList(grate),grateSheet);
        excelWriter.finish();

模板.xlsx

  • 学生信息

  • 班级信息(空白即可)

导出效果

  • 学生信息

  • 班级信息

小结

  1. 多sheet导出只需要在生成sheet的同时设置号下标即可
    2、存在使用模板的话,一定要设置工作区(com.alibaba.excel.write.metadata.WriteWorkbook)的templateInputStream属性,哪怕只有一个sheet使用模板
    3、模板填充用ExcelWriter#fill(),表格填充使用ExcelWriter#write。注意模板中同时使用列表和非列表的,需要填充两次

大家可以关注公众号“技术小邱”来进行交流,Thanks♪(・ω・)ノ

posted @ 2022-03-21 16:33  邱志强  阅读(4771)  评论(0编辑  收藏  举报