【问题标题】:How to create a WedgeRectCallout shape in Word using apache poi?如何使用 apache poi 在 Word 中创建 WedgeRectCallout 形状?
【发布时间】:2018-12-20 12:27:44
【问题描述】:

我需要使用 Apache POI 在 Word 文档中创建一个WedgeRectCallout 形状。我无法在 Apache POI 中找到对此的任何引用 Using the link you can see the WedgeRectCallout image

另外,the link 展示了如何在 Word 文档中添加文本框,而不是形状。

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

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

【问题讨论】:

    标签: java ms-word apache-poi


    【解决方案1】:

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

    Word 也使用Vector Markup Language (VML) 作为后备。这可以通过ooxml-schemas-1.4 提供com.microsoft.schemas.vml 来完成。这也将是最兼容的方式。

    您可以阅读有关Vector Markup Language (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>
    

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

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

    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 在类路径中。

    【讨论】:

    • 您是真正的 POI 专家。您的解决方案符合我的确切要求。
    猜你喜欢
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多