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

java 导出word使用wps可以打开microsoft word无法打开的问题 将我原本的代码直接后缀改为doc导出失败 因为版本不匹配,以下为解决流程:1、重新去用微软的word工具 打开导出模版为2023xml;2、将导出docx改为doc,然后成功打开;// 配置FreeMarker// 设置模板目录// 加载模板// 准备填充的数据// 这里的"variableName"是在XML模板中定义的变量名// 生成Word文档。 阅读详情

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

工具类的代码:

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

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规范的新特性,可以阅读优快云上另一篇文章,链接如下所示:

http://blog.youkuaiyun.com/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编码后的字符串。但愿你按照上面的步骤一次成功!吐舌头

Openharmony 命令行工具hdc的获取与安装 OpenHarmony实战:命令行工具hdc安装应用指南_hdc工具-优快云博客t=N7T8。 阅读详情

相关推荐

【SoloPi】SoloPi使用2-功能使用,录制回放

Soloπ是什么 Soloπ是一个无线化、非侵入式的Android自动化工具,公测版拥有录制回放、性能测试、一机多控三项主要功能,能为测试开发人员节省宝贵时间。 录制回放功能 Soloπ拥有录制操作的能力,用户只需要通过Soloπ执行用例步骤,Soloπ就能够将用户的操作记录下来,并且支持在各个设备上进行回放,这一切都能够在手机上独立完成。 ...

q_Catherine的博客 5829

点击按钮往word文件中固定地方添加数据库数据再下载

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

ct637337的博客 1268

保姆级教程:用Cadence Sigrity Power DC搞定HI3516A板卡电源压降仿真(含常见报错解决)

本文提供了一份详细的Cadence Sigrity Power DC直流压降仿真教程,特别针对HI3516A板卡设计。从环境准备、器件建模到仿真执行和结果解读,全面覆盖了电源完整性分析的关键步骤,并提供了常见报错的解决方案,帮助工程师快速掌握直流压降分析技术。

weixin_42569329的博客 323

Windows Embedded Standard开发初体验(一)

Windows Embedded Standard,微软又创造了一个新名词。与此同时,XP Embedded,成为了一个历史名词。微软在年初推出了新的Windows Embedded产品线命名规则:Windows CE改名为Windows Embedded Compact,而XP Embedded改名为Windows Embedded Standard,WEPOS改名为Windows Embedd...

编程开发资料库 1709

dify离线部署

以bge-m3为例,本地部署bge-m3首先在一台能连网的linux服务器上(部署有ollama)创建想要保存模型的文件夹编辑ollama.service,配置ollama模型的保存路径添加模型存储地址将models目录设置属主,必须做,否则ollama无法启动重新加载配置文件并重启ollama测试ollama 运行是否正常最后拉取 bge-m3可在/opt/LLMModels/bge_m3/models目录下看到拉取得模型使用tar命令压缩文件夹。

weixin_42538734的博客 3070

基于yolov5的鸟类图像准确识别

本项目主要基于yolov5进行鸟类准确识别,主要识别白鹭家族,红脚鹬,反嘴鹬,环颈珩,小白鹭以及夜鹭六类鸟

weixin_46064184的博客 3823

java接口下载office文件报错,word发现无法读取的内容

问题描述: 项目通过java接口来下载文件,发现下载office文件时,打开都不正常,比如下载office文件打开会报“word在 XX.docx发现无法读取的内容。是否恢复此文档的内容”。但如果通过nginx映射来下载,可以正常打开。 解决方法: 研究后发现,是因为没有设置Content-Type,其实每种office文件都有对应的Content-Type。可参考:https://www.jianshu.com/p/4b09c260f9b2?from=groupmessage 修改后的代码如下:.

qq_15068711的博客 5196

手把手教你用Foobar2000播放DSD音频(含DOP设置与SPDIF输出教程)

本文详细指导如何在Foobar2000中播放DSD音频,重点解析了DOP协议的原理与设置方法。通过安装SACD插件、配置输出设备及启用DOP模式,实现DSD音频的原生比特流输出,并特别讲解了如何通过SPDIF接口传输DSD信号,帮助发烧友充分释放高清音频设备的潜力。

weixin_29290963的博客 1824

JAVA利用Freemarker模版动态生成并导出Word文档(全网最详细)

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

qq_45087487的博客 1万+

STM32 CubeMX实战:手把手教你用I2C驱动IST8310磁力计(附完整代码)

本文详细介绍了如何使用STM32 CubeMX和I2C驱动IST8310磁力计,从硬件连接到代码实现的完整流程。重点讲解了I2C通信异常处理、传感器初始化序列优化以及中断驱动数据采集方案,帮助开发者快速搭建可靠的地磁场数据采集系统。

weixin_42531163的博客 189

AMESim柱塞泵建模全指南:从HCD库搭建到联合仿真

液压系统仿真中,轴向柱塞泵的建模始终是难点与热点。柱塞泵结构紧凑、功率密度高,在工程机械与航空航天领域应用广泛,然而其运动学与流体细节深度耦合,给仿真带来不小挑战。AMESim平台中的HCD库提供了一种从物理结构出发的建模思路,将柱塞泵分解为容积腔、节流口与机械约束等基础单元,从而真实刻画柱塞腔压力波动、配流特性和容积效率等关键行为,摆脱黑盒模型的局限。基于机理建模的仿真结果,可用于泵参数优化、故障特征分析以及控制策略验证。进一步结合AMESim与Simulink联合仿真,可以高效开发变量泵排量控制系统,研

weixin_29159441的博客 289

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

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

weixin_42512798的博客 2813

2025爬虫实战:某音直播间实时弹幕获取原理及源码分析

某音直播弹幕虽然没有直接挂在 DOM 上,但由于用的是西瓜播放器,弹幕是通过 JS 接口动态渲染的,这就给了我们 Hook 的机会。关键点是找到调用的位置,然后拦截并输出对象里的message字段。这个思路其实也适用于其他前端渲染的播放器,比如 B 站的 DPlayer、HLS.js、甚至很多自研播放器都有类似结构。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1814

Java Web项目中使用Freemarker生成Word文档遇到的问题

这段时间项目中使用了freemarker生成word文档。在项目中遇到了几个问题,在这里记录一下。首先就是关于遍历遇到的坑。整行整行的遍历是很简单的,只需要在整行的<w:tr></w:tr>的标签钱加上遍历的<#list list as list> </#list>就行了。我在这里要说的是前面还有合并单元格的时候的情况。如下图,水泥路面和沥青路面这...

weixin_33720956的博客 603

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java Web项目中使用Freemarker模版生成Word文档

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

w2393040183的专栏 780

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java Web项目中利用FreeMarker模板生成的word文档,其它格式文档同理,如pdf,txt,java,xml等等

利用FreeMarker模板生成的word文档,其它格式文档同理,如pdf,txt,java,xml等等 需要向项目中加入freemarker的JAR文件,可以通过下面的链接获得Freemarker的最新版本: http://freemarker.org/freemarkerdownload.html 实现思路如下: 1、把要生成的模板文件填入freemarker的占位字段

QC班长的博客 4627

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

使用freemarker生成word文档

1、需要下载freemarker相关jar包   在web项目下可以通过以下方式来生成word package com.jieyuechina.test; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; ...

zwl19860911的专栏 153

Java Web项目中使用freemarker操作flt生成带图片(base64)的Word文档

这是我在实际开发中的一个小案例,仅供参考,freemarker操作ftl ,ftl中的图片必须是黑乎乎的base64编码格式 其它直接 用${}动态替换即可,参考http://blog.youkuaiyun.com/jackfrued/article/details/39449021 freemaker替换图片的代码:

香帅的博客 8084
上一篇: spring结合redis如何实现数据的缓存
下一篇: HashMap实现原理
木木那年
博客等级 码龄12年 37粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值