Java使用freemarker导出word模板

来源:互联网 发布:刘洪波四大讲座 知乎 编辑:程序博客网 时间:2024/06/09 15:20
Java使用freemarker导出word模板
1, 新建一个word文档, 输入如下类容: 

 2, 将该word文件另存为xml格式(注意是另存为,不是直接改扩展名)
 3,图片处理
    搜索w:binData 或者 png可以快速定位图片的位置,图片             已经是0-F的字符串了, 如下: 

将上述0-F的字符串全部删掉,写上${open.pic}(变量名随便写)后保存
4,表格循环处理
搜索  w:tr 可以找到行的起点与结束点(注意第一对w:tr 是表头,应找第二对 w:tr), 
 4, 用<#list openlist as open> </#list>标签将第二对 w:tr 标签包围起来(userList是集合的key, user是集合中的每个元素

java代码
public void downOpenWord() throws IOException {String imgPath = ServletActionContext.getServletContext().getRealPath("/uploads/");Map<String, Object> dataMap = new HashMap<String, Object>();List<Map<String, Object>> list4 = new ArrayList<Map<String, Object>>();List<ImccOpen> imccOpenList = imccOpenService.ExprMessList();ImccOpen imccOpen=new ImccOpen();if(!imccOpenList.isEmpty()){for(int i=0;i<imccOpenList.size();i++){imccOpen=imccOpenList.get(i);imccOpen.setFlag(1);imccOpenDao.saveOrUpdatePo(imccOpen);Map<String, Object> map = new HashMap<String, Object>();map.put("text", imccOpen.getOpencontent());map.put("tel", imccOpen.getOpentel());map.put("name", imccOpen.getOpenname());map.put("pic", DocUtil.getImageStr(imgPath+"/"+imccOpen.getOpenpicture()+".jpg"));map.put("adr",imccOpen.getOpenadress());map.put("num", imccOpen.getOpennum());list4.add(map);}dataMap.put("openlist", list4);File file = null;          InputStream fin = null;          ServletOutputStream out = null;          try {              // 调用工具类WordGenerator的createDoc方法生成Word文档              file = WordGenerator.createDoc(dataMap, "resume");              fin = new FileInputStream(file);                            HttpServletResponse resp= (HttpServletResponse)              ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);resp.setCharacterEncoding("utf-8");              resp.setContentType("application/msword");              // 设置浏览器以下载的方式处理该文件默认名为resume.doc              resp.addHeader("Content-Disposition", "attachment;filename=resume.doc");                            out = resp.getOutputStream();              byte[] buffer = new byte[512];  // 缓冲区              int bytesToRead = -1;              // 通过循环将读入的Word文件的内容输出到浏览器中              while((bytesToRead = fin.read(buffer)) != -1) {                  out.write(buffer, 0, bytesToRead);              }          } finally {              if(fin != null) fin.close();              if(out != null) out.close();              if(file != null) file.delete(); // 删除临时文件          }  }}

util
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 (Exception e) {            e.printStackTrace();        }        BASE64Encoder encoder = new BASE64Encoder();        return encoder.encode(data);    }
wordCreat
package com.szhtp.faq.actityTest.util;import java.io.File;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.HashMap;import java.util.Map;import freemarker.template.Configuration;import freemarker.template.Template;public class WordGenerator {private static Configuration configuration = null;private static Map<String, Template> allTemplates = null;static {configuration = new Configuration();configuration.setDefaultEncoding("utf-8");configuration.setClassForTemplateLoading(WordGenerator.class, "/com/szhtp/faq/actityTest/util");allTemplates = new HashMap<String, Template>();// Java 7 钻石语法try {allTemplates.put("resume", configuration.getTemplate("open.ftl"));} catch (IOException e) {e.printStackTrace();throw new RuntimeException(e);}}private WordGenerator() {throw new AssertionError();}public static File createDoc(Map<?, ?> dataMap, String type) {String name = "temp" + (int) (Math.random() * 100000) + ".doc";File f = new File(name);Template t = allTemplates.get(type);try {// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");t.process(dataMap, w);w.close();} catch (Exception ex) {ex.printStackTrace();throw new RuntimeException(ex);}return f;}}


注意:
多张图片显示时,当list循环的时候,如果你不改变图片两个属性w:name和imagedata src的值,那么它永远也是调用第一张图片的地址,显示的都是第一张图片。
更改两个属性w:name和imagedata src的方法:

用变量个体的索引来改变两个属性的名字,变量个体的索引格式为“变量名字_index”例如:open_index,见下面红色加粗字体部分。

  <w:binData w:name="${"wordml://0200000"+open_index+1+".jpg"}" xml:space="preserve">${im}</w:binData>
      <v:shape id="图片" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:414.75pt;height:207.75pt;visibility:visible;mso-wrap-style:square">
       <v:imagedata src="${"wordml://0200000"+open_index+1+".jpg"}" o:title="菜单"/>

0 0