Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 228
user3247376 Avatar asked Jul 28 '17 12:07

user3247376


People also ask

How can I create a bar chart using Apache POI?

I would go a different route. Create an Excel file that includes a macro that creates the Bar Chart etc for some data (using Excel in the usual way). Then use Apache POI to create a file with the data you want and start Excel from Java, executing the macro that creates the charts.

What is Apache POI PowerPoint?

Apache POI Powerpoint Apache POI provides XSLF API to handle Powerpoint document by using the Java program. It is pure Java implementation of Powerpoint 97-2007 file format. It helps to read, create or modify document.

How to create a MS PowerPoint presentation in Java?

Creating a MS PowerPoint Presentation in Java 1 Introduction. In this article, we'll see how we can create a presentation using Apache POI. ... 2 Maven Dependencies. To begin, we'll need to add the following dependencies into our pom.xml: ... ... 3 Apache POI. ... 4 Working With Objects. ... 5 Altering a Presentation. ... 6 Conclusion. ...

How to change the defined name of chart in poi?

You can only use Excel template to preserve chart with POI. It mean you create an Excel template file with chart in it and link the chart's datasource to one definedName,then you can load the template file from POI and using code to change the definedName.


1 Answers

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.*.

like image 190
Axel Richter Avatar answered Oct 15 '22 20:10

Axel Richter