使用Docx4j操作PPT指南系列(三)

                                                     —— 添加文本框与其他图形元素

上一章介绍了如何使用Docx4j向PPT中添加标题元素,本章我们来尝试向PPT中加入文本框与其他的图形元素,与上一章不同,本章中将会增加“使用代码创建图形元素”的部分。

还是先来看一页PPT:

我们接下来将会在红框的位置添加一个文本框,并在文本框中增加“插入一个文本框 ”这样一段文字。

先使用Xml方式插入:

 private final int tTextAyX = 539552;
 private final int tTextAyY = 1556792;
 private final int tTextAyCX = 8064896;
 private final int tTextAyCY = 396332;

private void createStChartSlide(
   PresentationMLPackage presentationMLPackage,
   String title) {

  String partTitle = title;
  String partName = "/ppt/slides/" + getRandomID()+ ".xml";

  SlidePart slidePart = createCommonSlide(presentationMLPackage,
    partTitle, partName);

  Shape descShape;

  try {

   descShape = (Shape) XmlUtils.unmarshalString(
     getTextArea("插入一个文本框",tTextAyX, tTextAyY,
       tTextAyCX, tTextAyCY), Context.jcPML);
   ((Sld) slidePart.getJaxbElement()).getCSld().getSpTree()
     .getSpOrGrpSpOrGraphicFrame().add(descShape);

  } catch (JAXBException e1) {
   e1.printStackTrace();
  }

 }

 private String getRandomID(){
  return Math.abs(ran.nextInt()) +"";
 }

/**
  * 创建一页
  *
  * @param presentationMLPackage
  * @param title
  * @param partName
  * @return
  */
 private SlidePart createCommonSlide(
   PresentationMLPackage presentationMLPackage, String title,
   String partName) {

  MainPresentationPart mainPart = presentationMLPackage
    .getMainPresentationPart();

  SlideLayoutPart layoutPart;

  try {
   layoutPart = (SlideLayoutPart) presentationMLPackage.getParts()
     .getParts()
     .get(new PartName("/ppt/slideLayouts/slideLayout2.xml"));

   SlidePart slidePart = PresentationMLPackage.createSlidePart(
     mainPart, layoutPart, new PartName(partName));

   Shape titleShape = (Shape) XmlUtils.unmarshalString(
     getSlideTitle(title), Context.jcPML);

   ((Sld) slidePart.getJaxbElement()).getCSld().getSpTree()
     .getSpOrGrpSpOrGraphicFrame().add(titleShape);

   return slidePart;

  } catch (InvalidFormatException e) {
   e.printStackTrace();
  } catch (JAXBException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  return null;

 }

/**
  * @param preset
  * @param x
  * @param y
  * @param cx
  * @param cy
  * @return
  */
 private String getTextArea(String preset, int x, int y, int cx, int cy) {
  return "<p:sp  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" "
    + "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
    + "xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"
    + "<p:nvSpPr><p:cNvPr id=\"5\" name=\"TextBox 4\"/><p:cNvSpPr txBox=\"1\"/><p:nvPr/></p:nvSpPr>"
    + "<p:spPr><a:xfrm><a:off x=\""
    + x
    + "\" y=\""
    + y
    + "\"/><a:ext cx=\""
    + cx
    + "\" cy=\""
    + cy
    + "\"/>"
    + "</a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/></p:spPr><p:txBody>"
    + "<a:bodyPr wrap=\"square\" rtlCol=\"0\"><a:spAutoFit/></a:bodyPr><a:lstStyle/><a:p>"
    + "<a:r><a:rPr lang=\"en-US\" altLang=\"zh-CN\" dirty=\"0\" err=\"1\" smtClean=\"0\">"
    + "<a:latin typeface=\"微软雅黑\" pitchFamily=\"34\" charset=\"-122\"/>"
    + "<a:ea typeface=\"微软雅黑\" pitchFamily=\"34\" charset=\"-122\"/>"
    + "</a:rPr><a:t>"
    + preset
    + "</a:t></a:r>"
    + "<a:endParaRPr lang=\"zh-CN\" altLang=\"en-US\" dirty=\"0\">"
    + "<a:latin typeface=\"微软雅黑\" pitchFamily=\"34\" charset=\"-122\"/>"
    + "<a:ea typeface=\"微软雅黑\" pitchFamily=\"34\" charset=\"-122\"/></a:endParaRPr>"
    + "</a:p></p:txBody></p:sp>";
 }

通过上面的代码,我们就可以得到如图中的PPT页。如果我们不想采用XML方式的话,Docx4j还支持使用代码方式插入,代码相对复杂一些,但不难理解(完全符合Microsoft OOXml的结构),我们只需要将上面生成Shape部分的代码替换为下面的代码即可:

private void createShape(SlidePart slidePart, String value) {

  Shape shape = graphicObjectFactory.createShape();

  NvSpPr nvSpPr = graphicObjectFactory.createShapeNvSpPr();

  CTNonVisualDrawingProps cnvpr = objectFactory
    .createCTNonVisualDrawingProps();
  cnvpr.setId(1);
  nvSpPr.setCNvPr(cnvpr);
  nvSpPr.setCNvSpPr(objectFactory.createCTNonVisualDrawingShapeProps());
  nvSpPr.setNvPr(graphicObjectFactory.createNvPr());

  shape.setNvSpPr(nvSpPr);

  CTShapeProperties ctShapePr = objectFactory.createCTShapeProperties();

  CTTransform2D ctTransform2D = objectFactory.createCTTransform2D();

  CTPoint2D ctPoint2D = objectFactory.createCTPoint2D();
  CTPositiveSize2D ctPositiveSize2D = objectFactory
    .createCTPositiveSize2D();

  ctTransform2D.setOff(ctPoint2D);
  ctTransform2D.setExt(ctPositiveSize2D);

  ctShapePr.setXfrm(ctTransform2D);
  CTPresetGeometry2D ctPresetGeometry2D = objectFactory
    .createCTPresetGeometry2D();
  ctPresetGeometry2D.setPrst(STShapeType.RECT);
  ctPresetGeometry2D.setAvLst(objectFactory.createCTGeomGuideList());
  ctShapePr.setPrstGeom(ctPresetGeometry2D);
  ctShapePr.setNoFill(objectFactory.createCTNoFillProperties());

  CTTextBody txBody = objectFactory.createCTTextBody();
  CTTextBodyProperties bodyPr = objectFactory
    .createCTTextBodyProperties();
  bodyPr.setWrap(STTextWrappingType.SQUARE);
  bodyPr.setRtlCol(false);
  bodyPr.setSpAutoFit(objectFactory.createCTTextShapeAutofit());
  txBody.setBodyPr(bodyPr);
  txBody.setLstStyle(objectFactory.createCTTextListStyle());

  CTTextParagraph ctTextPr = objectFactory.createCTTextParagraph();
  CTRegularTextRun run = objectFactory.createCTRegularTextRun();

  CTTextCharacterProperties ctTpr = objectFactory
    .createCTTextCharacterProperties();

  // 14号字体
  ctTpr.setSz(1400);

  TextFont font = objectFactory.createTextFont();
  font.setTypeface("微软雅黑");

  ctTpr.setLatin(font);
  ctTpr.setEa(font);

  run.setRPr(ctTpr);

  // 设置内容
  run.setT(value);

  ctTextPr.getEGTextRun().add(run);

  ctTextPr.setEndParaRPr(objectFactory.createCTTextCharacterProperties());

  txBody.getP().add(ctTextPr);

  shape.setTxBody(txBody);

  shape.setSpPr(ctShapePr);

 }

其他图形元素的操作方式与文本框基本一致,在XML中加黑的部分

"<p:nvSpPr><p:cNvPr id=\"5\" name=\"TextBox 4\"/><p:cNvSpPr txBox=\"1\"/><p:nvPr/></p:nvSpPr>"

OK,以上是这一部分的全部内容,在下一章中我们将学习如何在PPT中插入一张图片。