framemarker导出word(含图片)

实现步骤:

1.编辑word模板,并将需要显示数据的地方标注出来。

2.将word模板另存为xml文件(为了兼容,最好使用Word 2003 XML文档)

3.替换标记。

使用xml编辑工具(我用的NotePad++)打开该xml文件,将标记的部分改为${tagName},如上文的number改为${number}。

注意:1.xml文件样式可能比较乱,为方便查看,可以使用xml在线格式化工具格式化。

   2.图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image}。

4.更改文件后缀为.ftl,注意:不要使用word代开ftl文件

5.代码实现:

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>framemarker导出word</title>
</head>
<body>
    <form action="wordExport" method="post" name="form1">
        <center>
            <h1>framemarker导出word</h1>
            <input type="submit" value="导出word">
        </center>        
    </form>
</body>
</html>

 我自己的端口号为9080

 

 编辑导出Word 的Servlet:

package com.framemarker.word.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

@SuppressWarnings("serial")
public class WordExport extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    Map<String, Object> dataMap = new HashMap<String, Object>();
    //存放成绩
    Map<String, Object> reportMap = new HashMap<String, Object>();
    reportMap.put("yuwen", "100");
    reportMap.put("shuxue", "99");
    reportMap.put("yingyu", "86");
    reportMap.put("wuli", "75");
    reportMap.put("huaxue", "80");
    reportMap.put("shengwu", "90");
    //存放个人信息及reportMap
    dataMap.put("number", "111222331");
    dataMap.put("roomNo", "110");
    dataMap.put("name", "张三");
    dataMap.put("score", "100");
    dataMap.put("image", WordUtils.imgEncode("C:/Users/HOME/Desktop/image.jpg"));
    dataMap.put("reportMap", reportMap);
    // 生成word并下载
    File file = null;
    InputStream inputStream = null;
    ServletOutputStream out = null;
    String fileName = "test.doc";
    String ftlName = "test1.ftl";
    try {
        file = WordUtils.wordCreate(dataMap, fileName, ftlName);
        inputStream = new FileInputStream(file);
        res.setCharacterEncoding("UTF-8");
        res.setContentType("application/msword");
        res.addHeader("Content-Disposition", "attachment;filename = export.doc");
        out = res.getOutputStream();
        byte[] buffer = new byte[1024]; // 缓冲区
        int bytesToRead = -1;
        // 通过循环将读入的Word文件的内容输出到浏览器中
        while ((bytesToRead = inputStream.read(buffer)) != -1) {
        out.write(buffer, 0, bytesToRead);
        }
    } catch (Exception e) {
        // TODO: handle exception
    } finally {
        if (inputStream != null)
        inputStream.close();
        if (out != null)
        out.close();
        if (file != null)
        file.delete();
    }
    }
}

工具类:

package com.framemarker.word.test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

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

public class WordUtils {
    /**
     * @param dataMap 存放标记和对应的值
     * @param fileName 生成的临时word文件名
     * @param ftlName 模板文件名
     * @return 生成的临时word文件
     * @throws IOException
     */
    public static File wordCreate(Map<String, Object> dataMap, String fileName, String ftlName) throws IOException {
    Configuration configuration = new Configuration();
    configuration.setDefaultEncoding("UTF-8");
    // 使用包路径加载模板
    configuration.setClassForTemplateLoading(WordUtils.class, "/com/framemarker/word/template");
    File outFile = new File(fileName);

    Template template = null;
    try {
        template = configuration.getTemplate(ftlName);
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
        template.process(dataMap, writer);
        writer.flush();
        writer.close();
    } catch (Exception e) {
        // TODO: handle exception
    }
    return outFile;
    }

    /**
     * 根据绝对路径获取该图片的编码
     * 
     * @param absolutePath
     * @return
     * @throws IOException
     */
    public static String imgEncode(String absolutePath) throws IOException {
    if (absolutePath == null || absolutePath == "")
        return "";
    File file = new File(absolutePath);
    if (!file.exists())
        return "";

    InputStream in = null;
    byte[] data = null;
    try {
        in = new FileInputStream(file);
        data = new byte[in.available()];
        in.read(data);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        in.close();
    }
    BASE64Encoder encoder = new BASE64Encoder();
    return encoder.encode(data);
    }
}

6.结果实现

 

 注意:有些标记不是简单替换就可以的,需要进行非空判断等操作,具体的需要去了解framemarker中标签的使用。

 

posted @ 2018-04-10 10:04  maxudong  阅读(1816)  评论(0编辑  收藏  举报