1.用Microsoft Office Word打开word原件;

2.把需要动态修改的内容替换成${XX}的形式,如果有图片,尽量选择较小的图片几十K左右的小图片,并调整好位置,占位(小图片转换的base64数据少,便于修改);如下图

java图片转qrcode java图片转word_word导出

 

 

3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】,保存的文件名不要是中文

4.用notepad++打开文件;

 

5. 将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName};

6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;

  代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${xx}</w:binData>

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

  如果需要循环,则使用:<#list maps as map></#list>  maps是Map<String, Object>中key,值为数组,map为自定义;

java图片转qrcode java图片转word_freemarker_02

7. 标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。把最开始得到的doc模板文件和ftl文件放在同一级目录下

8.代码部分

pom:

<!--  word导出 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.8</version>
</dependency>
<!-- 生成图片-->
<dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.0.19</version>
</dependency>

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>

工具类:

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

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.Map;


public class DoOffice_word_freemarker {


    private Configuration configuration = null;

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

    public void createDoc(HttpServletRequest request, Map<String, Object> dataMap, String fileName)
            throws IOException {
        // dataMap 要填入模本的数据文件
        //模板地址
        String tmpFile = request.getSession().getServletContext().getRealPath("/WEB-INF");
        configuration.setDirectoryForTemplateLoading(new File(tmpFile));
        Template t = configuration.getTemplate("template.ftl");
        // 输出文档路径及名称
        File outFile = new File(fileName);
        Writer out = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
            OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
            // 这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
            // out = new BufferedWriter(new OutputStreamWriter(new
            // FileOutputStream(outFile)));
            out = new BufferedWriter(oWriter);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(dataMap, out);
            out.close();
            fos.close();
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // System.out.println("---------------------------");
    }

    // 图片处理
    public static String getImageStr() {
        String imgFile = "f:/123.png";
        InputStream is = null;
        byte[] data = null;
        try {
            is = new FileInputStream(imgFile);
            data = new byte[is.available()];
            is.read(data);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

    public static boolean Base64ToImage(String imgStr,String imgFilePath) {
        // 对字节数组字符串进行Base64解码并生成图片



        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }

            OutputStream out = new FileOutputStream("f:/123.png");
            out.write(b);
            out.flush();
            out.close();

            return true;
        } catch (Exception e) {
            return false;
        }

    }
    public static void main(String[] args) throws IOException {

        Base64ToImage("","");
        Map<String, Object> datas = new HashMap<String, Object>();
        datas.put("bianhao", "1232");
        datas.put("dushuyi", "1235");
        datas.put("weizhi", "1423");
        datas.put("tuzhi", "25123");
        datas.put("kongshen", "1我23");
        datas.put("ksshuiwei", "123");
        datas.put("endshuiwei","请问123");
        datas.put("kstime", "123");
        datas.put("endtime", "1啊23");
        datas.put("counttime", "123");
        datas.put("result", "1夫人23");
        datas.put("img", getImageStr().substring(22,getImageStr().length()));
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("photo", getImageStr().substring(22,getImageStr().length()));
        dataMap.put("name", "Blue");
        dataMap.put("gender", "男");
        dataMap.put("birth", "1992-2-2");
        dataMap.put("grade", "1203班");
        dataMap.put("major", "软件");
        dataMap.put("Id", "201219010110");
        dataMap.put("phone", "123456");
        dataMap.put("roomId", "S-222");
        dataMap.put("zhengzhi", "团员");
        dataMap.put("IdCard", "411322199202022212");
        dataMap.put("address", "河南省郑州市地球村");
        dataMap.put("parent_phone1", "11111111");
        dataMap.put("parent_phone2", "22222222");
        dataMap.put("gold", "这里是目标,新学期新气象,好好学习,天天向上");
        DoOffice_word_freemarker mdoc = new DoOffice_word_freemarker();
        //mdoc.createDoc(datas, "d:/00.docx");
        //System.out.println(getImageStr().substring(22,getImageStr().length()));
    }


}

通过图片地址获取图片然后转换成base64格式:

public static String GetImageStrFromUrl(String imgURL) {
        byte[] data = null;
        try {
            // 创建URL
            URL url = new URL(imgURL);
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            InputStream inStream = conn.getInputStream();
            int count = conn.getContentLength();
            data = new byte[count];
            int readCount = 0;
            while (readCount<count){
                readCount += inStream.read(data,readCount,count-readCount);
            }

            //data = new byte[inStream.available()];
            inStream.read(data);
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64编码过的字节数组字符串
        return encoder.encode(data);
    }

主业务代码:

/**
     * WORD导出
     */
    @RequestMapping(value = "/word", method= RequestMethod.GET)
    @ResponseBody
    public String word(HttpServletRequest request) throws Exception {

        //模板地址(把最开始得到的doc模板文件和ftl文件放在同一级目录下)
        String tmpFile = request.getSession().getServletContext().getRealPath("/WEB-INF/template.doc");
        //导出文件保存地址/usr/apache-tomcat-7.0.69/webapps/template.doc
        String expFile = "D:/"+ DateUtils.getToday() +".doc";

     
        String daba_points = "JH-05";
        String daba_content = "查xx。";
        String daba_result = getResult("J1H-05");
        String daba_images = FileUtil.GetImageStrFromUrl("图片地址");
      

        Map<String, Object> datas = new HashMap<String, Object>();
      
    
        datas.put("daba_points", daba_points);
        datas.put("daba_content", daba_content);
        datas.put("daba_result",daba_result);
        datas.put("daba_images", daba_images);
      



        DoOffice_word_freemarker mdoc = new DoOffice_word_freemarker();
        mdoc.createDoc(request,datas, expFile);


        return daba_images;
    }

成果:

java图片转qrcode java图片转word_java图片转qrcode_03