如何解决 java.lang.ClassNotFoundException: org.docx4j.jaxb.ri.NamespacePrefixMapper

How to resolve java.lang.ClassNotFoundException: org.docx4j.jaxb.ri.NamespacePrefixMapper

我目前正在尝试使用 docx4j 库将文件从 html 转换为 docx。

我已经设法使用 itext5 从 html 转换为 pdf,但现在由于 jaxb,我在尝试转换为 docx 时遇到异常。

我的项目使用了 maven,所以我试图导入很多库......但徒劳无功......

        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>docx4j-ImportXHTML</artifactId>
            <version>8.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.docx4j</groupId>
            <artifactId>xhtmlrenderer</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0.1</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
          <groupId>org.glassfish.jaxb</groupId>
          <artifactId>jaxb-runtime</artifactId>
          <version>2.3.0.1</version>
        </dependency>

       <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-xjc</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-xjc</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-jxc</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.googlecode.jaxb-namespaceprefixmapper-interfaces</groupId>
            <artifactId>JAXBNamespacePrefixMapper</artifactId>
            <version>2.2.4</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.11.0</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

这是我的函数,它应该将 html 转换为 docx :

public static void htmlToDocx(String html_content, String html_filename, String docx_filename)
    {
        try {
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();

            NumberingDefinitionsPart ndp = new NumberingDefinitionsPart();
            wordMLPackage.getMainDocumentPart().addTargetPart(ndp);
            ndp.unmarshalDefaultNumbering();

            XHTMLImporterImpl xHTMLImporter = new XHTMLImporterImpl(wordMLPackage);

            xHTMLImporter.setHyperlinkStyle("Hyperlink");
            wordMLPackage.getMainDocumentPart().getContent().addAll(xHTMLImporter.convert(new File(html_filename), null));

            File output = new File(docx_filename);

            wordMLPackage.save(output);
            System.out.println("done");

            System.out.println("file path where it is stored is" + " "+ output.getAbsolutePath());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

最后,这是我的例外:

2019-06-13 16:16:04.092  WARN 2988 --- [pool-1-thread-1] org.docx4j.utils.ResourceUtils           : Couldn't get resource: docx4j.properties
2019-06-13 16:16:04.092  WARN 2988 --- [pool-1-thread-1] org.docx4j.Docx4jProperties              : Couldn't find/read docx4j.properties; docx4j.properties not found via classloader.
2019-06-13 16:16:04.092  INFO 2988 --- [pool-1-thread-1] o.d.o.packages.WordprocessingMLPackage   : Using paper size: A4
2019-06-13 16:16:04.092  INFO 2988 --- [pool-1-thread-1] o.d.o.packages.WordprocessingMLPackage   : Landscape orientation: false
2019-06-13 16:16:04.118  INFO 2988 --- [pool-1-thread-1] org.docx4j.jaxb.Context                  : java.vendor=Oracle Corporation
2019-06-13 16:16:04.119  INFO 2988 --- [pool-1-thread-1] org.docx4j.jaxb.Context                  : java.version=1.8.0_212
2019-06-13 16:16:04.119  INFO 2988 --- [pool-1-thread-1] org.docx4j.jaxb.Context                  : java.vm.name=OpenJDK 64-Bit Server VM
2019-06-13 16:16:05.222  INFO 2988 --- [pool-1-thread-1] org.docx4j.jaxb.Context                  : JAXB Reference Implementation is in use.
2019-06-13 16:16:05.283  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /word/document.xml
2019-06-13 16:16:05.388  INFO 2988 --- [pool-1-thread-1] org.docx4j.XmlUtils                      : setProperty com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
2019-06-13 16:16:05.388  INFO 2988 --- [pool-1-thread-1] org.docx4j.XmlUtils                      : actual: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
2019-06-13 16:16:05.388  INFO 2988 --- [pool-1-thread-1] org.docx4j.XmlUtils                      : setProperty com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
2019-06-13 16:16:05.388  INFO 2988 --- [pool-1-thread-1] org.docx4j.XmlUtils                      : actual: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
2019-06-13 16:16:05.398  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /word/styles.xml
2019-06-13 16:16:05.403  INFO 2988 --- [pool-1-thread-1] org.docx4j.utils.XPathFactoryUtil        : xpath implementation: org.docx4j.org.apache.xpath.jaxp.XPathFactoryImpl
2019-06-13 16:16:05.407  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /docProps/core.xml
2019-06-13 16:16:05.407  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /docProps/app.xml
2019-06-13 16:16:05.408  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /word/settings.xml
2019-06-13 16:16:05.409  INFO 2988 --- [pool-1-thread-1] o.d.o.p.relationships.RelationshipsPart  : adding part with proposed name: /word/numbering.xml
2019-06-13 16:16:05.440  INFO 2988 --- [pool-1-thread-1] o.d.convert.in.xhtml.XHTMLImporterImpl   : tableFormatting: CLASS_PLUS_OTHER
2019-06-13 16:16:05.440  INFO 2988 --- [pool-1-thread-1] o.d.convert.in.xhtml.XHTMLImporterImpl   : paragraphFormatting: CLASS_PLUS_OTHER
2019-06-13 16:16:05.440  INFO 2988 --- [pool-1-thread-1] o.d.convert.in.xhtml.XHTMLImporterImpl   : runFormatting: CLASS_PLUS_OTHER
2019-06-13 16:16:05.444  WARN 2988 --- [pool-1-thread-1] org.docx4j.utils.ResourceUtils           : Couldn't get resource: docx4j-ImportXHTML.properties
2019-06-13 16:16:05.444  WARN 2988 --- [pool-1-thread-1] o.d.c.in.xhtml.ImportXHTMLProperties     : Couldn't find/read docx4j-ImportXHTML.properties; docx4j-ImportXHTML.properties not found via classloader.
2019-06-13 16:16:05.465  INFO 2988 --- [pool-1-thread-1] o.d.convert.in.xhtml.XHTMLImporterImpl   : 
 /* TABLE STYLES */ 

 /* PARAGRAPH STYLES */ 
.DocDefaults {display:block;margin-bottom: 4mm;line-height: 115%;font-size: 11.0pt;}

 /* CHARACTER STYLES */ 
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: SAX XMLReader in use (parser): org.apache.xerces.parsers.SAXParser
org.docx4j.org.xhtmlrenderer.load INFO:: Loaded document in ~43ms
org.docx4j.org.xhtmlrenderer.load INFO:: TIME: parse stylesheets  60ms
org.docx4j.org.xhtmlrenderer.match INFO:: media = print
org.docx4j.org.xhtmlrenderer.match INFO:: Matcher created with 134 selectors
java.lang.RuntimeException: javax.xml.bind.JAXBException: JAXB: Can't instantiate JAXB Reference Implementation
 - with linked exception:
[java.lang.ClassNotFoundException: org.docx4j.jaxb.ri.NamespacePrefixMapper]
    at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:840)
    at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:716)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.addParagraphProperties(XHTMLImporterImpl.java:2315)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.populatePPr(XHTMLImporterImpl.java:1575)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.getPPr(XHTMLImporterImpl.java:1486)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.traverse(XHTMLImporterImpl.java:1261)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.traverse(XHTMLImporterImpl.java:825)
    at org.docx4j.convert.in.xhtml.XHTMLImporterImpl.convert(XHTMLImporterImpl.java:501)
    at jasper_listener.ReportGenerator.htmlToDocx(ReportGenerator.java:157)
    at jasper_listener.ReportGenerator.generate(ReportGenerator.java:142)
    at jasper_listener.CustomMessageListener.run(CustomMessageListener.java:45)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.xml.bind.JAXBException: JAXB: Can't instantiate JAXB Reference Implementation
 - with linked exception:
[java.lang.ClassNotFoundException: org.docx4j.jaxb.ri.NamespacePrefixMapper]
    at org.docx4j.jaxb.NamespacePrefixMapperUtils.tryUsingRI(NamespacePrefixMapperUtils.java:89)
    at org.docx4j.jaxb.NamespacePrefixMapperUtils.getPrefixMapper(NamespacePrefixMapperUtils.java:65)
    at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:789)
    ... 13 more
Caused by: java.lang.ClassNotFoundException: org.docx4j.jaxb.ri.NamespacePrefixMapper
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at org.docx4j.jaxb.NamespacePrefixMapperUtils.tryUsingRI(NamespacePrefixMapperUtils.java:73)
    ... 15 more

也许有人可以帮我解决这个异常...

谢谢, 纪尧姆。

使用 docx4j,您可以选择要使用的 JAXB。如果要使用参考实现,添加:

<dependency>
  <groupId>org.docx4j</groupId>
  <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
  <version>8.1.0</version>
</dependency>

进一步查看https://search.maven.org/artifact/org.docx4j/docx4j-JAXB-ReferenceImpl/8.1.0/jar

删除您手动添加的所有这些 dep,并将其留给 Maven 来正确完成。

注意:要使用Java8上的参考实现,可能需要注意endorsed dir机制。使用 Java 8,使用 https://search.maven.org/artifact/org.docx4j/docx4j-JAXB-Internal/8.1.0/jar

可能更容易

注2:mvn dependency:tree是你的朋友