Html转Doc的一种方案

   2023-03-08 学习力0
核心提示:  公司的合同相关部分提出需求要把html转doc文本,合同模块是现成的,基于现有合同模块初步考虑了一下可以采取以下三种方案  1.合同模块本身有合同的html展示,可以通过前端,基于html的Doc来直接生成doc文档。  2.公司的合同html文本是基于一套自己设

  公司的合同相关部分提出需求要把html转doc文本,合同模块是现成的,基于现有合同模块初步考虑了一下可以采取以下三种方案

  1.合同模块本身有合同的html展示,可以通过前端,基于html的Doc来直接生成doc文档。

  2.公司的合同html文本是基于一套自己设计的机制,把合同条款存在数据库,以组合节点做拼接成html来做html文本动态生成的,一种可行方案是把这套机制作为数据来源,基于doc相关的开放接口包来从代码生成doc文档

  3.把现在有的html文本用第三方包转化成doc,补充上缺失的信息

 

  公司当前采取的是第1种方案,用jQuery的wordExport生成的doc。这种doc实际的存储方式还是用html语法,如果只是需要doc文档展示用这种方案是没问题的,但是如果要解析doc内容,貌似是没法直接解析的。这也是目前需要进行转换的原因。

  如果要生成内容准确和丰富的doc,用第二种方案来做会比较好。第二种方案的缺点在于实现复杂,需要找一个第三方生成doc的包熟悉接口才能展开,而且当前合同数据存储时,内容中已经内嵌了html文本,用这种方案的话,需要再做内容过滤或者是从数据源的角度,额外规定一个适合于内容填充符合doc生成规则的数据来源。

  第三种方案的话,也是需要找第三方包来支持的。缺点在于不确定第三方包转换限制和精确程度如何。做了几个简单和有代表性的样例测试,基于docx4j来做html转doc是可行的。不过缺点在于docx4j对于源html的语法要求很严格,很多在html里面支持的可选语法在docx4j转换时就不支持。

  调试过程中统计到的语法错误至少有:

  * 属性值缺失引号,比如item_id=123这种

  * input标签缺少结束符,比如<input ... > ,并没有对于的/或</input>

       * 错误的属性,比如  甲方,这种

  数据库里面的合同条目有8400+条,一条一条调试太过于费时,所以考虑追加一步html格式化以及过滤的步骤,选取的是google的owasp-java-html-sanitizer。初步测试是可行的。

  

相关依赖包为:

<!-- docx4j 的pom依赖 -->
<!-- https://mvnrepository.com/artifact/org.docx4j/docx4j -->
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j</artifactId>
    <version>6.1.1</version>
</dependency>

<!-- owasp-java-html-sanitizer的pom依赖 -->
<!-- https://mvnrepository.com/artifact/com.googlecode.owasp-java-html-sanitizer/owasp-java-html-sanitizer -->
<dependency>
    <groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
    <artifactId>owasp-java-html-sanitizer</artifactId>
    <version>20181114.1</version>
</dependency>

 

规则过滤的关键代码

/**
     * 
     * Description: 添加过滤规则<br> 
     *  
     * @author XXX <br>
     * @taskId <br>
     * @param configs
     * @return <br>
     */
    private PolicyFactory loadFilterConfigs(Map<String, List<String>> configs) {
        HtmlPolicyBuilder builder = new HtmlPolicyBuilder();
        Set<String> labelConfigs = configs.keySet();
        for (String label : labelConfigs) {
            builder.allowElements(label);//设置支持的标签
            List<String> attributes = configs.get(label);// 如果没属性要求返回空数组
            log.debug("load label:" + label + " and attributes are :" + attributes);
            if (CollectionUtils.isEmpty(attributes)) {
                continue;
            }
            for (String attribute : attributes) {// 配置属性
                if (StringUtil.isEmpty(attribute)) {
                    continue;
                }
                builder.allowAttributes(attribute).onElements(label);
            }

        }
        return builder.toFactory();
    }

这里补充说明一下,owasp-java-html-sanitizer支持对于单个标签定制过滤规则:

    builder.allowElements(new ElementPolicy() {
        @Override
        public String apply(String elementName, List<String> attrs) {// 配置属性值过滤
            System.out
                    .println("filter :" + elementName + " attrs:" + attrs );
            if (attrs != null) {
                int itemIdIndex = attrs.indexOf("item_id");
                if (itemIdIndex < 0) {// 不包含item_id
                    return elementName;
                }
                String item_id = attrs.get(itemIdIndex + 1);
                if (attrs.contains(item_id)) {// 需要过滤
                    return null;
                }
                return elementName;

            }
            return elementName;
        }
    }, label);

我们合同生成doc有一个需求是把没有选定的checkbox不生成到doc中,我上面代码的意图是,想先收集哪些块是没有选定的,然后通过上面的规律规则把没有选定的块过滤掉。但是实际测试结果是,这种规则过滤只对当前标签单层有效,对于嵌套的子标签并不会继承。比如:

<div item_id='123'>
       <input type='checkbox' item_id='123' /> 
       <p>test</p>
<div>

这种通过上面这种思路简单配置时,<p>标签的内容并不会受到item_id的影响而过滤。这与实际的需求不符合。

当前公司基于节点的模式,做节点解析来剔除节点是很简单的,所以上面方案测试不成功就没有继续往下深入,对于内容筛选的需求就直接基于节点来处理,owasp-java-html-sanitizer只专注于做html格式化就好了。

 

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • HTML中将背景颜色渐变 html设置背景颜色渐变
    通过使用 css3 渐变可以让背景两个或多个指定的颜色之间显示平稳的过渡,由于用到css3所以需要考虑下浏览器兼容问题,例如:从左到右的线性渐变,且带有透明度的样式:#grad {background: -webkit-linear-gradient(left,rgba(255,0,0,0),rgba(255,0,0,1)); /*
    03-08
  • html5 Canvas 如何自适应屏幕大小
    但是这样创建出的画布不能随着浏览器窗口大小的改变而动态的改变画布的大小。而这一点往往又非常重要, 因为我们会经常改变浏览器窗口大小,不会一直保持某个固定的大小。 html代码 canvas width="300" height="300" id="myCanvas"/canvas设置样式 * {
    03-08
  • Vue中出现Do not use built-in or reserved HTML elements as component id:footer等等vue warn问题
    Vue中出现Do not use built-in or reserved HTM
    错误示图:原因:是因为在本地项目对应文件的script中,属性name出现了错误的命名方式,导致浏览器控制台报错!  诸如: name: header 、  、 name: menu , 等等都属于错误的命名方式等 错误代码命名如下:解决办法:办法1: 如果我们采用正确命名
    03-08
  • HTML在网页中插入音频视频简单的滚动效果
    HTML在网页中插入音频视频简单的滚动效果
    每次上网,打开网页后大家都会看到在网页的标签栏会有个属于他们官网的logo,现在学了HTML了,怎么不会制作这个小logo呢,其实很简单,也不需要死记硬背,每当这行代码出现的时候能知道这是什么意思就ok1 link rel="shortcuticon" type="image/x-icon" href="
    03-08
  • HTML的video标签,不能下载视频代码
    !-- 在线视频不能下载代码 --!DOCTYPE html html headscript src="../Demo/demo/book/JQuery/jQuery v2.2.0.js"/script/headbody div style="text-align:center;"video src="../images/PreviewVideo.mp4" width="820"controls="controls&
    03-08
  • ThinkPHP报错 The requested URL /admin/index/login.html was not found on this server.
    ThinkPHP报错 The requested URL /admin/index/
           解决方案在入口文件夹public下查看.htaccess是否存在。不存在则新建,存在的话,那内容替换为下面这串代码 就可以解决Not Fund#IfModule mod_rewrite.c#Options +FollowSymlinks -Multiviews#RewriteEngine On##RewriteCond %{REQUEST_FILENAME
    03-08
  • HTML特殊字符、列表、表格总结 html特殊符号对
            HTML实体字符  在HTML中一些特殊的字符需要用特殊的方式才能显示出来,比如小于号、版权等,  在课堂上老师教了我们一个有点意思的:空格,在教材上字符实体是“nbsp”通过老师  的演示我们发现不同的浏览器他所显示的效果不同,有的比
    03-08
  • 【JavaScript】使用document.write输出覆盖HTML
    您只能在 HTML 输出中使用 document.write。如果您在文档加载后使用该方法,会覆盖整个文档。分析HTML输出流是指当前数据形式是HTML格式的数据,这部分数据正在被导出、传输或显示,所以称为“流”。通俗的来说就是HTML文档的加载过程,如果遇到document.writ
    03-08
  • ASP.Net MVC 控制@Html.DisplayFor日期显示格式
    在做一個舊表的查詢頁時,遇到一個問題:字段在db里存儲的是DATETIME,但保存的值只有日期,沒有時間數據,比如2018/2/26 0:00:00,顯示出來比較難看,當然也可以做一個ViewModel,在字段上添加Attribute定義來更改名稱和顯示名稱,如下:[Display(Name = "建
    03-08
  • html 基础代码
    title淄博汉企/title/headbody bgcolor="#00CC66" topmargin="200" leftmargin="200" bottommargin="200"a name="top"/a今天br /天气nbsp;nbsp;nbsp;nbsp;nbsp;不错br /font color="#CC0000"格式控制标签br /b 文字加粗方式1\bbr /str
    03-08
点击排行