Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob、Apache POI、Java2Word、iText等各种方式,其实在从Office 2003开始,就可以将Office文档转换成XML文件,这样只要将需要填入的内容放上${}占位符,就可以使用像Freemarker这样的模板引擎将出现占位符的地方替换成真实数据,这种方式较之其他的方案要更为简单。

下面举一个简单的例子,比如在Web页面中填写个人简历,然后点击保存下载到本地,效果图如下所示。

打开下载的Word文件

首先在Eclipse Java EE版中新建一个Dynamic Web Project,项目结构如下图所示

需要向项目中加入freemarker的JAR文件,可以通过下面的链接获得Freemarker的最新版本:

http://freemarker.org/freemarkerdownload.html

模板文件resume.ftl是如何生成的呢,其实非常简单,将需要的Word文档做好之后,选择另存为XML文件,另存之后建议用Editplus、Notepad++、Sublime等工具打开查看一下,因为有的时候你写的占位符可能会被拆开,这样Freemarker就无法处理了。

打开XML文件看看吧,如果刚才你写的${title}、${name}被xml文件给拆散了,修改一下XML文件就OK了。

修改过后另存为resume.ftl模板文件,如下所示:

接下来就是Servlet(也可以是Struts2的Action、spring MVC的Controller等)和工具类WordGenerator的编写以及页面test.jsp的制作了,代码如下所示:

小服务的代码:

[java]  view plain copy
  1. package com.lovo.servlet;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.util.Enumeration;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.ServletOutputStream;
  11. import javax.servlet.annotation.WebServlet;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import com.lovo.util.WordGenerator;
  16. /**
  17. * Servlet implementation class MyServlet
  18. */
  19. @WebServlet("/saveDocServlet")
  20. public class MyServlet extends HttpServlet {
  21. private static final long serialVersionUID = 1L;
  22. @Override
  23. protected void service(HttpServletRequest req, HttpServletResponse resp)
  24. throws ServletException, IOException {
  25. req.setCharacterEncoding("utf-8");
  26. Map<String, Object> map = new HashMap<String, Object>();
  27. Enumeration<String> paramNames = req.getParameterNames();
  28. // 通过循环将表单参数放入键值对映射中
  29. while(paramNames.hasMoreElements()) {
  30. String key = paramNames.nextElement();
  31. String value = req.getParameter(key);
  32. map.put(key, value);
  33. }
  34. // 提示:在调用工具类生成Word文档之前应当检查所有字段是否完整
  35. // 否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错 这里暂时忽略这个步骤了
  36. File file = null;
  37. InputStream fin = null;
  38. ServletOutputStream out = null;
  39. try {
  40. // 调用工具类WordGenerator的createDoc方法生成Word文档
  41. file = WordGenerator.createDoc(map, "resume");
  42. fin = new FileInputStream(file);
  43. resp.setCharacterEncoding("utf-8");
  44. resp.setContentType("application/msword");
  45. // 设置浏览器以下载的方式处理该文件默认名为resume.doc
  46. resp.addHeader("Content-Disposition", "attachment;filename=resume.doc");
  47. out = resp.getOutputStream();
  48. byte[] buffer = new byte[512];  // 缓冲区
  49. int bytesToRead = -1;
  50. // 通过循环将读入的Word文件的内容输出到浏览器中
  51. while((bytesToRead = fin.read(buffer)) != -1) {
  52. out.write(buffer, 0, bytesToRead);
  53. }
  54. } finally {
  55. if(fin != null) fin.close();
  56. if(out != null) out.close();
  57. if(file != null) file.delete(); // 删除临时文件
  58. }
  59. }
  60. }

工具类的代码:

[java]  view plain copy
  1. package com.lovo.util;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStreamWriter;
  6. import java.io.Writer;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import freemarker.template.Configuration;
  10. import freemarker.template.Template;
  11. public class WordGenerator {
  12. private static Configuration configuration = null;
  13. private static Map<String, Template> allTemplates = null;
  14. static {
  15. configuration = new Configuration();
  16. configuration.setDefaultEncoding("utf-8");
  17. configuration.setClassForTemplateLoading(WordGenerator.class, "/com/lovo/ftl");
  18. allTemplates = new HashMap<>();   // Java 7 钻石语法
  19. try {
  20. allTemplates.put("resume", configuration.getTemplate("resume.ftl"));
  21. } catch (IOException e) {
  22. e.printStackTrace();
  23. throw new RuntimeException(e);
  24. }
  25. }
  26. private WordGenerator() {
  27. throw new AssertionError();
  28. }
  29. public static File createDoc(Map<?, ?> dataMap, String type) {
  30. String name = "temp" + (int) (Math.random() * 100000) + ".doc";
  31. File f = new File(name);
  32. Template t = allTemplates.get(type);
  33. try {
  34. // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
  35. Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
  36. t.process(dataMap, w);
  37. w.close();
  38. } catch (Exception ex) {
  39. ex.printStackTrace();
  40. throw new RuntimeException(ex);
  41. }
  42. return f;
  43. }
  44. }

JSP页面的代码:

[html]  view plain copy
  1. <%@ page pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8" />
  6. <title>Document</title>
  7. <style type="text/css">
  8. * { font-family: "微软雅黑"; }
  9. .textField { border:none; border-bottom: 1px solid gray; text-align: center; }
  10. #file { border:1px solid black; width: 80%; margin:0 auto; }
  11. h1 input{ font-size:72px; }
  12. td textarea { font-size: 14px; }
  13. .key { width:125px; font-size:20px; }
  14. </style>
  15. </head>
  16. <body>
  17. <form action="saveDocServlet" method="post">
  18. <div id="file" align="center">
  19. <h1><input type="text" name="title" class="textField" value="我的简历"/></h1>
  20. <hr/>
  21. <table>
  22. <tr>
  23. <td class="key">姓名:</td>
  24. <td><input type="text" name="name" class="textField"/></td>
  25. <td class="key">性别:</td>
  26. <td>
  27. <input type="radio" name="gender" value="男" checked/>男
  28. <input type="radio" name="gender" value="女" />女
  29. </td>
  30. </tr>
  31. <tr>
  32. <td class="key">联系电话:</td>
  33. <td><input type="text" name="tel" class="textField"/></td>
  34. <td class="key">家庭住址:</td>
  35. <td><input type="text" name="address" class="textField"/></td>
  36. </tr>
  37. <tr>
  38. <td colspan="4" class="key">个人简介:</td>
  39. </tr>
  40. <tr>
  41. <td colspan="4">
  42. <textarea rows="10" cols="100" name="content"></textarea>
  43. </td>
  44. </tr>
  45. </table>
  46. </div>
  47. <div align="center" style="margin-top:15px;">
  48. <input type="submit" value="保存Word文档" />
  49. </div>
  50. </form>
  51. </body>
  52. </html>

说明:小服务是使用注解进行配置的,因此你的服务器需要支持Servlet 3规范,我使用的服务器是Tomcat 7.0.52。如果你的服务器不支持Servlet 3规范那就使用web.xml来配置你的小服务吧,其他地方没有不同。如果你不熟悉Servlet 3规范的新特性,可以阅读CSDN上另一篇文章,链接如下所示:

http://blog.csdn.net/zhongweijian/article/details/8279650

此外,如果你希望在Word文档中插入图片,可以把Word另存为的XML文件中代表图片的那个很长的字符串(BASE64编码的字符串)换成一个占位符,在将要插入Word文档的图片对象转换成BASE64编码的字符串,用该字符串替换掉占位符就可以了,示意图和代码如下所示:

将图片转换成BASE64字符串的代码如下所示:

[java]  view plain copy
  1. public static String getImageString(String filename) throws IOException {
  2. InputStream in = null;
  3. byte[] data = null;
  4. try {
  5. in = new FileInputStream(filename);
  6. data = new byte[in.available()];
  7. in.read(data);
  8. in.close();
  9. } catch (IOException e) {
  10. throw e;
  11. } finally {
  12. if(in != null) in.close();
  13. }
  14. BASE64Encoder encoder = new BASE64Encoder();
  15. return data != null ? encoder.encode(data) : "";
  16. }

注意:这里使用的BASE64Encoder类在sun.misc包下,rt.jar中有这个类,但是却无法直接使用,需要修改访问权限,在Eclipse中可以这样修改。

在项目上点右键选择Properties菜单项进入如下图所示的界面:

这样设置后就可以使用BASE64Encoder类了,在项目中调用getImageString方法指定要插入的图片的完整文件名(带路径的文件名),该方法返回的字符串就是将图片处理成BASE64编码后的字符串。

Java项目中使用Freemarker生成Word文档相关推荐

  1. Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob.Apache POI.Java2Word.iText等各种方式,其实在从Office 2003开始,就 ...

  2. java web 操作word文档_Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜.基于Java的解决方式也是非常多的,包含使用Jacob.Apache POI.Java2Word.iText等各种方式,事实上在从Office 2003開始 ...

  3. Java通过POI或Freemarker生成word文档,使用Jfreechart创建统计图表

    最近做了一个使用Java生成统计分析报告word文档的功能,有提前制作好的word文档,其中共包含了普通文本变量,普通表格,动态表格.统计图表(柱状图.饼状图.折线图等),在此记录下POI和freem ...

  4. springboot中使用freemarker生成word文档并打包成zip下载(简历)

    一.设计出的简历模板图以及给的简历小图标切图         二.按照简历模板图新建简历word文件 :${字段名},同时将图片插入到word中,并将建好的word文件另存为xml文件:    三.直 ...

  5. Java通过freemarker生成word文档

    文档生成目录 摘要 项目预期效果 使用freemaker生成word文档并下载 一:导入所需要的maven依赖 二:根据word文档生成我们需要的ftl模板文件 三:将word需要的数据存入一个map ...

  6. Java使用freemarker生成word文档并转pdf文档

    Java使用freemarker生成word文档后转pdf 先来看看效果图 进入正题 项目需求: 为订单后生成对应的pdf文档,文档内包含图片. 方案一:使用freemarker和itext把html ...

  7. (详细)如何使用Freemarker生成Word文档中的文本、图片、表格、附件?

    前言-Freemarker简单介绍 近期项目工作中需要编写大量格式相同但数据不同的Word文档,需要实现自动生成文档的效果,但是通过网上冲浪和官方文档搜索,相对来说,没有分类整理的文档,因此自己抽空简 ...

  8. 使用FreeMarker生成word文档(带图片),word转pdf,预览pdf,pdf下载工具类

    一.下载或配置: 下载jar包 :freemaker的jar包下载 下载jar包 :aspose-words的jar包下载 或者配置maven依赖: pom.xml添加aspose的依赖包(maven ...

  9. 关于FreeMarker生成word文档后转换为pdf得解决方法及常见问题

    关于FreeMarker生成word文档后转换为pdf得解决方法及常见问题 最近在做一个项目要求之前下载出的word简历直接变成pdf 格式进行展现.因为格式比较复杂,所以采用的时模板并用Freema ...

最新文章

  1. 面试官:你都工作3年了,连选择排序法都不会,我怎么能选择你
  2. 基于cnn的短文本分类_基于时频分布和CNN的信号调制识别分类方法
  3. 数字采购:企业互联网新引擎
  4. 使用 VNC 无屏幕远程连接树莓派
  5. apache rewrite 规则转换 nginx rewrite 的网站
  6. 电影编码JPEG2000与H.264
  7. selenium的三种等待时间
  8. 国内手机产业混乱:产业一窝蜂 企业捞快钱
  9. MySQL免安装版 图文教程【5.7版本,纯净版win7安装】
  10. java学生信息管理系统
  11. java框架的作用_java三大框架的作用介绍
  12. 路由器设置显示服务器拒绝访问,路由器设置服务器拒绝访问
  13. 【小程序源码】游戏助手王者荣耀战力查询,游戏扫码登录器等
  14. FcaNet: Frequency Channel Attention Networks
  15. 【论文阅读笔记】faster rcnn 代码阅读细节
  16. 巧用 word 批注功能
  17. 对过去五年工作经历的总结
  18. ctf 点击1000000次
  19. GBASE数据库启动连接报908 错误
  20. Stanford cs140 Pintos Project2实验目标

热门文章

  1. android entries 变量选择,Spinner的使用(android:entries指定列表项)
  2. for循环的说课c语言,教学设计《程序的循环结构-For循环语句》
  3. idea2018破解有效期至2100年
  4. 3.5 基本属性测试
  5. 内存条 udimm rdimm 等和 ECC 功能
  6. antv g6多次渲染问题解决
  7. 【云原生】Kubernetes(k8s)Calico 客户端工具 calicoctl
  8. 华大MCU-----进入深度睡眼不能下载程序
  9. “棱镜”入侵手机App, 爱加密有效防窃听
  10. 【贪心算法】-背包问题