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




目录
相关文章
|
1月前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
131 5
|
4月前
|
XML 数据采集 存储
使用Java和XPath在XML文档中精准定位数据
在数据驱动的时代,从复杂结构中精确提取信息至关重要。XML被广泛用于数据存储与传输,而XPath则能高效地在这些文档中导航和提取数据。本文深入探讨如何使用Java和XPath精准定位XML文档中的数据,并通过小红书的实际案例进行分析。首先介绍了XML及其挑战,接着阐述了XPath的优势。然后,提出从大型XML文档中自动提取特定产品信息的需求,并通过代理IP技术、设置Cookie和User-Agent以及多线程技术来解决实际网络环境下的数据抓取问题。最后,提供了一个Java示例代码,演示如何集成这些技术以高效地从XML源中抓取数据。
175 7
使用Java和XPath在XML文档中精准定位数据
|
2月前
|
Java Linux
java读取linux服务器下某文档的内容
java读取linux服务器下某文档的内容
42 3
java读取linux服务器下某文档的内容
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
480 37
|
2月前
|
Java Apache Maven
Java将word文档转换成pdf文件的方法?
【10月更文挑战第13天】Java将word文档转换成pdf文件的方法?
444 1
|
2月前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
37 2
|
2月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
71 5
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
2月前
|
缓存 Java 程序员
Java|SpringBoot 项目开发时,让 FreeMarker 文件编辑后自动更新
在开发过程中,FreeMarker 文件编辑后,每次都需要重启应用才能看到效果,效率非常低下。通过一些配置后,可以让它们免重启自动更新。
39 0
|
3月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
124 2
下一篇
DataWorks