用 Freemarker 生成 word 文档(包含图片)

1. 用word写一个需要导出的word模板,然后存为xml格式。

2. 将xml中需要动态修改内容的地方,换成freemarker的标识符,例如:

<w:p wsp:rsidR="00D02906" wsp:rsidRDefault="00FA4C58" wsp:rsidP="00FA4C58">
        <w:pPr>
            <w:jc w:val="center"/>
            <w:rPr>
                <w:rFonts w:hint="fareast"/>
            </w:rPr>
        </w:pPr>
        <w:r>
            <w:t>${year}</w:t>
        </w:r>
        <w:r>
            <w:rPr>
                <wx:font wx:val="宋体"/>
            </w:rPr>
            <w:t>年度工作报告</w:t>
        </w:r>
</w:p>

3. 用代码生成:

import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @Class name:    CreateDoc
 * <p/>
 * Short description on the purpose of the program.
 * @author : youfeng
 * @modified : 8/29/11
 */
public class CreateDoc {

    private Configuration configuration = null;

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

    public void create() throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2011");
        map.put("modifyDate", "2011/8/29");
        map.put("modifyUser", "Zhu You Feng");

        configuration.setClassForTemplateLoading(this.getClass(), "/docTemplate/");
        Template t = configuration.getTemplate("doc1.ftl");
        File outFile = new File("D:/outFile.doc");
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
        t.process(map, out);
    }

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

    }
}

添加图片

如果你需要在word中添加图片,那你就在第一步制作模板时,加入一张图片占位,然后打开xml文档,可以看到如下的一片base64编码后的代码:

1 <w:binData w:name="wordml://03000001.png" xml:space="preserve">iVBORw0…(很省略很省略)…CC</w:binData>

只要将base64的代码替换成例如:${image},如下:

1 <w:binData w:name="wordml://03000001.png" xml:space="preserve">${image}</w:binData>

这里要注意“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。

然后用代码生成:

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

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @Class name:    CreateDoc
 * @author: youfeng
 * @modified: 8/29/11
 */
public class CreateDocWithImage {

    private Configuration configuration = null;

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

    public void create() throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("year", "2011");
        map.put("person", "Zhu You Feng");
        map.put("image", getImageStr());

        configuration.setClassForTemplateLoading(this.getClass(), "/docTemplate/");
        Template t = configuration.getTemplate("doc2.ftl");
        File outFile = new File("D:/outFile.doc");
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
        t.process(map, out);
    }

    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 static void main(String[] args) throws Exception {
        new CreateDocWithImage().create();

    }
}

自定义载入模板

import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class DocumentGenerator {
    private Configuration configuration = null;

    public static void main(String[] args) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2012");
        map.put("modifyDate", "2011/8/29");
        map.put("modifyUser", "Zhu You Feng");
        new DocumentGenerator().createDoc("", "D:/outFile2.doc", map);
    }

    public DocumentGenerator() {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassicCompatible(true);
        configuration.setTemplateLoader(new ByteArrayStreamTemplateLoader(new ByteArrayInputStream(
                        getBytesFromFile(new File("D:/ownProject/freemarkerToDoc/src/main/resources/docTemplate/doc1.ftl"))
                )));
    }

    /**
     * @param fileName
     * @param outFileName
     * @param dataMap
     */
    public void createDoc(String fileName, String outFileName, Map dataMap) {
        Template t = null;
        try {
            t = configuration.getTemplate(fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        File outFile = new File(outFileName);
        Writer out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        try {
            t.process(dataMap, out);
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public byte[] getBytesFromFile(File f) {
        if (f == null) {
            return null;
        }
        try {
            FileInputStream stream = new FileInputStream(f);
            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}


class ByteArrayStreamTemplateLoader implements TemplateLoader {

    InputStream in = null;

    public ByteArrayStreamTemplateLoader(ByteArrayInputStream inputStream) {
        in = inputStream;
    }

    public Object findTemplateSource(String name) throws IOException {
        System.out.println("findTemplateSource");
        return in;
    }

    public long getLastModified(Object templateSource) {
        return 0;
    }

    public Reader getReader(Object templateSource, String encoding) throws IOException {
        System.out.println("getReader");
        return new InputStreamReader(in);
    }

    public void closeTemplateSource(Object templateSource) throws IOException {
        System.out.println("closeTemplateSource");
        if (in != null) {
            in.close();
        }
    }
}

本文转自:http://www.cnblogs.com/zhuyoufeng/archive/2011/09/01/2161558.html

原文地址:https://www.cnblogs.com/dreammyle/p/4631331.html