Search code examples
javaapache-poipowerpoint

Using Apache POI, while creating a PowerPoint presentation using XMLSlideShow, how do I add image within a paragraph?


The Apache POI cookbook and various other examples talk about directly adding a picture in PowerPoint as shown below -

XMLSlideShow ppt = new XMLSlideShow();
ppt.createSlide();
byte[] pictureData = IOUtils.toByteArray(new FileInputStream("logo-leaf.png"));

XSLFPictureData pd
= ppt.addPicture(pictureData, PictureData.PictureType.PNG);
XSLFPictureShape picture = slide.createPicture(pd);
picture.setAnchor(new Rectangle(320, 230, 100, 92));

And this works very much as expected.

What I need is a paragraph to show a user profile image next to name and address repeated as per the data -

enter image description here.

This is similar to what we generally view in a social media pages shown in image above which can extend across slides.

I tried but could find relevant methods in XSLFShape.

May be there could be a better way to render this rather than using a paragraph. Any code block, pointers appreciated.


Solution

  • You may want to create group shapes that group a text box and an image shape.

    Example:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    import org.apache.poi.sl.usermodel.*;
    import org.apache.poi.xslf.usermodel.*;
    
    import org.apache.commons.io.IOUtils; 
    
    import java.awt.Rectangle;
    
    public class CreatePPTXGroupShape {
    
     public static void main(String[] args) throws Exception {
         
      Object[][] data = new Object[][] {
       new Object[] {"Koala", IOUtils.toByteArray(new FileInputStream("./Koala.png"))},
       new Object[] {"Squirrel", IOUtils.toByteArray(new FileInputStream("./Squirrel.png"))},
       new Object[] {"Fox", IOUtils.toByteArray(new FileInputStream("./Fox.png"))}
      };
    
      SlideShow slideShow = new XMLSlideShow();
    
      Slide slide = slideShow.createSlide();
      
      int groupLeft = 100;
      int groupTop = 50;
      int groupWidth = 250;
      int groupHeight = 100;
      int groupPadding= 10;
      
      for (Object[] row : data) {
       GroupShape shapeGroup = slide.createGroup();
       shapeGroup.setInteriorAnchor(new Rectangle(groupLeft, groupTop, groupWidth, groupHeight));
       shapeGroup.setAnchor(new Rectangle(groupLeft+groupPadding, groupTop+groupPadding, groupWidth-groupPadding, groupHeight-groupPadding));
     
       int x = groupLeft;
       int y = groupTop;
       int width = 100;
       int height = 100;
    
       TextShape textShape = shapeGroup.createTextBox();
       Rectangle rect = new Rectangle(x, y, width, height);
       textShape.setAnchor(rect);
       String text = (String)row[0];
       textShape.setText(text);
    
       x = groupLeft + 150;
       y = groupTop;
       width = 100;
       height = 100;
    
       byte[] pictureDataByte = (byte[])row[1];
       PictureData pictureData = slideShow.addPicture(pictureDataByte, PictureData.PictureType.PNG);
       PictureShape pictureShape = shapeGroup.createPicture(pictureData);
       rect = new Rectangle(x, y, width, height);
       pictureShape.setAnchor(rect);
    
       groupTop += 110;
      
      }
    
      FileOutputStream out = new FileOutputStream("./CreatePPTXGroupShape.pptx");
      slideShow.write(out);
      out.close();
     }
    }
    

    Result:

    enter image description here