我正在尝试读取 docx 文件并用常量字符串替换作者姓名。 这是我的 main 函数中的代码。
import jakarta.xml.bind.JAXBException;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.CTTrackChange;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException, Docx4JException {
try {
// Replace "path/to/your/document.docx" with the actual file path
String inputFilePath = "src/main/java/shapes.docx";
String outputFilePath = "output_no_user_info.docx";
// Load the document
WordprocessingMLPackage wmlPackage = WordprocessingMLPackage.load(new File(inputFilePath));
// Remove user information
removeUserInfo(wmlPackage);
// Save the modified document
FileOutputStream fos = new FileOutputStream(outputFilePath);
wmlPackage.save(fos);
fos.close();
System.out.println("User information removed successfully. Saved as: " + outputFilePath);
} catch (Docx4JException | JAXBException e) {
e.printStackTrace();
System.err.println("Error processing the document: " + e.getMessage());
}
}
public static void removeUserInfo(WordprocessingMLPackage wmlPackage) throws Docx4JException, JAXBException {
MainDocumentPart documentPart = wmlPackage.getMainDocumentPart();
List<Object> trackedChanges = documentPart.getJAXBNodesViaXPath("//w:ins | //w:del", true);
for (Object change : trackedChanges) {
if (change instanceof CTTrackChange) {
CTTrackChange trackChange = (CTTrackChange) change;
trackChange.setAuthor("External");
}
}
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Docx4jTest</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Archetype - Docx4jTest</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-core</artifactId>
<version>11.4.9</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-JAXB-MOXy</artifactId>
<version>11.4.5</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>4.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
我观察到的错误如下所示,当文档中存在任何形状时就会出现该错误。我看到 CTWordprocessingShape 和 org.eclipse.persistence.internal.oxm.Root 是要转换的不同类,并且代码在这行 (AbstractMarshalRecordImpl:211) 中被破坏。
Root xr = (Root) originalObject;
AbstractMarshalRecordImpl 代码的链接:- https://github.com/payara/patched-src-eclipselink/blob/master/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm /记录/AbstractMarshalRecordImpl.java
我对图书馆相当陌生,请告诉我是否有任何解决办法可以绕过该问题。 我尝试使用 ReferenceImpl 而不是 Moxy,ReferenceImpl 不会导致以下问题。
错误信息:- 类 org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape 无法转换为类 org.eclipse.persistence.internal.oxm.Root (org.docx4j.com.microsoft.schemas.office.word .x2010.wordprocessingShape.CTWordprocessingShape 和 org.eclipse.persistence.internal.oxm.Root 位于加载器“app”的未命名模块)
Exception in thread "main" java.lang.ClassCastException: class org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape cannot be cast to class org.eclipse.persistence.internal.oxm.Root (org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape and org.eclipse.persistence.internal.oxm.Root are in unnamed module of loader 'app')
at org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecordImpl.addXsiTypeAndClassIndicatorIfRequired(AbstractMarshalRecordImpl.java:211)
at org.eclipse.persistence.oxm.record.XMLRecord.addXsiTypeAndClassIndicatorIfRequired(XMLRecord.java:406)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:462)
at org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping.buildCompositeRow(XMLAnyCollectionMapping.java:683)
at org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping.writeFromObjectIntoRow(XMLAnyCollectionMapping.java:554)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.writeOutMappings(XMLObjectBuilder.java:349)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:465)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:445)
at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRowForDescriptor(XMLCompositeObjectMapping.java:466)
at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRow(XMLCompositeObjectMapping.java:447)
at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.writeSingleValue(XMLCompositeObjectMapping.java:680)
at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.writeFromObjectIntoRow(XMLCompositeObjectMapping.java:645)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.writeOutMappings(XMLObjectBuilder.java:349)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:465)
at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:445)
at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRowForDescriptor(XMLCompositeObjectMapping.java:466)
org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape and org.eclipse.persistence.internal.oxm.Root are in unnamed module of loader 'app'
建议您最后可能存在 JPMS(模块化)配置问题。
使用 docx4j-JAXB-MOXy 和
module-info.java
文件为我工作,其中包括:
requires org.docx4j.JAXB_MOXy;
请注意,您只需要
docx4j-JAXB-MOXy
;无需同时添加 docx4-core
和 org.eclipse.persistence.moxy
。 也不要混合不同的版本(11.4.5 与 11.4.9 混合)。
我在 Java 17 上使用 11.5.1 进行了测试。