freemarker制作复杂word模板

         最近项目遇到需要生成复杂word文档的功能。个人感觉poi对excel的操作强于对word的操作,jacob对写复杂的word来说操作量也比较大,网上看到有关freemarker制作word模板并能轻松导出,决定一试,果然方便,下面介绍下采用freemarker制作模板导出的步骤和方法。

         1、做好原始的word模板(按照自己的需求制作),下面是我项目中的需求模板

      

内容比较多(有多级表头,有图片等等),就不一一截图了。

             2、有了模板之后就可以开始进行变量的设置了,如上图中编制时间就可以修改成编制时间:${year}${month}${day}”。把所有需要动态设置的内容用变量替换。

             3、将处理好后的word文档另存为xml格式,‘Word 2003 XML文档(*.xml)’下载foxe_CHS.exe工具,打开处理好的xml格式文档。检查一遍是否所有的设置变量都确认无误(有时候在存储成xml文档的过程中,变量有可能会被拆分成几部分,如${year} 有可能被拆分成了'${ye'和'ar}',这时就需要自己去修改调整过来)



 
确认变量设置完成后,将文件存储为XX.ftl格式的文件。

 

             4、java后台模板载入:

  //设置模本装置方法和路径,FreeMarker支持多种模板装载方法.可以重servlet,classpath,数据库装载,
  //这里我们的模板是放在com/dse/gzzxhl/word/report/day包下面

  this.configuration = new Configuration();
  this.configuration.setDefaultEncoding("utf-8");
  configuration.setClassForTemplateLoading(this.getClass(), "/com/dse/gzzxhl/word/report/day");
  Template t=null;
  try {
   //shuiqingribao.ftl为要装载的模板
   t = configuration.getTemplate("xxx.ftl");
  } catch (IOException e) {
   e.printStackTrace();
   return false;
  }

             5、设置数据集

      dataMap.put("year",arr[0]);
      dataMap.put("month",Integer.parseInt(arr[1]));
      dataMap.put("day",Integer.parseInt(arr[2]));
      //生成雨情描述
      dataMap.put("yqdesc",getYqdesc(date,list0,list1,list2));
      //生成雨量统计数据集(暴雨以上量级)
      dataMap.put("yltjlist",getYltjList(list3));
      //雨情图片
       dataMap.put("jyurl", getImageStr("XXX.png"));
      //水情描述
      dataMap.put("sqdesc",getSqdesc(date,list4,list5,list6)[0]);
      //水情描述1
      dataMap.put("sqdesc1",getSqdesc(date,list4,list5,list6)[1]);
      //水情报警信息数据集
      dataMap.put("sqbjxxlist",sqbjxxlist); 

 

注意图片要用base64编码转换:方法如下

private String getImageStr(String url) {
        String imgFile = url;
        InputStream in = null;
        byte[] data = null;
        try {
         File file = new File(url);
         if(file.exists()){
          in = new FileInputStream(imgFile);
          data = new byte[in.available()];
          in.read(data);
          in.close();
         }
         else{
          System.out.println("文件"+url+"不存在!");
          return "";
         }
         } catch (IOException e) {
             e.printStackTrace();
         }
         BASE64Encoder encoder = new BASE64Encoder();
         return encoder.encode(data);
     }

 

          6、输出文档,代码如下:

String filePath = “XXX/XX/X"//要输出的路径

File outFile = new File(filePath);
  Writer out = null;
  try {
   FileOutputStream fos = new FileOutputStream(outFile);
      OutputStreamWriter oWriter = new OutputStreamWriter(fos,"UTF-8");
      out = new BufferedWriter(oWriter);  
  } catch (FileNotFoundException e1) {
   e1.printStackTrace();
   return false;
  }
  try {

//dataMap为设置好的数据集
   t.process(dataMap, out);
   return true;
  }
  catch (TemplateException e){
   e.printStackTrace();
   return false;
  }catch(IOException e1){
   e1.printStackTrace();
   return false;
  }
  finally{
   out.flush();
   out.close();
  }

          7、完成输出,生成文档。