廢話不多說,進入正題!
本文重點在於:對富文本圖片的導出(基礎的freemarker+word模板導出這里不做詳細解說哈)
參考文章:http://www.cnblogs.com/liaofeifight/p/5484891.html
(ps:大神的東西太深奧~~懵逼了
一周才搞定,為了方便后來在更加簡單,清晰的學習,樓主寫下這篇博客,感謝大神給了我個完善和進步的機會,也希望后來在繼續完善)
先說一下思路:由於我們是要用word來解析帶圖片的富文本(說白了就是解析一段html,當然這段html代碼是包含img標簽:圖片),so...傳統的word模板導出(word另存為xml,在修改后綴為ftl)是行不通的,因為他解析不了html代碼(至少我目前沒有找到這方便的解決方案,大神勿噴~),這樣的話我就要換用一種模板來處理這個模板:word模板另存為mht格式,再修改后綴為ftl。剩下的就是后台操作了,找到你存富文本的字段(html代碼)獲取里面的img標簽,找到圖片,並把圖片解析為base64字符串,填充到我們只做的模板上就ok了,大體思路就這樣了
一、模板制作(這個很重要)
提示:這里模板用office word來做,不要用wps
創建word文件:,我這里用第二個content來顯示我們要的富文本,然后將我們的word文件另存為mht文件,
最后我們就拿到我們要的mht模板了,這僅僅是個開始...各位看官往下看
打開我們的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了(模板處理到此結束)
二、解析html
這個大家不陌生吧?陌生的自己打臉去,下面的那三個我依然懵逼
handler.handledHtml(false);
String bodyBlock = handler.getHandledDocBodyBlock();
data.put("content", bodyBlock); 處理后的html代碼塊
data.put("imagesXmlHrefString", xmlimaHref);
data.put("imagesBase64String", handledBase64Block); 這兩個大家還有印象吧?沒錯就是我們之前手動在mht模板里加的那兩貨!
三、填充模板
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(帶富文本圖的喲)
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); } }
五、測試(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"這個也是一樣的
各位看官!搞懂這個是不是覺得單純的圖片導出太簡單了哇 哈哈(話說我還沒用過單純的圖片導出)
demo源碼:https://pan.baidu.com/s/1bpj2mCn