【问题标题】:Adding image with docx4j to doc file将带有 docx4j 的图像添加到 doc 文件
【发布时间】:2014-06-13 05:09:38
【问题描述】:

我正在尝试使用 Android 中的 docx4j 库将图像添加到 docx 文件中。
我遇到了一个例外:

E/AndroidRuntime(21818): java.lang.ExceptionInInitializerError
E/AndroidRuntime(21818):    at org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext.newSource(AbstractImageSessionContext.java:134)
E/AndroidRuntime(21818):    at org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext.needSource(AbstractImageSessionContext.java:280)
E/AndroidRuntime(21818):    at org.apache.xmlgraphics.image.loader.cache.ImageCache.needImageInfo(ImageCache.java:123)
E/AndroidRuntime(21818):    at org.apache.xmlgraphics.image.loader.ImageManager.getImageInfo(ImageManager.java:122)
E/AndroidRuntime(21818):    at org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.getImageInfo(BinaryPartAbstractImage.java:696)
E/AndroidRuntime(21818):    at org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.ensureFormatIsSupported(BinaryPartAbstractImage.java:352)
E/AndroidRuntime(21818):    at org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.ensureFormatIsSupported(BinaryPartAbstractImage.java:331)
E/AndroidRuntime(21818):    at org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.createImagePart(BinaryPartAbstractImage.java:298)
E/AndroidRuntime(21818):    at org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.createImagePart(BinaryPartAbstractImage.java:158)
                                ...
E/AndroidRuntime(21818): Caused by: java.lang.NoClassDefFoundError: sun.awt.AppContext
E/AndroidRuntime(21818):    at ae.javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:155)
E/AndroidRuntime(21818):    at ae.javax.imageio.ImageIO.<clinit>(ImageIO.java:65)
                                ...

指的是这段代码:

WordprocessingMLPackage wordMLPackage;
File file;
...
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, file);

我已经将AndroidDocxToHtml 示例(以及ae-awt.jar)中的所有必要库添加到我的应用程序的libs 文件夹中。
如果没有图像,我的应用程序会完美地生成 docx 文件。

有什么办法可以解决吗?
谢谢!

【问题讨论】:

    标签: android ms-word docx docx4j


    【解决方案1】:

    我得到了这个工作,但它需要覆盖来自 ae-awt 和 ae-xmlgraphics-commons 的大约 8 个文件。我硬编码它只处理 jpg 文件。

    删除对 sun.security.action.LoadLibraryAction 的所有引用,然后调用 System.loadLibrary("jpeg")

    移除 AppContext 并用 ImageIO 中的 ThreadGroup 替换它,如下所示:

       private static synchronized CacheInfo getCacheInfo() {
            ThreadGroup group = Thread.currentThread().getThreadGroup();
            CacheInfo info = (CacheInfo) instances.get(group);
    
            //CacheInfo info = (CacheInfo)context.get(CacheInfo.class);
            if (info == null) {
                info = new CacheInfo();
                instances.put(group, info);
            }
            return info;
        }
    

    与 imageio.spi.IIORegistry 相同

    在 ae-xmlgraphics-commons 中,对 ImageManager.java、DefaultImageContext 和 BinaryPartAbstractImage 进行了一些更改。前两个我不记得我做了什么(我不能轻易区分它们,也许不需要更改),但是 BinaryPartAbstractIMage 有很多更改。由于 sessionContext / Context 类型的问题(以某种方式试图确定图像类型并调用适当的预加载器),我将 getImageInfo() 硬编码为 IMAGE_JPEG。所以我假设所有图像都是 jpeg 并强制它始终使用 JPEG 预加载器。

    getImageInfo() ImageInfo info = new ImageInfo(url.toURI().toString(), ContentTypes.IMAGE_JPEG);

    文档中出现了扭曲的图像。我仍然需要弄清楚宽度/高度公式才能正确嵌入。

    【讨论】:

    • 感谢您的回答!我找到了一个无需使用 jpeg 进行硬编码的解决方案。问题是将预加载器设置为org.apache.xmlgraphics.util.Service。见我的answer
    【解决方案2】:

    对于也遇到这个问题的每个人。

    以下是使 docx4j 与图像正常工作的必要步骤:

    1. 使用 ae 将 OpenJDK 中缺失的类添加到适当的包中。
    2. 更改对新类的引用,例如将sun.awt.AppContext 更改为ae.sun.awt.AppContext
    3. org.apache.xmlgraphics.util.Service 中手动填充预加载器列表:

      private static List<String> getProviderNames(Class<?> cls, ClassLoader cl) {
          ...
          if (fillDefautsProviderNames(cls, l))
              return l;
          ...
      }
      
      private static boolean fillDefautsProviderNames(Class<?> cls, List<String> l) {
          if (cls == org.apache.xmlgraphics.image.loader.spi.ImagePreloader.class) {
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderTIFF");
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderGIF");
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderJPEG");
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderBMP");
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderEMF");
              l.add("org.apache.xmlgraphics.image.loader.impl.PreloaderEPS");
              l.add("org.apache.xmlgraphics.image.loader.impl.imageio.PreloaderImageIO");
              return true;
          }
          return false;
      }
      
    4. org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage中删除函数displayImageInfo(ImageInfo info)

    我已经准备了带有更改的存储库:ae-awtae-xmlgraphics-commonsdocx4j-android

    您可以在此处找到已编译的库:docx4j_images_prepared_libs.zip

    享受吧!

    【讨论】:

    • 你有办法使用 DOCX4J 库将 docx 转换为 pdf 吗?
    • @user1616685,我认为您可以使用以下方法进行转换:org.docx4j.convert.out.pdf.PdfConversion c = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage);,然后将结果保存到文件OutputStream os = new java.io.FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/converted.pdf"); c.output(os, new PdfSettings());
    • 您好,感谢您的评论:我已经尝试过了,但它带有Caused by: java.lang.NullPointerException at org.docx4j.utils.ResourceUtils.getResource(ResourceUtils.java:45) at org.docx4j.convert.out.pdf.viaXSLFO.Conversion.&lt;clinit&gt;(Conversion.java:101),请在此处查看我的问题以获取更多信息:stackoverflow.com/questions/31437747/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多