Beispiel #1
0
  /**
   * In Word, adjacent paragraphs with the same borders are enclosed in a single border (unless
   * bullets/numbering apply).
   *
   * <p>Similarly with shading. (If the 2 paragraphs are shaded different colors, then the color of
   * the first extends to the start of the second, so there is no white strip between them).
   *
   * <p>To do the same in HTML and PDF output, we put matching paragraphs into a content control,
   * and set the border/shading on that. This gives us an appropriate div or fo:block.
   */
  public static void groupAdjacentBorders(Body body) {

    List<Object> bodyElts = body.getContent();
    List<Object> groupedContent = null;
    groupedContent = groupBodyContent(bodyElts);
    if (groupedContent != null) {
      body.getContent().clear();
      body.getContent().addAll(groupedContent);
    }
  }
  /**
   * Traverse the document, and return a map of all styles which are used directly in the document.
   * (IE this does not include styles on which others are just BasedOn).
   *
   * @return
   */
  public Set<String> getStylesInUse() {

    org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) this.getJaxbElement();
    Body body = wmlDocumentEl.getBody();

    List<Object> bodyChildren = body.getContent();

    Set<String> stylesInUse = new HashSet<String>();
    FontAndStyleFinder finder = new FontAndStyleFinder(null, null, stylesInUse);
    finder.defaultCharacterStyle = this.getStyleDefinitionsPart().getDefaultCharacterStyle();
    finder.defaultParagraphStyle = this.getStyleDefinitionsPart().getDefaultParagraphStyle();

    new TraversalUtil(bodyChildren, finder);
    finder.finish();

    // Styles in headers, footers?
    RelationshipsPart rp = this.getRelationshipsPart();
    if (rp != null) {
      for (Relationship r : rp.getRelationships().getRelationship()) {
        Part part = rp.getPart(r);
        if (part instanceof FooterPart) {

          Ftr ftr = ((FooterPart) part).getJaxbElement();
          finder.walkJAXBElements(ftr);

        } else if (part instanceof HeaderPart) {

          Hdr hdr = ((HeaderPart) part).getJaxbElement();
          finder.walkJAXBElements(hdr);
        }
      }
    }

    // Styles in endnotes, footnotes?
    if (this.getEndNotesPart() != null) {
      log.debug("Looking at endnotes");
      CTEndnotes endnotes = this.getEndNotesPart().getJaxbElement();
      finder.walkJAXBElements(endnotes);
    }
    if (this.getFootnotesPart() != null) {
      log.debug("Looking at footnotes");
      CTFootnotes footnotes = this.getFootnotesPart().getJaxbElement();
      finder.walkJAXBElements(footnotes);
    }

    // Comments
    if (this.getCommentsPart() != null) {
      log.debug("Looking at comments");
      Comments comments = this.getCommentsPart().getJaxbElement();
      finder.walkJAXBElements(comments);
    }

    return stylesInUse;
  }
  protected String getMceIgnorable(Body body) {

    List<Object> content = body.getContent();

    // To avoid the traversing a large docx,
    // we'll try to use a hack here.
    // The idea is to force JAXB to include
    // namespace declarations for w14 and w15, by
    // using them in an innocuous manner.
    // It works by adding the following to the first
    // paragraph encountered:

    // <w:p w14:textId="fdcbd571" w14:paraId="fdcbd571" >
    //  <w:pPr>
    //    <w15:collapsed w:val="false"/>
    //  </w:pPr>
    //
    // If this turns out to cause problems, it could be
    // made configurable in docx4j.properties

    if (content.size() == 0) {
      return null;
    }

    P p = null;
    for (Object o : content) {
      if (o instanceof P) {
        p = (P) o;
        break;
      }
    }

    if (p == null) {
      // No top level paragraph, so
      // do the work of traversing the document

      log.debug("traversing for w14, w15");

      IgnorablePrefixFinder finder = new IgnorablePrefixFinder();
      if (body.getSectPr() != null && body.getSectPr().getFootnoteColumns() != null) {
        finder.needW15 = true;
      }
      new TraversalUtil(content, finder);

      String mceIgnorableVal = "";
      if (finder.needW14) {
        mceIgnorableVal = "w14";
      }

      if (finder.needW15) {
        mceIgnorableVal += " w15";
      }

      return mceIgnorableVal;

    } else {
      // The quick hack

      // For W14, we'll check/set paraId, textId
      if (p.getParaId() == null) {
        // Values MUST be greater than 0 and less than 0x80000000
        // So let's

        String uuid = java.util.UUID.randomUUID().toString();
        // That's 32 digits, but 8'll do nicely
        /*
         * 8 can create a number too large - using 7
         * Bob Fleischman - July 24, 2014
         */
        uuid = uuid.replace("-", "").substring(0, 7);

        p.setParaId(uuid);
        p.setTextId(uuid);
      }

      // For W15, collapse
      /*
       * Bob Fleischman - commented this out to generat docs without the namespace issue
      			PPr ppr = p.getPPr();
      			if (ppr==null) {
      				ppr = Context.getWmlObjectFactory().createPPr();
      				p.setPPr(ppr);
      			}
      			if (ppr.getCollapsed()==null) {
      				BooleanDefaultTrue notCollapsed = new BooleanDefaultTrue();
      				notCollapsed.setVal(Boolean.FALSE);
      				ppr.setCollapsed(notCollapsed);
      			}

      */ }

    return "w14 w15";
  }
  /**
   * Traverse the document, looking for fonts which have been applied, either directly, or via a
   * style.
   *
   * @return
   */
  public Set<String> fontsInUse() {

    log.info("fontsInUse..");

    getPropertyResolver(); // this inits our virtual DocDefaults style

    // Setup

    Set<String> fontsDiscovered = new java.util.HashSet<String>();

    //    	// Keep track of styles we encounter, so we can
    //    	// inspect these for fonts
    //    	Set<String> stylesInUse = new java.util.HashSet<String>();
    //
    //		org.docx4j.wml.Styles styles = null;
    //		if (this.getStyleDefinitionsPart()!=null) {
    //			styles = (org.docx4j.wml.Styles)this.getStyleDefinitionsPart().getJaxbElement();
    //		}
    //		// It is convenient to have a HashMap of styles
    //		Map<String, Style> stylesDefined = new java.util.HashMap<String, Style>();
    //		if (styles!=null) {
    //		     for (Iterator<Style> iter = styles.getStyle().iterator(); iter.hasNext();) {
    //		            Style s = iter.next();
    //		            stylesDefined.put(s.getStyleId(), s);
    //		     }
    //		}
    //    // We need to know what fonts and styles are used in the document

    org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) this.getJaxbElement();
    Body body = wmlDocumentEl.getBody();

    List<Object> bodyChildren = body.getContent();

    FontDiscoveryCharacterVisitor visitor = new FontDiscoveryCharacterVisitor(fontsDiscovered);
    RunFontSelector runFontSelector =
        new RunFontSelector(
            (WordprocessingMLPackage) this.pack, visitor, RunFontActionType.DISCOVERY);

    FontAndStyleFinder finder = new FontAndStyleFinder(runFontSelector, fontsDiscovered, null);
    finder.defaultCharacterStyle = this.getStyleDefinitionsPart().getDefaultCharacterStyle();
    finder.defaultParagraphStyle = this.getStyleDefinitionsPart().getDefaultParagraphStyle();
    new TraversalUtil(bodyChildren, finder);
    //		finder.finish();

    fontsDiscovered.add(runFontSelector.getDefaultFont());

    // fonts in headers, footers?
    RelationshipsPart rp = this.getRelationshipsPart();
    if (rp != null) {
      for (Relationship r : rp.getRelationships().getRelationship()) {
        Part part = rp.getPart(r);
        if (part instanceof FooterPart) {

          Ftr ftr = ((FooterPart) part).getJaxbElement();
          finder.walkJAXBElements(ftr);

        } else if (part instanceof HeaderPart) {

          Hdr hdr = ((HeaderPart) part).getJaxbElement();
          finder.walkJAXBElements(hdr);
        }
      }
    }

    // Styles in endnotes, footnotes?
    if (this.getEndNotesPart() != null) {
      log.debug("Looking at endnotes");
      CTEndnotes endnotes = this.getEndNotesPart().getJaxbElement();
      finder.walkJAXBElements(endnotes);
    }
    if (this.getFootnotesPart() != null) {
      log.debug("Looking at footnotes");
      CTFootnotes footnotes = this.getFootnotesPart().getJaxbElement();
      finder.walkJAXBElements(footnotes);
    }

    // Comments
    if (this.getCommentsPart() != null) {
      log.debug("Looking at comments");
      Comments comments = this.getCommentsPart().getJaxbElement();
      finder.walkJAXBElements(comments);
    }

    // Add fonts used in the styles we discovered
    // .. 2013 03 10: no longer necessary

    // Fonts can also be used in the numbering part
    // For now, treat any font mentioned in that part as in use.
    // Ideally, we'd only register fonts used in numbering levels
    // that were actually used in the document
    if (getNumberingDefinitionsPart() != null) {
      Numbering numbering = getNumberingDefinitionsPart().getJaxbElement();
      for (Numbering.AbstractNum abstractNumNode : numbering.getAbstractNum()) {
        for (Lvl lvl : abstractNumNode.getLvl()) {
          if (lvl.getRPr() != null && lvl.getRPr().getRFonts() != null) {
            String fontName = lvl.getRPr().getRFonts().getAscii();
            if (fontName != null) {
              fontsDiscovered.add(fontName);
              log.debug(
                  "Registered "
                      + fontName
                      + " for abstract list "
                      + abstractNumNode.getAbstractNumId()
                      + " lvl "
                      + lvl.getIlvl());
            }
          }
        }
      }
    }

    return fontsDiscovered;
  }
  public static WordprocessingMLPackage createPackage(PageSizePaper sz, boolean landscape)
      throws InvalidFormatException {

    // Create a package
    WordprocessingMLPackage wmlPack = new WordprocessingMLPackage();

    // Create main document part
    MainDocumentPart wordDocumentPart = new MainDocumentPart();

    // Create main document part content
    org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
    org.docx4j.wml.Body body = factory.createBody();
    org.docx4j.wml.Document wmlDocumentEl = factory.createDocument();

    wmlDocumentEl.setBody(body);

    // Create a basic sectPr using our Page model
    PageDimensions page = new PageDimensions();
    page.setPgSize(sz, landscape);

    SectPr sectPr = factory.createSectPr();
    body.setSectPr(sectPr);
    sectPr.setPgSz(page.getPgSz());
    sectPr.setPgMar(page.getPgMar());

    // Put the content in the part
    wordDocumentPart.setJaxbElement(wmlDocumentEl);

    // Add the main document part to the package relationships
    // (creating it if necessary)
    wmlPack.addTargetPart(wordDocumentPart);

    // Create a styles part
    Part stylesPart = new org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart();
    try {
      ((org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart) stylesPart)
          .unmarshalDefaultStyles();

      // Add the styles part to the main document part relationships
      // (creating it if necessary)
      wordDocumentPart.addTargetPart(stylesPart); // NB - add it to main doc part, not package!		

    } catch (Exception e) {
      // TODO: handle exception
      // e.printStackTrace();
      log.error(e.getMessage(), e);
    }

    // Metadata: docx4j 2.7.1 can populate some of this from docx4j.properties
    // See SaveToZipFile
    DocPropsCorePart core = new DocPropsCorePart();
    org.docx4j.docProps.core.ObjectFactory coreFactory =
        new org.docx4j.docProps.core.ObjectFactory();
    core.setJaxbElement(coreFactory.createCoreProperties());
    wmlPack.addTargetPart(core);

    DocPropsExtendedPart app = new DocPropsExtendedPart();
    org.docx4j.docProps.extended.ObjectFactory extFactory =
        new org.docx4j.docProps.extended.ObjectFactory();
    app.setJaxbElement(extFactory.createProperties());
    wmlPack.addTargetPart(app);

    // Return the new package
    return wmlPack;
  }
  public static void main(String[] args) throws Exception {

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
    CTSettings ct = new CTSettings();
    DocumentSettingsPart dsp = documentPart.getDocumentSettingsPart();
    if (dsp == null) {
      dsp = new DocumentSettingsPart();
      CTView ctView = Context.getWmlObjectFactory().createCTView();
      ctView.setVal(STView.PRINT);
      ct.setView(ctView);
      BooleanDefaultTrue b = new BooleanDefaultTrue();
      b.setVal(true);
      ct.setUpdateFields(b);
      dsp.setJaxbElement(ct);
      documentPart.addTargetPart(dsp);
    }

    org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) documentPart.getJaxbElement();
    Body body = wmlDocumentEl.getBody();

    ObjectFactory factory = Context.getWmlObjectFactory();

    /*
     * Create the following:
     *
     * <w:p> <w:r> <w:fldChar w:dirty="true" w:fldCharType="begin"/>
     * <w:instrText xml:space="preserve">TOC \o &quot;1-3&quot; \h \z \ u
     * \h</w:instrText> </w:r> <w:r/> <w:r> <w:fldChar w:fldCharType="end"/>
     * </w:r> </w:p>
     */
    P paragraphForTOC = factory.createP();
    R r = factory.createR();

    FldChar fldchar = factory.createFldChar();
    fldchar.setFldCharType(STFldCharType.BEGIN);
    fldchar.setDirty(true);
    r.getContent().add(getWrappedFldChar(fldchar));
    paragraphForTOC.getContent().add(r);

    R r1 = factory.createR();
    Text txt = new Text();
    txt.setSpace("preserve");
    txt.setValue("TOC \\o \"1-3\" \\h \\z \\u ");
    r.getContent().add(factory.createRInstrText(txt));
    paragraphForTOC.getContent().add(r1);

    FldChar fldcharend = factory.createFldChar();
    fldcharend.setFldCharType(STFldCharType.END);
    R r2 = factory.createR();
    r2.getContent().add(getWrappedFldChar(fldcharend));
    paragraphForTOC.getContent().add(r2);

    body.getContent().add(paragraphForTOC);

    documentPart.addStyledParagraphOfText("Heading1", "Hello 1");
    documentPart.addStyledParagraphOfText("Heading2", "Hello 2");
    documentPart.addStyledParagraphOfText("Heading3", "Hello 3");
    documentPart.addStyledParagraphOfText("Heading1", "Hello 1");

    wordMLPackage.save(
        new java.io.File(System.getProperty("user.dir") + "/OUT_TableOfContentsAdd.docx"));
  }
 private void setPageMargins() {
   try {
     Body body = wordMLPackage.getMainDocumentPart().getContents().getBody();
     Padding padding = bean.getReportLayout().getPagePadding();
     PageDimensions page = new PageDimensions();
     PgMar pgMar = page.getPgMar();
     pgMar.setBottom(BigInteger.valueOf(pixelsToDxa(padding.getBottom())));
     pgMar.setTop(BigInteger.valueOf(pixelsToDxa(padding.getTop())));
     pgMar.setLeft(BigInteger.valueOf(pixelsToDxa(padding.getLeft())));
     pgMar.setRight(BigInteger.valueOf(pixelsToDxa(padding.getRight())));
     SectPr sectPr = factory.createSectPr();
     body.setSectPr(sectPr);
     sectPr.setPgMar(pgMar);
   } catch (Docx4JException e) {
     e.printStackTrace();
   }
 }