Pregunta

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!

¿Fue útil?

Solución 2

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!

Otros consejos

I got this to work but it required overriding about 8 files from ae-awt and ae-xmlgraphics-commons. And I hardcoded it to handle jpg files only.

Remove all references to sun.security.action.LoadLibraryAction and just call System.loadLibrary("jpeg")

Remove AppContext and replace it with ThreadGroup from ImageIO, like this:

   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;
    }

Same with imageio.spi.IIORegistry

In ae-xmlgraphics-commons, made a few changes to ImageManager.java, DefaultImageContext and BinaryPartAbstractImage. The first 2 I dont remember what I did (i can't diff them easily, maybe no changes were needed), but there were many changes to BinaryPartAbstractIMage. I hardcoded the getImageInfo() to IMAGE_JPEG because of problems with the sessionContext / Context type (that somehow tried to determine the image type and call the appropriate preloader). So I made the assumption that all images are jpegs and force it to always use the JPEG preloader.

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

That got a warped image to appear in the doc. I still have to figure out the width/height formula to get it to embed correctly.

To all of you out there, who are trying to generate a docx file from android studio, please do not try the apache poi library. I lost too many days trying to integrate apache poi and xwpfdocument in my app. You can generate some text, but if you want to add pictures, then it is not possible to do it with apache poi, you will get at the end in the doxc file a rectangle instead of your picture saying the the picture can't be displayed.

I switched than to doxc4j I was having there also issues becuase android is not java, and you need to customize some libs and dependecies as @kirik88 mentioned.

What you need to do is you need to insert all jars of this repo: https://github.com/plutext/AndroidDocxToHtml/tree/master/libs to your android project as local libs. You import all of them except the three jars mentioned in the kirik88's comment: https://stackoverflow.com/a/23710079/20718567, there you download the zip folder with the three jars: ae-awt, ae-xmlgraphics-commons, docx4j-android and you insert then these three jars also in you android project, maybe you need to still do some small changes in these jars if android complains, but yeah this thing is working, and after too many days this is the only solution that is working to create doxc file from android with text+images. Thank you @kirik88 and @Jason Harrop(plutext).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top