盒子
盒子
文章目录
  1. 正文

Java生成word文档包含图片-Freemaker

接上节,利用poi生成word文档,导出的文档含图片,会导致文件打不开或者打开的文件没有图片.

在网上查的资料显示:POI,Freemaker,jacob,docx4j,itex都可以生成word文档.以上的方法都用过以后推荐使用 freemaker 生成含有图片的文档.

jacob 需要.dll,限定了只能在win平台下使用.

docx4j基于2007版word开发,学习资料较少,不过这个还是值得细细研究一番的.

正文

一. 前期准备:1.新建一个word文档,输入想要保存的格式,我们将它成为「模板」根据模板格式输出内容

freemaker

2.保存文件为xml格式

xml

3.用notepa++等工具打开xml文件,使用

${}

替换要输出的内容,如 “这是标题”替换为”${title}” 应该严格注意xml的格式,

xml

<w:t></w:t> //表示一行

循环输出可以用

<#list></#list>

保存后,另存为后缀为 .ftl 的文件

二. 编程实现

  • eclipse
  • jdk1.7
  • freemaker-2.3.13.jar
    package com;

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.HashMap;
    import java.util.Map;

    import sun.misc.BASE64Encoder;
    import freemarker.template.Configuration;
    import freemarker.template.Template;

    /**
    * 利用freemaker 根据word模板创建word文档到指定目录下 word文档包含图片 图片转换成base64处理
    *
    * @author Gengxu
    *
    */

    public class CreateDocWithImage {

    private Configuration configuration = null;

    public CreateDocWithImage() {
    configuration = new Configuration();
    configuration.setDefaultEncoding("utf-8");
    }

    /**
    * 将得到的图片转换为BASE64编码
    *
    * @return encoder
    */

    private String getImageStr() {
    String imgFile = "D:\\test.jpg";
    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);

    }

    public void create() throws Exception {

    Model model = new Model();

    Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
    map.put("title", model.getTitle());

    map.put("year", model.getYear());
    map.put("No", model.getNo());
    map.put("dizhi", model.getDizhi());
    map.put("mon", model.getMon());
    map.put("day", model.getDay());
    map.put("image", getImageStr());

    List&lt;Map&lt;String, Object&gt;&gt; wordBean = new ArrayList&lt;Map&lt;String, Object&gt;&gt;();
    // i为循环输出的行数,根据paixu的长度 自动添加行 ,添加列没写出
    WordBean wb = new WordBean();
    for (int i = 1; i &lt;= wb.getPaixu1().length; i++) {

    Map&lt;String, Object&gt; newMap = new HashMap&lt;String, Object&gt;();

    newMap.put("paixu", i);
    newMap.put("biaoduan", wb.getBiaoduan() + i);
    wordBean.add(newMap);
    }
    map.put("wordBeans", wordBean);

    /*
    * 手动添加循环 已替换为上面自动循环 可以是一个思路
    * List&lt;WordBean&gt; lists = new ArrayList&lt;WordBean&gt;();
    * WordBean w1 = new WordBean();
    * w1.setPaixu("1");
    * w1.setBiaoduan("标段一");
    * WordBean w2 = new WordBean();
    * w2.setPaixu("2");
    * w2.setBiaoduan("标段二");
    * WordBean w3 = new WordBean();
    * w3.setPaixu("3");
    * w3.setBiaoduan("标段3");
    * WordBean w4 = new WordBean();
    * w4.setPaixu("4");
    * w4.setBiaoduan("标段4");
    * lists.add(w1);
    * lists.add(w2);
    * lists.add(w3);
    * lists.add(w4);*
    * map.put("wordBeans", lists);
    */


    // 加载ftl文件 模板
    configuration.setClassForTemplateLoading(this.getClass(), "/com/ftl");
    Template t = configuration.getTemplate("good.ftl");

    // 创建指定输出目录
    // 此方法为输出到服务器磁盘
    // 通常通过浏览器以附件的形式下载,需要放到OutputStream流中,word不可以直接输出到流中,先保存到本地服务器,定时删除即可.
    String saveToFile = "D:\\说明";
    File dirFile = new File(saveToFile);
    boolean bFile = dirFile.exists();
    if (bFile == true) {
    System.out.println(dirFile.getName() + "目录已存在,存入即可");
    } else {
    System.out.println("该目录不存在,将创建" + "&lt;" + dirFile.getName() + "&gt;"
    + "目录");
    dirFile.mkdirs();
    }
    File outFile = new File(dirFile + "\\" + Math.random() * 10000
    + "说明.doc");
    System.out.println("路径为" + " " + outFile.getAbsolutePath());
    FileOutputStream fos = new FileOutputStream(outFile);
    OutputStreamWriter osw = new OutputStreamWriter(fos);
    Writer out = new BufferedWriter(osw);
    t.process(map, out);

    // 记得清空和关闭
    out.flush();
    out.close();
    }

    public static void main(String[] args) throws Exception {
    new CreateDocWithImage().create();

    }
    }

Model.java

package com;

public class Model {

/**
* @param args
*/


private String title= "这是标题";
private String year ="2015";
private int No = 110023;
private String dizhi="北京市";
private int mon = 11;
private int day = 20;

public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}

public int getNo() {
return No;
}
public void setNo(int no) {
No = no;
}
public String getDizhi() {
return dizhi;
}
public void setDizhi(String dizhi) {
this.dizhi = dizhi;
}
public int getMon() {
return mon;
}
public void setMon(int mon) {
this.mon = mon;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}

}

WordBean.java

package com;
/**
* 用于存放单元格list内的变量
* @author Administrator
*
*/

public class WordBean {

private int []paixu1 = new int[20];
//private String paixu;
private String biaoduan = "说明";

/*public String getPaixu() {
return paixu;
}

public void setPaixu(String paixu) {
this.paixu = paixu;
}*/


public String getBiaoduan() {
return biaoduan;
}

public void setBiaoduan(String biaoduan) {
this.biaoduan = biaoduan;
}

public int[] getPaixu1() {
return paixu1;
}

public void setPaixu1(int paixu1[]) {
this.paixu1 = paixu1;
}
}

三. 最终效果

word

源码 jar包 ftl模板下载地址:http://download.csdn.net/detail/geng_xu/9240635

如果代码有问题或者需要改进的地方,欢迎讨论.