Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...