Java Web 生成Word文档(freemarker方式)

首先在pom文件中加入下面这个依赖(不是Maven项目的话,把jar包导入项目便可)

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

1.建立带有格式的word文档,将该须要动态展现的数据使用变量符替换。以下:

2.将上述1所建立的文档另存为.xml格式。

3.编辑上述2的.xml文件去掉多余的xml标记,以下图(红圈是正确的格式,应该由${变量符}包裹着)

 4.将上述3的文档另存为.ftl格式,而后复制到Web项目(下图目录)。

 5.JSP页面提供生成word文档的按钮。

<a href="javascript:;" onclick="exportWord('${rightId}')" class="btn btn-success radius"><i class="Hui-iconfont">&#xe644;</i>导出Word</a> 

JS代码:
//生成word文档
function exportWord(rightId){
    layer.confirm('确认要生成word文档吗?',function(index){
        //关闭窗口
        layer.close(index);
        window.location.href ="<%= basePath%>/biz/SysRight_exportWord.action?rightId="+rightId+""
	});
}

效果以下:

 

6.Action中的exportWord()方法。

/**
	 * 生成word文档(测试使用)
	 * @Description: TODO
	 * @param @return
	 * @param @throws Exception   
	 * @return String  
	 * @throws
	 * @author uug
	 * @date 2018年12月9日
	 */
	public String exportWord() throws Exception {
        //须要显示的数据
		sysRight = sysRightService.exportWord(sysRight.getRightId());
		HttpServletResponse response = ServletActionContext.getResponse();
		HttpServletRequest request = ServletActionContext.getRequest();
		//建立Map
        Map<String, Object> map = new HashMap<String, Object>();
        //将数据put到Map中,第一个参数为.ftl文件中对应的${}名称,第二个参数为须要显示的内容
        map.put("rightId",sysRight.getRightId());
        map.put("rightName",sysRight.getRightName());
        map.put("resourcePath",sysRight.getResourcePath());
        map.put("rightPid",sysRight.getRightPid());
        //须要调用的模板名称
        String downloadType = "test";
        //导出时的名称
        String fileName = "权限列表";
        WordUtils.exportMillCertificateWord(request,response,map,downloadType , fileName);
		return null;
	}

 6.WordUtils工具类。javascript

@SuppressWarnings("deprecation")
public class WordUtils {
	//配置信息
    private static Configuration configuration = null;
  //这里注意的是利用WordUtils的类加载器动态得到模板文件的位置
    private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/asserts/templete/";
    //用于存放全部的.ftl文件
    private static Map<String, Template> allTemplates = null;
	
	static {
		configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
		allTemplates = new HashMap<String, Template>();
		try {
			configuration.setDirectoryForTemplateLoading(new File(templateFolder));
			//将test.ftl文件存入Map
			allTemplates.put("test", configuration.getTemplate("test.ftl"));
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	private WordUtils() {  
        throw new AssertionError();  
    }
 
	/**
	 * 
	 * @Description: TODO
	 * @param @param request
	 * @param @param response
	 * @param @param map 写入文件的数据
	 * @param @param downloadType  须要调用Map allTemplates对应的那个.ftl文件
	 * @param @param fileName0  设置浏览器如下载的方式处理该文件名
	 * @param @throws IOException   
	 * @return void  
	 * @throws
	 * @author uug
	 * @date 2018年12月9日
	 */
    public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String downloadType, String fileName0) throws IOException {
        //定义Template对象,注意模板类型名字与downloadType要一致
    	Template template= allTemplates.get(downloadType);
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,template);
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器如下载的方式处理该文件名
            String fileName = fileName0 + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
 
            out = response.getOutputStream();
            byte[] buffer = new byte[512];  // 缓冲区
            int bytesToRead = -1;
            // 经过循环将读入的Word文件的内容输出到浏览器中
            while((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if(fin != null) fin.close();
            if(out != null) out.close();
            if(file != null) file.delete(); // 删除临时文件
        }
    }
 
    /**
     * 建立doc文档
     * @Description: TODO
     * @param @param dataMap
     * @param @param template
     * @param @return   
     * @return File  
     * @throws
     * @author uug
     * @date 2018年12月9日
     */
    private static File createDoc(Map<?, ?> dataMap, Template template) {
        String name = "temp" + (int) (Math.random() * 100000) + ".doc"; 
        File f = new File(name);
        Template t = template;
        try {
            // 这个地方不能使用FileWriter由于须要指定编码类型不然生成的Word文档会由于有没法识别的编码而没法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
}

 7.效果以下:java