docx4j 将占位符替换为转换为 WordML 的 (x)html,但在结果文档中我看到了 WordML 标记

问题描述 投票:0回答:1

我有一个代码可以将 ${NAME} 等占位符替换为纯文本。 我使用 docx4j 和 docx4j-search-and-replace-util 来替换占位符。

它工作正常,但现在在“APP_ADDITIONAL_INFO”字段之一中,我需要用 Quill 编辑器中的简单格式化 HTML 替换占位符,例如:

<p><strong>Header</strong></p><p><strong>Text string</strong></p>
结果 .docx 文档包含此 html,而不是此字段的格式化文本。

我研究了这个问题并意识到为此目的有必要使用docx4j-ImportXHTML和JTidy。使用 JTidy,我可以将 HTML 转换为 XHTML,然后 ImportXHTML 将 XHTML 转换为 WordML 格式。

但现在在结果 .docx 中,我看到完整的 WordML 标记而不是格式化文本,从

开始

<w:document xmlns:dsp="http://schemas.microsoft.com/office/drawing/2008/diagram" 
等等,比如
<w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/><w:b/><w:i w:val="false"/><w:color w:val="000000"/><w:sz w:val="22"/></w:rPr><w:t>Formatted text string</w:t></w:r>

那么,我哪里错了?

我的代码是:

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);
    
    BufferedReader br = new BufferedReader(new StringReader(doc.getDescription()));

    StringWriter sw = new StringWriter();
    Tidy t = new Tidy();
    t.setDropEmptyParas(true);
    t.setShowWarnings(false); //to hide errors
    t.setQuiet(true); //to hide warning
    t.setUpperCaseAttrs(false);
    t.setXmlOut(true);
    t.setUpperCaseTags(false);
    t.setInputEncoding("UTF-8");
    t.setOutputEncoding("UTF-8");
    t.setXmlOut(true);
    t.parse(br,sw);
    StringBuffer sb = sw.getBuffer();
    String strClean = sb.toString();
    br.close();
    sw.close();

    wordMLPackage.getMainDocumentPart().getContent().addAll(XHTMLImporter.convert( strClean, null) );
    // the variable that should contain WordML markup
    String description = XmlUtils.marshaltoString(wordMLPackage.getMainDocumentPart().getJaxbElement(), true, true);
    
    // map with placeholders and replacing data
    Map<String, String> replaceMap = new HashMap<String, String>() {{
        put("${APP_EMPLOYEE}",              doc.getEmployeeName());
        put("${APP_JOB_TITLE}",             doc.getJobtitle());
        put("${APP_ADDITIONAL_INFO}",       description);
    }};

    byte[] cos = gt.generateDocXDocument(filePath, replaceMap, masterId);

    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"test.docx\"").body(cos);

在generateDocXDocument方法中:

    generateDocXDocument(String filePath, Map <String, String> replaceMap){
      byte[] decryptedBytesOfFile = storageService.loadFile(filePath);
      WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new ByteArrayInputStream(decryptedBytesOfFile));
      Docx4JSRUtil.searchAndReplace(wordMLPackage, replaceMap);
      OutputStream outputStream = new ByteArrayOutputStream();
      Save saver = new Save(wordMLPackage);
      saver.save(outputStream);
      return ((ByteArrayOutputStream) outputStream).toByteArray();
    }

我什至尝试不使用 docx4j-ImportXHTML 和 JTidy,而只是使用 WordML 标记更改占位符,例如:

    put("${APP_ADDITIONAL_INFO}", "<w:r><w:rPr><w:rFonts w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\"/><w:b/><w:i w:val=\"false\"/><w:color w:val=\"000000\"/><w:sz w:val=\"22\"/></w:rPr><w:t>Formatted text</w:t></w:r>");

但结果是相同的 - 结果 .docx 文件包含此标记。

java xhtml docx docx4j wordml
1个回答
0
投票

正如您所发现的,这是行不通的。您无法以这种方式用标记替换文本。

更好的方法是使用内容控制数据绑定;请参阅 使用 docx4J 生成文档时用 HTML 值替换内容控件

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.