页眉和页脚中的Word到HTML字段

时间:2015-10-22 16:20:17

标签: docx4j

我正在使用docx4j将Word模板转换为多个HTML文件,每章一个。

Word模板有几个由多个字段(DOCPROPERTY ...)映射的自定义属性,表示为简单字段和复杂字段。当word文档转换为HTML(如${...}[@... /]指令)时,我会填充这些属性以获取Freemarker代码。

在后面的步骤中,我会查找“标题1”段落以识别章节,然后在转换前将文档拆分为多个Word文档,然后将这些文档转换为HTML并写入临时文件。

每个文档都已成功转换为HTML并且字段被我的标记正确替换,但在写入页眉和页脚部分时表现错误:字段代码在字段值(例如DOCPROPERTY "PROPERTY_NAME" \* MERGEFORMAT ${constants['PROPERTY_NAME']})之前写入而不是字段仅限值(例如${constants['PROPERTY_NAME']})。

如果我将更新的文档写入docx文件,则生成的文档似乎没有任何错误。

如果它对解决问题很有用,那就是我分割文件的方法(每章):

  1. 克隆更新的WordprocessingMLPackage(克隆方法)
  2. 删除章节的“标题1”元素
  3. 之前的每个根元素
  4. 从下一章的“标题1”元素中删除每个根元素
  5. 转换克隆并清理的文档
  6. (实际上我每次都不使用克隆方法,但是我将更新后的文档写入ByteArrayOutputStream,然后根据克隆方法的来源为每一章读取它。)

    我怀疑这是一个docx4j错误,其他人是否尝试过类似的东西?

    最后这些是我的平台细节:

    • JDK 1.6
    • Docx4J v3.2.2

    提前感谢您提供任何帮助

    修改

    要生成freemarker标记来代替Word字段,我按如下方式设置文档属性值:

    1. 遍历文档,查找包含new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), visitor);的简单或复杂字段,其中visitor是我查找字段和设置属性的自定义回调
    2. 遍历我寻找的文件

      • FldChar个类型为BEGIN的元素,并使用FieldsPreprocessor.canonicalise((P) ((R) fc.getParent()).getParent(), fields);解析它们(我不使用canonicalise的返回值)fc找到FldChar ArrayList<FieldRef> }和字段为空CTSimpleField;然后我提取并解析字段的instrText属性
      • FldSimpleModel fldSimpleModel = new FldSimpleModel(); fldSimpleModel.build((CTSimpleField) o, null);个元素并使用fldSimpleModel.getFldArgument()解析它们;然后我使用wordMLPackage.getDocPropsCustomPart().setProperty(propertyName, finalValue);获取属性名称
    3. 我查找代替当前字段的freemarker代码,并使用List<Relationship> rels = wordMLPackage.getMainDocumentPart().getRelationshipsPart().getRelationships().getRelationship(); for (Relationship rel : rels) { Part p = wordMLPackage.getMainDocumentPart().getRelationshipsPart().getPart(rel); if (p == null) { continue; } if (p instanceof ContentAccessor) { new TraversalUtil(((ContentAccessor) p).getContent(), visitor); } }
    4. 将其设置为属性值
    5. 最后我从第1步开始对页眉和页脚执行相同的操作,如下所示:

      FieldUpdater updater = new FieldUpdater(wordMLPackage);
      try {
          updater.update(true);
      } catch (Docx4JException ex) {
          Logger.getLogger(WorkerDocx4J.class.getName()).log(Level.SEVERE, null, ex);
      }
      
    6. 最后我更新字段如下

      HTMLSettings settings = Docx4J.createHTMLSettings();
      settings.setWmlPackage(wordDoc);
      settings.setImageHandler(new InlineImageHandler(myDataModel));
      
      Docx4jProperties.setProperty("docx4j.Convert.Out.HTML.OutputMethodXML", true);
      
      ByteArrayOutputStream os = new ByteArrayOutputStream();
      
      os.write("[#ftl]\r\n".getBytes("UTF-8"));
      
      Docx4J.toHTML(settings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
      
      String template = new String(os.toByteArray(), "UTF-8");
      
    7. 填写所有字段属性后,我按照前面的描述克隆文档,并使用

      转换过滤后的克隆实例
      template

      然后我在<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <array> <dict> <key>PayloadCertificateFileName</key> <string>pkiclient.exe.cer</string> <key>PayloadContent</key> <data> MIIDWzCCAkOgAwIBAgIIbbXoNrXgWrUwDQYJKoZIhvcNAQELBQAw OzEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRUwEwYDVQQKDAxFSkJD QSBTYW1wbGUxCzAJBgNVBAYTAlNFMB4XDTE1MDYwOTExMTQzN1oX DTI1MDYwNjExMTQzN1owOzEVMBMGA1UEAwwMTWFuYWdlbWVudENB MRUwEwYDVQQKDAxFSkJDQSBTYW1wbGUxCzAJBgNVBAYTAlNFMIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA41riRAQHXODW w8ihGSmf/OYByA4z0fQHLdTPzcu3fg0wvY72b74Hwo4DHEtna8I+ ZQ0y16vx1y/RBQR7KWJR5NkKK+mdtxdlp4Ef7IrPBAg4donT8h7I S7/AMA8KEzzCza0nhK+lWejtLaWSnjVZ60nz/6R/kLn2chWOHFga 9JOdB7dPovv27eBE5+08xmRfzc5bguqVslcDcW6xLfkR3ChhXn7L C2V9DR+y3J+Tjo/iWkyJH3XAe+jHh8gpGvMroolm7axKSDEKl0PD LR2AYxrMDYpR70m6aMKs/q2dlbykCzDwLhXGxDmjcxyZU/cqyXMZ 5BEHI+7hSFGyXlv6tQIDAQABo2MwYTAdBgNVHQ4EFgQUtUUcq/GH iBHrkanRtz4Y6EnWSocwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME GDAWgBS1RRyr8YeIEeuRqdG3PhjoSdZKhzAOBgNVHQ8BAf8EBAMC AYYwDQYJKoZIhvcNAQELBQADggEBAMZMwmp5+YemWxnvWI4dw9Hz rnzuI4It2HLDnCTE7GDrE8TI3lb+ZNxuuK7NKr0IgIQsuZzEiRCb oq2OWnGXLvvqq5F0EybdiYCLU1E1OjqqQlOW9wWHB35PZUb6tQi2 hCoafFy9CUDLcRS95I0Og7rbszFZAcQrKpyF+qSRAFcrD6O1JCSk ad+giQBsfD/erRFPd7mVHVjm5O+T8Sz8LL5MgI7decRhjfADVW16 ZWdajhgBnmeW+KTnOJfEMjqMmU6JeSl26rbSqcWR28Or2smXkRkX LUA8j/B3FbUTQ+MOSJSj+rl54f0iAs4Tzey7Pgh7D2rtgrjM4M3M 0iky3FM= </data> <key>PayloadDescription</key> <string>Configures certificate settings.</string> <key>PayloadDisplayName</key> <string>ManagementCA</string> <key>PayloadIdentifier</key> <string>com.apple.security.root.43EA4618-C9DF-439E-A346-C4CCDD73FAA6</string> <key>PayloadType</key> <string>com.apple.security.root</string> <key>PayloadUUID</key> <string>43EA4618-C9DF-439E-A346-C4CCDD73FAA6</string> <key>PayloadVersion</key> <integer>1</integer> </dict> <dict> <key>PayloadContent</key> <dict> <key>CAFingerprint</key> <data> </data> <key>Challenge</key> <string>Password1</string> <key>Key Type</key> <string>RSA</string> <key>Keysize</key> <integer>2048</integer> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>150615987102</string> </array> </array> </array> <key>URL</key> <string>http://172.20.16.158:8080/ejbca/publicweb/apply/scep/testSCEP/pkiclient.exe</string> </dict> <key>PayloadDescription</key> <string>Configures SCEP settings</string> <key>PayloadDisplayName</key> <string>SCEP</string> <key>PayloadIdentifier</key> <string>com.apple.security.scep.FC189619-2F84-4E39-AE66-5E037D8A8A84</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>FC189619-2F84-4E39-AE66-5E037D8A8A84</string> <key>PayloadVersion</key> <real>1</real> </dict> </array> <key>PayloadDisplayName</key> <string>EJBTest</string> <key>PayloadIdentifier</key> <string>bhaidass-macbook-pro.local.736DF58F-4375-420A-B9D6-7950684E0B3A</string> <key>PayloadRemovalDisallowed</key> <false/> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>A8F41F59-643C-44B5-9447-8AB88D6FCA49</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </plist> 变量中获得了生成的freemarker模板。

      以下XML是更新文档属性后生成的文档的footer1.xml部分的内容,如下所述:footer1.xml after field updates

      非常奇怪的事情(在我看来)是如果找不到某些属性,第5步抛出异常(ok),字段更新在错误的字段停止(ok)并且页眉和页脚中的所有字段都是正确的。在这种情况下,这是footer1.xml的内容。

      在最后一种情况下,字段以不同的方式定义。我认为HTML转换器可以很好地处理最后一种情况,并在第一种情况下做错了。

      我做错了什么或者我能做得更好?

0 个答案:

没有答案