Search code examples
javaapache-poipowerpoint

Setting line join style in Apache Poi Powerpoint shapes


I have a multi-segment line in an Apache Poi XSLFFreeformShape.

By default, the corner join style appears to be Round.

How do I set it to Bevel or Miter?

I'm not finding join styles among the stroke style methods supported by superclass XSLFSimpleShape.

EDIT

Here's what I'm doing for other line attributes:

private void applyLineState( @Nonnull XSLFFreeformShape shape) {
    shape.setLineWidth( ...);
    shape.setLineDash( ... );
    shape.setLineColor( ... );
    shape.setLineHeadDecoration(DecorationShape.NONE);
    shape.setLineCap(LineCap.FLAT);

    // Q: How to set join style for corners?
}

Solution

  • Seems apache poi does not provide setting any line join properties until now. But one could have a look at source code of XSLFSimpleShape for how to set other CTLineProperties. Then program the needed methods using the low level org.openxmlformats.schemas.drawingml.x2006.main.* classes.

    Following complete example shows this:

    import java.io.FileOutputStream;
    
    import org.apache.poi.xslf.usermodel.*;
    import org.apache.poi.sl.usermodel.*;
    
    import org.apache.xmlbeans.XmlObject;
    import org.openxmlformats.schemas.drawingml.x2006.main.*;
    import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
    
    import java.awt.Rectangle;
    import java.awt.geom.Path2D;
    
    public class CreatePPTXFreeformShapeFromPath {
        
     private static CTLineProperties getLn(XSLFShape shape) {
      XmlObject o = shape.getXmlObject();
      if (!(o instanceof CTShape)) return null; 
      CTShape sp = (CTShape)o;
      CTShapeProperties spr = sp.getSpPr();
      if (spr == null) return null;
      return (spr.isSetLn()) ? spr.getLn() : spr.addNewLn();
     }
     
     private enum LineJoinProperty {
      ROUND, MITER, BEVEL
     }
     
     public static void setLineJoinProperty(XSLFSimpleShape shape, LineJoinProperty property) {
      CTLineProperties ln = getLn(shape);
      if (ln == null) return;
      if (ln.isSetBevel()) ln.unsetBevel();
      if (ln.isSetMiter()) ln.unsetMiter();
      if (ln.isSetRound()) ln.unsetRound();
      if (property == LineJoinProperty.BEVEL) {
       CTLineJoinBevel bevel = ln.addNewBevel();
      } else if (property == LineJoinProperty.MITER) { 
       CTLineJoinMiterProperties miter = ln.addNewMiter();
      } else if (property == LineJoinProperty.ROUND) { 
       CTLineJoinRound round = ln.addNewRound();
      }
     }
    
     public static void main(String[] args) throws Exception {
    
      XMLSlideShow slideShow = new XMLSlideShow();
      XSLFSlide slide = slideShow.createSlide();
    
      Path2D.Double path2D = new Path2D.Double();
      path2D.moveTo(0d,0d);
      path2D.lineTo(20d,0d);
      path2D.lineTo(20d,20d);
      path2D.lineTo(40d,20d);
      path2D.lineTo(40d,40d);
      path2D.lineTo(60d,40d);
      path2D.lineTo(60d,60d);
      path2D.lineTo(80d,60d);
      path2D.lineTo(80d,80d);
      path2D.lineTo(100d,80d);
      path2D.lineTo(100d,100d);
      path2D.closePath();
    
      XSLFFreeformShape shape;
      
      //default
      shape = slide.createFreeform();
      shape.setPath(path2D);
      shape.setLineWidth(5.0);
      shape.setLineColor(java.awt.Color.BLACK);
      shape.setAnchor(new Rectangle(50, 100, 300, 300));
    
      //miter
      shape = slide.createFreeform();
      shape.setPath(path2D);
      shape.setLineWidth(5.0);
      shape.setLineColor(java.awt.Color.BLACK);
      shape.setAnchor(new Rectangle(200, 100, 300, 300));
      setLineJoinProperty(shape, LineJoinProperty.MITER);
    
      //bevel
      shape = slide.createFreeform();
      shape.setPath(path2D);
      shape.setLineWidth(5.0);
      shape.setLineColor(java.awt.Color.BLACK);
      shape.setAnchor(new Rectangle(350, 100, 300, 300));
      setLineJoinProperty(shape, LineJoinProperty.BEVEL);
      
      FileOutputStream out = new FileOutputStream("CreatePPTXFreeformShapeFromPath.pptx");
      slideShow.write(out);
      out.close();
     }
    }
    

    This is tested using apache poi 4.1.2 and ooxml-schemas-1.4.jar. Note, this example needs ooxml-schemas-1.4.jar as poi-ooxml-schemas-4.1.2.jar only contains org.openxmlformats.schemas.drawingml.x2006.main.* classes which are used by apache poi 4.1.2 directly.