Search code examples
javaapache-poipresentationapache-poi-4

Using Apache Poi XMLSlideShow, in a XSLFTable table, can we include a rounded rectangle in each cell behind a text paragraph?


In a XSLFTable table, there are two columns - one with text and another is a percentage figure as shown in image below.

enter image description here

While creating the table and data is pretty straightforward, how can the rounded rectangle shape be included in each cell below the text (in the first column), where in width of the rectangle shape is actually the number from second cell ?

Here is the code for the table (in Kotlin, but should be easily converted in Java via IDEA) -


val pptx = XMLSlideShow()
val slide = ppt.createSlide()

val tbl = slide.createTable()
tbl.anchor = Rectangle(10, 90, 200, 150)

// row 1
val tr = tbl.addRow()
val td1 = tr.addCell()
val td2 = tr.addCell()
val r1 = td1.addNewTextParagraph().addNewTextRun()
r1.setText("Option 1")
val r2 = td2.addNewTextParagraph().addNewTextRun()
r2.setText("8.3%")

// row 2
// ...

// row 3
val tr1 = tbl.addRow()
val td3 = tr1.addCell()
val td4 = tr1.addCell()
val r3 = td3.addNewTextParagraph().addNewTextRun()
r1.setText("Option 3")
val r4 = td4.addNewTextParagraph().addNewTextRun()
r4.setText("51.9%")
r4.isBold = true

// row 4
// ...

tbl.setColumnWidth(0, 150.0)
tbl.setColumnWidth(0, 50.0)

Solution

  • One can't have shapes be included in each cell below the text in a PowerPoint table cell. A PowerPoint table cell is a text shape only. Therefore it can contain text only. PowerPoint not provides shapes or pictures aligned inline with text. A table cell may have a background but that cannot be a shape but a picture only.

    So first question about such requirements always is: How would you create what you need using PowerPoint GUI?

    I would do it using group shapes that group two text boxes and a rectangle shape for each option.

    Complete Example:

    import java.io.FileOutputStream;
    
    import org.apache.poi.sl.usermodel.*;
    import org.apache.poi.xslf.usermodel.*;
    
    import java.awt.Rectangle;
    
    public class CreatePPTXGroupShape02 {
    
     public static void main(String[] args) throws Exception {
         
      Object[][] data = new Object[][] {
       new Object[] {"Option1", 8.3, java.awt.Color.LIGHT_GRAY},
       new Object[] {"Option2", 38.3, java.awt.Color.LIGHT_GRAY},
       new Object[] {"Option3", 51.9, java.awt.Color.GREEN},
       new Object[] {"Option4", 1.3, java.awt.Color.LIGHT_GRAY}
      };
    
      SlideShow slideShow = new XMLSlideShow();
    
      Slide slide = slideShow.createSlide();
      
      int groupLeft = 100;
      int groupTop = 50;
      int groupWidth = 500;
      int groupHeight = 40;
      int groupPadding= 10;
    
      TextShape textShape;
      Rectangle rect;
      String text;
      Number value;
      AutoShape autoShape;
      java.awt.Color color;
      
      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;
       int height = 40;
       
       text = (String)row[0];
       value = (Number)row[1];
       color = (java.awt.Color)row[2];
    
       // AutoShape = rounded rect bar  
       width = (int)Math.round(400d * value.doubleValue() / 100d);
       autoShape = shapeGroup.createAutoShape();
       rect = new Rectangle(x, y, width, height);
       autoShape.setAnchor(rect);
       autoShape.setShapeType(ShapeType.ROUND_RECT);
       autoShape.setFillColor(color);
    
       // TextBox = option text
       width = 400;
       textShape = shapeGroup.createTextBox();
       rect = new Rectangle(x, y, width, height);
       textShape.setAnchor(rect);
       textShape.setText(text);
    
       // TextBox = percentages
       x = groupLeft + 400;
       y = groupTop;
       width = 100;
       height = 40;
    
       textShape = shapeGroup.createTextBox();
       rect = new Rectangle(x, y, width, height);
       textShape.setAnchor(rect);
       text = String.valueOf(value);
       textShape.setText(text + " %");
    
       groupTop += 40;
      
      }
    
      FileOutputStream out = new FileOutputStream("./CreatePPTXGroupShape.pptx");
      slideShow.write(out);
      out.close();
     }
    }
    

    Result:

    enter image description here