spring mvc export excel有时失败,数据在页面上显示garblend

时间:2017-12-12 03:17:32

标签: excel spring-mvc spring-boot thymeleaf

我的项目中有以下数据报告,我想将其导出为ex​​cel: enter image description here 但奇怪的是,有时它会成功导出,有时会失败。我已经尝试了很多次,结果当excel表超过17行时,它会导致这样:

  1. 页面重定向到包含garblend数据的新页面。
  2. 帖子请求已更改为获取请求。
  3. enter image description here

    即使导出失败,也确保成功创建了excel,因为我已将其写入磁盘并检查了该文件。以下是控制器,我出了什么问题?

       @RequestMapping("/download")
        public void download(HttpServletRequest request, HttpServletResponse response, ReportCondition condition){
            try {
                List<HashMap<String, String>> mapList = reportFormService.find(condition);
                if(mapList == null || mapList.size() == 0){
                    logger.info("No reports...");
                }
    
                Map<String, Date> dateMap = DateConditionUtil.getStartEndDate1(condition.getStartDate(), condition.getEndDate());
                String startDate = DateFormatUtils.format(dateMap.get("startDate"), "yyyyMMdd");
                String endDate = DateFormatUtils.format(dateMap.get("endDate"), "yyyyMMdd");
                String[] titleArr = new String[]{"序号","日期","应用系统","短信服务商","请求发送总数","请求成功数量","实际短信条数","实际成功条数","费用","失败数量","成功率"};
                String[] fieldArr = new String[]{"ID","RECORDDATE","APPNAME","PROVIDERNAME","SENDCOUNT","SUCCESSCOUNT","SENDSUM","SUCCESSSUM","TOTALFEE","FAILURECOUNT","SUCCESSRATE"};
    
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                WorkBookUtil.createExcel(titleArr, fieldArr, mapList, os);
    
                try(BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(os.toByteArray()));
                    BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())){
                    byte[] buff = new byte[1024];
                    int bytes;
                    while (-1 != (bytes = bis.read(buff, 0, buff.length))) {
                        bos.write(buff, 0, bytes);
                    }
                    bos.flush();
                }catch (Exception e){
                    logger.error(e);
                }
    
                response.setCharacterEncoding("utf-8");
                response.setHeader("content-disposition", "attachment;filename=" + String.format("%s-%s.xls", startDate, endDate));
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
    
            } catch (IOException e){
                logger.error("Export failed", e);
            }
        }
    

2 个答案:

答案 0 :(得分:1)

在创建.xls文件之前,应首先设置响应头。所以试试这个:

response.setCharacterEncoding("utf-8");
response.setHeader("content-disposition", "attachment;filename=" + String.format("%s-%s.xls", startDate, endDate));
response.setContentType("application/vnd.ms-excel;charset=utf-8");

ByteArrayOutputStream os = new ByteArrayOutputStream();
WorkBookUtil.createExcel(titleArr, fieldArr, mapList, os);
// ...

答案 1 :(得分:0)

尝试在将字节写入用户之前添加响应标头。添加内容长度标题也会有所帮助。通过createExcel致电os.toByteArray().length后,您就可以了解相关信息。另外close() bos flush()之后{{1}}。