Как создать форму WedgeRectCallout в Word, используя apache poi? - PullRequest
0 голосов
/ 18 декабря 2018

Мне нужно создать WedgeRectCallout фигуру в документе Word, используя Apache POI.Я не могу найти какую-либо ссылку на это в Apache POI Используя ссылку, вы можете увидеть изображение WedgeRectCallout

Кроме того, ссылка показывает, как добавить текстовое поле.в документе Word, но не в форме.

В C # я могу сделать то же самое, используя библиотеку Spire.Doc и написав следующий код:

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

1 Ответ

0 голосов
/ 19 декабря 2018

Новейшие Word версии используют wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" для фигур.Но это не поддерживается ни низким уровнем ooxml-schemas, ни apache 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();
 }
}

Результат:

enter image description here

Примечание. Для этого необходимо, чтобы apache poi 4.0.1 и ooxml-schemas-1.4.jar находились в пути к классам.

...