如何优雅地导出报表
发布日期:2021-05-08 05:28:22 浏览次数:16 分类:精选文章

本文共 1800 字,大约阅读时间需要 6 分钟。

前言

在实际工作中,我们经常需要导出报表。然而,当多个用户同时进行报表导出时,可能会给服务器带来较大的压力,尤其是当报表导出涉及大量数据库查询时,这不仅会占用大量IO资源,还可能导致服务器资源被耗尽。此前,我们公司也曾遇到过类似的情况:系统在某一时刻因多个用户同时导报表而崩溃,甚至触发了报警短信。经过排查,我们发现这与某一时刻出现的高并发导报表请求密切相关。

如何避免?

在实际应用中,我们需要与业务和技术团队达成共识,找到双方都能接受的解决方案。我们可以采用MQ削峰或限流的方式来优化处理。当用户点击导报按钮时,我们可以引导其跳转至一个下载列表页面,待所有任务完成后再返回结果。同时,服务器会发布一条MQ消息,将待处理的报表任务存入数据库。

这样做的好处是:首先,我们可以将报表生成任务存储到数据库中;其次,MQ客户端负责消费任务进行处理;最后,我们还可以为使用方提供一个查询导出进度的接口。这样既能减少服务器的IO压力,又能让用户了解任务状态。

附:一款比较友好的下载工具——EasyExcel

使用EasyExcel这个工具可以让我们更高效地处理报表导出任务。下面是使用它的步骤说明:

依赖管理 在项目中添加依赖:

com.alibaba
easyexcel
2.0.0-beta3

注解处理 在代码中添加以下注解:

@Data
public class RevenuePerformanceDto {
// 消耗课时
@ExcelProperty(value = "消耗课时", index = 1)
private BigDecimal consumeHours = BigDecimal.ZERO;
// 消耗课时费
@ExcelProperty(value = "消耗课时费", index = 2)
private BigDecimal consumeHoursFees = BigDecimal.ZERO;
// 预排课时数
@ExcelProperty(value = "预排课时数", index = 3)
private BigDecimal scheduledHours = BigDecimal.ZERO;
// 预计营收
@ExcelProperty(value = "预计营收", index = 4)
private BigDecimal estimatedRevenue = BigDecimal.ZERO;
// 差额收入
@ExcelProperty(value = "差额收入", index = 5)
private BigDecimal differentialIncome = BigDecimal.ZERO;
// 营收收入
@ExcelProperty(value = "营收收入", index = 6)
private BigDecimal revenue = BigDecimal.ZERO;
}

代码实现 在需要导出报表的方法中使用EasyExcel:

List
list = this.byCity(model).getData();
String fileName = "报表" + DateUtils.getNow();
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
EasyExcel.write(response.getOutputStream(), RevenuePerformanceForCityDto.class)
.sheet("报表")
.doWrite(list);

通过以上方法,我们可以高效地处理大量报表导出任务,同时减少服务器资源的占用。这种方法既能满足业务需求,又能优化服务器性能,值得在实际项目中尝试使用。

上一篇:提升MySQL查询性能常用套路
下一篇:HTTPS

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年04月16日 16时53分41秒