异步 excel 导出组件设计和实现

本文介绍了一个异步Excel导出组件的设计和实现,遵循支持大数据量、降低内存消耗、统一导出规范的原则。组件通过公共服务提供统一接口,使用自定义线程池异步处理,结合文件系统避免请求超时。公共组件包提供统一导出方法,方便业务方接入,支持多种导出方式,如直接使用list数据导出、查询list数据导出和分页查询数据导出。
摘要由CSDN通过智能技术生成

设计原则

  • 支持大数据量场景下的excel导出。采用异步导出方式
  • 降低excel导出时的内存消耗。基于EasyExcel再次封装,支持excel定制化
  • 统一excel导出规范。后端导出接口统一化、前端导出交互组件化,简化开发流程
  • 封装公共导出方法,管理导出的整个生命周期。接入方只用关心业务逻辑,且代码复用性高
  • 使用自定义线程池异步处理,避免导出占用大量的服务器资源,影响业务接口正常响应
  • 引入文件系统。避免因导出文件过大、导出逻辑耗时过长带来的请求超时等的问题

设计思路

  1. 公共服务提供统一的excel导出接口,前端通过统一的接口来导出。统一导出接口会根据导出的url参数转发请求到各业务方的接口实现上,并带上导出参数
  2. 公共组件包中提供通用异步导出方法。该方法封装查库、数据写入excel、excel文件上传、同步导出状态等逻辑
  3. 公共服务提供统一的获取导出excel文件下载地址的方法,支持异步轮询下载导出文件
    在这里插入图片描述
    扩展点: 可在通用导出服务中添加导出审计日志,记录重要敏感数据的导出情况。并且可以添加导出权限控制异常告警等扩展功能。

组件实施方案

1. 公共服务提供统一接口

包括统一的获取sid接口 以及 查询导出状态接口

@RestController
@Api(tags = "Excel导出服务")
@RequestMapping("/excels")
public class ExcelController {
   
    @Autowired
    private ExcelService excelService;
    @ApiOperation(value = "获取sid", notes = "sid为当前excel导出请求唯一标识,用于异步获取导出状态")
    @PostMapping("/export/sid")
    public BizResponse<String> sid(@RequestParam String url, @ApiParam("导出查询参数") @RequestBody JSONObject params) {
   
        String sid = excelService.getSid(url, params);
        return BizResponse.success(sid);
    }
    @ApiOperation(value = "查询导出状态", notes = "轮询该接口来获取最新的导出状态,轮询时间推荐从1s开始指数型递增")
    @PostMapping("/export/status")
    public BizResponse<ExportResultResponse> status(@RequestParam String sid) {
   
        ExportResultResponse response = excelService.status(sid);
        return BizResponse.success(response);
    }
}
2. 公共组件包提供统一导出方法

传统的同步导出方法直接在响应流中返回excel数据。当导出数据很大,或者导出数据依赖外部服务时,导出会出现请求超时、网关熔断等情况。

public class ExcelUtil {
   
    ...
    /**
     * 导出excel
     *
     * @param list     数据列表
     * @param clazz    导出模型类
     * @param filename 导出文件名
     * @param response httpServletResponse
     * @deprecated 已废弃。推荐使用 {@code exportForSid} 异步导出方法
     */
    @Deprecated
    public static <T> void export(String filename, Class<T> clazz, List<T> list, HttpServletResponse response) {
   
        try {
   
            filename = URLEncoder.encode(filename, "UTF-8");
        } catch (UnsupportedEncodingException e) {
   
            // do nothing here.
        }
        try (ServletOutputStream outputStream = response.getOutputStream()) {
   
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.addHeader("Content-Disposition", "attachment; filename=" + filename + EXPORT_UPLOAD_EXTENSIONS);
            EasyExcel.write(outputStream, clazz).sheet(filename).doWrite(list);
        } catch (IOException e) {
   
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, filename + "导出失败"
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值