糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > Java项目中使用Freemarker生成Word文档

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

时间:2018-11-11 05:55:19

相关推荐

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

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

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

打开下载的Word文件

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

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

/freemarkerdownload.html

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

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

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

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

小服务的代码:

[java]view plain copypackagecom.lovo.servlet; importjava.io.File; importjava.io.FileInputStream; importjava.io.IOException; importjava.io.InputStream; importjava.util.Enumeration; importjava.util.HashMap; importjava.util.Map; importjavax.servlet.ServletException; importjavax.servlet.ServletOutputStream; importjavax.servlet.annotation.WebServlet; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importcom.lovo.util.WordGenerator; /** *ServletimplementationclassMyServlet */ @WebServlet("/saveDocServlet") publicclassMyServletextendsHttpServlet{ privatestaticfinallongserialVersionUID=1L; @Override protectedvoidservice(HttpServletRequestreq,HttpServletResponseresp) throwsServletException,IOException{ req.setCharacterEncoding("utf-8"); Map<String,Object>map=newHashMap<String,Object>(); Enumeration<String>paramNames=req.getParameterNames(); //通过循环将表单参数放入键值对映射中 while(paramNames.hasMoreElements()){ Stringkey=paramNames.nextElement(); Stringvalue=req.getParameter(key); map.put(key,value); } //提示:在调用工具类生成Word文档之前应当检查所有字段是否完整 //否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错这里暂时忽略这个步骤了 Filefile=null; InputStreamfin=null; ServletOutputStreamout=null; try{ //调用工具类WordGenerator的createDoc方法生成Word文档 file=WordGenerator.createDoc(map,"resume"); fin=newFileInputStream(file); resp.setCharacterEncoding("utf-8"); resp.setContentType("application/msword"); //设置浏览器以下载的方式处理该文件默认名为resume.doc resp.addHeader("Content-Disposition","attachment;filename=resume.doc"); out=resp.getOutputStream(); byte[]buffer=newbyte[512];//缓冲区 intbytesToRead=-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();//删除临时文件 } } }

工具类的代码:

[java]view plain copypackagecom.lovo.util; importjava.io.File; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.OutputStreamWriter; importjava.io.Writer; importjava.util.HashMap; importjava.util.Map; importfreemarker.template.Configuration; importfreemarker.template.Template; publicclassWordGenerator{ privatestaticConfigurationconfiguration=null; privatestaticMap<String,Template>allTemplates=null; static{ configuration=newConfiguration(); configuration.setDefaultEncoding("utf-8"); configuration.setClassForTemplateLoading(WordGenerator.class,"/com/lovo/ftl"); allTemplates=newHashMap<>();//Java7钻石语法 try{ allTemplates.put("resume",configuration.getTemplate("resume.ftl")); }catch(IOExceptione){ e.printStackTrace(); thrownewRuntimeException(e); } } privateWordGenerator(){ thrownewAssertionError(); } publicstaticFilecreateDoc(Map<?,?>dataMap,Stringtype){ Stringname="temp"+(int)(Math.random()*100000)+".doc"; Filef=newFile(name); Templatet=allTemplates.get(type); try{ //这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 Writerw=newOutputStreamWriter(newFileOutputStream(f),"utf-8"); t.process(dataMap,w); w.close(); }catch(Exceptionex){ ex.printStackTrace(); thrownewRuntimeException(ex); } returnf; } }

JSP页面的代码:

[html]view plain copy<%@pagepageEncoding="UTF-8"%> <!DOCTYPEhtml> <html> <head> <metacharset="UTF-8"/> <title>Document</title> <styletype="text/css"> *{font-family:"微软雅黑";} .textField{border:none;border-bottom:1pxsolidgray;text-align:center;} #file{border:1pxsolidblack;width:80%;margin:0auto;} h1input{font-size:72px;} tdtextarea{font-size:14px;} .key{width:125px;font-size:20px;} </style> </head> <body> <formaction="saveDocServlet"method="post"> <divid="file"align="center"> <h1><inputtype="text"name="title"class="textField"value="我的简历"/></h1> <hr/> <table> <tr> <tdclass="key">姓名:</td> <td><inputtype="text"name="name"class="textField"/></td> <tdclass="key">性别:</td> <td> <inputtype="radio"name="gender"value="男"checked/>男 <inputtype="radio"name="gender"value="女"/>女 </td> </tr> <tr> <tdclass="key">联系电话:</td> <td><inputtype="text"name="tel"class="textField"/></td> <tdclass="key">家庭住址:</td> <td><inputtype="text"name="address"class="textField"/></td> </tr> <tr> <tdcolspan="4"class="key">个人简介:</td> </tr> <tr> <tdcolspan="4"> <textarearows="10"cols="100"name="content"></textarea> </td> </tr> </table> </div> <divalign="center"style="margin-top:15px;"> <inputtype="submit"value="保存Word文档"/> </div> </form> </body> </html>

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

/zhongweijian/article/details/8279650

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

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

[java]view plain copypublicstaticStringgetImageString(Stringfilename)throwsIOException{ InputStreamin=null; byte[]data=null; try{ in=newFileInputStream(filename); data=newbyte[in.available()]; in.read(data); in.close(); }catch(IOExceptione){ throwe; }finally{ if(in!=null)in.close(); } BASE64Encoderencoder=newBASE64Encoder(); returndata!=null?encoder.encode(data):""; }

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

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

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

如果觉得《Java项目中使用Freemarker生成Word文档》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。