阿里easyExcel使用—补充(easyExcel2.1.6 版本)

7 篇文章 0 订阅
5 篇文章 0 订阅

阿里easyExcel系列

1、阿里easyExcel使用—上(1.1.2-beta5版本)
2、阿里easyExcel使用—下(easyExcel2.0.0 版本)
3、阿里easyExcel使用—补(easyExcel2.1.6 版本)

在这里插入图片描述
源码地址:https://github.com/alibaba/easyexcel
升级版本 升级版本 升级版本


1、本版本主要是解决了一些2.0.x遗留的一些问题

例如
无法使cell数据自定义宽度,使用了也没有效果

2、工具获取

这里博主根据阿里easyExcel源码整理并封装了大部分读写方法包括

  • 单sheet读、写
  • 多sheet读、写
  • 指定sheet读、写
  • 模板导出
  • 指定多个sheet读取

如果有需要可以通过下面地址获取源码:

GitHub地址https://github.com/MandalasWang/Easyexcle_Function


3、依赖

  <!--阿里easyExcel工具包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>

4、代码util

/**
 * @author wyy
 * @version 2.0
 * @date 2020/6/18 11:20
 * 版本升级为对应的2.0.0以上
 * 性能更加高效  导出数据更加稳定
 * 支持 64M内存1分钟内读取75M(46W行25列)
 **/
public class ReportExcelUtil {



    /**
     * 导出 Excel :一个 sheet,带表头.只有一个sheet 并以response流输出
     *
     * @param response  HttpServletResponse
     * @param data      数据 list,每个元素为一个 BaseRowModel
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的 sheet 名
     * @param model     映射实体类,Excel 模型
     * @throws Exception 异常
     */
    public <T> void writeExcel(HttpServletResponse response, List<T> data,
                               String fileName, String sheetName, Class  model) throws Exception {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(getOutputStream(fileName, response), model)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet(sheetName)
                .registerWriteHandler(horizontalCellStyleStrategy)
                //最大长度自适应 目前没有对应算法优化 建议注释不用 会出bug
                 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(data);

    }


    /**
     * 导出 Excel :一个 sheet,带表头.指定两个sheet名称 直接作为response流输出
     *
     * @param response  HttpServletResponse
     * @param data2      数据 list,每个元素为一个 BaseRowModel
     * @param fileName  导出的文件名
     * @param fileName 导入文件的 sheet 名
     * @param model     映射实体类,Excel 模型
     * @throws Exception 异常
     */
    public <T> void writeExcelComplexSheet(HttpServletResponse response, List<T> data1, List<T> data2,
                               String fileName, String sheetName1,String sheetName2, Class model) throws Exception {
        if(sheetName1.trim().equals(sheetName2)){
            throw new MyException(RetResponse.makeErrRsp("请不要输入相同的sheet名称"));
        }
        ExcelWriter excelWriter = EasyExcel.write(getOutputStream(fileName, response)).build();
        //这里 需要指定写用哪个class去写
        WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetName1).head(model).build();
        excelWriter.write(data1, writeSheet);
        writeSheet = EasyExcel.writerSheet(1, sheetName2).head(model).build();
        excelWriter.write(data2, writeSheet);
        //千万别忘记finish 会帮忙关闭流
        excelWriter.finish();
    }

    /**
     * 导出 Excel :一个 sheet,带表头.指定两个sheet名称 直接作为response流输出
     *
     * @param response  HttpServletResponse
     * @param data2      数据 list,每个元素为一个 BaseRowModel
     * @param fileName  导出的文件名
     * @param fileName 导入文件的 sheet 名
     * @param model     映射实体类,Excel 模型
     * @throws Exception 异常
     */
    public <T> void writeExcelComplexSheet(OutputStream outputStream, List<T> data1, List<T> data2,
                                            String sheetName1,String sheetName2, Class model) throws Exception {
        if(sheetName1.trim().equals(sheetName2)){
            throw new MyException(RetResponse.makeErrRsp("请不要输入相同的sheet名称"));
        }
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
        //这里 需要指定写用哪个class去写
        WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetName1).head(model).build();
        excelWriter.write(data1, writeSheet);
        writeSheet = EasyExcel.writerSheet(1, sheetName2).head(model).build();
        excelWriter.write(data2, writeSheet);
        //千万别忘记finish 会帮忙关闭流
        excelWriter.finish();
    }

    /**
     * 导出 Excel :一个 sheet,带表头. 输出流 简单的写入流
     *
     * @param outputStream  OutputStream
     * @param data      数据 list,每个元素为一个 BaseRowModel
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的 sheet 名
     * @param model     映射实体类,Excel 模型
     * @throws Exception 异常
     */
    public <T> void writeExcelIn(OutputStream outputStream, List<T> data,
                               String sheetName, Class model) throws Exception {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(outputStream, model)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet(sheetName)
                .registerWriteHandler(horizontalCellStyleStrategy)
                //最大长度自适应 目前没有对应算法优化 建议注释不用 会出bug
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(data);

    }



    /**
     * 重复写入多个sheetNo 并导出
     * @param outputStream  输出流
     * @param data  数据源list
     * @param sheetName  sheet名
     * @param model  导出模板类
     * @param sheetNo 想要导出多少个sheet
     * @param <T>
     * @throws Exception
     */
    public <T> void repeatedWrite (OutputStream outputStream, List<T> data,
                                    String sheetName, Class model,Integer sheetNo) {
        ExcelWriter excelWriter = null;
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        try {
            // 这里 指定文件 写入输出流
            excelWriter = EasyExcel.write(outputStream, model).
                    registerWriteHandler(horizontalCellStyleStrategy).build();
            // 去调用写入,这里传入sheetNo 表示循环多少次写多少个sheet
            for (int i = 0; i < sheetNo; i++) {
                // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变
                WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetName + i).head(model).build();
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                excelWriter.write(data, writeSheet);
            }
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }


    /**
     * 导出 Excel :一个 sheet,带表头.模板写入指定sheet并导出 不用浏览器的outputStream
     * 指定写入到哪个sheet中
     *
     * @param outputStream OutputStream 输出流
     * @param data         数据 list,每个元素为一个 BaseRowModel
     * @param in           输入流  模板
     * @param sheetNo      导入文件的 sheet  指定输出在哪一个sheet中,角标从0开始
     * @param model        映射实体类,Excel 模型
     */
    public <T> void writeExcelInSheetNo(OutputStream outputStream, List<T> data,
                                  InputStream in,String sheetName, Class model,Integer sheetNo) {
        ExcelWriter excelWriter;
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo).sheetName(sheetName).build();
        //填写要写入的流文件  Excel文件
        excelWriter = EasyExcel.write(outputStream,model).withTemplate(in)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .build();
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        excelWriter.write(data, writeSheet);
        excelWriter.finish();
    }



    /**
     * 图片导出
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link ImageData}
     * <p>
     * 2. 直接写即可
     * @param inputStream 输入流
     * @param  fileName   文件名
     * @param clazz 模板
     * @param data  数据集合
     * @deprecated  当前方法可以使用但是请按照阿里官方文档传入参数
     */
    public void imageWrite(InputStream inputStream , String fileName,
                               Class<? extends ImageDemo> clazz, List<? extends ImageDemo> data) throws Exception {
        try {
            Field[] fields = clazz.getFields();
            ImageDemo imageDemo = clazz.newInstance();
            for(Field field : fields){
                field.setAccessible(true);
                Object obj = field.get(imageDemo);
               if(field.getAnnotation(ExcelProperty.class) != null){
                   if(null == obj){
                       throw new NullPointerException("请传入对应的属性值!");
                   }
               }
            }
            EasyExcel.write(fileName, clazz).sheet().doWrite(data);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }



    /**
     * 导出文件时为Writer生成OutputStream.
     *
     * @param fileName 文件名
     * @param response response
     * @return 响应流输出
     * @throws Exception exception
     */
    private OutputStream getOutputStream(String fileName,
                                         HttpServletResponse response) throws Exception {
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "no-store");
            response.addHeader("Cache-Control", "max-age=0");
            return response.getOutputStream();
        } catch (IOException e) {
            throw new Exception("导出excel表格失败!", e);
        }
    }



}

5、演示test

  /**
     * 简单的导出单sheet
     * @throws FileNotFoundException
     */
    @Test
    public void simpleWrite() throws FileNotFoundException {

        File file = new File("D:\\work\\excel\\report.xlsx");
        OutputStream outputStream = new FileOutputStream(file);
        try {
            reportExcelUtil.writeExcelIn(outputStream,dataDemos,"1",DataDemo.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值