前言
有时候我们需要导出一些报表,但是当有多人同时导出报表时,可能对服务器的压力,尤其是数据库的压力比较大,因为导出报表可能涉及到的查询语句比较多 而且比较耗时,io压力比较大。我们公司在前端时间就出现过cup压力升高,报警的短信,查看具体进程是因为某时刻导出报表的人比较多。
怎么避免
有时候客户导出报表后不一定期望立即能够返回结果,当任务过多时可以让他等待。于是我们可以让利用mq来削峰 或限流。这就需要业务和技术之间达成一个共识,业务或技术之间有一方能够进行妥协是可以接受的。
于是,当点击下载时可以跳到一个下载列表页面让用户等待,同时发一个mq消息,让服务器排队处理。
这样的话 就可以先把要导出的报表接口存库,mq客户端负责消费,另外提供个接口给使用方查看导出进度。
附一个比较好用的下载工具:EasyExcel
- 引入依赖
<!--easy-excel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.0.0-beta3</version>
</dependency>
- 打上注解
@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;
- 代码中
List<RevenuePerformanceForCityDto> list = (List<RevenuePerformanceForCityDto>) this.byCity(model).getData();
String fileName = "报表" + DateUtils.getNow();
response.setHeader("Content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
EasyExcel.write(response.getOutputStream(), RevenuePerformanceForCityDto.class).
sheet("报表").
doWrite(list);