Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

how to add a picture to a .docx document with Apache POI XWPF in java

I've created a simple docx-Document, using Java POI 3.7. XWPF. Then, I added a picture by using the Method XWPFDocument.addpicture(byte[] arg0, int arg1).

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("logo.jpg");
byte [] picbytes = IOUtils.toByteArray(pic);
docx.addPicture(picbytes, Document.PICTURE_TYPE_JPEG);

Since file size of the docx grows, the picture was added "physically" to the document; but it is not displayed at all in MS Word. Seems like there is a reference to the picture missing in the document.

What's the way to do this? How is picture handling done with apache POI? And where are more tutorials on the web, there is nearly no documents or tutorials at all for XWPF, which explains handling of paragraphs, runs, etc.

The only thing I found about this is here: https://issues.apache.org/bugzilla/show_bug.cgi?id=49765 but it does not help at all.

Many thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I know this post is very old but still I am posting the answer so that all those who are searching for this answer can use it. For inserting the picture in the word document you have to write two programs. The first one is :-

package org.word.POI;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

/*
Romesh Soni
soni.romesh@gmail.com
*/

public class TestCustom
{

    public static void main(String []a) throws FileNotFoundException, IOException, InvalidFormatException
    {

        CustomXWPFDocument document = new CustomXWPFDocument(new FileInputStream(new File("C:\Users\amitabh\Documents\Apache POI\Word File\new.doc")));
        FileOutputStream fos = new FileOutputStream(new File("C:\Users\amitabh\Documents\Apache POI\Word File\new.doc"));

        String blipId = document.addPictureData(new FileInputStream(new File("C:\Users\amitabh\Pictures\pics\3.jpg")), Document.PICTURE_TYPE_JPEG);

        System.out.println(document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG));

        //System.out.println(document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG));
        document.createPicture(blipId,document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG), 500, 500);


        document.write(fos);
        fos.flush();
        fos.close();

    }

}

Now here I have used "CustomeXwPFDocument" in this code and you will not get any imports through any jar file so you have to add another .java class in your package. the code for "CustomXWPFDocument" class goes like this:-

package org.word.POI;

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

Use POI 3.9 jars for this program. The best URL is:- http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.9-20121203.zip

Now you are ready to fly. Best of luck.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...