代码生成器 freemakerr生成的邮件中 为什么图片没有显示

FreeMarker使用说明 + 附件图片[来钦波个人总结] - Web前端当前位置:& &&&FreeMarker使用说明 + 附件图片[来钦波个人总结]FreeMarker使用说明 + 附件图片[来钦波个人总结]&&网友分享于:&&浏览:22次FreeMarker使用说明 + 附件图片[回钦波个人总结]
FreeMarker使用说明关键字: freemarker FrFreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 l FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 l 虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图) l FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件 l FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境 l FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库 l FreeMarker是免费的 1、通用目标 l 能够生成各种文本:HTML、XML、RTF、Java源代码等等 l 易于嵌入到你的产品中:轻量级;不需要Servlet环境 l 插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等 l 你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器 2、强大的模板语言 l 所有常用的指令:include、if/elseif/else、循环结构 l 在模板中创建和改变变量 l 几乎在任何地方都可以使用复杂表达式来指定值 l 命名的宏,可以具有位置参数和嵌套内容 l 名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突 l 输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换 3、通用数据模型 l FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示 l 你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰 4、为Web准备 l 在模板语言中内建处理典型Web相关任务(如HTML转义)的结构 l 能够集成到Model2 Web应用框架中作为JSP的替代 l 支持JSP标记库 l 为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员 5、智能的国际化和本地化 l 字符集智能化(内部使用UNICODE) l 数字格式本地化敏感 l 日期和时间格式本地化敏感 l 非US字符集可以用作标识(如变量名) l 多种不同语言的相同模板 6、强大的XML处理能力 l &#recurse& 和&#visit&指令(2.3版本)用于递归遍历XML树 l 在模板中清楚和直觉的访问XML对象模型 FreeMarker设计指南(1) -------------------------------------------- 1、快速入门 (1)模板 + 数据模型 = 输出 l FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念 l 他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据 l 经常会遇到的问题是:在Web页面(或其它类型的文档)中显示的信息在设计页面时是无效的,是基于动态数据的 l 在这里,你可以在HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker会在输出页面给最终用户时,用适当的数据替代这些代码 l 下面是一个例子:
Welcome ${user}!
Our latest product: ${latestProduct.name}! l 这个例子是在简单的HTML中加入了一些由${…}包围的特定代码,这些特定代码是FreeMarker的指令,而包含FreeMarker的指令的文件就称为模板(Template) l 至于user、latestProduct.url和latestProduct.name来自于数据模型(data model) l 数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、文件,甚至于在程序中直接生成 l 模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型 l 下面是一个可能的数据模型: (root) | +- user = "Big Joe" | +- latestProduct | +- url = "products/greenmouse.html" | +- name = "green mouse"l 数据模型类似于计算机的文件系统,latestProduct可以看作是目录,而user、url和name看作是文件,url和name文件位于latestProduct目录中(这只是一个比喻,实际并不存在) l 当FreeMarker将上面的数据模型合并到模板中,就创建了下面的输出:
Welcome Big Joe!
Our latest product: green mouse! (2)数据模型 l 典型的数据模型是树型结构,可以任意复杂和深层次,如下面的例子: (root) | +- animals | | | +- mouse | | | | | +- size = "small" | | | | | +- price = 50 | | | +- elephant | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- python | | | +- size = "medium" | | | +- price = 4999 | +- test = "It is a test" | +- whatnot | +- because = "don't know"l 类似于目录的变量称为hashes,包含保存下级变量的唯一的查询名字 l 类似于文件的变量称为scalars,保存单值 l scalars保存的值有两种类型:字符串(用引号括起,可以是单引号或双引号)和数字(不要用引号将数字括起,这会作为字符串处理) l 对scalars的访问从root开始,各部分用“.”分隔,如animals.mouse.price l 另外一种变量是sequences,和hashes类似,只是不使用变量名字,而使用数字索引,如下面的例子: (root) | +- animals | | | +- (1st) | | | | | +- name = "mouse" | | | | | +- size = "small" | | | | | +- price = 50 | | | +- (2nd) | | | | | +- name = "elephant" | | | | | +- size = "large" | | | | | +- price = 5000 | | | +- (3rd) | | | +- name = "python" | | | +- size = "medium" | | | +- price = 4999 | +- whatnot | +- fruits | +- (1st) = "orange" | +- (2nd) = "banana"l 这种对scalars的访问使用索引,如animals[0].name (3)模板 l 在FreeMarker模板中可以包括下面三种特定部分: ? ${…}:称为interpolations,FreeMarker会在输出时用实际值进行替代 ? FTL标记(FreeMarker模板语言标记):类似于HTML标记,为了与HTML标记区分,用#开始(有些以@开始,在后面叙述) ? 注释:包含在&#--和--&(而不是&!--和--&)之间 l 下面是一些使用指令的例子: ? if指令 &#if animals.python.price & animals.elephant.price& Pythons are cheaper than elephants today.&#else& Pythons are not cheaper than elephants today. ? list指令
We have these animals:
Price &#list animals as being&
${being.name}
${being.price} Euros
输出为: Freemarker指令 | Log4J使用说明
下面附件图片:可供参考
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。FreeMarker
Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用、、Java2Word、等各种方式,其实在从Office
2003开始,就可以将Office文档转换成XML文件,这样只要将需要填入的内容放上${}占位符,就可以使用像FreeMarker这样的模板引擎将出现占位符的地方替换成真实数据,这种方式较之其他的方案要更为简单。这个功能就是由XML+FreeMarker来实现的,Word从2003开始支持XML格式,大致的步骤:用office2003或者以上的版本编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。使用Freemarker其实就只准备模板和数据。
制作resume.ftl模板
首先用office【版本要2003以上,以下的不支持xml格式】编辑文档的样式,将需要动态填充的内容使用Freemarker标签替换,将Word文档另存为XML格式(注意是另存为,不是直接改扩展名)&,建议用Editplus、Notepad++、Sublime等工具打开查看一下,因为有的时候你写的占位符可能会被拆开,这样Freemarker就无法处理了。
打开XML文件看看,如果刚才你写的${qno}、${title}等被xml文件给拆散了,修改一下XML文件就OK了
修改过后另存为resume.ftl模板文件,如下所示:
接下来修改图片,搜索w:binData
或者 png可以快速定位图片的位置,图片已经是0-F的字符串了,换成一个占位符,在将要插入Word文档的图片对象转换成BASE64编码的字符串,用该字符串替换掉占位符就可以了,示意图如下所示:
接下来就可以编码啦:
服务的代码:
@RequestMapping(value = &/demo/word&, method = RequestMethod.POST)
public void word(@RequestParam(value = &image&, required = false) MultipartFile image, ModelMap model, HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding(&utf-8&);
Map&String, Object& map =
Enumeration&String& paramNames = req.getParameterNames();
// 通过循环将表单参数放入键值对映射中
/*while (paramNames.hasMoreElements()) {
String key = paramNames.nextElement();
String value = req.getParameter(key);
map.put(key, value);
InputStream in = image.getInputStream();
String reportImage = WordGenerator.getImageString(in);
String jsonStr = &{\&exam\&: [{\&ecnt\&: 4,\&eid\&: \&25\&,\&options\&: [{\&choice\&: \&3\&,\&option\&: \&男\&,\&rowratio\&: \&75.00%\&}, {\&choice\&: \&1\&,\&option\&: \&女\&,\&rowratio\&: \&25.00%\&}],\&qno\&: \&3\&,\&title\&: \&你的性别是\&,\&types\&: \&单选题\&}]}&;
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
List exams = jsonObject.getJSONArray(&exam&);
List&Map&String, Object&& arrayList = new ArrayList&Map&String, Object&&();
for (int i = 0; i & exams.size(); i++) {
map = new HashMap&String, Object&();
JSONObject exam = (JSONObject) exams.get(i);
map.put(&ecnt&, exam.get(&ecnt&));
map.put(&eid&, exam.get(&eid&));
map.put(&qno&, exam.get(&qno&));
map.put(&title&, exam.get(&title&));
map.put(&types&, exam.get(&types&));
map.put(&reportImage&, reportImage);
List&Map&String, String&& options = (List) exam.getJSONArray(&options&);
List&Map&String, Object&& optionList = new ArrayList&Map&String, Object&&();
for (Map tempMap : options) {
Map optionMap = new HashMap&String, Object&();
optionMap.put(&choice&, tempMap.get(&choice&));
optionMap.put(&option&, tempMap.get(&option&));
optionMap.put(&rowratio&, tempMap.get(&rowratio&));
optionList.add(optionMap);
map.put(&options&, optionList);
arrayList.add(map);
// 提示:在调用工具类生成Word文档之前应当检查所有字段是否完整
// 否则Freemarker的模板殷勤在处理时可能会因为找不到值而报错 这里暂时忽略这个步骤了
File file =
InputStream fin =
OutputStream out =
// 调用工具类WordGenerator的createDoc方法生成Word文档
Map root = new HashMap&String, Object&();
root.put(&questTitle&, &测试word导出&);
root.put(&exams&, arrayList);
file = WordGenerator.createDoc(root, &resume&);
fin = new FileInputStream(file);
resp.setCharacterEncoding(&utf-8&);
resp.setContentType(&application/ms-charset=utf-8&);
// 设置浏览器以下载的方式处理该文件默认名为resume.doc
resp.addHeader(&Content-Disposition&, &filename=resume.doc&);
out = resp.getOutputStream();
// 写出流信息
/* while ((len = fs.read()) != -1) {
os.write(len);
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(); // 删除临时文件
}工具类的代码:
import java.io.F
import java.io.FileOutputS
import java.io.IOE
import java.io.InputS
import java.io.OutputStreamW
import java.io.W
import java.util.HashM
import java.util.M
import freemarker.template.C
import freemarker.template.T
import sun.misc.BASE64E
public class WordGenerator {
private static Configuration configuration =
private static Map&String, Template& allTemplates =
configuration = new Configuration();
configuration.setDefaultEncoding(&utf-8&);
configuration.setClassForTemplateLoading(WordGenerator.class, &/cn/comm/ftl&);
allTemplates = new HashMap&&(); // Java 7 钻石语法
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);
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), &utf-8&);
t.process(dataMap, w);
w.flush();
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
//将图片转换成BASE64字符串
public static String getImageString(InputStream in) throws IOException {
//InputStream in =
byte[] data =
// in = new FileInputStream(filename);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
} finally {
if (in != null)
in.close();
BASE64Encoder encoder = new BASE64Encoder();
return data != null ? encoder.encode(data) : &&;
}jsp代码:
&%@ page pageEncoding=&UTF-8&%&
&!DOCTYPE html&
&meta charset=&UTF-8& /&
&title&Document&/title&
&style type=&text/css&&
* { font-family: &微软雅黑&; }
.textField { border: border-bottom: 1 text-align: }
#file { border:1 width: 80%; margin:0 }
h1 input{ font-size:72 }
td textarea { font-size: 14 }
.key { width:125 font-size:20 }
&form action=&/mybase/demo/word& method=&post& enctype=&multipart/form-data&&
&div id=&file& align=&center&&
&h1&&input type=&text& name=&title& class=&textField& value=&测试word导出&/&&/h1&
&td colspan=&4&&
&input type=&file& name=&image& /&
&div align=&center& style=&margin-top:15&&
&input type=&submit& value=&保存Word文档& /&
注意:这里使用的BASE64Encoder类在sun.misc包下,rt.jar中有这个类,但是却无法直接使用,需要修改访问权限,在Eclipse中可以这样修改。
在项目上点右键选择Properties菜单项进入如下图所示的界面:
这样设置后就可以使用BASE64Encoder类了,在项目中调用getImageString方法指定要插入的图片的完整文件名(带路径的文件名),该方法返回的字符串就是将图片处理成BASE64编码后的字符串。
到这里就可以导出一个复杂的带表格,图片的wors文档啦。导出来就是这样的,如下图:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1570次
排名:千里之外
(1)(1)(1)(4)(4)2015年2月 总版技术专家分月排行榜第二
2015年2月 Web 开发大版内专家分月排行榜第一2015年1月 Web 开发大版内专家分月排行榜第一2014年12月 Web 开发大版内专家分月排行榜第一2014年11月 Web 开发大版内专家分月排行榜第一2014年10月 Web 开发大版内专家分月排行榜第一
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。FreeMarker之生成复杂word(包含图片)-中国学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
FreeMarker之生成复杂word(包含图片)
来源:互联网 更新时间: 17:30:40 责任编辑:鲁晓倩字体:
/java/10228.html
http://blog.csdn.net/woshizhangliang999/article/details/
相关文章:
上一篇文章:下一篇文章:
最新添加资讯
24小时热门资讯
Copyright © 2004- All Rights Reserved. 中国学网 版权所有
京ICP备号-1 京公网安备02号

我要回帖

更多关于 代码生成器 freemaker 的文章

 

随机推荐