gpt4 book ai didi

java - 缓存基本 XWPFDocument 模板并重用它们来生成文档

转载 作者:太空宇宙 更新时间:2023-11-04 10:42:53 25 4
gpt4 key购买 nike

我们正在实现一个门户,用于处理修改和生成 Microsoft Office 2007 文档 (docx) 的请求。后端是用 Java 实现的,使用 Apache POI 作为操作 docx 文件内容的 API。通过来自用 JavaScript 编写的前端的 RestAPI 调用来访问后端。

后端就像一个文档服务器,处理大约 15 个不同的 docx 文档,这些文档充当模板并包含需要替换为实际值的标记。来自前端的请求实际上是一个 token 值映射,后端需要在模板中替换它并为每个请求生成一个新文档。工作流程如下:

  • 接收前端请求:token-value映射
  • 将模板文档读取为 XWPFDocument 对象
  • 解析并替换 XWPFDocument 的所有 XWPFParagraph/XWPFTable 元素中的文本
  • 将修改后的 XWPFDocument 写入不同的文件路径

我目前正在尝试实现缓存机制,这是一个真正的性能问题,它是针对每个请求访问磁盘并读取文件的。我需要将每个模板文档视为原型(prototype),并为后端收到的每个请求返回一个克隆,与此类似:

XWPFDocument theDocument = documentCache.clone(documentConfiguration.getInputType());

clone方法目前实现如下:

public XWPFDocument clone(DocumentDictionary.DocumentType type){

if(PACKAGE_MAP.isEmpty())
getPackages();

XWPFDocument document = null;
try {
document = new XWPFDocument(PACKAGE_MAP.get(type));
}catch(IOException exception){
logger.error("Unable to clone document for input type {}", type);
}

return document;
}

此实现没有产生预期的结果,第一个请求处理按预期工作,但第二个请求在写入文档时失败,并出现错误:

Caused by: org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.

在每次请求时重新读取文档的情况下,上述异常不会重复。查看 Apache POI API,在读/写过程中使用的 XWPFDocument 和 ZipPackage 的 clone() 方法受到保护,因此我无法使用编程语言提供的基本功能,问题似乎来自于 ZipPackage 在文档的读/写过程中共享和使用这一事实。

有人能够使用 Java 和 Apache POI 实现这样的机制吗?

最佳答案

您可以为每个模板类型预加载byte[],然后使用ByteArrayInputStream作为克隆的基础

您还可以仅在请求时实例化模板,因此 getPackages() 变为 getPackage(DocumentDictionary.DocumentType type) 并检查 foreach 中的单一类型

XWPFDocument是在运行时编写的,因此当您对其段落、表格或一般运行进行修改时,您正在编辑模板文档,因此您必须以其他方式重新加载它。

private void getPackages() {
for (DocumentDictionary.DocumentType type : DocumentDictionary.DocumentType.values()) {
PACKAGE_MAP.put(type, FileUtils.readFileToByteArray(new File(getTemplateFromType(type))));
}
}

private String getTemplateFromType(DocumentDictionary.DocumentType type) {
switch(type) {
case TYPE_1:
return "/path/to/template/type_1.docx";
...
}
}

public XWPFDocument clone(DocumentDictionary.DocumentType type) {
if(PACKAGE_MAP.isEmpty())
getPackages();

XWPFDocument document = null;
try {
document = new XWPFDocument(new ByteArrayInputStream(PACKAGE_MAP.get(type)));
} catch(IOException exception) {
logger.error("Unable to clone document for input type {}", type);
}

return document;
ByteArrayInputStream();
}

关于java - 缓存基本 XWPFDocument 模板并重用它们来生成文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48748811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com