上一章写了导出html其实基本能满足条件,开写mht格式下的word
mhtblog.ftl
MIME-Version: 1.0
Content-Type: multipart/related; boundary="----=_NextPart_01CFAA79.4B969C00"
此文档为“单个文件网页”,也称为“Web 档案”文件。如果您看到此消息,但是您的浏览器或编辑器不支持“Web 档案”文件。请下载支持“Web 档案”的浏览器,如 Microsoft Internet Explorer。
------=_NextPart_01CFAA79.4B969C00
Content-Location: file:///C:/9FD15EF4/file8676.htm
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
xmlns:o=3D"urn:schemas-microsoft-com:office:office"
xmlns:w=3D"urn:schemas-microsoft-com:office:word"
xmlns=3D"http://www.w3.org/TR/REC-html40">
${title}
<#if category??>
博文属于:
${category}
#if>
<#if classifyName??>
博文分类标签:
${classifyName}
#if>
<#if allTagName??>
<#list allTagName as tagName>
${tagName}
#list>
#if>
${content}
BlogHandler.java
public class BlogHandler extends AppBaseAction{
private Configuration configuration = null;
public Map
public final static String TITLE = "title";
public final static String CATEGORY = "category";
public final static String CLASSIFYNAME = "classifyName";
public final static String CONTENT = "content";
public final static String ALLTAGNAME = "allTagName";
public BlogHandler() {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
}
public void createDoc(Writer out) {
//设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
//模板
configuration.setClassForTemplateLoading(this.getClass(), "/com/yuqiaotech/pms/util");
Template t=null;
try {
//test.ftl为要装载的模板
t = configuration.getTemplate("blog.ftl");
t.process(dataMap, out);
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//模板
private String generateTemp(String str) {
configuration.setClassForTemplateLoading(this.getClass(), "/com/yuqiaotech/pms/util");
Template t = null;
String htmlStr = "";
try {
t = configuration.getTemplate(str);
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
t.setEncoding("UTF-8");
t.process(dataMap, writer);
htmlStr = stringWriter.toString();
writer.flush();
writer.close();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return htmlStr;
}
/*
* 标签src替换为加上域名的链接
*/
public String exchangeImg(String content){
String regex = "]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
String src = "";
String scheme = getRequest().getScheme() + "://"
+ getRequest().getServerName() + ":" + getRequest().getServerPort();
//避免重复的图片链接
HashSet
while (matcher.find()) {
src = matcher.group(1);
set.add(src);
}
for(String str : set) {
if(str.contains(scheme)){
continue;
}
content = content.replace(str, scheme+str);
}
return content;
}
/*
* 去除fontfamily默认为宋体字
*
*/
public String setFamily(String content){
String regex = "font-family.*?;";
content = content.replaceAll(regex, "");
return content;
}
/*
*
* ==>
*
*/
public String exImageToD(String content) throws FileNotFoundException, IOException {
String regex = "]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";
content = content.replaceAll("(style=)","$13D");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
String src = "";
String[] sp;
File file = null;
while (matcher.find()){
src = matcher.group(1);
sp = src.split("/");
file = new File(getRequest().getRealPath("/")+src.replace(getRequest().getContextPath(), ""));
if(isExitsImage(file)) {
content = content.replaceFirst(regex, appendShap(getImageSize(file),sp[sp.length-1]));
}
}
return content;
}
//根据内容获取图片链接
public List
String regex = "]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
String src = "";
List
while (matcher.find()){
src = matcher.group(1);
srcs.add(src);
}
return srcs;
}
//获得图片的base64码
public String getImageBase(String src) {
File file = new File(getRequest().getRealPath("/")+src.replace(getRequest().getContextPath(), ""));
if(!isExitsImage(file)) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
public boolean isExitsImage(File file) {
return file.exists();
}
private String appendShap(BufferedImage image,String str){
String shape = "
+ "
+ "
return shape;
}
private BufferedImage getImageSize(File image) throws FileNotFoundException, IOException {
return ImageIO.read(new FileInputStream(image));
}
这里面要注意的一个问题是type=3D\"#_x0000_t75\ 这是一定要加上的不然在2003中能看到图片,到了2007中就看不到了
action
public void exportBlog() throws UnsupportedEncodingException {
String title = article.getTitle();
getResponse().addHeader(
"Content-Disposition",
"attachment;filename="
+ new String(title.getBytes("GBK"), "iso-8859-1")
+ ".doc");
getResponse().setContentType("application/x-download");// 设置为下载application/x-download
getResponse().setCharacterEncoding("utf-8");
PrintWriter output = null;
try {
output = getResponse().getWriter();
BlogHandler handler = new BlogHandler();
handler.dataMap.put(BlogHandler.TITLE, article.getTitle());
handler.dataMap.put(BlogHandler.CATEGORY, article.getCategory());
handler.dataMap.put(BlogHandler.CLASSIFYNAME,
article.getClassifyName());
handler.dataMap.put(BlogHandler.CONTENT,
handler.exImageToD(article.getContent()));
String hql = "select tagName from TagMark where entityType='Blog' and relateEntityId = "
+ articleId;
List
if(alltagName.size() > 0){
handler.dataMap.put(BlogHandler.ALLTAGNAME, alltagName);
}
List
Map
List
应该代码很明确了,我再简单说一下思路,首先从数据库中获取带css样式的content,并且content包含img,然后利用freemark生成预定的模板,将数据填充进去,而mht是携带base64格式图片的,所以这里必须进行一个转码,然后就可以生成word了,思路应该挺简单的,就是需要对图片链接进行一个处理就行了。下一章介绍导出pdf