JavaWeb实现导出Word文档到本地(使用FreeMarker模版引擎实现)

简介: http://freemarker.org/ Freemarker官网,英文,可以用谷歌浏览器的自动翻译,英文水平高的忽略这句。。 简单来说:FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。

介绍一个专注于Java的网站:Java之音

http://freemarker.org/

Freemarker官网,英文,可以用谷歌浏览器的自动翻译,英文水平高的忽略这句。。

简单来说:FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。FreeMarker被设计用来生成HTMLWeb页面,特别是基于MVC模式的应用程序。

这里使用freemarker生成Word文档,非常方便。

惯例,先看看Demo整体结构:

Demo结构:


这里要引入freemarker包,通过Freemarker加载word文档的模版

生成Word文档类ToCreateDoc

package org.javasun.createDoc;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

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

public class ToCreateDoc {

	private Configuration configuration = null;

	public ToCreateDoc() {
		configuration = new Configuration();
		configuration.setDefaultEncoding("UTF-8");
	}

	public void createDoc(Writer out, Map<String, Object> dataMap, String ftlName) {
		configuration.setClassForTemplateLoading(getClass(), "/ftl");
		try {
		    	
			Template t = null;
			t = configuration.getTemplate(ftlName,"UTF-8");
			t.process(dataMap, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

Servlet,填数据发送客户端处理:

package org.javasun.servlet;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.javasun.createDoc.ToCreateDoc;

@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
	public DownloadServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 设置response类型
		String fileName = "test.doc";
		// 设置响应正文的MIME类型
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-Disposition", "attachment;" + " filename=" + fileName);
		// 获取数据,设置数据
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("company", "XXX百货公司");
		dataMap.put("companyname", "XXX批发商");
		dataMap.put("addr", "太原市XXXX");
		dataMap.put("contact", "张文先生");
		dataMap.put("phone", "12345678");

		List<Map<String, String>> payList = new ArrayList<>();
		for (int i = 1; i < 8; i++) {
			Map<String, String> iMap = new HashMap<>();
			iMap.put("proName", "智能手机" + i + "0");
			iMap.put("pay", i * 1000 + "");
			iMap.put("num", "105");
			iMap.put("total", "100333");
			payList.add(iMap);
		}

		dataMap.put("itemlist", payList);
		// 把本地文件发送给客户端
		Writer out = response.getWriter();
		ToCreateDoc tcd = new ToCreateDoc();
		tcd.createDoc(out, dataMap, "demo.ftl");
		out.close();
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

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></title>
<script type="text/javascript">
	function download_file(url){		  
	    if (typeof (download_file.iframe) == "undefined")  
	    {  
	        var iframe = document.createElement("iframe");  
	        download_file.iframe = iframe;  
	        document.body.appendChild(download_file.iframe);  
	    }  
	    download_file.iframe.src = url;  
	    download_file.iframe.style.display = "none";
	}  
</script>
</head>
<body>
	<button onclick="download_file('download');" >单击生成Word文档</button>
</body>
</html>

点击按钮,Word文档就会自动下载,下载的文件如图:


我们可以看到,很方便,只要定义好文件模版,就可以将数据库数据导入成文档格式保存或者打印。

 

那么如何定义模版呢?

将需要的Word文档做好之后(一般是没有数据的一种文档模版格式),选择另存为XML文件,存为XML的目的是方便检查,看看${}占位符的内容是否被分开了(分开之后会导致很多问题,所以要调整格式,修改一下XML文件),之后另存为.ftl模版文件就OK了,在项目中引用就可以实现内容按所想的格式输出。

 

如何引用?

Freemarker提供了3种加载模板目录的方法。 它使用Configuration类加载模板

3种方法分别是:

public voidsetClassForTemplateLoading(Class clazz, String pathPrefix);

public voidsetDirectoryForTemplateLoading(File dir) throws IOException;

public voidsetServletContextForTemplateLoading(Object servletContext, String path);


分别基于类路径、文件系统以及Servlet Context路径。

 

注意事项(导出的Word文档很容易出现乱码)如何解决?

我们在做模板导出时需要注意以下三处编码集的设置,有一处没有设置就会导致到处uWord文档出现中文乱码。

(1)configuration.setDefaultEncoding("UTF-8");

(2)Template t =configuration.getTemplate("模板文件","UTF-8");

(3)Writer out = newBufferedWriter(new OutputStreamWriter(文件输出流 fos, "UTF-8"))。

 

 Demo下载地址:https://github.com/guodalin8/ToWordTest




目录
相关文章
|
26天前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
18 1
|
26天前
|
SQL 关系型数据库 MySQL
javaweb实现分页查询(一)
javaweb实现分页查询(一)
17 0
|
26天前
|
SQL 关系型数据库 MySQL
javaweb中实现分页,持续更新……
javaweb中实现分页,持续更新……
15 1
|
1月前
|
Java Spring 容器
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
|
1月前
JavaWeb 开发之 ServletContext 的和使用
JavaWeb 开发之 ServletContext 的和使用
21 1
|
20天前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
33 1
|
XML SQL Java
Java后端进阶之路: JavaWeb(三)
Java后端进阶之路: JavaWeb
30 1
|
2月前
|
Java Linux 数据安全/隐私保护
Java【代码 16】将word、excel文件转换为pdf格式和将pdf文档转换为image格式工具类分享(Gitee源码)aspose转换中文乱码问题处理
【2月更文挑战第3天】Java 将word、excel文件转换为pdf格式和将pdf文档转换为image格式工具类分享(Gitee源码)aspose转换中文乱码问题处理
86 0
|
2月前
|
Java 程序员 数据安全/隐私保护
分享一个word转pdf的工具类Aspose[java]
分享一个word转pdf的工具类Aspose[java]
41 0
|
2月前
|
Java
Java中把word转换成图片
Java中把word转换成图片
61 0