构建用于程序化编辑 Open Office XML(OOXML)文档(如 PowerPoint、Excel 和 Word)的应用程序从未如此简单。根据项目范围,Java 开发人员可以在代码中利用开源的第三方库,或者使用简化插件的 API 来操作存储和显示在 OOXML 结构中的内容。
在本文中,我们将专门讨论 PowerPoint 演示文稿 XML(PPTX)文件的结构,并学习如何操作 PPTX 内容的基本过程。然后,我们将讨论一个流行的开源 Java 库,用于程序化操作 PPTX 文件(特别是替换文本字符串的实例),并随后探索一个免费的第三方 API 解决方案,该方案可以帮助简化该过程并减少本地内存消耗。
PowerPoint PPTX 文件的结构是怎样的?
像所有 OOXML 文件一样,PowerPoint PPTX 文件的结构是包含一系列分层组织的 XML 文件的 ZIP 存档。它们本质上是一系列目录,其中大部分负责存储和安排我们在 PowerPoint 应用程序(或任何 PPTX 文件阅读器)中看到的资源。
PPTX 存档从一个基本的根结构开始,其中定义了我们在 PowerPoint 中看到的各种内容类型(例如,多媒体内容)。PPTX 文档的核心位于目录级别,组件如幻灯片(例如,firstSlide.xml、secondSlide.xml 等)、幻灯片布局(例如,模板)、幻灯片母版(例如,全局样式和占位符)以及其他内容(例如,图表、媒体和主题)被清晰地组织起来。PPTX 文件中相互依赖组件之间的关系存储在 _rels
目录中的 .rels
XML 文件中。当对幻灯片或其他内容进行更改时,这些关系文件会自动更新。
考虑到这种文件结构,假设我们想在不使用 PowerPoint 或任何其他 PPTX 阅读器打开文件的情况下手动替换 PowerPoint 幻灯片中的文本字符串。为此,我们首先需要将 PPTX 存档转换为 ZIP 文件(带有 .zip
扩展名),然后解压其内容。之后,我们将检查 ppt/presentation.xml
文件,该文件按顺序列出幻灯片,然后导航到 ppt/slides/
目录以找到目标幻灯片(例如,secondSlide.xml
)。要修改幻灯片,我们将打开 secondSlide.xml
,找到我们需要的文本运行(通常结构为 <a:t> "string" </a:t>
,位于 <a:r></a:r>
标签内),并用新字符串替换文本内容。然后,我们将检查 _rels
目录,以确保幻灯片关系保持完整;之后,我们将文件重新打包为 ZIP 存档,并重新引入 .pptx
扩展名。
在 Java 中程序化更改 PPTX 文件
要在 Java 中处理完全相同的过程,我们需要根据上下文考虑几种不同的可能性。显然,没有人愿意临时将整个 OOXML 结构映射到自定义 Java 程序中------因此,我们需要根据项目约束确定使用开源库还是即插即用的 API 服务是否更有意义。
如果我们选择开源路线,Apache POI
将是一个不错的选择。Apache POI 是一个开源的 Java API,专门设计用于帮助开发人员处理 Microsoft 文档,包括 PowerPoint PPTX(以及 Excel XLSX、Word DOCX 等)。
对于涉及 PPTX 文件的项目,我们首先需要导入适用于 PowerPoint 项目的相关 Apache POI 类(例如,XMLSlideShow
、XSLFSlide
和 XSLFTextShape
)。然后,我们将使用 XMLSlideShow
类加载 PPTX 文件,调用 getSlides()
方法,使用 XSLFTextShape
类过滤文本内容,并调用 getText()
和 setText()
方法来替换特定字符串。
这将完全可行,但值得注意的是,使用像 Apache POI 这样的开源库的挑战在于内存的处理方式。Apache POI 将所有数据加载到本地内存中,尽管有一些解决方法------例如,增加 JVM 堆大小或实现基于流的 API------但我们在处理大规模的 PPTX 文件时可能会消耗大量资源。
利用第三方 API 解决
如果我们无法在本地处理 PPTX 编辑工作流,那么云 API 解决方案可能会有所帮助。这种解决方案将大部分文件处理工作卸载到外部服务器,并返回结果,从而减少开销。作为额外的好处,它还简化了构建字符串替换请求的过程。我们将查看以下一个 API 解决方案。
以下示例 Java 代码可用于调用一个免费的 Web API,该 API 可替换 PPTX 文档中找到的所有字符串实例。该 API 可免费使用,并且需要一个免费的 API 密钥,其参数极其简单易用。
为了构建我们的 API 调用,我们首先需要将客户端库纳入我们的 Maven 项目。我们将在 pom.xml
中添加以下(JitPack
)仓库引用:
xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
接下来,我们将在 pom.xml
中添加以下依赖引用:
xml
<dependencies>
<dependency>
<groupId>com.github.Cloudmersive</groupId>
<artifactId>Cloudmersive.APIClient.Java</artifactId>
<version>v4.25</version>
</dependency>
</dependencies>
完成这些后,我们现在将以下导入类复制并添加到文件顶部:
java
// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditDocumentApi;
现在,我们将使用以下代码初始化 API 客户端,然后配置 API 密钥授权。setAPIKey()
方法将捕获我们的 API 密钥字符串:
java
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");
最后,我们将使用以下代码实例化 API 客户端,配置替换操作,执行替换过程(返回一个 byte[]
数组),并捕获/记录错误:
java
EditDocumentApi apiInstance = new EditDocumentApi();
ReplaceStringRequest reqConfig = new ReplaceStringRequest(); // ReplaceStringRequest | Replacement document configuration input
try {
byte[] result = apiInstance.editDocumentPptxReplace(reqConfig);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling EditDocumentApi#editDocumentPptxReplace");
e.printStackTrace();
}
以下 JSON 定义了我们的请求结构;我们将在代码中使用它来配置字符串替换操作的参数。
json
{
"InputFileBytes": "string",
"InputFileUrl": "string",
"MatchString": "string",
"ReplaceString": "string",
"MatchCase": true
}
我们可以通过将文件读入一个字节数组并将其转换为 Base64 编码的字符串,为这个 API 请求准备一个 PPTX 文档。
总结
在本文中,我们讨论了 PowerPoint PPTX 文件的结构方式,以及这种结构如何使其能够在 PPTX 阅读器之外轻松编辑 PowerPoint 文档。然后,我们建议 Apache POI 库作为 Java 开发人员的开源解决方案,用于程序化替换 PPTX 文件中的字符串,然后还探索了一个免费的第三方 API 解决方案,用于以较低的本地内存成本处理相同的过程。