2011-10-06 86 views
9

He creado un documento docx simple, utilizando Java POI 3.7. XWPF. Luego, agregué una imagen por usando el Método XWPFDocument.addpicture(byte[] arg0, int arg1).cómo agregar una imagen a un documento .docx con Apache POI XWPF en java

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 de 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 o tutoriales para XWPF, 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 lo hace ayuda en absoluto.

Muchas gracias de antemano.

+0

¿Has probado con POI 3.8 beta 4? Algunos errores de imagen se han solucionado desde 3.7 final, por lo que vale la pena ver si la actualización resuelve su problema – Gagravarr

+0

Sí, la única diferencia es que en POI 3.8 beta 4 se cambia el nombre del método XWPFDocument.addPicture (byte [] arg0, int arg1) a XWPFDocument.addPictureData (byte [] arg0, int arg1) - quizás para delinear que este método solo agrega los datos de la imagen al documento, pero no agrega la imagen en un párrafo que se mostrará en palabra, etc. La pregunta de cómo esto sigue sin respuesta. Creo que un objeto CTPicture (org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture) debe crearse y agregarse a un párrafo; sin embargo, no he descubierto cómo hacerlo. –

+0

¿Ha intentado llamar a [addPicture] (http://poi.apache.org/apidocs/org/apache/poi/xwpf/usermodel/XWPFRun.html#addPicture%28java.io.InputStream,%20int,%20java.lang .String,% 20int,% 20int% 29) en la ejecución de texto donde desea que aparezca su imagen? – Gagravarr

Respuesta

0

He usado docx4j y he encontrado que funciona. Probé con POI pero no pude hacerlo funcionar. Busque el código para usar docx4j.

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; 

}

11

Sé que este post es muy viejo, pero todavía estoy publicando la respuesta de modo que todos los que están en busca de esta respuesta puede utilizarlo. Para insertar la imagen en el documento de Word, debe escribir dos programas. La primera 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 
[email protected] 
*/ 

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 utilizado "CustomeXwPFDocument" en este código y que no recibirá las importaciones a través de cualquier archivo jar lo que hay que añadir otra clase .java en el paquete. el código de la clase "CustomXWPFDocument" es la 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 = "" + 
       "<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"); 
    } 
} 

Uso de puntos de interés 3.9 frascos para este programa. La mejor URL es: - http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.9-20121203.zip

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

+0

Gracias amigo, esto ayudó mucho. Sin embargo, no es necesario crear dos programas. Simplemente puede usar el código del método 'createPicture' como quiera en cualquier lugar. –

+0

@Amitabh Rajan: ¿Es posible agregar una imagen en una página y línea en particular y también con la alineación central? – softmage99

+0

@MageshBabu: - amigo, creo que es posible, pero lamento no poder ayudarte en esto. Estuve trabajando en POI el año pasado en una tarea muy pequeña, pero creo que lo que dices es posible. Por favor, juega con el código y creo que obtendrás la respuesta. Lamento mucho no haber podido ayudarte. –

4

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

Puede esperar hasta que mi parche es aceptado y puesto en libertad o tratar de aplicar el parche a la última de pago PDI SVN (http://poi.apache.org/subversion.html, de sólo lectura enlace de acceso funcionará) y la construcción de los POI jar de las fuentes.

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); 
+0

Bienvenido a StackOverflow. Puede crear bloques de código sangrándolos con 4 espacios (o seleccione todo el bloque y haga clic en el ícono '{}'). – Sumurai8

+0

la solución elegante todavía no está aquí, febrero de 2016 – Exceptyon

0
@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. 
-2

Debido XWPFRun.AddPicture no funciona (se fichero daños xdoc) me las arreglo para 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 = "" + "<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; 
     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 corriendo ejemplo:

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