用freemarker导出word,带echart图,并弹出下载弹框

HTML转word主要用freemarker模板来处理,如果只是导出文字内容,那很好处理。但是带图片了就比较麻烦。
步骤大概是:在前台,我们把echart图转为base64形式传到后台(echart图是由canvas写的,所以用canvas的一个方法可以直接将图转为base64,这样的话问题就来了,base64长度很长,我们直接用get方法提交的话参数限制,提交会不成功。可是用post方法必须要有返回值,我们想点击按钮直接弹出下载选择框就成为泡影了,下面是我借鉴别人的一个方法)

前台代码:

$.post("<%=path%>/studentAnalysis/ajaxLessonImg.htm",     //会在下面进行代码演示 {img1:barBase64Info1,img2:barBase64Info2,img3:barBase64Info3,img4:barBase64Info4,img5:barBase64Info5},function(result){
        if(result==""){
            layer.msg("网络链接超时!")   
        }else{
            alert(result);
            return;
            var gradeName=$("#gradeName").val();
            var className=$("#className").val();
            var subjectName=$("#subjectName").val();
            var lessonId=$("#lessonId").val();
            var begintime=$("#begintime").val();
            window.location.href="<%=path%>/studentAnalysis/importLessonWord.htm? //会在下面进行代码演示imgUrl="+result+"&gradeName="+gradeName+"&className="+className+"&subjectName="+subjectName+"&lessonId="+lessonId+"&begintime="+begintime;
        }
  });

//意思是先用post方法提交base64至后台,然后后台把base64转为图片存在指定服务器上,然后将图片名再返回到前台,用post请求的返回处理,再进行get请求,此时get请求带的参数就是图片简短的名称,不会出现参数过长的情况。是不是很明智。
接下来我们来看下

后台的处理代码:

         @RequestMapping("ajaxLessonImg.htm")
         @ResponseBody
         public String ajaxLessonImg(HttpServletRequest request,HttpServletResponse response
                 ) throws Exception{
             Map<String,Object>map=new LinkedHashMap<>();
             //图片临时存放目录
             String file=System.getProperty("catalina.home")+\\webapps\\PicServer\\tempImg\\;   //图片要存放的路径
             String img1=request.getParameter("img1").toString();
             String img2=request.getParameter("img2").toString();
             String img3=request.getParameter("img3").toString();
             String img4=request.getParameter("img4").toString();
             String img5=request.getParameter("img5").toString();
             String[] imgArray={img1,img2,img3,img4,img5};
             List<String>fileList=new ArrayList<>();
             for(String base64:imgArray){
                 String fileName=ImageUtil.savePictoServer(base64,file); //将base64转为图片的方法
                 fileList.add(fileName);
             }
              return new Gson().toJson(fileList);

         }

上面gson用到的包
这里写图片描述

展示imgutil里如果对base64进行处理解码还原:

/**
     * 将一个base64转换成图片保存在  path文件夹下  ,命名随机
     * @param base64String
     * @param path  是一个文件夹路径
     * @param imgName 图片名字(没有后缀)
     * @throws Exception
     */
    public static String savePictoServer(String base64String,String path)throws Exception{

        BASE64Decoder decoder = new BASE64Decoder();  //此类需引入的jar包
        //要把+在上传时变成的空格再改为+
        base64String = base64String.replaceAll(" ", "+");
        //去掉“data:image/png;base64,”后面才是base64编码,去掉之后才能解析
        base64String = base64String.replace("data:image/png;base64,","");
        //在本地指定位置建立文件夹,path由控制台那边进行定义
        File dir=new File(path);
        if(!dir.exists()){
         dir.mkdirs();
        }
        String uuidImg=UUID.randomUUID().toString()+".png";
        String fileName=path+uuidImg;
        try {  
            byte[] buffer = decoder.decodeBuffer(base64String);  
            OutputStream os = new FileOutputStream(fileName);
            for(int i =0;i<buffer.length;++i){
                if(buffer[i]<0){//调整异常数据
                    buffer[i]+=256;
                }
            }
            os.write(buffer);  
            os.close();  
        } catch (IOException e) {  
            throw new RuntimeException();  
        }  

       return uuidImg;
    }

需要用的base64相关的包:
这里写图片描述

接下来看看最终使用freemarker模板,并弹出下载弹出框的代码:

 @RequestMapping("importLessonWord.htm")
 public void importLessonWord(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("gradeName")String gradeName,@ModelAttribute("className")String className,
        @ModelAttribute("subjectName")String subjectName,@ModelAttribute("lessonId")String lessonId,@ModelAttribute("begintime")String begintime
         ) throws Exception{
     SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd");
     String time=sdf.format(new Date());
     Map<String,Object>map=new LinkedHashMap<>();                            
     String file=System.getProperty("catalina.home")+tempDirectory;
     String imgUrl=request.getParameter("imgUrl").toString();
     final List<String>fileList=new Gson().fromJson(imgUrl, List.class);
      //图片64位数编码(img1,img2,img3,img4,img5)
      int i=1;
      for(String fileName:fileList){
          String imgBase64=ImageUtil.getImageStr(file+fileName); //模板需要传入base64所以又要将图片转为base64,代码如下代码块
          map.put("img"+i,imgBase64);
          i++;
      }
      //开启一个线程删除临时存放的统计图图片
      new Thread(){
          public void run() {
              for(String fileName:fileList){
                  String fileUrl=System.getProperty("catalina.home")+tempDirectory;
                  File file = new File(fileUrl+fileName);
                  if(file.exists()){
                      file.delete();
                  }
              }
            }
      }.start();

        Template dateTmp = getTemplateObject("lesson.ftl",request);
       //文件名称
        String creadeFile  = java.net.URLEncoder.encode("课堂分析报表-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()), "UTF-8");
        //获取输出字符对象
        PrintWriter pw=response.getWriter();
        // 生成提示信息
        response.setContentType("application/vnd.ms-doc");
        // 设置响应头
        response.setHeader("content-disposition", "attachment;filename="+creadeFile+".doc");
        dateTmp.process(map, pw);
 }

/**
  * 读取图片在本地存储的位置
   * @param imgFile
   * @throws Exception
   */
  public static String getImageStr(String imgFile) {  
         InputStream in = null;  
         byte[] data = null;  
         try {  
             in = new FileInputStream(imgFile);  
             data = new byte[in.available()];  
             in.read(data);  
             in.close();  
         } catch (IOException e) {  
             e.printStackTrace();  
         }  
         BASE64Encoder encoder = new BASE64Encoder();  
         return encoder.encode(data);  
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值