Search code examples
javaapache-poiborderxwpf

How to add image with border into table cell in Word with Apache POI?


I am trying to insert a picture with a border into a table in Microsoft Word with Apache POI. I am able to add an image into a cell with the code below:

// table is a XWPFTable object instantiated earlier in the code
XWPFParagraph paragraph = table.getRow(0).getCell(0).addParagraph();
XWPFRun run = paragraph.createRun();
FileInputStream fis = new FileInputStream("C:\\ [filepath for the image]");
run.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG, "Name", 6217920, 3474720);

I tried looking for ways to add a border to the image, but I haven't been able to find any resources online. I came across this link: Format Picture with Fill and Line using apache poi in Java but it does not help in this case.

(To be specific, I want to add a solid black line which is 2 1/4 pt thick around the image)

Does anybody know how to do achieve this? Thanks in advance.


Solution

  • As always if the current high level apache poi classes not provide some Office Open XML features, do the following:

    First do what is provided and have a look at the underlying XML you get created. In that case, do:

    // table is a XWPFTable object instantiated earlier in the code
    XWPFParagraph paragraph = table.getRow(0).getCell(0).addParagraph();
    XWPFRun run = paragraph.createRun();
    FileInputStream fis = new FileInputStream("C:\\ [filepath for the image]");
    XWPFPicture picture = run.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG, "Name", Units.pixelToEMU(300), Units.pixelToEMU(150));
    System.out.println(picture.getCTPicture());
    

    You will get something like:

    <xml-fragment xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:rel="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
      <pic:nvPicPr>
        <pic:cNvPr id="0" name="Picture 0" descr="Name"/>
        <pic:cNvPicPr>
          <a:picLocks noChangeAspect="true"/>
        </pic:cNvPicPr>
      </pic:nvPicPr>
      <pic:blipFill>
        <a:blip rel:embed="rId2"/>
        <a:stretch>
          <a:fillRect/>
        </a:stretch>
      </pic:blipFill>
      <pic:spPr>
        <a:xfrm>
          <a:off x="0" y="0"/>
          <a:ext cx="2857500" cy="1428750"/>
        </a:xfrm>
        <a:prstGeom prst="rect">
          <a:avLst/>
        </a:prstGeom>
      </pic:spPr>
    </xml-fragment>
    

    Now open the result in Word and add what you want. In that case add the border around the picture. Then save the result, unzip the *.docx Zip archive and have a look at /word/document.xml to get what has changed.

    You will find something like:

    <a:ln w="28575">
      <a:solidFill>
        <a:srgbClr val="000000"/>
      </a:solidFill>
    </a:ln>
    

    added to <pic:spPr>.

    Now try creating that using the low level ooxml-schema classes of apache poi:

    ...
    XWPFPicture picture = run.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG, "Name", Units.pixelToEMU(300), Units.pixelToEMU(150));
    System.out.println(picture.getCTPicture());
    
    picture.getCTPicture().getSpPr().addNewLn().setW(Units.toEMU(2.25));
    picture.getCTPicture().getSpPr().getLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{0,0,0});
    System.out.println(picture.getCTPicture());
    ...