create text box in document .docx using apache poi

后端 未结 2 1409
予麋鹿
予麋鹿 2021-01-26 09:49

I want create a text box in a document .docx but I didn´t find a method that help me do it and any example. Someone know how can i do it?

相关标签:
2条回答
  • 2021-01-26 10:46

    For HWPF (i.e. the old binary doc format) there is a very rudimentary interface via HWPFDocument.getMainTextBoxRange(). I believe it is only suitable for reading, though.

    For XWPF (the newer docx format that you asked for) it appears that Text Boxes are always embedded in a Drawing (using DrawingML; please correct me if I am wrong). At least this is how I interpret clauses 17.3.1.40, 20.4.2.37 and 20.4.2.38 of ECMA-376, Part 1. Thus, your method of choice should be XSSFDrawing.createTextbox(). However, I haven't yet come across an easy to use link between this drawing class (which stems from POI's Excel component) and XWPF.

    0 讨论(0)
  • 2021-01-26 10:56

    Inserting a real Word Text-box is not fully possible with apache-poi until now. A real Word Text-box is contained in a CTShape from schemasMicrosoftComVml or com.microsoft.schemas.vml. The XML looks like:

    <w:r>
     <w:pict>
      <v:shape style="width:100pt;height:24pt">
       <v:textbox>
        <w:txbxContent>
         <w:p>
          <w:r>
           <w:t>The TextBox text...</w:t>
          </w:r>
         </w:p>
        </w:txbxContent>
       </v:textbox>
      </v:shape>
     </w:pict>
    </w:r>
    

    As you see the namespaces in v:shape and v:textbox are different from the rest.

    So if we know and respect this, we can currently insert such CTShape. But only inline with the text. Creating a CTWrap for this is currently not possible, as far as I know, because the CTWrap from the schemasMicrosoftComOfficeWord is not shipped within the poi-ooxml-schemas-3.13-*.jar and the com.microsoft.schemas.vml and com.microsoft.schemas.office classes from ooxml-schemas-1.3.jar need a org.apache.poi.POIXMLTypeLoader which is not shipped with version 3.13.

    Example for an inline Textbox:

    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 schemasMicrosoftComVml.CTGroup;
    import schemasMicrosoftComVml.CTShape;
    
    import org.w3c.dom.Node;
    
    public class CreateWordTextBox {
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument doc= new XWPFDocument();
    
      XWPFParagraph paragraph = doc.createParagraph();
      XWPFRun run=paragraph.createRun();  
      run.setText("The Body text: ");
    
      CTGroup ctGroup = CTGroup.Factory.newInstance();
    
      CTShape ctShape = ctGroup.addNewShape();
      ctShape.setStyle("width:100pt;height:24pt");
      CTTxbxContent ctTxbxContent = ctShape.addNewTextbox().addNewTxbxContent();
      ctTxbxContent.addNewP().addNewR().addNewT().setStringValue("The TextBox text...");
    
      Node ctGroupNode = ctGroup.getDomNode(); 
      CTPicture ctPicture = CTPicture.Factory.parse(ctGroupNode);
      run=paragraph.createRun();  
      CTR cTR = run.getCTR();
      cTR.addNewPict();
      cTR.setPictArray(0, ctPicture);
    
      doc.write(new FileOutputStream("WordTextBox.docx"));
    
     }
    }
    

    But a positioned text-frame is possible:

    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFramePr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHAnchor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVAnchor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STXAlign;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STWrap;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
    /*
    To
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFramePr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHAnchor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVAnchor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STXAlign;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STWrap;
    the fully ooxml-schemas-1.3.jar is needed as mentioned in https://poi.apache.org/faq.html#faq-N10025
    */
    
    import java.math.BigInteger;
    
    public class CreateWordTextFrame {
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument doc= new XWPFDocument();
    
      XWPFParagraph paragraph = doc.createParagraph();
      XWPFRun run=paragraph.createRun();  
      run.setText("The body text:");
    
      CTSdtContentBlock ctSdtContentBlock = doc.getDocument().getBody().addNewSdt().addNewSdtContent();
    
      CTP ctP = ctSdtContentBlock.addNewP();
      ctP.addNewR().addNewT().setStringValue("The TextFrame text...");
    
      CTPPr ctPPr = ctP.addNewPPr();
      CTFramePr ctFramePr = ctPPr.addNewFramePr();
      ctFramePr.setHAnchor(STHAnchor.TEXT);
      ctFramePr.setVAnchor(STVAnchor.TEXT);
      ctFramePr.setXAlign(STXAlign.CENTER);
      ctFramePr.setWrap(STWrap.AROUND);
      ctFramePr.setW(BigInteger.valueOf(4000));
      ctFramePr.setHSpace(BigInteger.valueOf(400));
    
      CTPBdr ctPBdr = ctPPr.addNewPBdr();
      CTBorder ctBorder = ctPBdr.addNewLeft(); ctBorder.setColor("000000"); ctBorder.setVal(STBorder.SINGLE); ctBorder.setSz(BigInteger.valueOf(4)); ctBorder.setSpace(BigInteger.valueOf(7));
      ctBorder = ctPBdr.addNewRight(); ctBorder.setColor("000000"); ctBorder.setVal(STBorder.SINGLE); ctBorder.setSz(BigInteger.valueOf(4)); ctBorder.setSpace(BigInteger.valueOf(7));
      ctBorder = ctPBdr.addNewTop(); ctBorder.setColor("000000"); ctBorder.setVal(STBorder.SINGLE); ctBorder.setSz(BigInteger.valueOf(4)); ctBorder.setSpace(BigInteger.valueOf(7));
      ctBorder = ctPBdr.addNewBottom(); ctBorder.setColor("000000"); ctBorder.setVal(STBorder.SINGLE); ctBorder.setSz(BigInteger.valueOf(4)); ctBorder.setSpace(BigInteger.valueOf(7));
    
      paragraph = doc.createParagraph();
      run=paragraph.createRun();  
      run.setText("Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... ");
    
      doc.write(new FileOutputStream("WordTextFrame.docx"));
    
     }
    }
    

    This needs the fully ooxml-schemas-1.3.jar as mentioned in https://poi.apache.org/faq.html#faq-N10025.

    Edit

    If we downgrade to ooxml-schemas-1.1.jar - available from http://search.maven.org/#artifactdetails|org.apache.poi|ooxml-schemas|1.1|jar - then a free positionable Text-box is also possible with apache-poi version 3.13.

    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 schemasMicrosoftComVml.CTGroup;
    import schemasMicrosoftComVml.CTShape;
    import schemasMicrosoftComOfficeWord.CTWrap;
    import schemasMicrosoftComOfficeWord.STWrapType;
    /*
    To 
    import schemasMicrosoftComOfficeWord.CTWrap;
    import schemasMicrosoftComOfficeWord.STWrapType;
    ooxml-schemas-1.1.jar is needed - available from http://search.maven.org/#artifactdetails|org.apache.poi|ooxml-schemas|1.1|jar
    */
    
    import org.w3c.dom.Node;
    
    public class CreateWordTextBox {
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument doc= new XWPFDocument();
    
      XWPFParagraph paragraph = doc.createParagraph();
      XWPFRun run=paragraph.createRun();  
      run.setText("The Body text: ");
    
      CTGroup ctGroup = CTGroup.Factory.newInstance();
    
      CTShape ctShape = ctGroup.addNewShape();
      ctShape.addNewWrap().setType(STWrapType.SQUARE);
      ctShape.setStyle("position:absolute;mso-position-horizontal:center;margin-top:40pt;width:100pt;height:24pt");
      CTTxbxContent ctTxbxContent = ctShape.addNewTextbox().addNewTxbxContent();
      ctTxbxContent.addNewP().addNewR().addNewT().setStringValue("The TextBox text...");
    
      Node ctGroupNode = ctGroup.getDomNode(); 
      CTPicture ctPicture = CTPicture.Factory.parse(ctGroupNode);
      run=paragraph.createRun();  
      CTR cTR = run.getCTR();
      cTR.addNewPict();
      cTR.setPictArray(0, ctPicture);
    
      paragraph = doc.createParagraph();
      run=paragraph.createRun();  
      run.setText("Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... Lorem ipsum semit color ... ");
    
    
      doc.write(new FileOutputStream("WordTextBox.docx"));
    
     }
    }
    
    0 讨论(0)
提交回复
热议问题