积木报表导出数据量太大报错

积木报表导出数据量太大报错问题处理

  1. 问题背景
  2. 解决方案
  3. 运行结果
  4. 关键代码

问题背景

积木报表在导出大量数据时可能会遇到报错‌,‌这通常是由于数据量大导致的性能问题或数据处理方式不当引起的。‌以下是一些可能导致报错的原因及相应的解决方法:‌

‌性能问题‌:‌当数据量非常大时,‌积木报表在导出过程中可能会遇到性能瓶颈,‌导致导出过程缓慢甚至失败。‌这可能是因为报表工具本身或其所依赖的库(‌如Apache POI)‌在处理大量数据时的性能不足。‌解决这一问题的方法包括优化SQL查询、‌调整分页大小、‌使用更适合处理大量数据的库(‌如阿里巴巴的EasyExcel)‌进行导出,‌或者采用异步处理的方式来避免接口超时1。‌
‌数据处理方式‌:‌如果待导出的数据包含特殊字符,‌如英文双引号或等号,‌这可能导致JSON反序列化报错。‌这种情况下,‌需要检查业务数据,‌确保数据格式正确,‌避免包含可能导致报错的特殊字符23。‌
‌内存溢出‌:‌如果报表工具或其依赖的库不支持流式(‌分批)‌导出,‌大量数据的处理可能会导致内存溢出。‌解决这一问题的方法包括使用流式导出的方式,‌或者检查报表工具是否支持异步分页呈现和流式(‌分批)‌导出Excel的功能4。‌
综上所述,‌解决积木报表在导出大量数据时报错的问题,‌需要从优化数据处理方式、‌调整导出设置、‌以及确保数据格式正确等方面入手。‌通过这些方法,‌可以有效提高报表导出的稳定性和性能。‌

解决方案

1、在项目中写个拦截器,拦截积木报表导出接口
2、获取到积木报表查询的数据,自己实现导出功能,这里我使用的是阿里的easyExcel导出

运行结果

在这里插入图片描述
在这里插入图片描述

关键代码

1、添加拦截器

拦截积木报表导出接口/jmreport/exportAllExcelStream
@Component
@Slf4j
public class ExportExcelInterceptor implements HandlerInterceptor {

    @Autowired
    private ExportUtil exportUtil;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        if (requestURI.endsWith("/jmreport/exportAllExcelStream")) {
            // 在这里执行拦截逻辑,例如验证用户权限、记录日志等
            log.info("Intercepted request: {}" , requestURI);
            exportUtil.exportExcel(request, response, handler);
            return false;
            // 返回true表示继续处理请求,返回false表示中断请求处理
        }
        return true;
        // 对于其他请求,不进行拦截
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 请求处理完成后的逻辑,如果需要的话
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求完成后的逻辑,如果需要的话
    }

}

2、注入拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {
	
	@Resource
	private ExportExcelInterceptor exportExcelInterceptor;

	@Override
	public void addCorsMappings(CorsRegistry registry ){
		//
	}
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry ){
		// 
	}
	
	@Override
	public void addInterceptors(InterceptorRegistry registry ){
		// 注入自己写的拦截器
		registry.addInterceptor(exportExcelInterceptor);
	}
 }

3、实现导出

@Component
@Slf4j
public class ExportUtil {

    @Autowired
    private e jmReportDesignService;
    @Autowired
    private JmReportBaseConfig jmBaseConfig;
    @Autowired
    private JimuReportDbDao jimuReportDbDao;

    @Autowired
    private JimuReportDao reportDao;

    @Autowired
    private IJimuReportService jimuReportService;


    public  void exportExcel(HttpServletRequest request, HttpServletResponse response, final Object handler) throws Exception{
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.addHeader("Content-Disposition", "attachment;filename=jmexport.xlsx");
        log.info("===========exportAllExcelStream 执行导出EXCEL action ==========");
        HashMap map = new HashMap(request.getParameterMap());
        // 获取请求参数
        StringBuilder body = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                body.append(line);
            }
        }
        JSONObject jsonObject = JSONObject.parseObject(body.toString());
        boolean isToken = map.containsKey("token");
        if (isToken) {
            map.remove("token");
        }
        String excelConfigId = jsonObject.getString("excelConfigId");
        JSONObject queryParam = jsonObject.getJSONObject("queryParam");
        Map<String, Object> resMap = this.d(excelConfigId);
        List downCodeList = (List)resMap.get("downCodeList");
        Integer var16 = this.jmBaseConfig.getPageSizeNumber();
        this.getData(response, excelConfigId, queryParam, downCodeList, var16);
    }


    public Map<String, Object> getData(HttpServletResponse response, String var1, JSONObject var2, List<String> var3,  int var5)
            throws IOException {
        HashMap var6 = new HashMap(5);
        log.debug("数据源集合数据::" + var3);
        JSONObject jsonObject = new JSONObject();
        boolean isonly = false;
        if (null != var2) {
            jsonObject = JSON.parseObject(var2.toJSONString());
            jsonObject.put("pageSize", var5);
            isonly = "1".equals(jsonObject.getString("onlyPageData"));
        }
        List<JmReportDb> jmReportDbs = jimuReportDbDao.selectList(var1);
        JimuReport jimuReport = this.reportDao.get(var1);
        String jsonStr = jimuReport.getJsonStr();
        this.jsonStr(jsonObject, jsonStr);
        Map reportData = jimuReportService.getDataById(jimuReport, jsonObject, isonly, var3);
        this.getMapData(jsonStr, reportData);
        jimuReport.setDataList(reportData);
        ReportDbInfo reportDbInfo = (ReportDbInfo)reportData.get(jmReportDbs.get(0).getDbCode());
        List<Map<String, Object>> list = reportDbInfo.getList();
        JSONObject var11 = JSON.parseObject(jsonStr);
        JSONObject var12 = var11.getJSONObject("rows");
        if (var12.containsKey("-1")) {
            var12.remove("-1");
        }

        if (var12.containsKey("len")) {
            var12.remove("len");
        }
        List<List<Object>> dataList = new ArrayList<>();
        List<String> dataKeys = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(list)){
            Map<String, Object> dataMap = list.get(0);
            dataMap.keySet().forEach(key->{
                dataKeys.add(key);
            });
        }
        for (Map<String, Object> map : list) {
            List<Object> values = new ArrayList<>();
            map.keySet().forEach(key->{
                values.add(map.get(key));
            });
            dataList.add(values);
        }
        JSONObject jsonObject2 = JSONObject.parseObject(jsonStr);
        JSONObject rows = jsonObject2.getJSONObject("rows");
        JSONObject jsonObject3 = rows.getJSONObject("3");
        JSONObject cells = jsonObject3.getJSONObject("cells");
        JSONObject jsonObject4 = rows.getJSONObject("2");
        JSONObject headNames = jsonObject4.getJSONObject("cells");
        Set<String> strings = cells.keySet();
        List<String> keyList = new ArrayList<>(strings);
        List<String> keys = new ArrayList<>();
        for (int j = 0; j < dataKeys.size(); j++) {
            for (int i = 1; i <= keyList.size() ; i++) {
                JSONObject jsonObject1 = cells.getJSONObject(String.valueOf(i));
                if(jsonObject1.getString("text").contains(dataKeys.get(j))){
                    keys.add(String.valueOf(i));
                }
            }
        }

        List<List<String>> heads = new ArrayList<>();
        for (int i = 0; i < keys.size(); i++) {
            List<String> textList = new ArrayList<>();
            String text = headNames.getJSONObject(keys.get(i)).getString("text");
            textList.add(text);
            heads.add(textList);
        }
        EasyExcel.write(response.getOutputStream()).head(new ArrayList<>())
                .sheet("sheet")
                .doWrite(dataList);
        return var6;
    }

    private void jsonStr(JSONObject var1, String var2) {
        if (var1.containsKey("jmViewFirstLoad") && String.valueOf(1).equals(var1.getString("jmViewFirstLoad"))) {
            JSONObject var3 = JSONObject.parseObject(var2);
            if (var3.containsKey("rpbar")) {
                JSONObject var4 = var3.getJSONObject("rpbar");
                if (var4.containsKey("pageSize")) {
                    Integer var5 = var4.getInteger("pageSize");
                    if (var5 != null && !"".equals(var5)) {
                        var1.put("pageSize", var5);
                    }
                }
            }
        }

    }

    private void getMapData(String var1, Map<String, Object> var2) {
        JSONObject var3 = JSON.parseObject(var1);
        if (var3.containsKey("completeBlankRowList")) {
            JSONArray var4 = var3.getJSONArray("completeBlankRowList");
            if (var4.size() > 0) {
                Iterator var5 = var2.keySet().iterator();

                while(true) {
                    Object var11;
                    int var12;
                    JSONObject var13;
                    Integer var17;
                    int var19;
                    do {
                        Object var18;
                        do {
                            String var6;
                            do {
                                do {
                                    JSONObject var7;
                                    do {
                                        if (!var5.hasNext()) {
                                            return;
                                        }

                                        var6 = (String)var5.next();
                                        var7 = null;

                                        for(int var8 = 0; var8 < var4.size(); ++var8) {
                                            JSONObject var9 = var4.getJSONObject(var8);
                                            if (var9.getString("db").equals(var6)) {
                                                var7 = var9;
                                                break;
                                            }
                                        }
                                    } while(var7 == null);

                                    var17 = var7.getInteger("rows");
                                } while(var17 == null);
                            } while(var17 <= 0);

                            var18 = var2.get(var6);
                        } while(!(var18 instanceof ReportDbInfo));

                        ReportDbInfo var10 = (ReportDbInfo)var18;
                        var11 = var10.getList();
                        var12 = ((List)var11).size();
                        var13 = new JSONObject();
                        if (var11 == null) {
                            var11 = new ArrayList();
                        } else if (var12 != 0) {
                            Map var14 = (Map)((List)var11).get(0);
                            Iterator var15 = var14.keySet().iterator();

                            while(var15.hasNext()) {
                                String var16 = (String)var15.next();
                                var13.put(var16, "");
                            }
                        }

                        var19 = var12 % var17;
                    } while(var19 <= 0 && var12 != 0);

                    for(int var20 = var17 - var19; var20 > 0; --var20) {
                        ((List)var11).add(var13);
                    }
                }
            }
        }

    }

    public void a(List<String> var1, String var2, Map<String, Object> var3) {
        ArrayList var4 = new ArrayList();
        int var5 = 0;
        boolean var6 = false;
        String var7 = "";
        ArrayList var8 = new ArrayList();
        ArrayList var9 = new ArrayList();
        Iterator var10 = var1.iterator();

        while(true) {
            while(var10.hasNext()) {
                String var11 = (String)var10.next();
                JmReportDb var12 = this.jimuReportDbDao.getReportDb(var2, var11);
                if (null == var12) {
                    var1.remove(var11);
                } else {
                    DbModel var13 = new DbModel();
                    var13.setCode(var11);
                    var13.setOrder(var5);
                    if ("1".equals(var12.getIsPage())) {
                        var6 = true;
                        var7 = var11;
                        var13.setPage(true);
                    } else {
                        var13.setPage(false);
                    }

                    if (var6 && !"1".equals(var12.getIsPage())) {
                        var9.add(var11);
                    } else if (!var6 && !"1".equals(var12.getIsPage())) {
                        var8.add(var11);
                    }

                    var4.add(var13);
                    var13 = null;
                    ++var5;
                }
            }

            var3.put("moredbSource", var6);
            var3.put("downCodeList", var9);
            var3.put("upCodeList", var8);
            var3.put("pageCode", var7);
            var3.put("dbList", var4);
            return;
        }
    }



    private Map<String, Object> d(String var1) {
        JimuReport var2 = this.jmReportDesignService.getById(var1);
        List var3 = this.jimuReportDbDao.selectList(var1);
        ArrayList var4 = new ArrayList();
        Iterator var5 = var3.iterator();

        while(var5.hasNext()) {
            JmReportDb var6 = (JmReportDb)var5.next();
            var4.add(var6.getDbCode());
        }

        String var19 = var2.getJsonStr();
        ArrayList var20 = new ArrayList();
        JSONObject var7 = JSONObject.parseObject(var19);
        JSONObject var8 = var7.getJSONObject("rows");
        var8 = this.c(var8);
        Iterator var9 = var8.keySet().iterator();

        label80:
        while(true) {
            String var10;
            int var11;
            do {
                do {
                    do {
                        do {
                            do {
                                if (!var9.hasNext()) {
                                    HashMap var21 = new HashMap(5);
                                    this.a((List)var20, (String)var1, (Map)var21);
                                    return var21;
                                }

                                var10 = (String)var9.next();
                            } while("cells".equals(var10));
                        } while("isDrag".equals(var10));
                    } while("len".equals(var10));
                } while("-1".equals(var10));

                var11 = Integer.parseInt(var10);
            } while(var11 < 0);

            JSONObject var12 = var8.getJSONObject(var10).getJSONObject("cells");
            var12 = this.c(var12);
            Iterator var13 = var12.keySet().iterator();

            while(true) {
                String var14;
                do {
                    if (!var13.hasNext()) {
                        continue label80;
                    }

                    var14 = (String)var13.next();
                } while("-1".equals(var14));

                JSONObject var15 = var12.getJSONObject(var14);
                Object var16 = var15.get("text");
                boolean var17 = g.d(var16) && (var16.toString().contains("#{") || var16.toString().contains("${"));
                if (var17) {
                    String var18 = var16.toString();
                    var18 = var18.replace("${", "").replace("#{", "");
                    if (var18.contains(".")) {
                        var18 = var18.substring(0, var18.indexOf("."));
                    }

                    if (!var20.contains(var18) && var4.contains(var18)) {
                        var20.add(var18);
                    }
                }
            }
        }
    }

    private JSONObject c(JSONObject var1) {
        ArrayList var2 = new ArrayList();
        Collections.sort(var2);
        JSONObject var9 = new JSONObject(true);

        JSONObject var7;
        for(Iterator var5 = var2.iterator(); var5.hasNext(); var7 = null) {
            Integer var6 = (Integer)var5.next();
            var7 = var1.getJSONObject(String.valueOf(var6));
            var9.put(String.valueOf(var6), var7);
        }

        return var9;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值