2 fnzf14428547 fnzf14428547 于 2016.02.03 15:06 提问

代码需要优化!!!!!!
public void exportArrearDatail(HttpServletRequest request, HttpServletResponse response){
    String templateId = request.getParameter("templateId");
    String fileNames = request.getParameter("fileName");
    String fileName = null;
    try {
        fileName = java.net.URLDecoder.decode(fileNames, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    String areaId = request.getParameter("areaId");
    String dataType = request.getParameter("dataType");
    ExcelUtil excel = new ExcelUtil();
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("templateId", templateId);
    if (areaId != null && !areaId.equals("")) {
        map.put("areaId", areaId);
    }
    if ("effective".equals(dataType)) {
        map.put("effective", "'有效'");
    }
    excel.createBookAndSheet(false, "sheet1");
    excel.writeRow(0, "查询号码", "设备状态", "商品名称", "欠费账龄", "欠费金额",
            "计费类型", "计费标签", "家长姓名", "区域名称", "学校名称", "班级名称", "学生姓名",
            "计费号码", "登录账号");

    int count = arrearAnalysisService.countUserNum(map);
    if (count > 0) {
        List list = new ArrayList();
        ArrearInfo arrearInfo = null;
        int rowNum = 1;
    //就是下面这个循环
    //我试了下就是参数里面的10000是每页显示的数字,如果超出10000它也不会生成第二页
    //用什么值能替换它让它不是固定的 ,而是跟着总数走的
        for (int row = 0; row < count/10000; row += 10000) {
            Page<ArrearInfo> page = arrearAnalysisService.getArrearInfoByPage(map, row*10000, 10000, "arrearAmount", SqlOrderEnum.DESC.getAction());
            list = page.getList();
            for (int i = 0; i < list.size(); i++) {
                arrearInfo = (ArrearInfo) list.get(i);
                if (arrearInfo == null) {
                    break;
                }
                excel.writeRow(rowNum++, arrearInfo.getPhoneNumber(), arrearInfo.getDeviceStatus(), arrearInfo.getGoodsName(), arrearInfo.getArrearAge(),
                        arrearInfo.getArrearAmount(), arrearInfo.getBillingType(), arrearInfo.getBillingLabel(), arrearInfo.getUserName(),arrearInfo.getAreaName(),
                        arrearInfo.getShoolName(), arrearInfo.getClassName(), arrearInfo.getStudentName(), arrearInfo.getPayNumber(), arrearInfo.getLoginNumber());
            }
        }
    }

    Runtime.getRuntime().gc();
    DownloadUtil.downloadXlsx(response, fileName + "用户信息", excel.getInputStream());
}

4个回答

caozhy
caozhy   Ds   Rxr 2016.02.03 18:19

arrearAnalysisService.getArrearInfoByPage
不要一下读取那么多的记录,这样导致内存不够。

你的page可以小一些,然后多循环几次。比如pagesize/100,内侧循环再来个100

fnzf14428547
fnzf14428547 不行啊,我也不知道我写的对不对,反正还是老样子
接近 2 年之前 回复
fnzf14428547
fnzf14428547 现在内存不溢出了,就是点导出要等好久才能出现下载
接近 2 年之前 回复
Yiran8935
Yiran8935   2016.02.03 15:17

这个跟数据量有没有关系,EXCEL的最大储存行数为65536行,你看看有没有超过,还有先用小于万件的数据调试下,看有没有内存溢出的情况发生

fnzf14428547
fnzf14428547 我们最大的数据是5w多,不过我改了下代码,现在可以导出了,不过要等很久才能出现下载
接近 2 年之前 回复
fnzf14428547
fnzf14428547 回复Yiran8935: 就是点导出excel我刚才试了下14000的数据还可以,但是要等好久才能出现下载,估计数据在大一点网页就报错了,log上没报错
接近 2 年之前 回复
Yiran8935
Yiran8935 回复fnzf14428547: 有没有报错信息,是哪一行报错之类的,多上log啊
接近 2 年之前 回复
fnzf14428547
fnzf14428547 没有超过65536行,小的也不行,直接就报500错误,内存溢出
接近 2 年之前 回复
oyljerry
oyljerry   Ds   Rxr 2016.02.03 16:22

内存溢出是不是你操作excel的函数调用就不正确,比如你只写入10条数据试试呢,逐步增加,看是否有一个一个门槛数据

fnzf14428547
fnzf14428547 14000条可以导出的,反应速度很慢,具体多大会内存溢出我还没试出来
接近 2 年之前 回复
91program
91program   Ds   Rxr 2016.02.03 16:12

数据库太大,依赖于优化循环是提高不了性能的。
如果代码段功能正常,可以考虑将之放在线程中,这样可以在处理数据的过程中继续响应用户操作。

91program
91program 回复fnzf14428547: 不会就使用搜索引擎啊,如:Baidu/Bing。只要你会使用它,很多问题都可以解决的。
接近 2 年之前 回复
fnzf14428547
fnzf14428547 可是我不会放入线程中啊
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!