通用异步导出Excel封装

之前也做过关于Excel的导出案例,此次也是在其基础上进行改造升级:

但是之前的导出存在这么几个问题:

  • 如果是数据量很大容易导致页面卡死(我曾导出30w条数据,直接导致OOM)
  • 用户体验很糟糕,数据量一多就会等很久,而且用户没办法做别的事情。
  • 每次点击导出都需要走一遍完整的导出过程(这个其实还好)
  • 没办法对每次导出的数据进一个规整

今天使用异步导出来解决上述问题。


一、UML图

1-1、导出图

通用异步导出Excel封装


1-2、下载图

通用异步导出Excel封装



从上面的图中可以看出,整个下载是异步的,用户不需要在页面等待,每次导出我们都生成一个记录和一个文件,用户可以多次下载。


二、功能实现

2-1、记录实体

/**
 * Excel列表数据
 *
 * @author 小道仙97
 * @date 2021/8/8
 */

public class ExcelList {

    /**
     * id
     */

    private String id;

    /**
     * 文件名
     */

    private String name;

    /**
     * 下载行数
     */

    private Integer rows;

    /**
     * 下载耗时
     */

    private Long takeUpTime;

    /**
     * 下载地址
     */

    private String downloadUrl;
}


2-2、Controller

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Excel导出
 *
 * @author 小道仙97
 * @date 2021-08-08
 */

@RestController
public class ExportExcelController {

    @Autowired
    private ExportExcel exportExcel;

    // 模仿下载列表
    public static List<ExcelList> list = new ArrayList<>(10);

    /**
     * Excel 导出
     * @throws Exception
     */

    @GetMapping("/excel/export")
    public void export() {
        Long startTime = System.currentTimeMillis();
        String name = "Excel异步导出测试" + UUID.randomUUID().toString() + ".xlsx";
        String id = UUID.randomUUID().toString();
        ExcelList excelList = new ExcelList();
        excelList.setId(id);
        excelList.setName(name);
        list.add(excelList);
        // 异步导出
        exportExcel.asyncExportExcel(id,name,startTime);

    }

    /**
     * 获取导出列表 - 模拟
     */

    @GetMapping("/excel/list")
    public List<ExcelList> list() {
       return list;
    }

    /**
     * 文件下载
     */

    @GetMapping("/excel/downLoad")
    public void downLoad(HttpServletResponse response,@RequestParam  String url) {
        FileUtils.download(url, response);
    }
}


2-3、异步下载实现

ExportExcel

注:使用异步注解@Async 需要先在启动类上开启 @EnableAsync

import org.springframework.scheduling.annotation.Async;

public interface ExportExcel {

    /**
     * 异步导出
     * @param id 唯一记录Id
     * @param name 文件名称
     * @param startTime 下载开始时间
     */

    @Async
    void asyncExportExcel(String id,String name,Long startTime);
}


TestExportExcelImpl

@Service
public class TestExportExcelImpl implements ExportExcel {

    @Override
    public void asyncExportExcel(String id,String name,Long startTime) {
        // 模拟查询数据过程
        String[] header = new String[]{"姓名","年纪"};
        String[] keys = new String[]{"name","age"};
        List<Map<String, Object>> content = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name","小道仙");
        map1.put("age","23");
        content.add(map1);
        Map<String, Object> map2 = new HashMap<>();
        map2.put("name","小道仙97");
        map2.put("age","97");
        content.add(map2);

        try {
            // 获取Excel导出文件流
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ExcelUtils.exportExcel(header,keys,content,"first",os);
            byte[] content1 = os.toByteArray();
            InputStream inputStream = new ByteArrayInputStream(content1);
            // 上传文件 返回下载地址
            String url = FileUtils.uploadInputStream(inputStream, name);
            /**
             * 找到当前数据并封装结果集
             *
             * 其实这里很简单并无这么复杂,实际情况我们只需要一个 update 语句就可以搞定
             */

            for (ExcelList item : ExportExcelController.list) {
                if (item.getId().equals(id)) {
                    item.setRows(content.size());
                    item.setDownloadUrl(url);
                    item.setTakeUpTime(System.currentTimeMillis() - startTime);
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


三、演示

下面的演示的前提都是在启动了项目的基础上

3-1、导出

因为没有做任何的返回值,所以是空返回,这里也可以自定义任何提示返回。

http://127.0.0.1:8888/excel/export


3-2、下载列表

http://127.0.0.1:8888/excel/list

返回结果如下:

[
    {
        "id""d3cb3551-cb33-445e-8e60-9534197f6647",
        "name""Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx",
        "rows"2,
        "takeUpTime"5,
        "downloadUrl""2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx"
    }
]


3-3、下载

http://127.0.0.1:8888/excel/downLoad?url=2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx




原文始发于微信公众号(小道仙97):通用异步导出Excel封装

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/41408.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!