博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java导出富文本到word
阅读量:6921 次
发布时间:2019-06-27

本文共 5347 字,大约阅读时间需要 17 分钟。

hot3.png

源码地址:

github:

gitosc:

背景

最近用java开发一个中车项目管理系统,里面有一个维修单word导出功能。

可用方案

在网上查找资料,总结出两种比较可行的方案。

(1) 制作word模板,导出成mht文件(单页面网页格式),然后往模板里渲染数据,最终生成word文档。

(2) 制作word模板,导出成xml文件,然后往模板里渲染数据,最终生成word文档。

两种都是采用模板的思想,比用poi去组织word格式简单的很多很多。不同点在于导出文件的格式不同,一个是mht文件,一个是xml文件。考虑到本项目中的维修单个别字段采用了富文本编辑器实现,保存进数据库中是html格式的字符串,所以采用第一种方案,即通过mht文件来实现。

实现思路

由于我们是要用word来解析带图片的富文本(说白了就是解析一段html,当然这段html代码是包含img标签:图片),so...传统的word模板导出(word另存为xml,在修改后缀为ftl)是行不通的,因为他解析不了html代码(至少我目前没有找到这方便的解决方案,大神勿喷~),这样的话我就要换用一种模板来处理这个模板:word模板另存为mht格式,再修改后缀为ftl。剩下的就是后台操作了,找到你存富文本的字段(html代码)获取里面的img标签,找到图片,并把图片解析为base64字符串,填充到我们只做的模板上就ok了。

实现步骤及注意事项

创建mht模板

根据模板引擎的语法规则填入占位符制作word模板,保存为mht文件。eg:

然后打开mht文件,在mht文件中插入图片资源的base64及xml 的href引用的占位。如下图:

${imagesBase64String} 和 ${imagesXmlHrefString}这两个是我们手动加进去的,这也是解析富文本的关键所在。

由于mht文件是采用的是“us-ascii”编码,属性后面都必须带有3D前缀。所以包含html内容的需进行一下替换操作。

全文检索gb2312把他改成utf-8,同时需要加上3D前缀,对应着格式来改 一般就这两种:

<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">

Content-Type: text/html; charset=3D"utf-8"

处理数据

一般的属性数据组织起来简单,无非就是从数据库中获取,处理也简单。现在模拟一个富文本的数据

//用map存放数据    HashMap
data = new HashMap
(); //创建富文本 StringBuilder sb = new StringBuilder(); sb.append("
"); sb.append("
"); sb.append("
wesley 演示 导出富文本!@@#######¥¥%%%%………………&&&**~~~~~~&&&&&&&&、、、、、、、、"); sb.append("
----多图分割线---"); sb.append("
"); sb.append("
中国梦,幸福梦!"); sb.append("
"); RichObject richObject = new RichObject(); richObject.setHtml(sb.toString()); //--------------------此处可以spring配置文件配置,也可以直接读取属性文件获取------------------ //从mht文件中找 richObject.setDocSrcLocationPrex("file:///C:/268D4AA4"); //这里是从mht中获取的资源文件所在的文件夹 richObject.setDocSrcParent("word.files"); //资源文件夹名字 richObject.setNextPartId("01D2C8DD.BC13AF60"); //下一部分的ID //以下三个属性字段我也不是很懂 查询网上是这么用的 不过根据字段应该大致能猜到是做什么用的。 richObject.setShapeidPrex("_x56fe__x7247__x0020"); richObject.setTypeid("#_x0000_t75"); richObject.setSpidPrex("_x0000_i"); richObject.setWebAppliction(false); //这里封装了一个Hnadler处理对象,来处理数据。 RichHtmlHandler richHtmlHandler = WordGeneratorWithFreemarker.createRichHtmlHandler(richObject); List
richHtmlHandlerList = new ArrayList
(); richHtmlHandlerList.add(richHtmlHandler); //这里就是我们刚才加的两个字段,也是我们富文本文件处理的关键两个字段 data.put("imagesXmlHrefString", WordGeneratorWithFreemarker.getXmlImgHref(richHtmlHandlerList));// logger.debug("------imagesXmlHrefString-------"+WordGeneratorWithFreemarker.getXmlImgHref(richHtmlHandlerList)); data.put("imagesBase64String", WordGeneratorWithFreemarker.getImagesBase64String(richHtmlHandlerList)); logger.debug("------imagesBase64String-------"+WordGeneratorWithFreemarker.getImagesBase64String(richHtmlHandlerList)); data.put("name", "wesley"); data.put("datetime","2017-05-10"); data.put("title","演示demo"); data.put("context1", richHtmlHandler.getHandledDocBodyBlock()); data.put("context2", richHtmlHandler.getHandledDocBodyBlock()); data.put("context3", richHtmlHandler.getHandledDocBodyBlock()); data.put("context4", richHtmlHandler.getHandledDocBodyBlock()); data.put("context5", richHtmlHandler.getHandledDocBodyBlock()); data.put("context6", richHtmlHandler.getHandledDocBodyBlock());

渲染模板

String docFilePath = "w:\\temp_by_wesley.doc";//目标文件    String templatePath = Class.class.getResource("/ftl").getPath();    templatePath = java.net.URLDecoder.decode(templatePath,"utf-8");//这里我的路径有空格添加此处理    logger.debug("------templatePath-------"+templatePath);    WordGeneratorWithFreemarker.createDoc(templatePath,"word.ftl",data,docFilePath);	/**     * 创建doc文件     * [@param](https://my.oschina.net/u/2303379) templatePath 模板所在路径 xxx/xxx/template     * [@param](https://my.oschina.net/u/2303379) templateName 模板名字 xxx.ftl     * [@param](https://my.oschina.net/u/2303379) dataMap 数据集合     * [@param](https://my.oschina.net/u/2303379) outPath 输出文件路径  xxx/xxx/xxx.doc     */    public static void createDoc(String templatePath, String templateName, Map
dataMap, String outPath) throws Exception{ logger.debug("WordGeneratorWithFreemarker createDoc()"); Freemarker.fprint(templatePath,templateName,dataMap,outPath); } /** * 基于文件的输出 * * @param templatePath 模板所在路径 xxx/xxx/template * @param templateName 模板名字 xxx.ftl * @param dataMap 数据集合 * @param outPath 输出文件路径 xxx/xxx/xxx.doc */ public static void fprint(String templatePath, String templateName, Map
root, String outPath) { logger.debug("Freemarker fprint file"); try { getInstance(templatePath); Template template = getTemplate(templateName); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outPath)), "UTF-8")); template.process(root, out); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException(e); } catch (TemplateException e) { e.printStackTrace(); throw new RuntimeException(e); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } }

效果展示

到此富文本导出就完成了。

转载于:https://my.oschina.net/zhengweishan/blog/1475577

你可能感兴趣的文章
ubuntu 15.10 mongodb.service 起不起来解决方案
查看>>
【公益】开放一台Eureka注册中心给各位Spring Cloud爱好者
查看>>
pandas基础练习
查看>>
6-pandas索引
查看>>
springmvc rest api和页面访问异常统一处理
查看>>
spring自动装配优先级处理
查看>>
归并排序
查看>>
减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同
查看>>
Two Sum
查看>>
Lucene4.3进阶开发之乱世丛生(二)
查看>>
DIKW模型与数据工程
查看>>
HTML解析原理概括(转载)
查看>>
iOS 计算某个时间到现在是多少月/天/时
查看>>
Git使用详细教程
查看>>
创建自己的 Yum repository
查看>>
云的世界不再免费,最好的cloudfoundryV1已被废弃
查看>>
KeyTool
查看>>
Ubuntu(Linux) 下 unzip 命令使用详解
查看>>
Docker启动容器时的port公开方式,破除一些含糊的地方
查看>>
mongodb增量备份脚本与原理
查看>>