cómo agregar una imagen a un documento .docx con Apache POI XWPF en Java

Creé un documento docx simple, usando Java POI 3.7. XWPF. Luego, agregué una imagen usando el Método 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); 

Dado que el tamaño del archivo del docx crece, la imagen se agregó “físicamente” al documento; pero no se muestra en absoluto en MS Word. Parece que hay una referencia a la imagen que falta en el documento.

¿Cuál es la manera de hacer esto? ¿Cómo se maneja la imagen con Apache POI? Y donde hay más tutoriales en la web, casi no hay documentos ni tutoriales para XWPF, lo que explica el manejo de párrafos, ejecuciones, etc.

Lo único que encontré sobre esto es aquí: https://issues.apache.org/bugzilla/show_bug.cgi?id=49765 pero no ayuda en absoluto.

Muchas gracias de antemano.

Sé que esta publicación es muy antigua, pero aún así estoy publicando la respuesta para que todos los que estén buscando esta respuesta puedan usarla. Para insertar la imagen en el documento de Word, debe escribir dos progtwigs. El primero es :-

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

Ahora aquí he usado “CustomeXwPFDocument” en este código y no obtendrás ninguna importación a través de ningún archivo jar, así que tienes que agregar otra clase .java en tu paquete. el código para la clase “CustomXWPFDocument” es el siguiente:

 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 = "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; //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 jar para este progtwig. La mejor URL es: – http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.9-20121203.zip

Ahora estás listo para volar. La mejor de las suertes.

La solución elegante está por venir, echa un vistazo a: https://issues.apache.org/bugzilla/show_bug.cgi?id=55476

Puede esperar hasta que mi parche sea aceptado y liberado o tratar de aplicar el parche al último POI SVN checkout ( http://poi.apache.org/subversion.html , el enlace de acceso de solo lectura funcionará) y construir los PDI jar de las fonts .

El enfoque sugerido por tsd.tom funcionará:

 XWPFParagraph par = docx.createParagraph(); XWPFRun run = par.createRun(); run.addPicture(pic, XWPFDocument.PICTURE_TYPE_JPEG, "logo.JPG",300,300); 

El enlace de error que ha proporcionado en realidad tiene una solución de trabajo: http://sofes.miximages.com/java/show_bug.cgi“); // commons-io.jar byte[] bytes = IOUtils.toByteArray(is); String filenameHint = null; String altText = null; int id1 = 0; int id2 = 1; org.docx4j.wml.P p = newImage( wordMLPackage, bytes,filenameHint, altText,id1, id2,6000 ); // Now add our p to the document wordMLPackage.getMainDocumentPart().addObject(p); wordMLPackage.save(new java.io.File(“helloworld.docx”) ); is.close(); } public static org.docx4j.wml.P newImage( WordprocessingMLPackage wordMLPackage, byte[] bytes, String filenameHint, String altText, int id1, int id2, long cx) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); Inline inline = imagePart.createImageInline(filenameHint, altText,id1, id2, cx,false); // Now add the inline in w:p/w:r/w:drawing org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory(); org.docx4j.wml.P p = factory.createP(); org.docx4j.wml.R run = factory.createR(); p.getContent().add(run); org.docx4j.wml.Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); return p;

}

 @Pradeep Your code public static void main(String[] args) throws Exception { WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(); //wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Title", "Hello World"); //wordMLPackage.getMainDocumentPart().addParagraphOfText("Text"); java.io.InputStream is = new java.io.FileInputStream("path\\to\\images.jpg"); // commons-io.jar byte[] bytes = IOUtils.toByteArray(is); String filenameHint = null; String altText = null; int id1 = 0; int id2 = 1; org.docx4j.wml.P p = newImage( wordMLPackage, bytes,filenameHint, altText,id1, id2,6000 ); // Now add our p to the document wordMLPackage.getMainDocumentPart().addObject(p); wordMLPackage.save(new java.io.File("helloworld.docx") ); is.close(); } public static org.docx4j.wml.P newImage( WordprocessingMLPackage wordMLPackage, byte[] bytes, String filenameHint, String altText, int id1, int id2, long cx) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); Inline inline = imagePart.createImageInline(filenameHint, altText,id1, id2, cx,false); // Now add the inline in w:p/w:r/w:drawing org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory(); org.docx4j.wml.P p = factory.createP(); org.docx4j.wml.R run = factory.createR(); p.getContent().add(run); org.docx4j.wml.Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); return p; works , but all the above codes does not work, i tried it personally thanks, a lot. 

Debido a que XWPFRun.addPicture no funciona (daña el archivo xdoc) me las arreglo para crear una imagen como esta:

  private void addPicture(final String fileName, final int id, int width, int height, final XWPFRun run) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream("/home/maq/ebworkspace/TeamForge_Tools/" + fileName); final String blipId = run.getDocument().addPictureData(fileInputStream, Document.PICTURE_TYPE_JPEG); final int EMU = 9525; width *= EMU; height *= EMU; //String blipId = getAllPictures().get(id).getPackageRelationship().getId(); final CTInline inline = run.getCTR().addNewDrawing().addNewInline(); final String picXml = "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData(); XmlToken xmlToken = null; xmlToken = XmlToken.Factory.parse(picXml); inline.set(xmlToken); //graphicData.set(xmlToken); inline.setDistT(0); inline.setDistB(0); inline.setDistL(0); inline.setDistR(0); final CTPositiveSize2D extent = inline.addNewExtent(); extent.setCx(width); extent.setCy(height); final CTNonVisualDrawingProps docPr = inline.addNewDocPr(); docPr.setId(id); docPr.setName("Picture " + id); docPr.setDescr("Generated"); } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { //close streams if (fileInputStream != null) { try { fileInputStream.close(); } catch (final IOException ioEx) { //can be ignored } } } } 

Y ejemplo de ejecución:

  addPicture(filePath, xdoc.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG), 100, 50, xRun);