Java之利用FreeMarker导出Word实例

gavinnu 8年前
   <h3>提出问题</h3>    <p>Java中如何利用FreeMarker导出word文档???</p>    <h3>解决问题</h3>    <p>1.先用word准备一个模板,如下图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b5e2e0805ea34bb0a55f60cd94dd80a3.png"></p>    <p>2.我们把word文档另存为xml格式的文件,用Notepad++工具打开,一下只截取部分内容.</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4da1feb6f60eded903f9c4451f0f5c3f.png"></p>    <p>3.我们开始处理第一个问题:文字处理,Ctrl+F找到XML文档中文字,将“以下省略一万字”替换为${textDeal},保存文件,将文件的后缀改为.ftl,自此模板制作成功。</p>    <p>4.编码实现文本替换:</p>    <pre>  <code class="language-java">package com.hwy.test;    import freemarker.template.Configuration;  import freemarker.template.Template;  import java.io.*;  import java.util.HashMap;  import java.util.Map;  /**   * word导出   * Created by Ay on 2016/6/27.   */  public class WordDocExportTest {        public static void main(String[] args) throws Exception{          /** 初始化配置文件 **/          Configuration configuration = new Configuration();          /** 设置编码 **/          configuration.setDefaultEncoding("utf-8");          /** 我的ftl文件是放在D盘的**/          String fileDirectory = "D:\\";          /** 加载文件 **/          configuration.setDirectoryForTemplateLoading(new File(fileDirectory));          /** 加载模板 **/          Template template = configuration.getTemplate("FreeMarker中word导出XML.ftl");          /** 准备数据 **/          Map<String,String> dataMap = new HashMap<>();          /** 在ftl文件中有${textDeal}这个标签**/          dataMap.put("textDeal","一下省略一万字");          /** 指定输出word文件的路径 **/          String outFilePath = "D:\\myFreeMarker.doc";          File docFile = new File(outFilePath);          FileOutputStream fos = new FileOutputStream(docFile);          Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"),10240);          template.process(dataMap,out);            if(out != null){              out.close();          }      }  }</code></pre>    <p>5.编码实现图片的替换</p>    <p><img src="https://simg.open-open.com/show/eef02f960f32494e1a492c741f56093e.png"></p>    <p>具体代码如下:</p>    <pre>  <code class="language-java">package com.hwy.test;  import freemarker.template.Configuration;  import freemarker.template.Template;  import sun.misc.BASE64Encoder;  import java.io.*;  import java.util.HashMap;  import java.util.Map;  /**   * word导出   * Created by Ay on 2016/6/27.   */  public class WordDocExportTest {        public static void main(String[] args) throws Exception{          /** 初始化配置文件 **/          Configuration configuration = new Configuration();          /** 设置编码 **/          configuration.setDefaultEncoding("utf-8");          /** 我的ftl文件是放在D盘的**/          String fileDirectory = "D:\\";          /** 加载文件 **/          configuration.setDirectoryForTemplateLoading(new File(fileDirectory));          /** 加载模板 **/          Template template = configuration.getTemplate("FreeMarker中word导出XML.ftl");          /** 准备数据 **/          Map<String,String> dataMap = new HashMap<>();            /** 图片路径 **/          String imagePath = "D:\\apple.jpg";          /** 将图片转化为**/          InputStream in = null;          byte[] data = null;          try {              in = new FileInputStream(imagePath);              data = new byte[in.available()];              in.read(data);              in.close();          } catch (Exception e) {              e.printStackTrace();          }finally {              if(in != null){                  in.close();              }          }          /** 进行base64位编码 **/          BASE64Encoder encoder = new BASE64Encoder();            /** 在ftl文件中有${textDeal}这个标签**/          dataMap.put("textDeal","一下省略一万字");          /** 图片数据**/          dataMap.put("myImage",encoder.encode(data));            /** 指定输出word文件的路径 **/          String outFilePath = "D:\\myFreeMarker.doc";          File docFile = new File(outFilePath);          FileOutputStream fos = new FileOutputStream(docFile);          Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"),10240);          template.process(dataMap,out);            if(out != null){              out.close();          }      }  }</code></pre>    <p>结果,I love you这张图片又出现了:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/24017a93ed4941a46ca97a47977dfc95.png"></p>    <p>6.freeMarker表格处理</p>    <p>1)同样道理,找到表格的位置,替换成freeMarker标签,图片如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/705cd9ba4f32b14c62573d55fa2d279d.png"></p>    <p>具体代码:</p>    <pre>  <code class="language-java">package com.hwy.test;  import freemarker.template.Configuration;  import freemarker.template.Template;                  import java.io.*;  import java.util.ArrayList;  import java.util.HashMap;  import java.util.List;  import java.util.Map;      /**   * word导出   * Created by Ay on 2016/6/27.   */  public class WordDocExportTest {        public static void main(String[] args) throws Exception{          /** 初始化配置文件 **/          Configuration configuration = new Configuration();          /** 设置编码 **/          configuration.setDefaultEncoding("utf-8");          /** 我的ftl文件是放在D盘的**/          String fileDirectory = "D:\\";          /** 加载文件 **/          configuration.setDirectoryForTemplateLoading(new File(fileDirectory));          /** 加载模板 **/          Template template = configuration.getTemplate("FreeMarker中word导出XML.ftl");          /** 准备数据 **/          Map<String,List<Student>> dataMap = new HashMap<>();            /** 表格数据初始化 **/          List<Student> studentList = new ArrayList<>();          studentList.add(new Student("100424060","小毅","男","25"));          studentList.add(new Student("100424030","小兰","女","25"));            /** 表格数据 studentList和freemarker标签要对应**/          dataMap.put("studentList",studentList);            /** 指定输出word文件的路径 **/          String outFilePath = "D:\\myFreeMarker.doc";          File docFile = new File(outFilePath);          FileOutputStream fos = new FileOutputStream(docFile);          Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"),10240);          template.process(dataMap,out);            if(out != null){              out.close();          }      }  }</code></pre>    <p>Student类如下: 这里有一个问题,如果Student类写在WordDocExportTest类中,就会出现问题,很奇怪,只能单独另启一个类了。</p>    <pre>  <code class="language-java">package com.hwy.test;    /**   * Created by Ay on 2016/6/29.   */  public class Student{      private String id;      private String name;      private String sex;      private String age;        public String getId() {          return id;      }        public void setId(String id) {          this.id = id;      }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public String getSex() {          return sex;      }        public void setSex(String sex) {          this.sex = sex;      }        public String getAge() {          return age;      }        public void setAge(String age) {          this.age = age;      }        public Student(String id, String name, String sex, String age) {          this.id = id;          this.name = name;          this.sex = sex;          this.age = age;        }  }</code></pre>    <p>结果如下:</p>    <pre>  <code class="language-java">![这里写图片描述](http://upload-images.jianshu.io/upload_images/2321678-fe12900dbb9277fd?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</code></pre>    <p>7.word中字体样式调整</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c2bf2a7dee6aa5d24750c7143dbafb79.png"></p>    <p>1)我们把四种的字体“这里是字体样式......”在word中字体样式改为仿宋_gb2312,大小改为30号如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/74fab6b67472a46a1af0c9a417a192d9.png"></p>    <p>2)用同样的方法,把word转变为 <strong>ftl</strong> 文件,打开如下</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/abe94509ea386e36751443c57fbaf385.png"></p>    <p>所有以后word需要什么的样式,都是在原先word调好样式,在转变为ftl文件即可</p>    <p>8.页眉页脚设置</p>    <p>1)相同道理,在原先word插入页眉“Hello Freemarker”,另存为xml文件,再后缀为ftl文件即可,既是我们要的文件</p>    <h3> </h3>    <p> </p>    <p>来自:http://www.jianshu.com/p/f58802a29d8a</p>    <p> </p>