如何使用 Apache POI 将 docx 中的文本(标签)替换为 HTML?

2023-12-05

我们将有一些模板 docx 文件,其中会有一些标签,例如 ${content}。我需要用 HTML 替换这个标签。

为此,我想在 XWPFDocument 中使用 altChunk 元素。以下答案在如何使用 Apache POI 将 altChunk 元素添加到 XWPFDocument,我可以将 altChunk 放在 docx 的末尾。

我怎样才能用它替换我的标签?或者我可以使用任何其他库,可能是 docx4j?

UPD: Template docx files with tags are created by end users with MS Word and looks like: Sample docx template


如果“${content}”位于主体元素它自己的,然后通过找到来解决该要求IBodyElement,创建一个XmlCursor,插入altChunk,然后删除IBodyElement将是可能的。

以下代码通过扩展示例来演示这一点如何使用 Apache POI 将 altChunk 元素添加到 XWPFDocument。它提供了一种替换已发现的方法IBodyElement,其中包含一个特殊文本,带有altChunk其中引用了MyXWPFHtmlDocument。它用XmlCursor以获得文本正文中所需的位置。的用法XmlCursor代码中已注释。

模板.docx:

enter image description here

Code:

import java.io.*;

import org.apache.poi.*;
import org.apache.poi.ooxml.*;
import org.apache.poi.openxml4j.opc.*;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAltChunk;

public class WordInsertHTMLaltChunkInDocument {

 //a method for creating the htmlDoc /word/htmlDoc#.html in the *.docx ZIP archive  
 //String id will be htmlDoc#.
 private static MyXWPFHtmlDocument createHtmlDoc(XWPFDocument document, String id) throws Exception {
  OPCPackage oPCPackage = document.getPackage();
  PackagePartName partName = PackagingURIHelper.createPartName("/word/" + id + ".html");
  PackagePart part = oPCPackage.createPart(partName, "text/html");
  MyXWPFHtmlDocument myXWPFHtmlDocument = new MyXWPFHtmlDocument(part, id);
  document.addRelation(myXWPFHtmlDocument.getId(), new XWPFHtmlRelation(), myXWPFHtmlDocument);
  return myXWPFHtmlDocument;
 }

 //a method for replacing a IBodyElement containing a special text with CTAltChunk which
 //references MyXWPFHtmlDocument
 private static void replaceIBodyElementWithAltChunk(XWPFDocument document, String textToFind, 
                                                     MyXWPFHtmlDocument myXWPFHtmlDocument) throws Exception {
  int pos = 0;
  for (IBodyElement bodyElement : document.getBodyElements()) {
   if (bodyElement instanceof XWPFParagraph) {
    XWPFParagraph paragraph = (XWPFParagraph)bodyElement;
    String text = paragraph.getText();
    if (text != null && text.contains(textToFind)) {
     //create XmlCursor at this paragraph
     XmlCursor cursor = paragraph.getCTP().newCursor();
     cursor.toEndToken(); //now we are at end of the paragraph
     //there always must be a next start token. Either a p or at least sectPr.
     while(cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START);
     //now we can insert the CTAltChunk here
     String uri = CTAltChunk.type.getName().getNamespaceURI();
     cursor.beginElement("altChunk", uri);
     cursor.toParent();
     CTAltChunk cTAltChunk = (CTAltChunk)cursor.getObject();
     //set the altChunk's Id to reference the given MyXWPFHtmlDocument
     cTAltChunk.setId(myXWPFHtmlDocument.getId());

     //now remove the found IBodyElement
     document.removeBodyElement(pos);

     break; //break for each loop
    }
   }
   pos++;
  }
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument(new FileInputStream("template.docx"));

  MyXWPFHtmlDocument myXWPFHtmlDocument = createHtmlDoc(document, "htmlDoc1");
  myXWPFHtmlDocument.setHtml(myXWPFHtmlDocument.getHtml().replace("<body></body>",
   "<body><p>Simple <b>HTML</b> <i>formatted</i> <u>text</u></p></body>"));

  replaceIBodyElementWithAltChunk(document, "${content}", myXWPFHtmlDocument);

  FileOutputStream out = new FileOutputStream("result.docx");
  document.write(out);
  out.close();
  document.close();

 }

 //a wrapper class for the  htmlDoc /word/htmlDoc#.html in the *.docx ZIP archive
 //provides methods for manipulating the HTML
 //TODO: We should *not* using String methods for manipulating HTML!
 private static class MyXWPFHtmlDocument extends POIXMLDocumentPart {

  private String html;
  private String id;

  private MyXWPFHtmlDocument(PackagePart part, String id) throws Exception {
   super(part);
   this.html = "<!DOCTYPE html><html><head><style></style><title>HTML import</title></head><body></body>";
   this.id = id;
  }

  private String getId() {
   return id;
  }

  private String getHtml() {
   return html;
  }

  private void setHtml(String html) {
   this.html = html;
  }

  @Override
  protected void commit() throws IOException {
   PackagePart part = getPackagePart();
   OutputStream out = part.getOutputStream();
   Writer writer = new OutputStreamWriter(out, "UTF-8");
   writer.write(html);
   writer.close();
   out.close();
  }

 }

 //the XWPFRelation for /word/htmlDoc#.html
 private final static class XWPFHtmlRelation extends POIXMLRelation {
  private XWPFHtmlRelation() {
   super(
    "text/html", 
    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk", 
    "/word/htmlDoc#.html");
  }
 }
}

结果.docx:

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Apache POI 将 docx 中的文本(标签)替换为 HTML? 的相关文章

  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • 如何在codeigniter中将上传图片比例限制为16:9?

    这是我用来上传图像的代码 this gt load gt library upload ext pathinfo file name PATHINFO EXTENSION img name now ext imgConfig upload
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 检查 jQuery 1.7 中是否存在基于文本的选择选项

    所以我有以下 HTML 片段
  • 图像背景不透明度不影响边框

    如何设置背景不透明度而不影响边框线不透明度 我找到的解决方案没有帮助 div class selected img src assets img image product 1 thumbnail jpg alt product 1 thu
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • foreach 循环并返回未定义的值

    我想知道是否有人可以解释为什么这个函数返回undefined而不是建立的对象 var people name John name Dean name Jim function test name people forEach functio
  • cy.origin() 和立即重定向

    我在测试受 oauth 保护的应用程序时遇到问题 当没有公共页面时 问题就会显现出来 如果用户未经过身份验证 就会立即重定向到 OAuth 服务器 我设法以更简单的设置重现该问题 在 fake app 域中运行的假应用程序 在 fake o
  • Android Google Maps,如何让每个Marker InfoWindow打开不同的Activity?

    我使用以下代码段在谷歌地图上显示多个位置 我将这些坐标作为数组获取 在地图上显示标记后 我想在单击标记的信息窗口后进行活动 单个标记的每个信息窗口在单击后应具有不同的活动 我有 4 个标记 我想通过单击信息窗口来访问 4 个不同的活动 我应
  • 如何在 bash shell 中使用部分读取配置文件

    我有这样的配置文件 rsync includes user data conf rsync exclude tmp pyc vendor javascript utils data 我有我想在 rsync 和该文件中的其他配置数据中排除的模
  • 网站真的需要迎合未启用 Javascript 的浏览器吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 为什么许多专业的 Web
  • Objective-C中有没有类似于C#的yield return的东西

    Objective C 中有没有类似于 C 的东西yield return 不 Objective C 中没有任何东西可以让您轻松构建可迭代的解决方案 一般来说 快速枚举Objective C 是使用与 C Java 或 C 完全不同的机制
  • 如何将odoo 8数据库升级到odoo 9?

    我正在尝试将 odoo 安装从 8 0 升级到 9 0 到目前为止我所做的如下 从生产系统备份odoo数据库 在我当前的系统中安装备份数据库作为测试 将 odoo 文件夹复制到我系统上的文件夹中 检查一下 是否一切正常 有用 更新到最新v8
  • 递归调用 Firestore

    我有一个 Firebase Firestore 其中 Components 作为根集合 集合中的每个文档 组件 可能有一个名为 children 的数组 数组中的每个项目都是另一个组件的 id 本质上是一对多关系 由于每个孩子也是一个组件
  • AWS Lambda并发请求限制以及如何增加它?

    我想要同时处理 1000 万个请求 AWS lambda 是否能够做到这一点 因为他们提到 AWS lambda 限制仅为 100 个并发请求 在 AWS 控制台内导航至支持中心 在这里您可以创建一个服务限额增加用于 AWS Lambda
  • 如何让div在页面中居中? (高度宽度)?

    愚蠢的问题 但我找不到答案 因为所有答案都假设 div 的宽度居中 我需要的是以高度和宽度的方式将 div 居中 以便位于页面的非常中心 我尝试了这个 但它只是以页面宽度而不是高度的方式将 div 居中 myDiv width 500px
  • 如何在 GAE 端点中检索自定义用户对象?

    我刚刚在我的谷歌应用程序引擎 Java 应用程序上创建了自己的自定义身份验证 这并不像我接下来要做的事情那么麻烦 身份验证工作正常 但现在我尝试向默认用户对象添加一些附加字段 这样我就不必对服务器进行如此多的调用 到目前为止我所做的是创建一
  • 使用 nohup CLI 在 PHP 后台运行 php 脚本

    我正在尝试在后台运行一个 php 脚本 但它不起作用 我只能直接从 ssh 终端运行 使用相同的 cli 脚本 在终端上 首先我访问路径 cd labs lung com br ztbot bin v2 php之后 我在后台运行我的脚本 n
  • RewriteRule htaccess 如果文件存在

    我想使用 htaccess 来检查 htaccess 文件所在的目录中是否存在名为 Offline txt 的文件 如果存在则执行以下操作 RewriteRule websiteOffline php L 并且对特定范围的 IP 地址也有例
  • 通过 php 发送电子邮件

    我第一次来这里 我有 2 个文件 index html sendemail php At index html我有我的表格的代码 section div class parallax div class container div clas
  • 如何在 Protractor/WebdriverJS 中设置默认浏览器窗口大小

    由于某种原因 当我在工作中运行测试时 浏览器会最大化 但当我在家运行测试时 它只会打开大约 50 宽度的浏览器窗口 这会导致向下滚动等方面出现一些差异 因此我理想情况下希望让它在运行测试的每台计算机上打开相同大小的浏览器窗口 最好的方法是什
  • 打印大型 Swing 组件

    我有一个 Swing 表单 其中有一个 JScrollPane 内的自定义表格 它只是一个 JPanel 而不是 JTable 子类 我正在尝试打印它 如果我只是将整个框架发送到打印机 滚动窗格就会被切断 并且如果我将框架的大小调整为滚动窗
  • DependencyProperty 作为实例变量?

    虽然网络上的大多数代码示例都使用依赖属性的静态声明 但我发现在某些情况下它们被定义为公共只读实例成员 将 DependencyProperty 定义为实例成员 而不是静态 有什么优点吗 Note 我不想讨论静态成员是好还是坏的问题 更具体地
  • 维基百科 API 是否支持 CORS 还是仅支持 JSONP?

    这个问题涉及到另一个问题 这是一年前问过的 作者询问如何使用 JavaScript 和 Wikipedia API 发出跨域请求 一条评论是 en wikipedia org 似乎不允许 CORS 建议他改用 JSONP 我知道我可以使用
  • 动态更新fabric.js路径点

    我正在尝试动态地将点添加到路径对象 当我这样做时 路径会正确渲染 但边界矩形永远不会更新 这使得用户几乎不可能在画布上选择和移动路径 正如您在下面的代码中看到的 路径最初是使用单个点创建的 然后我动态添加第二个点以及控制点 执行此操作后 边
  • 如何使用 Apache POI 将 docx 中的文本(标签)替换为 HTML?

    我们将有一些模板 docx 文件 其中会有一些标签 例如 content 我需要用 HTML 替换这个标签 为此 我想在 XWPFDocument 中使用 altChunk 元素 以下答案在如何使用 Apache POI 将 altChun