Search code examples
androidms-worddocxdocx4j

Adding image with docx4j to doc file


I'm trying to add an image to a docx file using docx4j library within Android.
I've faced to an exception:

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)
                                ...

It is referring to this code:

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

I've already added all necessary libraries from AndroidDocxToHtml example (and ae-awt.jar too) to libs folder of my app.
Without images my app generates docx files perfectly.

Is there any way to solve it?
Thanks!


Solution

  • For everyone, who faced this problem too.

    Here are necessary steps to make docx4j works fine with images:

    1. Add missed classes from OpenJDK to appropriate packages with ae.
    2. Change references to new classes, for example sun.awt.AppContext to ae.sun.awt.AppContext.
    3. In org.apache.xmlgraphics.util.Service manually fill list with preloaders:

      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. Delete function displayImageInfo(ImageInfo info) in org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage.

    I've prepared repositories with changes: ae-awt, ae-xmlgraphics-commons, docx4j-android.

    You can find compiled libs here: docx4j_images_prepared_libs.zip

    Enjoy!