Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert picture in word document

This is the first time I am working on Apache POI and the question which I am going to ask has been asked already on this site but no clear answer were given for them so I have no choice but to take all your help.

I am trying to write a java program which takes images from one folder and insert that image into a word document. I am using Apache POI for this program. Here I am posting my code.

import java.io.*;
import java.util.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.*;

public class ImagesDoc 
{
    public static void main(String[] args) throws IOException 
    {
        XWPFDocument docx = new XWPFDocument();
        XWPFParagraph par = docx.createParagraph();
        XWPFRun run = par.createRun();
        run.setText("Hello, World. This is my first java generated docx-file. Have fun.");
        run.setFontSize(13);
        InputStream pic = new FileInputStream("C:\\Users\\amitabh\\Pictures\\pics\\pool.jpg");
        byte [] picbytes = IOUtils.toByteArray(pic);
        docx.addPicture(picbytes, Document.PICTURE_TYPE_JPEG);

        FileOutputStream out = new FileOutputStream("C:\\Users\\amitabh\\Pictures\\pics\\simple1.docx"); 
        docx.write(out); 
        out.close(); 
        pic.close();
    }
}

I am able to create the word document file and I am able to insert the text as well but docx.addPicture(picbytes, Document.PICTURE_TYPE_JPEG); line is giving me the error as"add cast to docx". I have added all possible jars for this program. For this error I have searched all over the net and found that many people are having similar problem. "addPicture" for XWPFDocument reference is not working. Please help me to resolve this problem.

like image 544
Amitabh Ranjan Avatar asked Jul 19 '13 11:07

Amitabh Ranjan


2 Answers

First, I would like to point out the example provided by apache poi - Link, i.e. the correct way to do it would be

doc.createParagraph().createRun().addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(200), Units.toEMU(200));

However, there is still an existing bug which renders the .docx file unreadable after executing the above statement. It might be resolved soon, in which case the above-mentioned statement will do the work. For the meantime, there is a work-around.

First, generate the docx file without any pictures. Then add this class CustomXWPFDocument to your package.

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

import java.io.IOException;
import java.io.InputStream;

public class CustomXWPFDocument extends XWPFDocument
{
    public CustomXWPFDocument(InputStream in) throws IOException
    {
        super(in);
    }

    public void createPicture(String blipId,int id, int width, int height)
    {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        //String blipId = getAllPictures().get(id).getPackageRelationship().getId();


        CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try
        {
            xmlToken = XmlToken.Factory.parse(picXml);
        }
        catch(XmlException xe)
        {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
}

Then, create the updated document by adding your pictures like this :-

CustomXWPFDocument document = new CustomXWPFDocument(new FileInputStream(new File("C:\\Users\\Avarice\\Desktop\\doc1.docx")));
        FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\Avarice\\Desktop\\doc2.docx"));
        String id = document.addPictureData(new FileInputStream(new File("C:\\Users\\Avarice\\Desktop\\thumbnail.jpg")), Document.PICTURE_TYPE_JPEG);
        document.createPicture(id,document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG), 64, 64);
        document.write(fos);
        fos.flush();
        fos.close();

You should also have the following jars in your build path:-

poi-ooxml-schemas

xmlbeans

dom4j

like image 92
Avik Avatar answered Oct 19 '22 19:10

Avik


    I have used poi 3.10 to generate word doc and to insert a picture. you need 2 classes.. here is the example

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.List;

    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.util.Units;
    import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
    import org.apache.poi.xwpf.usermodel.Document;
    import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
    import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFHeader;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.xmlbeans.XmlException;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

    public class ImageAttachmentInDocument {
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {

            DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
            Calendar cal = Calendar.getInstance();
            String date = dateFormat.format(cal.getTime());

            // Create a document file
            CustomXWPFDocument document = new CustomXWPFDocument();

            // Adding a file
            try {

                // Working addPicture Code below...
                XWPFParagraph paragraphX = document.createParagraph();
                paragraphX.setAlignment(ParagraphAlignment.CENTER);

                String blipId = paragraphX.getDocument().addPictureData(
                        new FileInputStream(new File("D://c2//WLB.jpg")),
                        Document.PICTURE_TYPE_JPEG);
                System.out.println("4" + blipId);
                System.out.println(document
                        .getNextPicNameNumber(Document.PICTURE_TYPE_JPEG));
                document.createPicture(blipId,
                        document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG),
                        200, 75);
                System.out.println("5");

            } catch (InvalidFormatException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // insert doc details
            // Createa a para -1
            XWPFParagraph paragraphOne = document.createParagraph();
            paragraphOne.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun paragraphOneRunOne = paragraphOne.createRun();
            paragraphOneRunOne.setBold(true);
            paragraphOneRunOne.setFontSize(20);
            paragraphOneRunOne.setFontFamily("Verdana");
            paragraphOneRunOne.setColor("000070");
            paragraphOneRunOne.setText("Daily Status Report");

            // Createa a para -2
            XWPFParagraph paragraphTwo = document.createParagraph();
            paragraphTwo.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun paragraphTwoRunOne = paragraphTwo.createRun();
            paragraphTwoRunOne.setFontSize(12);
            paragraphTwoRunOne.setFontFamily("Verdana");
            paragraphTwoRunOne.setColor("000070");
            paragraphTwoRunOne.setText(date);
            paragraphTwoRunOne.addBreak();

            // Createa a para -3
            XWPFParagraph paragraphThree = document.createParagraph();
            paragraphThree.setAlignment(ParagraphAlignment.LEFT);
            XWPFRun paragraphThreeRunOne = paragraphThree.createRun();
            paragraphThreeRunOne.setFontSize(14);
            paragraphThreeRunOne.setFontFamily("Verdana");
            paragraphThreeRunOne.setColor("000070");
            paragraphThreeRunOne.setText("5.30 AM PST");
            paragraphThreeRunOne.addBreak();

            // Createa a para -4
            XWPFParagraph paragraphFour = document.createParagraph();
            paragraphFour.setAlignment(ParagraphAlignment.LEFT);
            XWPFRun paragraphFourRunOne = paragraphFour.createRun();
            paragraphFourRunOne.setBold(true);
            paragraphFourRunOne.setUnderline(UnderlinePatterns.SINGLE);
            paragraphFourRunOne.setFontSize(10);
            paragraphFourRunOne.setFontFamily("Verdana");
            paragraphFourRunOne.setColor("000070");
            paragraphFourRunOne.setText("ABCD");

            // insert doc details end

            XWPFParagraph paragraphFive = document.createParagraph();
            paragraphFive.setAlignment(ParagraphAlignment.RIGHT);
            XWPFRun paragraphFiveRunOne = paragraphFive.createRun();
            paragraphFiveRunOne.addBreak();
            paragraphFourRunOne.setBold(true);
            paragraphFourRunOne.setUnderline(UnderlinePatterns.SINGLE);
            paragraphFourRunOne.setFontSize(10);
            paragraphFourRunOne.setFontFamily("Verdana");
            paragraphFourRunOne.setColor("000070");
            paragraphFourRunOne.setText("ABCD00000000000");

            FileOutputStream outStream = null;
            try {
                double x = Math.random();
                String fileName = "D:\\c2\\" + String.valueOf(x) + ".docx";
                outStream = new FileOutputStream(fileName);
            } catch (FileNotFoundException e) {
                System.out.println("First Catch");
                e.printStackTrace();
            }
            try {
                document.write(outStream);
                outStream.close();
            } catch (FileNotFoundException e) {
                System.out.println("Second Catch");
                e.printStackTrace();
            } catch (IOException e) {
                System.out.println("Third Catch");
                e.printStackTrace();
            }
        }
    }

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

import java.io.IOException;
import java.io.InputStream;

public class CustomXWPFDocument extends XWPFDocument
{
    public CustomXWPFDocument()    {
     super();
    }

    public CustomXWPFDocument(InputStream in) throws IOException
    {
        super(in);
    }



    public void createPicture(String blipId,int id, int width, int height)
    {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        //String blipId = getAllPictures().get(id).getPackageRelationship().getId();


        CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try
        {
            xmlToken = XmlToken.Factory.parse(picXml);
        }
        catch(XmlException xe)
        {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
}
like image 27
Arindam Avatar answered Oct 19 '22 19:10

Arindam