Java之下载word文档

需求:web页面点击按钮,触发浏览器下载功能,预览或者保存word本地文件。

可预见的问题:java库选择的是freemarker、word基本的模板的制作。

我电脑的环境是tomcat6+jdk1.6+MyEclipse 10 

第一步:制作简单的ftl模板文件

新建一个doc文件,如下图所示  在需要进行动态变化和遍历的地方添加变量,如下图所示。

另存为xml格式的文件。

使用notepad++或者其他工具打开xml文件,查看生成的模板是否正确。

$符号和变量名没有被分开算正常。${topic}这几个符号是紧密相连的算正常。如果被分开的话,重新编辑一下,确保如我说的那样,其他变量类同。

最后将文件保存之后重命名,后缀由xml改为ftl。使得freemarker能识别相应的模板。

第二步:将ftl文件放入项目中。编写下载word的java代码。

项目的文件存放位置。

项目是比较简单的web项目,使用的是Struts2。下面是web.xml中的配置,一切从简。

只有一个简单的跳转,当链接访问/saveDocServlet的时候请求会进入MyServlet中,进行逻辑处理。

下面是MyServlet的代码;

package com.zhutong.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
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 com.zhutong.util.WordGenerator;

public class MyServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		Map<String, Object> map = new HashMap<String, Object>();
/*		Enumeration<String> paramNames = req.getParameterNames();
		// 通过循环将表单参数放入键值对映射中
		while (paramNames.hasMoreElements()) {
			String key = paramNames.nextElement();
			String value = req.getParameter(key);
			map.put(key, value);
		}*/
		map.put("topic", "我是标题");
		map.put("module", "我是模块");
		// 提示:在调用工具类生成Word文档之前应当检查所有字段是否完整
		// 否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错 这里暂时忽略这个步骤了
		File file = null;
		InputStream fin = null;
		ServletOutputStream out = null;
		try {
			// 调用工具类WordGenerator的createDoc方法生成Word文档
			file = WordGenerator.createDoc(map, "resume");
			fin = new FileInputStream(file);

			resp.setCharacterEncoding("utf-8");
			resp.setContentType("application/msword");
			// 设置浏览器以下载的方式处理该文件默认名为resume.doc
			resp.addHeader("Content-Disposition","attachment;filename=resume.doc");

			out = resp.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(); // 删除临时文件
		}
	}
}
map中key值对应ftl模板${topic}中的属性,可以直接取到key值对应的value值。value值可以是写死的,可以是前后台交互的变量,上面代码中注释的是其中一部分,稍加扩展就可以实现。

上面代码中引用到一个生成word文件的工具类WordGenerator.createDoc(map,"resume")

下面是工具类的对应的代码:

package com.zhutong.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

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

@SuppressWarnings("deprecation")
public class WordGenerator {
	private static Configuration configuration = null;
	private static HashMap<String, Template> allTemplates = null;

	static {
		configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
		configuration.setClassForTemplateLoading(WordGenerator.class,"/com/zhutong/ftl");
		/*
		 * allTemplates = new HashMap<>(); // Java 7 钻石语法
		 */
		allTemplates = new HashMap<String, Template>();
		try {
			allTemplates.put("resume", configuration.getTemplate("resume.ftl"));
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	private WordGenerator() {
		throw new AssertionError();
	}

	public static File createDoc(Map<?, ?> dataMap, String type) {
		String name = "temp" + (int) (Math.random() * 100000) + ".doc";
		File f = new File(name);
		Template t = allTemplates.get(type);
		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;
	}

	
}

写到这里,后台的代码已经写完了。方便起见,在浏览器中输入*****:**/****/saveDocServlet


对应生成的结果为:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值