POI 处理word 文档中 文本框模板

最近处理word模板中发现存在文本框类型的模板,以前从未处理过只能百度一下了,结果大部分出现的都是https://jingyan.baidu.com/article/e4d08ffdd352690fd2f60d8b.html 这种情况的,大多数针对的都是固定的文档格式,感觉很难弄明白,官网也直指大概提了一下,并没有明显的demo,不过从侧面来讲倒是提供了解决的办法,只能靠自己了,首先需要处理的模板后缀名称改成rar格式,本身word就是一堆xml的集合,在解压之后找到对应的document.xml,这个就是对应的整个文档结构了,慢慢遍历自己的节点,找打需要修改的地方,一层一层的去寻找,然后移动对应的XmlCursor到制定位置,去寻找,整个过程很浪费耐心,所以处理之前一定要格式化好的xml,网上有在线的工具,我只是把自己处理的过程分享一下,因为我是替换的文本,所以结构先列出来

    public static List<String>patternList=new ArrayList();
    //需要处理的节点名称
     static {    
         patternList.add("mc:AlternateContent");
        patternList.add("mc:Choice");
        patternList.add("w:drawing");
         patternList.add("wp:anchor");
        patternList.add("a:graphic");
        patternList.add("a:graphicData");
        patternList.add("wps:wsp");
         patternList.add("wps:txbx");
         patternList.add("w:txbxContent");
         patternList.add("w:p");
         patternList.add("w:r");
        patternList.add("w:t");    
    }

里面包含每一需要处理的节点的名称,然后就是进行回朔找到patternList中最后一个元素位置,也就是w:t的位置,当XmlCursor光标移动到对应的位置就可以执行正常的替换工作,

详细代码如下

    public static void changeTextBox( XWPFDocument document,Map<String, String>map) {
        
        
        for(XWPFParagraph paragraph:document.getParagraphs())
            for(XmlObject object:paragraph.getCTP().getRArray())
        {
     XmlCursor cursor = object.newCursor();
     eachchild(cursor, 0,map);
        }
    }

//回朔查找,因为并不是每一个文本框中只有一个可替换的地方
    public static void eachchild(XmlCursor cursor,int start,Map<String, String>map) {

//预计子节点个数应该是小于10个节点
        for(int i=0;i<10;i++)
        {

//如果可以移动到子节点i
            if(cursor.toChild(i)) {

          //如果移动到达的子节点正好是按照顺序是需要的节点 则继续前往下一层
            if(cursor.getDomNode().getNodeName().equals(patternList.get(start))) {
                if(start==patternList.size()-1) {
                    String reString=cursor.getTextValue();
                    for(String e:map.keySet()) {
                        if(reString.contains(e)) {
                        //    执行替换
                            reString=reString.replaceAll(e, map.get(e));
                        }
                    }

      //bingo  设置替换节点内容
                    cursor.setTextValue(reString);
                }

   //继续下一层  遍历
                eachchild(cursor,start+1,map);
            }else {
                cursor.toParent();
            }
        }
        }

//  此处很重要,如果命中或者未命中都需要 遍历其他节点
        cursor.toParent();
    }

PS:整个代码就是这个样子了,其他的自行补充完整,图片这一块懒得去处理了,只是提供一个大概的解决思路。提供的信息不多,相信你搜索到这篇文章的时候,很多预备知识都已经知道了,我就不再累述。如有问题请私信联系,当然更期待有心人能够补充的更加详细更加完整。转载注明出处,谢谢!

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值