Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add image into a word .docx document header using POI XWPF

I've been trying to add .png image to .docx file header with Apache POI. I did´t find a method that help me. someone know how do it? Whith this code I could add only text.

XWPFDocument docc = new XWPFDocument(); 
CTP ctpHeader = CTP.Factory.newInstance(); 
CTR ctrHeader = ctpHeader.addNewR(); 
CTText ctHeader = ctrHeader.addNewT(); 
String headerText = "mi encabezado"; 
ctHeader.setStringValue(headerText); 

XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, docc); XWPFParagraph[] parsHeader = new XWPFParagraph[1]; 
parsHeader[0] = headerParagraph; header.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader);
like image 939
MMora Avatar asked Dec 10 '22 18:12

MMora


1 Answers

Example for creating a Word document with header and footer and an image in the header:

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

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));


  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}

Edit Mar 29 2016:

This had worked until apache poi 3.13. Now with 3.14 it works not more. Reason: POI will not save the blip reference for images in header paragraphs anymore.

/word/header1.xml:

Code compiled and run with 3.13:

...
<pic:blipFill><a:blip r:embed="rId1"/>
...

Same code compiled and run with 3.14:

...
<pic:blipFill><a:blip r:embed=""/>
...

Edit Mar 31 2016:

Found the problem. Someone was the opinion the public final PackageRelationship getPackageRelationship() needs to be deprecated. So in XWPFRun.java the code in public XWPFPicture addPicture(...) was changed

from version 3.13:

...
            CTBlipFillProperties blipFill = pic.addNewBlipFill();
            CTBlip blip = blipFill.addNewBlip();
            blip.setEmbed(picData.getPackageRelationship().getId());
...

to version 3.14:

...
            CTBlipFillProperties blipFill = pic.addNewBlipFill();
            CTBlip blip = blipFill.addNewBlip();
            blip.setEmbed(parent.getDocument().getRelationId(picData));
...

But parent.getDocument() is the XWPFDocument always while the picData possible is related to the XWPFHeaderFooter.

At the beginning of the public XWPFPicture addPicture(...) the programmers have already know this.

...
        if (parent.getPart() instanceof XWPFHeaderFooter) {
            XWPFHeaderFooter headerFooter = (XWPFHeaderFooter)parent.getPart();
            relationId = headerFooter.addPictureData(pictureData, pictureType);
            picData = (XWPFPictureData) headerFooter.getRelationById(relationId);
        } else {
            XWPFDocument doc = parent.getDocument();
            relationId = doc.addPictureData(pictureData, pictureType);
            picData = (XWPFPictureData) doc.getRelationById(relationId);
        }
...

So if the depreciation should really be enforced, this if..else must also be used while setting the blipID. But why the depreciation at all?

The apache poi 3.14 version lol

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

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  XWPFPicture picture = run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));
  System.out.println(picture); //XWPFPicture is added
  System.out.println(picture.getPictureData()); //but without access to XWPFPictureData (no blipID)

  String blipID = "";
  for(XWPFPictureData picturedata : header.getAllPackagePictures()) {
   blipID = header.getRelationId(picturedata);
   System.out.println(blipID); //the XWPFPictureData are already there
  }
  picture.getCTPicture().getBlipFill().getBlip().setEmbed(blipID); //now they have a blipID also
  System.out.println(picture.getPictureData());

  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}

Edit Mar 28 2017:

In apache poi version 3.16 Beta 2 this seems to be fixed since the following code works using apache poi version 3.16 Beta 2:

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

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;

import java.math.BigInteger;

public class CreateWordHeaderFooter2 {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum....");

  // create header start
  CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);

  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
  tabStop.setVal(STTabJc.RIGHT);
  int twipsPerInch =  1440;
  tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

  run = paragraph.createRun();  
  run.setText("The Header:");
  run.addTab();

  run = paragraph.createRun();  
  String imgFile="Koala.png";
  run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50));


  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("The Footer:");


  doc.write(new FileOutputStream("test.docx"));

 }
}
like image 180
Axel Richter Avatar answered Jan 05 '23 00:01

Axel Richter