I'm trying to add image to new word doc with docx4j

docx4j, image, java

Solution

Here is a simple example, you can take it as a basis.

import java.io.*;

import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.*;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;

public class Example {
    public static void main(String[] args) throws Exception {
        WordprocessingMLPackage wordprocessingMLPackage = WordprocessingMLPackage.createPackage();
        File file = new File("C://java-duke-logo.jpg" );

        InputStream inputStream = new java.io.FileInputStream(file );
        long fileLength = file.length();    

        byte[] bytes = new byte[(int)fileLength];

        int offset = 0;
        int numRead = 0;

        while(offset < bytes.length
               && (numRead = inputStream.read(bytes, offset, bytes.length-offset)) >= 0) {
            offset += numRead;
        }

        inputStream.close();

        String filenameHint = null;
        String altText = null;

        int id1 = 0;
        int id2 = 1;

        P p = newImage(wordprocessingMLPackage, bytes, filenameHint, altText, id1, id2);

        wordprocessingMLPackage.getMainDocumentPart().addObject(p);
        wordprocessingMLPackage.save(new File("C://Example.docx"));
    }

    public static P newImage( WordprocessingMLPackage wordMLPackage, byte[] bytes, 
            String filenameHint, String altText, int id1, int id2) throws Exception {
        BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
        Inline inline = imagePart.createImageInline( filenameHint, altText, id1, id2);

        ObjectFactory factory = new ObjectFactory();

        P  p = factory.createP();
        R  run = factory.createR();

        p.getParagraphContent().add(run);        
        Drawing drawing = factory.createDrawing();      
        run.getRunContent().add(drawing);       
        drawing.getAnchorOrInline().add(inline);

        return p;
    }   
}

Example.docx:

Problem

I'm trying to add image to new word document using docx4j. I've taken this code from online and modified it for my program, however I receive a strange error and I'm not sure what is causing it or how to debug it... Here's my code ``` private static void test() { WordprocessingMLPackage wordMLPackage = null; try { wordMLPackage = WordprocessingMLPackage.createPackage(); } catch (InvalidFormatException e1) { // TODO Auto-generated catch block e1.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Cannnot create package."); } wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Title", "Hello Word! \n\t" + "Try This!"); byte[] bytes = null; try { bytes = convertImageToByteArray(); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Image file not found."); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Image file exception: " + e1.toString()); } try { addImageToPackage(wordMLPackage, bytes); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Cannot add image to package: " + e.toString()); } try { wordMLPackage.save(new java.io.File("HelloWord7.docx")); } catch (Docx4JException e) { // TODO Auto-generated catch block e.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Cannot save image to file."); } } private static void addImageToPackage(WordprocessingMLPackage wordMLPackage, byte[] bytes) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); int docPrId = 1; int cNvPrId = 2; Inline inline = imagePart.createImageInline("Filename hint", "Alternative text", docPrId, cNvPrId, false); P paragraph = addInlineImageToParagraph(inline); wordMLPackage.getMainDocumentPart().addObject(paragraph); } private static P addInlineImageToParagraph(Inline inline) { // Now add the in-line image to a paragraph ObjectFactory factory = new ObjectFactory(); P paragraph = factory.createP(); R run = factory.createR(); paragraph.getContent().add(run); Drawing drawing = (Drawing) factory.createDrawing(); run.getContent().add(drawing); ((org.docx4j.wml.Drawing) drawing).getAnchorOrInline().add(inline); return paragraph; } private static byte[] convertImageToByteArray() throws IOException { // get DataBufferBytes from Raster WritableRaster raster = logo.getRaster(); DataBufferByte data = (DataBufferByte)raster.getDataBuffer(); return (data.getData()); } ``` I'm getting the following error on ``` BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); ``` Error returned is: Docx4JException: Error checking image format. Here's is how 'logo' is loaded, ``` try { BufferedImage logo = ImageIO.read(getClass().getResourceAsStream("/logo.png")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Cannot load logo for word doc"); } ``` Any help is appreciated, thanks NEW INFORMATION I'm running application as runnable jar and I receive the same error as mentioned above for various image types eg: png, jpg. I have tried running the application within eclipse by calling test() from main() and the application gets stuck, why? How can I debug it? I have modified the code a bit, I pass file to createImagePart instead of byte[] array. ``` public static P newImage(WordprocessingMLPackage wordMLPackage, File file, String filenameHint, String altText, int id1, int id2) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, file); //.createImagePart(wordMLPackage, bytes); javax.swing.JOptionPane.showMessageDialog(panel, "Created image part"); Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false); ObjectFactory factory = new ObjectFactory(); P p = factory.createP(); R run = factory.createR(); p.getContent().add(run); Drawing drawing = (Drawing) factory.createDrawing(); run.getContent().add(drawing); ((org.docx4j.wml.Drawing) drawing).getAnchorOrInline().add(inline); return p; } private static void test() throws Exception { File file = new File("logo.png" ); if (!file.canRead()) javax.swing.JOptionPane.showMessageDialog(panel, "Cannot read file"); if (!file.exists()) javax.swing.JOptionPane.showMessageDialog(panel, "File does not exist"); javax.swing.JOptionPane.showMessageDialog(panel, file.getAbsolutePath()); String filenameHint = null; String altText = null; int id1 = 0; int id2 = 1; P p = newImage(wordMLPackage, file, filenameHint, altText, id1, id2); wordMLPackage.getMainDocumentPart().addObject(p); wordMLPackage.save(new File("Example.docx")); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { wordMLPackage = WordprocessingMLPackage.createPackage(); } catch (InvalidFormatException e2) { // TODO Auto-generated catch block e2.printStackTrace(); javax.swing.JOptionPane.showMessageDialog(panel, "Could not create wordMLPackage: " + e2.toString()); } new Calculator().setVisible(true); } }); } ```

Original source