Search code examples
javachartsapache-poi

java create a chart in a powerpoint using APACHE POI


How do we create a chart in a ppt in java using apache poi. Which POI API do we use. Below is code I am using to create a text box

XSLFSlide slide = pptx.createSlide();
XSLFTextShape textShape = slide.createTextBox();
textShape.setText(data);

The slide object doesnt contain any api for creating a chart.

Any solution to this?

Thanks in advance


Solution

  • There is nothing like a XSLFChartShape usable in a powerpoint slide in apache poi until now.

    But of course if one knows the internal structure of the *.pptx ZIP archive and the XML therein, then it is possible creating this from scratch using the apache poi OPCPackage classes and the low level CT* classes from org.openxmlformats.schemas.drawingml.x2006.* and org.openxmlformats.schemas.presentationml.x2006.*.

    Following code is doing this and creates a slide having a pie chart and a bar chart.

    This is a draft only to show the approach.

    import java.io.*;
    
    import org.apache.poi.*;
    import org.apache.poi.xslf.usermodel.*;
    import org.apache.poi.util.*;
    import org.apache.poi.openxml4j.opc.*;
    import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
    
    import org.apache.xmlbeans.*;
    
    import org.openxmlformats.schemas.drawingml.x2006.chart.*;
    import org.openxmlformats.schemas.drawingml.x2006.main.*;
    import org.openxmlformats.schemas.presentationml.x2006.main.*;
    
    import javax.xml.namespace.QName;
    
    import java.util.regex.Pattern;
    
    import java.awt.geom.Rectangle2D;
    import java.awt.Rectangle;
    
    public class CreatePPTXCharts {
    
     public CreatePPTXCharts() throws Exception {
      XMLSlideShow slideShow = new XMLSlideShow();
      XSLFSlide slide = slideShow.createSlide();
    
      MyXSLFChartShape myXSLFChartShape = createXSLFChart(slide);
      myXSLFChartShape.setAnchor(new Rectangle(50,100,300,300));
    
      drawPieChart(myXSLFChartShape);
    
      myXSLFChartShape = createXSLFChart(slide);
      myXSLFChartShape.setAnchor(new Rectangle(370,100,300,300));
    
      drawBarChart(myXSLFChartShape);
    
    
      FileOutputStream out = new FileOutputStream("CreatePPTXCharts.pptx");
      slideShow.write(out);
      out.close();
     }
    
     //a method for creating the chart XML document /ppt/charts/chart*.xml in the *.pptx ZIP archive
     //and creating a MyXSLFChartShape as slide shape  
     public MyXSLFChartShape createXSLFChart(XSLFSlide slide) throws Exception {
    
      OPCPackage oPCPackage = slide.getSlideShow().getPackage();
      int chartCount = oPCPackage.getPartsByName(Pattern.compile("/ppt/charts/chart.*")).size() + 1;
      PackagePartName partName = PackagingURIHelper.createPartName("/ppt/charts/chart" + chartCount + ".xml");
      PackagePart part = oPCPackage.createPart(partName, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml");
    
      MyXSLFChart myXSLFChart = new MyXSLFChart(part);
      MyXSLFChartShape myXSLFChartShape = new MyXSLFChartShape(slide, myXSLFChart);
    
      return myXSLFChartShape;
    
     }
    
     public void drawPieChart(MyXSLFChartShape myXSLFChartShape) {
    
      CTChartSpace chartSpace = myXSLFChartShape.getMyXSLFChart().getChartSpace();
      CTPieChart cTPieChart = chartSpace.addNewChart().addNewPlotArea().addNewPieChart();
      cTPieChart.addNewVaryColors().setVal(true);
      CTPieSer cTPieSer = cTPieChart.addNewSer();
      cTPieSer.addNewIdx().setVal(0);
      CTStrRef cTStrRef = cTPieSer.addNewTx().addNewStrRef();
      cTStrRef.setF("Label 0");
      cTStrRef.addNewStrCache().addNewPtCount().setVal(1);
      CTStrVal cTStrVal = cTStrRef.getStrCache().addNewPt();
      cTStrVal.setIdx(0);
      cTStrVal.setV("Val");
    
      cTStrRef = cTPieSer.addNewCat().addNewStrRef();
      cTStrRef.setF("Categories");
      
      cTStrRef.addNewStrCache().addNewPtCount().setVal(3);
      for (int r = 1; r < 4; r++) { 
       cTStrVal = cTStrRef.getStrCache().addNewPt();
       cTStrVal.setIdx(r-1);
       cTStrVal.setV("Cat" + r);
      }
    
      CTNumRef cTNumRef = cTPieSer.addNewVal().addNewNumRef();
      cTNumRef.setF("0");
    
      cTNumRef.addNewNumCache().addNewPtCount().setVal(3);
      for (int r = 1; r < 4; r++) { 
       CTNumVal cTNumVal = cTNumRef.getNumCache().addNewPt();
       cTNumVal.setIdx(r-1);
       cTNumVal.setV("" + (10*r));
      }
    
     }
    
     public void drawBarChart(MyXSLFChartShape myXSLFChartShape) {
    
      CTChartSpace chartSpace = myXSLFChartShape.getMyXSLFChart().getChartSpace();
      CTChart cTChart = chartSpace.addNewChart();
      CTPlotArea cTPlotArea = cTChart.addNewPlotArea();
      CTBarChart cTBarChart = cTPlotArea.addNewBarChart();
      cTBarChart.addNewVaryColors().setVal(true);
      cTBarChart.addNewBarDir().setVal(STBarDir.COL);
    
      for (int r = 1; r < 5; r++) {
       CTBarSer cTBarSer = cTBarChart.addNewSer();
       CTStrRef cTStrRef = cTBarSer.addNewTx().addNewStrRef();
       cTStrRef.setF("Label " + r);
       cTStrRef.addNewStrCache().addNewPtCount().setVal(1);
       CTStrVal cTStrVal = cTStrRef.getStrCache().addNewPt();
       cTStrVal.setIdx(0);
       cTStrVal.setV("Val" + r);
    
       cTBarSer.addNewIdx().setVal(r-1);  
       cTStrRef = cTBarSer.addNewCat().addNewStrRef();
       cTStrRef.setF("Categories");
       cTStrRef.addNewStrCache().addNewPtCount().setVal(3);
       for (int c = 1; c < 4; c++) { 
        cTStrVal = cTStrRef.getStrCache().addNewPt();
        cTStrVal.setIdx(c-1);
        cTStrVal.setV("Cat" + c);
       }
    
       CTNumRef cTNumRef = cTBarSer.addNewVal().addNewNumRef();
       cTNumRef.setF("" + r);
       cTNumRef.addNewNumCache().addNewPtCount().setVal(3);
       for (int c = 1; c < 4; c++) { 
        CTNumVal cTNumVal = cTNumRef.getNumCache().addNewPt();
        cTNumVal.setIdx(c-1);
        cTNumVal.setV("" + ((10+r)*c));
       }
      } 
    
      //telling the BarChart that it has axes and giving them Ids
      cTBarChart.addNewAxId().setVal(123456);
      cTBarChart.addNewAxId().setVal(123457);
    
      //cat axis
      CTCatAx cTCatAx = cTPlotArea.addNewCatAx(); 
      cTCatAx.addNewAxId().setVal(123456); //id of the cat axis
      CTScaling cTScaling = cTCatAx.addNewScaling();
      cTScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
      cTCatAx.addNewDelete().setVal(false);
      cTCatAx.addNewAxPos().setVal(STAxPos.B);
      cTCatAx.addNewCrossAx().setVal(123457); //id of the val axis
      cTCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
      //val axis
      CTValAx cTValAx = cTPlotArea.addNewValAx(); 
      cTValAx.addNewAxId().setVal(123457); //id of the val axis
      cTScaling = cTValAx.addNewScaling();
      cTScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
      cTValAx.addNewDelete().setVal(false);
      cTValAx.addNewAxPos().setVal(STAxPos.L);
      cTValAx.addNewCrossAx().setVal(123456); //id of the cat axis
      cTValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
      //legend
      CTLegend cTLegend = cTChart.addNewLegend();
      cTLegend.addNewLegendPos().setVal(STLegendPos.B);
      cTLegend.addNewOverlay().setVal(false);
    
     }
    
     public static void main(String[] args) throws Exception {
      CreatePPTXCharts createPPTXCharts = new CreatePPTXCharts();
     }
    
    //________________________________________________________________________
    
    
     //a class for providing a MyXSLFChartShape
     private class MyXSLFChartShape {
      private CTGraphicalObjectFrame _graphicalObjectFrame;
      private XSLFSlide slide;
      private MyXSLFChart myXSLFChart;
    
      MyXSLFChartShape(XSLFSlide slide, MyXSLFChart myXSLFChart) throws Exception {
    
       String rId = "rId" + (slide.getRelationParts().size()+1);
       slide.addRelation(rId, XSLFRelation.CHART, myXSLFChart);
    
       long cNvPrId = 1;
       String cNvPrName = "MyChart";
       int cNvPrNameCount = 1;
       for (CTGraphicalObjectFrame currGraphicalObjectFrame : slide.getXmlObject().getCSld().getSpTree().getGraphicFrameList()) {
        if (currGraphicalObjectFrame.getNvGraphicFramePr() != null) {
         if (currGraphicalObjectFrame.getNvGraphicFramePr().getCNvPr() != null) {
          cNvPrId++;
          if (currGraphicalObjectFrame.getNvGraphicFramePr().getCNvPr().getName().startsWith(cNvPrName)) {
           cNvPrNameCount++;
          }
         }
        }
       }
    
       CTGraphicalObjectFrame graphicalObjectFrame = slide.getXmlObject().getCSld().getSpTree().addNewGraphicFrame();
       CTGraphicalObjectFrameNonVisual cTGraphicalObjectFrameNonVisual = graphicalObjectFrame.addNewNvGraphicFramePr();
       cTGraphicalObjectFrameNonVisual.addNewCNvGraphicFramePr();
       cTGraphicalObjectFrameNonVisual.addNewNvPr();
    
       CTNonVisualDrawingProps cTNonVisualDrawingProps = cTGraphicalObjectFrameNonVisual.addNewCNvPr();
       cTNonVisualDrawingProps.setId(cNvPrId);
       cTNonVisualDrawingProps.setName("MyChart" + cNvPrNameCount);
    
       CTGraphicalObject graphicalObject = graphicalObjectFrame.addNewGraphic();
       CTGraphicalObjectData graphicalObjectData = CTGraphicalObjectData.Factory.parse(
         "<c:chart xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\" "
        +"xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
        +"r:id=\"" + rId + "\"/>"
       );
       graphicalObjectData.setUri("http://schemas.openxmlformats.org/drawingml/2006/chart");
       graphicalObject.setGraphicData(graphicalObjectData);
    
       _graphicalObjectFrame = graphicalObjectFrame;
       this.slide = slide;
       this.myXSLFChart = myXSLFChart;
    
       this.setAnchor(new Rectangle());
      }
    
      private void setAnchor(Rectangle2D anchor) {
       CTTransform2D xfrm = (_graphicalObjectFrame.getXfrm() != null) ? _graphicalObjectFrame.getXfrm() : _graphicalObjectFrame.addNewXfrm();
       CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
       long x = Units.toEMU(anchor.getX());
       long y = Units.toEMU(anchor.getY());
       off.setX(x);
       off.setY(y);
       CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt();
       long cx = Units.toEMU(anchor.getWidth());
       long cy = Units.toEMU(anchor.getHeight());
       ext.setCx(cx);
       ext.setCy(cy);
      }
    
      private MyXSLFChart getMyXSLFChart() {
       return myXSLFChart;
      }
    
     }
    
     //a wrapper class for the ChartSpaceDocument /ppt/charts/chart*.xml in the *.pptx ZIP archive  
     private class MyXSLFChart extends POIXMLDocumentPart {
    
      private CTChartSpace chartSpace;
    
      private MyXSLFChart(PackagePart part) throws Exception {
       super(part);
       chartSpace = ChartSpaceDocument.Factory.newInstance().addNewChartSpace();
      }
    
      private CTChartSpace getChartSpace() {
       return chartSpace;
      }
    
      @Override
      protected void commit() throws IOException {
       XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
       xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
       PackagePart part = getPackagePart();
       OutputStream out = part.getOutputStream();
       chartSpace.save(out, xmlOptions);
       out.close();
      }
    
     }
    
    }
    

    Code which is producing the same but having XSSFWorkbooks as data tables.

    import java.io.*;
    
    import org.apache.poi.*;
    import org.apache.poi.xslf.usermodel.*;
    import org.apache.poi.xssf.usermodel.*;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.*;
    import org.apache.poi.util.*;
    import org.apache.poi.openxml4j.opc.*;
    import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
    
    import org.apache.xmlbeans.*;
    
    import org.openxmlformats.schemas.drawingml.x2006.chart.*;
    import org.openxmlformats.schemas.drawingml.x2006.main.*;
    import org.openxmlformats.schemas.presentationml.x2006.main.*;
    
    import javax.xml.namespace.QName;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.List;
    import java.util.regex.Pattern;
    
    import java.awt.geom.Rectangle2D;
    import java.awt.Rectangle;
    
    public class CreatePPTXChartsXSSFWb {
    
     public CreatePPTXChartsXSSFWb() throws Exception {
      XMLSlideShow slideShow = new XMLSlideShow();
      XSLFSlide slide = slideShow.createSlide();
    
      MyXSLFChartShape myXSLFChartShape = createXSLFChart(slide);
      myXSLFChartShape.setAnchor(new Rectangle(50,100,300,300));
    
      drawPieChart(myXSLFChartShape);
    
      myXSLFChartShape = createXSLFChart(slide);
      myXSLFChartShape.setAnchor(new Rectangle(370,100,300,300));
    
      drawBarChart(myXSLFChartShape);
    
      FileOutputStream out = new FileOutputStream("CreatePPTXChartsXSSFWb.pptx");
      slideShow.write(out);
      out.close();
     }
    
     //a method for creating the chart XML document /ppt/charts/chart*.xml in the *.pptx ZIP archive
     //and creating a MyXSLFChartShape as slide shape  
     public MyXSLFChartShape createXSLFChart(XSLFSlide slide) throws Exception {
    
      OPCPackage oPCPackage = slide.getSlideShow().getPackage();
      int chartCount = oPCPackage.getPartsByName(Pattern.compile("/ppt/charts/chart.*")).size() + 1;
      PackagePartName partName = PackagingURIHelper.createPartName("/ppt/charts/chart" + chartCount + ".xml");
      PackagePart part = oPCPackage.createPart(partName, "application/vnd.openxmlformats-officedocument.drawingml.chart+xml");
    
      MyXSLFChart myXSLFChart = new MyXSLFChart(part);
      MyXSLFChartShape myXSLFChartShape = new MyXSLFChartShape(slide, myXSLFChart);
    
      return myXSLFChartShape;
     }
    
     public void drawPieChart(MyXSLFChartShape myXSLFChartShape) {
    
      XSSFWorkbook workbook = myXSLFChartShape.getMyXSLFChart().getXSLFXSSFWorkbook().getXSSFWorkbook();
      XSSFSheet sheet = workbook.getSheetAt(0);
      sheet.createRow(0).createCell(0).setCellValue("Cat");
      sheet.getRow(0).createCell(1).setCellValue("Val");
      for (int r = 1; r < 4; r++) {
       sheet.createRow(r).createCell(0).setCellValue("Cat" + r);
       sheet.getRow(r).createCell(1).setCellValue(10*r);
      }
    
      CTChartSpace chartSpace = myXSLFChartShape.getMyXSLFChart().getChartSpace();
      CTPieChart cTPieChart = chartSpace.addNewChart().addNewPlotArea().addNewPieChart();
      cTPieChart.addNewVaryColors().setVal(true);
      CTPieSer cTPieSer = cTPieChart.addNewSer();
      cTPieSer.addNewIdx().setVal(0);
      CTStrRef cTStrRef = cTPieSer.addNewTx().addNewStrRef();
      cTStrRef.setF("Sheet0!$B$1");
      cTStrRef.addNewStrCache().addNewPtCount().setVal(1);
      CTStrVal cTStrVal = cTStrRef.getStrCache().addNewPt();
      cTStrVal.setIdx(0);
      cTStrVal.setV("Val");
    
      cTStrRef = cTPieSer.addNewCat().addNewStrRef();
      cTStrRef.setF("Sheet0!$A$2:$A$4");
      
      cTStrRef.addNewStrCache().addNewPtCount().setVal(3);
      for (int r = 1; r < 4; r++) { 
       cTStrVal = cTStrRef.getStrCache().addNewPt();
       cTStrVal.setIdx(r-1);
       cTStrVal.setV("Cat" + r);
      }
    
      CTNumRef cTNumRef = cTPieSer.addNewVal().addNewNumRef();
      cTNumRef.setF("Sheet0!$B$2:$B$4");
    
      cTNumRef.addNewNumCache().addNewPtCount().setVal(3);
      for (int r = 1; r < 4; r++) { 
       CTNumVal cTNumVal = cTNumRef.getNumCache().addNewPt();
       cTNumVal.setIdx(r-1);
       cTNumVal.setV("" + (10*r));
      }
     }
    
     public void drawBarChart(MyXSLFChartShape myXSLFChartShape) {
    
      XSSFWorkbook workbook = myXSLFChartShape.getMyXSLFChart().getXSLFXSSFWorkbook().getXSSFWorkbook();
      XSSFSheet sheet = workbook.getSheetAt(0);
      sheet.createRow(0);
      for (int c = 1; c < 4; c++) { 
       sheet.getRow(0).createCell(c).setCellValue("Cat" + c);
      }
      for (int r = 1; r < 5; r++) {
       sheet.createRow(r).createCell(0).setCellValue("Val" + r);
       for (int c = 1; c < 4; c++) { 
        sheet.getRow(r).createCell(c).setCellValue((10+r)*c);
       }
      }
    
      CTChartSpace chartSpace = myXSLFChartShape.getMyXSLFChart().getChartSpace();
      CTChart cTChart = chartSpace.addNewChart();
      CTPlotArea cTPlotArea = cTChart.addNewPlotArea();
      CTBarChart cTBarChart = cTPlotArea.addNewBarChart();
      cTBarChart.addNewVaryColors().setVal(true);
      cTBarChart.addNewBarDir().setVal(STBarDir.COL);
    
      for (int r = 1; r < 5; r++) {
       CTBarSer cTBarSer = cTBarChart.addNewSer();
       CTStrRef cTStrRef = cTBarSer.addNewTx().addNewStrRef();
       cTStrRef.setF("Sheet0!$A$" + (r+1));
       cTStrRef.addNewStrCache().addNewPtCount().setVal(1);
       CTStrVal cTStrVal = cTStrRef.getStrCache().addNewPt();
       cTStrVal.setIdx(0);
       cTStrVal.setV("Val" + r);
       cTBarSer.addNewIdx().setVal(r-1);
    
       CTAxDataSource cttAxDataSource = cTBarSer.addNewCat();
       cTStrRef = cttAxDataSource.addNewStrRef();
       cTStrRef.setF("Sheet0!$B$1:$D$1");   
       cTStrRef.addNewStrCache().addNewPtCount().setVal(3);
       for (int c = 1; c < 4; c++) { 
        cTStrVal = cTStrRef.getStrCache().addNewPt();
        cTStrVal.setIdx(c-1);
        cTStrVal.setV("Cat" + c);
       }
    
       CTNumDataSource ctNumDataSource = cTBarSer.addNewVal();
       CTNumRef cTNumRef = ctNumDataSource.addNewNumRef();
       cTNumRef.setF("Sheet0!$B$" + (r+1) + ":$D$" + (r+1));
       cTNumRef.addNewNumCache().addNewPtCount().setVal(3);
       for (int c = 1; c < 4; c++) { 
        CTNumVal cTNumVal = cTNumRef.getNumCache().addNewPt();
        cTNumVal.setIdx(c-1);
        cTNumVal.setV("" + ((10+r)*c));
       }
      } 
    
      //telling the BarChart that it has axes and giving them Ids
      cTBarChart.addNewAxId().setVal(123456);
      cTBarChart.addNewAxId().setVal(123457);
    
      //cat axis
      CTCatAx cTCatAx = cTPlotArea.addNewCatAx(); 
      cTCatAx.addNewAxId().setVal(123456); //id of the cat axis
      CTScaling cTScaling = cTCatAx.addNewScaling();
      cTScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
      cTCatAx.addNewDelete().setVal(false);
      cTCatAx.addNewAxPos().setVal(STAxPos.B);
      cTCatAx.addNewCrossAx().setVal(123457); //id of the val axis
      cTCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
      //val axis
      CTValAx cTValAx = cTPlotArea.addNewValAx(); 
      cTValAx.addNewAxId().setVal(123457); //id of the val axis
      cTScaling = cTValAx.addNewScaling();
      cTScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
      cTValAx.addNewDelete().setVal(false);
      cTValAx.addNewAxPos().setVal(STAxPos.L);
      cTValAx.addNewCrossAx().setVal(123456); //id of the cat axis
      cTValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
    
      //legend
      CTLegend cTLegend = cTChart.addNewLegend();
      cTLegend.addNewLegendPos().setVal(STLegendPos.B);
      cTLegend.addNewOverlay().setVal(false);
    
     }
    
    
     public static void main(String[] args) throws Exception {
      CreatePPTXChartsXSSFWb createPPTXCharts = new CreatePPTXChartsXSSFWb();
     }
    
     //a class for providing a MyXSLFChartShape
     private class MyXSLFChartShape {
      private CTGraphicalObjectFrame _graphicalObjectFrame;
      private XSLFSlide slide;
      private MyXSLFChart myXSLFChart;
    
      MyXSLFChartShape(XSLFSlide slide, MyXSLFChart myXSLFChart) throws Exception {
    
       String rId = "rId" + (slide.getRelationParts().size()+1);
       slide.addRelation(rId, XSLFRelation.CHART, myXSLFChart);
    
       long cNvPrId = 1;
       String cNvPrName = "MyChart";
       int cNvPrNameCount = 1;
       for (CTGraphicalObjectFrame currGraphicalObjectFrame : slide.getXmlObject().getCSld().getSpTree().getGraphicFrameList()) {
        if (currGraphicalObjectFrame.getNvGraphicFramePr() != null) {
         if (currGraphicalObjectFrame.getNvGraphicFramePr().getCNvPr() != null) {
          cNvPrId++;
          if (currGraphicalObjectFrame.getNvGraphicFramePr().getCNvPr().getName().startsWith(cNvPrName)) {
           cNvPrNameCount++;
          }
         }
        }
       }
    
       CTGraphicalObjectFrame graphicalObjectFrame = slide.getXmlObject().getCSld().getSpTree().addNewGraphicFrame();
       CTGraphicalObjectFrameNonVisual cTGraphicalObjectFrameNonVisual = graphicalObjectFrame.addNewNvGraphicFramePr();
       cTGraphicalObjectFrameNonVisual.addNewCNvGraphicFramePr();
       cTGraphicalObjectFrameNonVisual.addNewNvPr();
    
       CTNonVisualDrawingProps cTNonVisualDrawingProps = cTGraphicalObjectFrameNonVisual.addNewCNvPr();
       cTNonVisualDrawingProps.setId(cNvPrId);
       cTNonVisualDrawingProps.setName("MyChart" + cNvPrNameCount);
    
       CTGraphicalObject graphicalObject = graphicalObjectFrame.addNewGraphic();
       CTGraphicalObjectData graphicalObjectData = CTGraphicalObjectData.Factory.parse(
         "<c:chart xmlns:c=\"http://schemas.openxmlformats.org/drawingml/2006/chart\" "
        +"xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
        +"r:id=\"" + rId + "\"/>"
       );
       graphicalObjectData.setUri("http://schemas.openxmlformats.org/drawingml/2006/chart");
       graphicalObject.setGraphicData(graphicalObjectData);
    
       _graphicalObjectFrame = graphicalObjectFrame;
       this.slide = slide;
       this.myXSLFChart = myXSLFChart;
    
       this.setAnchor(new Rectangle());
      }
    
      private void setAnchor(Rectangle2D anchor) {
       CTTransform2D xfrm = (_graphicalObjectFrame.getXfrm() != null) ? _graphicalObjectFrame.getXfrm() : _graphicalObjectFrame.addNewXfrm();
       CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
       long x = Units.toEMU(anchor.getX());
       long y = Units.toEMU(anchor.getY());
       off.setX(x);
       off.setY(y);
       CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt();
       long cx = Units.toEMU(anchor.getWidth());
       long cy = Units.toEMU(anchor.getHeight());
       ext.setCx(cx);
       ext.setCy(cy);
      }
    
      private MyXSLFChart getMyXSLFChart() {
       return myXSLFChart;
      }
     }
    
     //a wrapper class for the ChartSpaceDocument /ppt/charts/chart*.xml in the *.pptx ZIP archive  
     private class MyXSLFChart extends POIXMLDocumentPart {
    
      private CTChartSpace chartSpace;
      private MyXSLFXSSFWorkbook myXSLFXSSFWorkbook;
    
      private MyXSLFChart(PackagePart part) throws Exception {
       super(part);
    
       OPCPackage oPCPackage = part.getPackage();
       int chartCount = oPCPackage.getPartsByName(Pattern.compile("/ppt/embeddings/.*.xlsx")).size() + 1;
       PackagePartName partName = PackagingURIHelper.createPartName("/ppt/embeddings/Microsoft_Excel_Worksheet" + chartCount + ".xlsx");
       PackagePart xlsxpart = oPCPackage.createPart(partName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    
       myXSLFXSSFWorkbook = new MyXSLFXSSFWorkbook(xlsxpart);
     
       String rId = "rId" + (this.getRelationParts().size()+1);
       XSLFXSSFRelation xSLFXSSFRelationPACKAGE = new XSLFXSSFRelation(
        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package");
    
       this.addRelation(rId, xSLFXSSFRelationPACKAGE, myXSLFXSSFWorkbook);
    
       chartSpace = ChartSpaceDocument.Factory.newInstance().addNewChartSpace();
       CTExternalData cTExternalData = chartSpace.addNewExternalData();
       cTExternalData.setId(rId);
       //cTExternalData.addNewAutoUpdate().setVal(true);
      }
    
      private CTChartSpace getChartSpace() {
       return chartSpace;
      }
    
      private MyXSLFXSSFWorkbook getXSLFXSSFWorkbook() {
       return myXSLFXSSFWorkbook;
      }
    
      @Override
      protected void commit() throws IOException {
       XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
       xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
       PackagePart part = getPackagePart();
       OutputStream out = part.getOutputStream();
       chartSpace.save(out, xmlOptions);
       out.close();
      }
    
     }
    
     //a wrapper class for the XSSFWorkbook /ppt/embeddings/Microsoft_Excel_Worksheet*.xlsx in the *.pptx ZIP archive  
     private class MyXSLFXSSFWorkbook extends POIXMLDocumentPart {
    
      private XSSFWorkbook workbook;
    
      private MyXSLFXSSFWorkbook(PackagePart part) throws Exception {
       super(part);
       workbook = new XSSFWorkbook();
       XSSFSheet sheet = workbook.createSheet();
      }
    
      private XSSFWorkbook getXSSFWorkbook() {
       return workbook;
      }
    
      @Override
      protected void commit() throws IOException {
       PackagePart part = getPackagePart();
       OutputStream out = part.getOutputStream();
       workbook.write(out);
       workbook.close();
       out.close();
      }
     }
    
     //a class to note the relations
     private class XSLFXSSFRelation extends POIXMLRelation {
      private XSLFXSSFRelation(String rel) {
       super(null, rel, null);
      }
     }
    } 
    

    Edit January 29 2019:

    Above code was working using apache poi 3.16 up to apache poi 3.17. To make it work using current apache poi 4.0.1 the only need is changing the imports a little bit:

    ...
    import org.apache.poi.openxml4j.opc.*;
    //import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
    import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
    import org.apache.poi.ooxml.*;
    
    import org.apache.xmlbeans.*;
    ...
    

    This is because the Office Open XML stuff now is in org.apache.poi.ooxml.*and not more in org.apache.poi.*.


    Edit August 2023:

    Current Apache POI versions (since Apache POI 4.1.0) provide XDDF for charts. Using this it is much simpler to create charts for PowerPoint.

    Example:

    import java.io.FileOutputStream;
    
    import org.apache.poi.xslf.usermodel.*;
    import org.apache.poi.util.Units;
    import org.apache.poi.xddf.usermodel.*;
    import org.apache.poi.xddf.usermodel.chart.*;
    
    import java.awt.Rectangle;
    
    public class CreatePowerPointXDDFChart {
        
     public static void main(String[] args) throws Exception {
      try (XMLSlideShow slideShow = new XMLSlideShow()) {
       
       // create a new empty slide
       XSLFSlide slide = slideShow.createSlide();
       
       // create chart
       XSLFChart chart = slideShow.createChart();
       chart.setTitleText("Test Chart");
       
       // set axis
       XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
       XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
       leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
       leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
    
       // define chart data for bar chart
       XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
    
       // add chart categories (x-axis data)
       String[] categories = new String[] { "Category 1", "Category 2", "Category 3" };
       String categoryDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(1, categories.length, 0, 0));
       XDDFCategoryDataSource categoryData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
    
       // add chart values (y-axis data)
       Double[] values = new Double[] { 10.0, 20.0, 15.0 };
       String valuesDataRange = chart.formatRange(new org.apache.poi.ss.util.CellRangeAddress(1, values.length, 1, 1));
       XDDFNumericalDataSource<Double> valueData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, 1);
       XDDFBarChartData bar = (XDDFBarChartData) data;
       bar.setBarDirection(BarDirection.BAR);
    
       // add series
       XDDFChartData.Series series = data.addSeries(categoryData, valueData);
       series.setTitle("Series 1", chart.setSheetTitle("Series 1", 1));
       
       // plot chart
       chart.plot(data);
    
       // set chart dimensions !!Units are EMU (English Metric Units)!!
       Rectangle chartDimensions = new Rectangle(
        100*Units.EMU_PER_POINT, 
        50*Units.EMU_PER_POINT, 
        400*Units.EMU_PER_POINT, 
        400*Units.EMU_PER_POINT);
       // add chart to slide
       slide.addChart(chart, chartDimensions);
    
       // Write the output to a file
       try (FileOutputStream fileOut = new FileOutputStream("./CreatePowerPointXDDFChart.pptx")) {
        slideShow.write(fileOut);
       }
      }
     }
    
    }
    

    Edit September 2023:

    To make it work using Apache POI 4.1.2 and higher, one must repair incorrect number format settings.

    ...
       //repair axes number format settings
       if (bottomAxis.hasNumberFormat()) bottomAxis.setNumberFormat("@");
       if (leftAxis.hasNumberFormat()) leftAxis.setNumberFormat("#,##0.00");
    ...