废话很少说,进入正题!html
本文重点在于:对富文本图片的导出(基础的freemarker+word模板导出这里不作详细解说哈)java
参考文章:http://www.cnblogs.com/liaofeifight/p/5484891.htmlapp
(ps:大神的东西太深奥~~懵逼了学习
一周才搞定,为了方便后来在更加简单,清晰的学习,楼主写下这篇博客,感谢大神给了我个完善和进步的机会,也但愿后来在继续完善)测试
先说一下思路:因为咱们是要用word来解析带图片的富文本(说白了就是解析一段html,固然这段html代码是包含img标签:图片),so...传统的word模板导出(word另存为xml,在修改后缀为ftl)是行不通的,由于他解析不了html代码(至少我目前没有找到这方便的解决方案,大神勿喷~),这样的话我就要换用一种模板来处理这个模板:word模板另存为mht格式,再修改后缀为ftl。剩下的就是后台操做了,找到你存富文本的字段(html代码)获取里面的img标签,找到图片,并把图片解析为base64字符串,填充到咱们只作的模板上就ok了,大致思路就这样了ui
1、模板制做(这个很重要)spa
提示:这里模板用office word来作,不要用wps3d
建立word文件:,我这里用第二个content来显示咱们要的富文本,而后将咱们的word文件另存为mht文件,code
最后咱们就拿到咱们要的mht模板了,这仅仅是个开始...各位看官往下看orm
打开咱们的mht文件并处理:在咱们的文件里面找到下面这些东西,若是没有找到呢?....这个问题,我就只有呵呵了
${imagesBase64String} 和 ${imagesXmlHrefString}这两个是咱们手动加进去的,简析富文本图片的核心就在这里(反正我也是蒙的~)
全文检索gb2312把他改为utf-8,同时须要加上3D前缀,对应着格式来改 通常就这两种:
<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">和Content-Type: text/html; charset=3D"utf-8"
提示:全部的都要改为utf-8(你不改也是能够的)
而后保存一下,再把文件的后缀名改为ftl格式的就ok了(模板处理到此结束)
2、解析html
这个你们不陌生吧?陌生的本身打脸去,下面的那三个我依然懵逼
handler.handledHtml(false);
String bodyBlock = handler.getHandledDocBodyBlock();
data.put("content", bodyBlock); 处理后的html代码块
data.put("imagesXmlHrefString", xmlimaHref);
data.put("imagesBase64String", handledBase64Block); 这两个你们还有印象吧?没错就是咱们以前手动在mht模板里加的那两货!
3、填充模板
String docFilePath = "d:\\temp.doc"; System.out.println(docFilePath); File f = new File(docFilePath); OutputStream out; try { out = new FileOutputStream(f); WordGeneratorWithFreemarker.createDoc(data, "temp.ftl", out); } catch (FileNotFoundException e) { } catch (MalformedTemplateNameException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
4、导出word(带富文本图的哟)
public static void createDoc(Map<String, Object> dataMap,String templateName, OutputStream out)throws Exception { Template t = configuration.getTemplate(templateName); t.setEncoding("utf-8"); WordHtmlGeneratorHelper.handleAllObject(dataMap); try { Writer w = new OutputStreamWriter(out,Charset.forName("utf-8")); t.process(dataMap, w); w.close(); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } }
5、测试(main)
public static void main(String[] args) throws Exception { HashMap<String, Object> data = new HashMap<String, Object>(); StringBuilder sb = new StringBuilder(); sb.append("<div>"); sb.append("<img style='height:100px;width:200px;display:block;' src='F:\\aaa.png' />"); sb.append("<img style='height:100px;width:200px;display:block;' src='F:\\bbb.png' />"); sb.append("</br><span>中国梦,幸福梦!</span>"); sb.append("</div>"); RichHtmlHandler handler = new RichHtmlHandler(sb.toString()); handler.setDocSrcLocationPrex("file:///C:/8595226D"); handler.setDocSrcParent("file3405.files"); handler.setNextPartId("01D214BC.6A592540"); handler.setShapeidPrex("_x56fe__x7247__x0020"); handler.setSpidPrex("_x0000_i"); handler.setTypeid("#_x0000_t75"); handler.handledHtml(false); String bodyBlock = handler.getHandledDocBodyBlock(); System.out.println("bodyBlock:\n"+bodyBlock); String handledBase64Block = ""; if (handler.getDocBase64BlockResults() != null && handler.getDocBase64BlockResults().size() > 0) { for (String item : handler.getDocBase64BlockResults()) { handledBase64Block += item + "\n"; } } data.put("imagesBase64String", handledBase64Block); String xmlimaHref = ""; if (handler.getXmlImgRefs() != null && handler.getXmlImgRefs().size() > 0) { for (String item : handler.getXmlImgRefs()) { xmlimaHref += item + "\n"; } } data.put("imagesXmlHrefString", xmlimaHref); data.put("name", "张三"); data.put("content", bodyBlock); String docFilePath = "d:\\temp.doc"; System.out.println(docFilePath); File f = new File(docFilePath); OutputStream out; try { out = new FileOutputStream(f); WordGeneratorWithFreemarker.createDoc(data, "temp.ftl", out); } catch (FileNotFoundException e) { } catch (MalformedTemplateNameException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
查看结果:
到此~导出word带富文本图片的功能就借宿了,详细代码我放在附件里面(这里着重讲mht模板的一些改动,处理富文本的java代码我就没有单独贴出来了哈,demo里面有哦)
有完整的demo,你们放心不会像我同样懵逼一周了 哈哈
开玩笑的~!话说我从开始到完整的作出来 仍是花了5天左右的时间,
再次感谢参考的文章:http://www.cnblogs.com/liaofeifight/p/5484891.html
最后在再给你们扩展一下:一个word 出现多个富文本,而且每一个富文本有多个图片的思路:
String old_handledBase64Block = ""; if(data.containsKey("imagesBase64String")){ old_handledBase64Block = (String) data.get("imagesBase64String"); handledBase64Block = old_handledBase64Block + handledBase64Block; } data.put("imagesBase64String", handledBase64Block);
简单说一下 ,其实就是在处理下一个富文本的时候 要拿到上一个富文本里面处理中的"imagesBase64String" 再把它累加起来,
否则后面的会给前面的覆盖掉~"imagesXmlHrefString"这个也是同样的
各位看官!搞懂这个是否是以为单纯的图片导出太简单了哇 哈哈(话说我还没用过单纯的图片导出)