Insert picture in word document

后端 未结 2 1862
有刺的猬
有刺的猬 2020-11-30 10:46

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 h

相关标签:
2条回答
  • 2020-11-30 11:05
        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");
        }
    }
    
    0 讨论(0)
  • 2020-11-30 11:13

    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

    0 讨论(0)
提交回复
热议问题