提问者:小点点

如何使用apache poi在Word中创建WelgeRectCallout形状?


我需要使用ApachePOI在Word文档中创建WelgeRectCallout形状。我在Apache中找不到对此的任何引用POI使用该链接,您可以看到WelgeRectCallout图像

此外,该链接还显示了如何在Word文档中添加文本框,但不是形状。

在C#中,我可以使用Spire. Doc库并编写以下代码来做同样的事情:

ShapeObject Shape1 = para1.AppendShape(30, 50, ShapeType.WedgeRectCallout);

共1个答案

匿名用户

最新的Word版本使用wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"来表示形状。但是低级ooxml-schemasapache poi都不支持这一点。只有在非常低的级别上直接操作XML才有可能。

但是Word也使用矢量标记语言(VML)作为后备。这可以通过ooxml-schemas-1.4提供com.microsoft. schemas.vml来完成。这也是最兼容的方式。

您可以阅读矢量标记语言(VML)。最简单的标注形状将是以下XML

<w:pict>
 <v:shape coordsize="21600,21600" adj="7200,21600" path="m 1,1 l 1,14400, 7200,14400, @0,@1, 14400,14400, 21600,14400, 21600,1 x e" style="position:absolute;margin-left:1in;margin-top:-150px;width:100px;height:150px;z-index:251659264;visibility:visible;rotation:0;" strokecolor="#0000FF" fillcolor="yellow">
  <v:formulas>
   <v:f eqn="val #0"/>
   <v:f eqn="val #1"/>
  </v:formulas>
  <v:handles><v:h position="#0,#1"/></v:handles>
  <v:path textboxrect="1,1,21600,14400"/>
  <v:textbox>
   <w:txbxContent><w:p><w:r><w:t>The callout</w:t><w:br/></w:r><w:r><w:t>text...</w:t><w:br/></w:r></w:p>
   </w:txbxContent>
  </v:textbox>
 </v:shape>
</w:pict>

如您所见,形状的轮廓由路径确定。因此,如果您了解路径的工作原理,也可以创建其他形状。

创建标注形状的示例代码:

import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPicture;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTxbxContent;

import com.microsoft.schemas.vml.CTGroup;
import com.microsoft.schemas.vml.CTShape;
import com.microsoft.schemas.vml.CTFormulas;
import com.microsoft.schemas.vml.CTTextbox;

import org.w3c.dom.Node;

public class CreateWordShapes {

 public static void appendCalloutShape(XWPFRun run, String left, String top, String width, String height, 
                                       String strokecolor, String fillcolor, String calloutext, boolean hashandles) throws Exception {
  CTGroup ctGroup = CTGroup.Factory.newInstance();

  CTShape ctShape = ctGroup.addNewShape();
  ctShape.setCoordsize("21600,21600");
  if (hashandles) { //is not Libreoffice Writer compatible
   ctShape.setAdj("" + 21600*1/3 + ",21600");
   CTFormulas cTFormulas = ctShape.addNewFormulas();
   cTFormulas.addNewF().setEqn("val #0");
   cTFormulas.addNewF().setEqn("val #1");
   ctShape.setPath2("m 1,1 l 1," + 21600*2/3 + ", " + 21600*1/3 + "," + 21600*2/3 + ", @0,@1, " + 21600*2/3 + "," + 21600*2/3 + ", 21600," + 21600*2/3 + ", 21600,1 x e");
   ctShape.addNewHandles().addNewH().setPosition("#0,#1");
  } else { // is Libreoffice Writer compatible
   ctShape.setPath2("m 1,1 l 1," + 21600*2/3 + ", " + 21600*1/3 + "," + 21600*2/3 + ", " + 21600*1/3 + ",21600, " + 21600*2/3 + "," + 21600*2/3 + ", 21600," + 21600*2/3 + ", 21600,1 x e");
  }

  ctShape.addNewPath().setTextboxrect("1,1,21600," + 21600*2/3);

  ctShape.setStyle("position:absolute;margin-left:" + left + ";margin-top:" + top + ";width:" + width + ";height:" + height + ";z-index:251659264;visibility:visible;rotation:0;");
  ctShape.setStrokecolor(strokecolor);
  ctShape.setFillcolor(fillcolor);

  CTTextbox cTTextbox = ctShape.addNewTextbox();

  CTTxbxContent ctTxbxContent = cTTextbox.addNewTxbxContent();
  XWPFParagraph textboxparagraph = new XWPFParagraph(ctTxbxContent.addNewP(), run.getDocument());
  XWPFRun textboxrun = null;
  String[] lines = calloutext.split("\n");
  for (int i = 0; i < lines.length; i++) {
   textboxrun = textboxparagraph.createRun();
   textboxrun.setText(lines[i]);
   textboxrun.addBreak();
  }

  Node ctGroupNode = ctGroup.getDomNode(); 
  CTPicture ctPicture = CTPicture.Factory.parse(ctGroupNode);
  CTR cTR = run.getCTR();
  cTR.addNewPict();
  cTR.setPictArray(0, ctPicture);
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run =  paragraph.createRun();  
  run.setText("Callout shape over text: Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor Lorem ipsum semit dolor.");

  appendCalloutShape(run, "200pt", "0", "1in", "1in", "black", "#00FF00", "The callout\ntext...", false);

  paragraph = document.createParagraph();
  paragraph = document.createParagraph();
  paragraph = document.createParagraph();
  paragraph = document.createParagraph();
  run =  paragraph.createRun();  
  run.setText("Callout shape:");

  appendCalloutShape(run, "1in", "-150px", "100px", "150px", "#0000FF", "yellow", "The callout\ntext...", true);


  FileOutputStream out = new FileOutputStream("test.docx");
  document.write(out);
  out.close();
  document.close();
 }
}

结果:

注意:这需要apache poi 4.0.1ooxml-schemas-1.4。jar在类路径中。