zoukankan      html  css  js  c++  java
  • 解决docx4j 变量替换 由于变量存在样式式或空白字符 导致替换失败问题

    参考文章:https://blog.csdn.net/qq_35598240/article/details/84439929

    使用docx4j进行变量替换时 变量(形如:${变量})必须是无格式的,并且不能有拼写检查等,官方提供了一个VariablePrepare.prepare(wordMLPackage)的方法,但是只能解决拼写检查等少数情况,对样式(如加粗)等无效,从网上找到一篇博文(见参考文章),方法可行,但保留格式部分不能正常运行,注释后使用.代码如下:

      1 package com.tool;
      2 
      3 import java.util.regex.Pattern;
      4 
      5 import javax.xml.bind.JAXBContext;
      6 import javax.xml.bind.JAXBException;
      7 
      8 import org.docx4j.XmlUtils;
      9 import org.docx4j.jaxb.Context;
     10 import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
     11 import org.docx4j.wml.Document;
     12 
     13 public class DocxVariableClearUtils {
     14 
     15     /**
     16      * 清理文档接口方法,将被格式 分割的 替换变量 还原
     17      *
     18      * @param documentPart
     19      */
     20     public static boolean cleanDocumentPart(MainDocumentPart documentPart) throws Exception {
     21         if (documentPart == null) {
     22             return false;
     23         }
     24         Document document = documentPart.getContents();
     25         String wmlTemplate = XmlUtils.marshaltoString(document, true, false, Context.jc);
     26         document = (Document) XmlUtils.unwrap(DocxVariableClearUtils.doCleanDocumentPart(wmlTemplate, Context.jc));
     27         documentPart.setContents(document);
     28         return true;
     29     }
     30 
     31     /**
     32      * 去任意XML标签 及 空白字符
     33      */
     34     private static final Pattern XML_PATTERN = Pattern.compile("<[^>]*>|\s");
     35 
     36     private DocxVariableClearUtils() {
     37     }
     38 
     39     /**
     40      * start符号
     41      */
     42     private static final char PREFIX = '$';
     43 
     44     /**
     45      * 中包含
     46      */
     47     private static final char LEFT_BRACE = '{';
     48 
     49     /**
     50      * 结尾
     51      */
     52     private static final char RIGHT_BRACE = '}';
     53 
     54     /**
     55      * 未开始
     56      */
     57     private static final int NONE_START = -1;
     58 
     59     /**
     60      * 未开始
     61      */
     62     private static final int NONE_START_INDEX = -1;
     63 
     64     /**
     65      * 开始
     66      */
     67     private static final int PREFIX_STATUS = 1;
     68 
     69     /**
     70      * 左括号
     71      */
     72     private static final int LEFT_BRACE_STATUS = 2;
     73 
     74     /**
     75      * 右括号
     76      */
     77     private static final int RIGHT_BRACE_STATUS = 3;
     78 
     79 
     80     /**
     81      * doCleanDocumentPart
     82      *
     83      * @param wmlTemplate
     84      * @param jc
     85      * @return
     86      * @throws JAXBException
     87      */
     88     public static Object doCleanDocumentPart(String wmlTemplate, JAXBContext jc) throws JAXBException {
     89         System.out.println("======执行清除方法=====");
     90         // 进入变量块位置
     91         int curStatus = NONE_START;
     92         // 开始位置
     93         int keyStartIndex = NONE_START_INDEX;
     94         // 当前位置
     95         int curIndex = 0;
     96         char[] textCharacters = wmlTemplate.toCharArray();
     97         StringBuilder documentBuilder = new StringBuilder(textCharacters.length);
     98         documentBuilder.append(textCharacters);
     99         // 新文档
    100         StringBuilder newDocumentBuilder = new StringBuilder(textCharacters.length);
    101         // 最后一次写位置
    102         int lastWriteIndex = 0;
    103         for (char c : textCharacters) {
    104             switch (c) {
    105                 case PREFIX:
    106                     // TODO 不管其何状态直接修改指针,这也意味着变量名称里面不能有PREFIX
    107                     keyStartIndex = curIndex;
    108                     curStatus = PREFIX_STATUS;
    109                     break;
    110                 case LEFT_BRACE:
    111                     if (curStatus == PREFIX_STATUS) {
    112                         curStatus = LEFT_BRACE_STATUS;
    113                     }
    114                     break;
    115                 case RIGHT_BRACE:
    116                     if (curStatus == LEFT_BRACE_STATUS) {
    117                         // 接上之前的字符
    118                         newDocumentBuilder.append(documentBuilder.substring(lastWriteIndex, keyStartIndex));
    119                         // 结束位置
    120                         int keyEndIndex = curIndex + 1;
    121                         // 替换
    122                         String rawKey = documentBuilder.substring(keyStartIndex, keyEndIndex);
    123                         System.out.println("-----需要替换的标签:"+rawKey);
    124                         // 干掉多余标签
    125                         String mappingKey = XML_PATTERN.matcher(rawKey).replaceAll("");
    126                         System.out.println("-----替换完成的字符:"+mappingKey);
    127                         
    128 //                        if (!mappingKey.equals(rawKey)) {
    129 //                            char[] rawKeyChars = rawKey.toCharArray();
    130 //                            // 保留原格式
    131 //                            StringBuilder rawStringBuilder = new StringBuilder(rawKey.length());
    132 //                            // 去掉变量引用字符
    133 //                            for (char rawChar : rawKeyChars) {
    134 //                                if (rawChar == PREFIX || rawChar == LEFT_BRACE || rawChar == RIGHT_BRACE) {
    135 //                                    continue;
    136 //                                }
    137 //                                rawStringBuilder.append(rawChar);
    138 //                            }
    139 //                            // FIXME 要求变量连在一起
    140 //                            String variable = mappingKey.substring(2, mappingKey.length() - 1);
    141 //                            System.out.println("-----替换完成的变量variable:"+variable);
    142 //                            System.out.println("-----rawStringBuilder:"+rawStringBuilder);
    143 //                            int variableStart = rawStringBuilder.indexOf(variable);
    144 //                            if (variableStart > 0) {
    145 //                                rawStringBuilder = rawStringBuilder.replace(variableStart, variableStart + variable.length(), mappingKey);
    146 //                                System.out.println("-----最后rawStringBuilder:"+rawStringBuilder);
    147 //                            }
    148 //                            newDocumentBuilder.append(rawStringBuilder.toString());
    149 //                        } else {
    150                             newDocumentBuilder.append(mappingKey);
    151 //                        }
    152                         lastWriteIndex = keyEndIndex;
    153 
    154                         curStatus = NONE_START;
    155                         keyStartIndex = NONE_START_INDEX;
    156                     }
    157                 default:
    158                     break;
    159             }
    160             curIndex++;
    161         }
    162         // 余部
    163         if (lastWriteIndex < documentBuilder.length()) {
    164             newDocumentBuilder.append(documentBuilder.substring(lastWriteIndex));
    165         }
    166         return XmlUtils.unmarshalString(newDocumentBuilder.toString(), jc);
    167     }
    168 }
  • 相关阅读:
    重构drf后的环境变量配置
    分离的前后台交互
    虚拟环境的搭建
    Python
    Python
    Python
    Python操作MongoDb数据库
    Python操作SQLite/MySQL/LMDB
    数据库-如何创建SQL Server身份验证用户
    Python
  • 原文地址:https://www.cnblogs.com/dirgo/p/11949871.html
Copyright © 2011-2022 走看看