@Override
    public List<Object> apply(Object o) {

      // NB: the tests in this method have to be comprehensive,
      // so if support for glow etc is introduced, tests for those
      // will need to be added

      if (o instanceof org.docx4j.wml.P) {
        P p = (P) o;

        // W14?
        if (p.getParaId() != null) {
          needW14 = true;
        }
        // W15?
        if (!needW15) {
          PPr ppr = p.getPPr();
          if (ppr != null) {
            if (ppr.getCollapsed() != null) {
              needW15 = true;
            }

            if (ppr.getSectPr() != null && ppr.getSectPr().getFootnoteColumns() != null) {
              needW15 = true;
            }
          }
        }

      } else if (o instanceof SdtElement) {
        SdtPr sdtPr = ((SdtElement) o).getSdtPr();
        if (sdtPr != null) {
          if (contains(
              sdtPr.getRPrOrAliasOrLock(),
              "http://schemas.microsoft.com/office/word/2010/wordml",
              w14SdtPrNames)) {
            needW14 = true;
          }
          if (contains(
              sdtPr.getRPrOrAliasOrLock(),
              "http://schemas.microsoft.com/office/word/2012/wordml",
              w15SdtPrNames)) {
            needW15 = true;
          }
        }
      } else if (o instanceof Tr) { // TODO does this need to be unwrapped?
        if (((Tr) o).getParaId() != null) {
          needW14 = true;
        }
      } else if (o instanceof CTObject) {
        if (((CTObject) o).getAnchorId() != null) {
          needW14 = true;
        }
      } else if (o instanceof Pict) {
        if (((Pict) o).getAnchorId() != null) {
          needW14 = true;
        }
      }

      return null;
    }
Beispiel #2
0
  /**
   * Creates document footer including page number
   *
   * @param doc WordprocessingMLPackage for the document.
   * @throws InvalidFormatException
   */
  private void createFooter(WordprocessingMLPackage doc) throws InvalidFormatException {
    MainDocumentPart content = doc.getMainDocumentPart();

    // Create footer
    FooterPart footer = new FooterPart();

    Ftr ftr = objectFactory.createFtr();
    P footerParagraph = objectFactory.createP();

    setStyle(footerParagraph, "footer");

    PPr parProps = objectFactory.createPPr();
    Jc al = objectFactory.createJc();
    al.setVal(JcEnumeration.RIGHT);
    parProps.setJc(al);
    footerParagraph.setPPr(parProps);

    // Add field start
    R run = objectFactory.createR();
    FldChar fldChar = objectFactory.createFldChar();
    fldChar.setFldCharType(STFldCharType.BEGIN);
    run.getContent().add(fldChar);
    footerParagraph.getContent().add(run);

    // Add pageNumber field
    run = objectFactory.createR();
    Text txt = objectFactory.createText();
    txt.setSpace("preserve");
    txt.setValue(" PAGE   \\* MERGEFORMAT ");
    run.getContent().add(objectFactory.createRInstrText(txt));
    footerParagraph.getContent().add(run);

    // Add field end
    run = objectFactory.createR();
    fldChar = objectFactory.createFldChar();
    fldChar.setFldCharType(STFldCharType.END);
    run.getContent().add(fldChar);
    footerParagraph.getContent().add(run);

    ftr.getContent().add(footerParagraph);
    footer.setJaxbElement(ftr);

    Relationship rel = content.addTargetPart(footer);

    // Relate footer to document
    List<SectionWrapper> sections = doc.getDocumentModel().getSections();

    SectPr sectPr = sections.get(sections.size() - 1).getSectPr();

    if (null == sectPr) {
      sectPr = objectFactory.createSectPr();
      content.addObject(sectPr);
      sections.get(sections.size() - 1).setSectPr(sectPr);
    }

    FooterReference footerReference = objectFactory.createFooterReference();
    footerReference.setId(rel.getId());
    footerReference.setType(HdrFtrRef.DEFAULT);
    sectPr.getEGHdrFtrReferences().add(footerReference);
  }
Beispiel #3
0
  /**
   * Adds page break to document
   *
   * @param content Document's main part
   * @throws Docx4JException
   */
  private void addPageBreak(MainDocumentPart content) throws Docx4JException {
    Br breakObj = objectFactory.createBr();
    breakObj.setType(STBrType.PAGE);

    P paragraph = objectFactory.createP();
    paragraph.getContent().add(breakObj);
    content.getContents().getBody().getContent().add(paragraph);
  }
Beispiel #4
0
  /**
   * Fija la alineación de un párrafo
   *
   * @param paragraph Párrafo a alinear
   * @param alignment Valor de alineamiento
   */
  private void alignParagraph(P paragraph, JcEnumeration alignment) {
    PPr parProps = paragraph.getPPr();
    if (null == parProps) parProps = objectFactory.createPPr();
    Jc al = objectFactory.createJc();
    al.setVal(alignment);
    parProps.setJc(al);

    paragraph.setPPr(parProps);
  }
 // create paraghraph with no space after
 private P createParagraph() {
   P paragraph = factory.createP();
   PPr pPr = factory.createPPr();
   Spacing spacing = new Spacing();
   spacing.setAfter(BigInteger.ZERO);
   pPr.setSpacing(spacing);
   paragraph.setPPr(pPr);
   return paragraph;
 }
Beispiel #6
0
 public static P createNewPage(MainDocumentPart mdp) {
   ObjectFactory objectFactory = new ObjectFactory();
   org.docx4j.wml.P p = objectFactory.createP();
   org.docx4j.wml.R run = objectFactory.createR();
   Br br = objectFactory.createBr();
   br.setType(STBrType.PAGE);
   run.getContent().add(br);
   p.getContent().add(run);
   mdp.getContent().add(p);
   return p;
 }
 private void setHorizontalAlignment(P paragraph, JcEnumeration hAlign) {
   if (hAlign != null) {
     PPr pprop = paragraph.getPPr();
     if (pprop == null) {
       pprop = new PPr();
       paragraph.setPPr(pprop);
     }
     Jc align = new Jc();
     align.setVal(hAlign);
     pprop.setJc(align);
     paragraph.setPPr(pprop);
   }
 }
 private void addHyperlinkTableCell(
     Tr tableRow,
     BandElement be,
     Hyperlink link,
     int width,
     Map<String, Object> style,
     int horizontalMergedCells,
     String verticalMergedVal) {
   org.docx4j.wml.P.Hyperlink hyp =
       newHyperlink(wordMLPackage.getMainDocumentPart(), link.getText(), link.getUrl());
   P paragraph = createParagraph();
   paragraph.getContent().add(hyp);
   addTableCell(
       tableRow, be, paragraph, width, style, horizontalMergedCells, verticalMergedVal, false);
 }
Beispiel #9
0
  private void initChildren(org.docx4j.wml.P para) {
    this.children = null;

    if (para == null) {
      return;
    }

    List<Object> pKids = para.getParagraphContent();
    if (!pKids.isEmpty()) {
      this.children = new ArrayList<ElementML>(pKids.size());

      ElementML ml = null;
      for (Object o : pKids) {
        Object value = JAXBIntrospector.getValue(o);

        if (value instanceof org.docx4j.wml.RunIns) {
          ml = new RunInsML(value, this.isDummy);
          ml.setParent(ParagraphML.this);
          this.children.add(ml);
        } else if (value instanceof org.docx4j.wml.RunDel) {
          ml = new RunDelML(value, this.isDummy);
          ml.setParent(ParagraphML.this);
          this.children.add(ml);
        } else if (value instanceof org.docx4j.wml.P.Hyperlink) {
          ml = new HyperlinkML(value, this.isDummy);
          ml.setParent(ParagraphML.this);
          this.children.add(ml);

        } else if (value instanceof org.docx4j.wml.CTSmartTagRun) {
          InlineTransparentML transparent = new InlineTransparentML(value, this.isDummy);
          // Current implementation is using InlineTransparentML
          // as surrogate container.
          if (transparent.getChildrenCount() > 0) {
            List<ElementML> list = new ArrayList<ElementML>(transparent.getChildren());
            for (ElementML elem : list) {
              elem.delete();
              elem.setParent(ParagraphML.this);
              this.children.add(elem);
            }
          }
        } else if (value instanceof org.docx4j.wml.CTMarkupRange) {
          // suppress <w:bookmarkStart> and <w:bookmarkEnd>
          JAXBIntrospector inspector = Context.jc.createJAXBIntrospector();
          QName name = inspector.getElementName(o);
          if (name != null
              && (name.getLocalPart() == "bookmarkStart" || name.getLocalPart() == "bookmarkEnd")) {
            // suppress
          } else {
            ml = new RunML(o, this.isDummy);
            ml.setParent(ParagraphML.this);
            this.children.add(ml);
          }
        } else {
          ml = new RunML(o, this.isDummy);
          ml.setParent(ParagraphML.this);
          this.children.add(ml);
        }
      }
    }
  } // initChildren()
Beispiel #10
0
  /**
   * Create a paragraph containing the string simpleText, without adding it to the document. If
   * passed null, the result is an empty P.
   *
   * @param simpleText
   * @return
   */
  public org.docx4j.wml.P createParagraphOfText(String simpleText) {

    org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
    org.docx4j.wml.P para = factory.createP();

    if (simpleText != null) {
      org.docx4j.wml.Text t = factory.createText();
      t.setValue(simpleText);

      org.docx4j.wml.R run = factory.createR();
      run.getContent().add(t); // ContentAccessor	

      para.getContent().add(run); // ContentAccessor
    }

    return para;
  }
 @Override
 protected void newPage() {
   flushNow();
   Br objBr = new Br();
   objBr.setType(STBrType.PAGE);
   P para = createParagraph();
   para.getContent().add(objBr);
   wordMLPackage.getMainDocumentPart().getContent().add(para);
   if (bean.getReportLayout().isHeaderOnEveryPage()) {
     try {
       printHeaderBand();
       newRow = true;
     } catch (QueryException e) {
       e.printStackTrace();
     }
   }
 }
Beispiel #12
0
  /**
   * Create a paragraph containing the string simpleText, styled using the specified style (up to
   * user to ensure it is a paragraph style) without adding it to the document.
   *
   * @param styleId
   * @param text
   * @return
   */
  public org.docx4j.wml.P createStyledParagraphOfText(String styleId, String text) {

    org.docx4j.wml.P p = createParagraphOfText(text);

    StyleDefinitionsPart styleDefinitionsPart = this.getStyleDefinitionsPart();

    if (getPropertyResolver().activateStyle(styleId)) {
      // Style is available
      org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
      org.docx4j.wml.PPr pPr = factory.createPPr();
      p.setPPr(pPr);
      org.docx4j.wml.PPrBase.PStyle pStyle = factory.createPPrBasePStyle();
      pPr.setPStyle(pStyle);
      pStyle.setVal(styleId);
    }

    return p;
  }
Beispiel #13
0
 private void initParagraphProperties(org.docx4j.wml.P para) {
   this.pPr = null;
   if (para != null) {
     // if not an implied ParagraphML
     PPr pProp = para.getPPr();
     if (pProp != null) {
       this.pPr = new ParagraphPropertiesML(pProp);
       this.pPr.setParent(ParagraphML.this);
     }
   }
 }
 public P newImage(
     WordprocessingMLPackage wordMLPackage,
     byte[] bytes,
     String filenameHint,
     String altText,
     int id1,
     int id2,
     long cx)
     throws Exception {
   BinaryPartAbstractImage imagePart =
       BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
   Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, cx, false);
   // Now add the inline in w:p/w:r/w:drawing
   ObjectFactory factory = Context.getWmlObjectFactory();
   P p = createParagraph();
   R run = factory.createR();
   p.getContent().add(run);
   Drawing drawing = factory.createDrawing();
   run.getContent().add(drawing);
   drawing.getAnchorOrInline().add(inline);
   return p;
 }
Beispiel #15
0
  public void flattenP(org.docx4j.wml.P p) {

    /*
    		<w:p w:rsidR="00283267" w:rsidRDefault="00E8712C">
    			<w:r><w:t>S</w:t></w:r>
    			<w:sdt><w:sdtPr><w:tag w:val="0" /><w:id w:val="589321610" /></w:sdtPr><w:sdtContent><w:r><w:t>Para1</w:t></w:r></w:sdtContent></w:sdt>
    		</w:p>
    */

    log.info("Flattening nested p ");
    boolean startAgain;
    do {
      startAgain = false;
      for (Object o : p.getContent()) {

        if (o instanceof SdtRun) { // This code path not used
          log.debug(".. detected nested sdt ");
          p.replaceElement(o, ((SdtRun) o).getSdtContent().getContent());
          // need to refresh the list we are iterating
          startAgain = true;
          break;
        } else if (o instanceof javax.xml.bind.JAXBElement) {

          if (((JAXBElement) o).getDeclaredType().getName().equals("org.docx4j.wml.SdtRun")) {
            log.debug(((JAXBElement) o).getDeclaredType().getName() + ".. detected SdtRun");
            org.docx4j.wml.SdtRun sdtRun = (org.docx4j.wml.SdtRun) ((JAXBElement) o).getValue();
            p.replaceElement(o, sdtRun.getSdtContent().getContent());
          } else {
            log.debug(((JAXBElement) o).getDeclaredType().getName() + ".. not an sdt");
          }

        } else {
          log.debug(o.getClass().getName() + ".. not an sdt");
        }
      }
    } while (startAgain);
  }
  /**
   * This is where we add the actual styling information. In order to do this we first create a
   * paragraph. Then we create a text with the content of the cell as the value. Thirdly, we create
   * a so-called run, which is a container for one or more pieces of text having the same set of
   * properties, and add the text to it. We then add the run to the content of the paragraph. So far
   * what we've done still doesn't add any styling. To accomplish that, we'll create run properties
   * and add the styling to it. These run properties are then added to the run. Finally the
   * paragraph is added to the content of the table cell.
   */
  private void addStyling(Tc tableCell, String content, boolean bold, String fontSize) {
    P paragraph = factory.createP();

    Text text = factory.createText();
    text.setValue(content);

    R run = factory.createR();
    run.getContent().add(text);

    paragraph.getContent().add(run);

    RPr runProperties = factory.createRPr();
    if (bold) {
      addBoldStyle(runProperties);
    }

    if (fontSize != null && !fontSize.isEmpty()) {
      setFontSize(runProperties, fontSize);
    }

    run.setRPr(runProperties);

    tableCell.getContent().add(paragraph);
  }
  private P createPageNumParagraph() {
    CTSimpleField pgnum = factory.createCTSimpleField();
    pgnum.setInstr(" PAGE \\* MERGEFORMAT ");
    RPr RPr = factory.createRPr();
    RPr.setNoProof(new BooleanDefaultTrue());
    PPr ppr = factory.createPPr();
    Jc jc = factory.createJc();
    jc.setVal(JcEnumeration.CENTER);
    ppr.setJc(jc);
    PPrBase.Spacing pprbase = factory.createPPrBaseSpacing();
    pprbase.setBefore(BigInteger.valueOf(240));
    pprbase.setAfter(BigInteger.valueOf(0));
    ppr.setSpacing(pprbase);

    R run = factory.createR();
    run.getContent().add(RPr);
    pgnum.getContent().add(run);

    JAXBElement<CTSimpleField> fldSimple = factory.createPFldSimple(pgnum);
    P para = createParagraph();
    para.getContent().add(fldSimple);
    para.setPPr(ppr);
    return para;
  }
  private void addHyperlinkCellStyle(
      Tc tableCell, BandElement be, P hyperlink, Map<String, Object> style) {
    setCellMargins(tableCell, style);
    setBackground(tableCell, style);
    setVerticalAlignment(tableCell, style);
    setHorizontalAlignment(hyperlink, style);
    setCellBorders(tableCell, style);

    R run = (R) ((org.docx4j.wml.P.Hyperlink) hyperlink.getContent().get(0)).getContent().get(0);
    RPr runProperties = run.getRPr();
    setFont(tableCell, style, runProperties);
    if (be != null) {
      setTextDirection(tableCell, be.getTextRotation());
    }

    tableCell.getContent().add(hyperlink);
  }
  void addNumbering(P p, Element e, Map<String, CSSValue> cssMap) {

    if (concreteList == null) {
      // We've just entered a list, so create a new one
      abstractList = createNewAbstractList();
      concreteList = ndp.addAbstractListNumberingDefinition(abstractList);
    }

    // Do we have a definition for this level yet?
    Lvl lvl = getLevel(abstractList, listStack.size() - 1);
    if (lvl == null) {
      // Nope, need to create it
      abstractList.getLvl().add(createLevel(listStack.size() - 1, cssMap));
    }

    setNumbering(p.getPPr(), concreteList.getNumId());
  }
  private void addCellStyle(
      Tc tableCell, BandElement be, String content, P paragraph, Map<String, Object> style) {
    if (style != null) {

      // inner html text
      if (content.startsWith("<html>")) {
        try {
          wordMLPackage
              .getMainDocumentPart()
              .addAltChunk(AltChunkType.Html, content.getBytes(), tableCell);
          tableCell.getContent().add(paragraph);
        } catch (Docx4JException e) {
          e.printStackTrace();
        }
        return;
      }

      Text text = factory.createText();
      text.setValue(content);

      R run = factory.createR();
      run.getContent().add(text);

      paragraph.getContent().add(run);

      setHorizontalAlignment(paragraph, style);

      RPr runProperties = factory.createRPr();

      setFont(tableCell, style, runProperties);
      setCellMargins(tableCell, style);
      setBackground(tableCell, style);
      setVerticalAlignment(tableCell, style);
      setCellBorders(tableCell, style);
      if (be != null) {
        setTextDirection(tableCell, be.getTextRotation());
      }

      run.setRPr(runProperties);

      tableCell.getContent().add(paragraph);
    }
  }
Beispiel #21
0
  private static List<Object> groupBodyContent(List<Object> bodyElts) {

    List<Object> resultElts = new ArrayList<Object>();
    List<Object> paragraphElts = null;
    SdtBlock sdtBorders = null;
    SdtBlock sdtShading = null;
    PBdr lastBorders = null;
    PBdr currentBorders = null;
    CTShd lastShading = null;
    CTShd currentShading = null;
    P paragraph = null;

    for (Object o : bodyElts) {
      if (o instanceof JAXBElement) {
        o = ((JAXBElement) o).getValue();
      }
      if (o instanceof P) {
        paragraph = (P) o;
        paragraphElts = groupRuns(paragraph.getContent());
        paragraph.getContent().clear();
        if (paragraphElts != null) {
          paragraph.getContent().addAll(paragraphElts);
        }

        currentBorders = null;
        currentShading = null;
        if (paragraph.getPPr() != null) {
          // TODO: use effective ppr properties!
          // ie take styles into account
          currentBorders = paragraph.getPPr().getPBdr();
          currentShading = paragraph.getPPr().getShd();
        }

        if (bordersChanged(currentBorders, lastBorders)) {
          // could mean null to borders; borders to null; or bordersA to bordersB
          if (currentBorders == null) {
            sdtBorders = null;
          } else {
            sdtBorders = createSdt(TAG_BORDERS);
            resultElts.add(sdtBorders);
          }
        }

        if (shadingChanged(currentShading, lastShading)) {
          // handle change to shading before addElement
          if (currentShading == null) {
            sdtShading = null;
          } else {
            sdtShading = createSdt(TAG_SHADING);

            // need to set margins, so there isn't a white strip
            // between paragraphs.  hmm, model.properties.paragraph
            // won't translate this.  so do it at the fo level
            if (sdtBorders != null) {
              sdtBorders.getSdtContent().getContent().add(sdtShading);
            } else {
              resultElts.add(sdtShading);
            }
          }
        }
      } else if (o instanceof Tbl) {
        groupTable((Tbl) o);
      }
      if (sdtShading != null) {
        sdtShading.getSdtContent().getContent().add(o);
      } else if (sdtBorders != null) {
        sdtBorders.getSdtContent().getContent().add(o);
      } else {
        resultElts.add(o);
      }

      // setup for next loop
      lastBorders = currentBorders;
      lastShading = currentShading;
    }
    return resultElts;
  }
Beispiel #22
0
  @Override
  public void write(OutputStream ous) {
    WordprocessingMLPackage doc;

    try {
      doc = WordprocessingMLPackage.createPackage();
      MainDocumentPart content = doc.getMainDocumentPart();

      // Create header and footer
      createHeader(doc);
      createFooter(doc);

      // Add first page
      P docTitle = content.addStyledParagraphOfText("Heading1", p.getTitle());
      alignParagraph(docTitle, JcEnumeration.CENTER);
      addPageBreak(content);

      // Add sections
      Iterator<DocumentSectionInstance> itdsi =
          SWBComparator.sortSortableObject(di.listDocumentSectionInstances());
      while (itdsi.hasNext()) {
        DocumentSectionInstance dsi = itdsi.next();
        SemanticClass cls =
            dsi.getSecTypeDefinition() != null
                    && dsi.getSecTypeDefinition().getSectionType() != null
                ? dsi.getSecTypeDefinition().getSectionType().transformToSemanticClass()
                : null;

        if (null == cls || !dsi.getSecTypeDefinition().isActive()) continue;

        // Add section title
        content.addStyledParagraphOfText("Heading2", dsi.getSecTypeDefinition().getTitle());

        // Gather sectionElement instances
        Iterator<SectionElement> itse =
            SWBComparator.sortSortableObject(dsi.listDocuSectionElementInstances());
        List<SectionElement> sectionElementInstances = new ArrayList<SectionElement>();
        while (itse.hasNext()) {
          SectionElement se = itse.next();
          sectionElementInstances.add(se);
        }

        if (cls.isSubClass(Instantiable.swpdoc_Instantiable, false)) {
          // Get visible props from config
          String[] props = dsi.getSecTypeDefinition().getVisibleProperties().split("\\|");

          // Add properties table
          if (props.length > 0 && !sectionElementInstances.isEmpty()) {
            int writableWidthTwips =
                doc.getDocumentModel()
                    .getSections()
                    .get(0)
                    .getPageDimensions()
                    .getWritableWidthTwips();
            int cellWidthTwips =
                new Double(Math.floor((writableWidthTwips / props.length))).intValue();

            Tbl propsTable =
                TblFactory.createTable(
                    sectionElementInstances.size() + 1, props.length, cellWidthTwips);
            setStyle(propsTable, "TableGrid");

            // Add table header
            Tr headerRow = (Tr) propsTable.getContent().get(0);
            int c = 0;
            for (String prop : props) {
              Tc col = (Tc) headerRow.getContent().get(c++);
              P colContent = objectFactory.createP(); // (P) col.getContent().get(0);
              TcPr cellProps = col.getTcPr();
              cellProps.getTcW().setType(TblWidth.TYPE_DXA);

              Text colText = objectFactory.createText();
              colText.setValue(prop.substring(0, prop.indexOf(";")));
              R colRun = objectFactory.createR();
              colRun.getContent().add(colText);

              setFontStyle(colRun, false, true);

              colContent.getContent().add(colRun);
              col.getContent().set(0, colContent);
              // alignParagraph(colContent, JcEnumeration.CENTER);
              // fillTableCell(col);
            }

            // Add rows
            int r = 1;
            for (SectionElement se : sectionElementInstances) {
              Tr row = (Tr) propsTable.getContent().get(r++);
              c = 0;
              for (String prop : props) {
                Tc col = (Tc) row.getContent().get(c++);
                String idProperty = prop.substring(prop.indexOf(";") + 1, prop.length());
                SemanticProperty sprop =
                    SWBPlatform.getSemanticMgr()
                        .getVocabulary()
                        .getSemanticPropertyById(idProperty);
                P colContent;

                if (null == sprop) {
                  colContent = content.createParagraphOfText("");
                } else {
                  if (!sprop.getPropId().equals(Referable.swpdoc_file.getPropId())) {
                    colContent =
                        content.createParagraphOfText(
                            se.getSemanticObject().getProperty(sprop) != null
                                ? se.getSemanticObject().getProperty(sprop)
                                : "");
                  } else {
                    colContent = content.createParagraphOfText(se.getTitle());
                  }
                }
                col.getContent().set(0, colContent);
                alignParagraph(colContent, JcEnumeration.BOTH);
                setStyle(colContent, "Normal");
              }
            }

            // Add table to document
            content.addObject(propsTable);
          }
        } else if (cls.equals(FreeText.sclass)) {
          XHTMLImporterImpl importer = new XHTMLImporterImpl(doc);
          for (SectionElement se : sectionElementInstances) {
            FreeText freeText = (FreeText) se;
            if (null != se) {
              String sContent = freeText.getText();
              if (null != sContent && !sContent.isEmpty()) {
                sContent =
                    sContent.replace(
                        "<!DOCTYPE html>",
                        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
                sContent =
                    sContent.replace("<html>", "<html xmlns=\"http://www.w3.org/1999/xhtml\">");

                // Override styles and alignment
                List<Object> objects = importer.convert(sContent, null);
                for (Object o : objects) {
                  if (o instanceof Tbl) setStyle((Tbl) o, "TableGrid");
                  if (o instanceof P) {
                    // Fix harcoded runProperties
                    List<Object> pChilds = ((P) o).getContent();
                    for (Object child : pChilds) {
                      if (child instanceof R) {
                        // ((R)child).setRPr(objectFactory.createRPr());
                        RPr rpr = ((R) child).getRPr();
                        if (null != rpr) {
                          rpr.getRFonts().setAsciiTheme(null);
                          rpr.getRFonts().setAscii(null);
                          rpr.getRFonts().setHAnsiTheme(null);
                          rpr.getRFonts().setHAnsi(null);
                        }
                      }
                    }
                    alignParagraph((P) o, JcEnumeration.BOTH);
                    setStyle((P) o, "Normal");
                  }
                }
                content.getContent().addAll(objects);
              }
            }
          }
        } else if (cls.equals(Activity.sclass)) {
          for (SectionElement se : sectionElementInstances) {
            Activity a = (Activity) se;
            if (a.getDescription() != null && !a.getDescription().isEmpty()) {
              XHTMLImporterImpl importer = new XHTMLImporterImpl(doc);
              content.addStyledParagraphOfText("Heading3", a.getTitle());

              String sContent = a.getDescription();
              if (null != sContent && !sContent.isEmpty()) {
                sContent =
                    sContent.replace(
                        "<!DOCTYPE html>",
                        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
                sContent =
                    sContent.replace("<html>", "<html xmlns=\"http://www.w3.org/1999/xhtml\">");

                // Override styles and alignment
                List<Object> objects = importer.convert(sContent, null);
                for (Object o : objects) {
                  if (o instanceof Tbl) setStyle((Tbl) o, "TableGrid");
                  if (o instanceof P) {
                    // Fix harcoded runProperties
                    List<Object> pChilds = ((P) o).getContent();
                    for (Object child : pChilds) {
                      if (child instanceof R) {
                        // ((R)child).setRPr(null);
                        RPr rpr = ((R) child).getRPr();
                        if (null != rpr) {
                          rpr.getRFonts().setAsciiTheme(null);
                          rpr.getRFonts().setAscii(null);
                          rpr.getRFonts().setHAnsiTheme(null);
                          rpr.getRFonts().setHAnsi(null);
                        }
                      }
                    }
                    alignParagraph((P) o, JcEnumeration.BOTH);
                    setStyle((P) o, "Normal");
                  }
                }
                content.getContent().addAll(objects);
              }
            }
          }
        } else if (cls.equals(Model.sclass)) {
          File img = new File(assetsPath + "/" + p.getId() + ".png");
          if (img.exists()) {
            FileInputStream fis = new FileInputStream(img);
            long length = img.length();

            if (length > Integer.MAX_VALUE) {
              log.error("File too large in model generation");
            } else {
              // Read image bytes
              byte[] bytes = new byte[(int) length];
              int offset = 0;
              int numRead = 0;
              while (offset < bytes.length
                  && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
              }

              if (offset < bytes.length) {
                log.error("Could not completely read file " + img.getName());
              }

              fis.close();

              // Generate ImagePart
              BinaryPartAbstractImage imagePart =
                  BinaryPartAbstractImage.createImagePart(doc, bytes);
              Inline inline = imagePart.createImageInline("", "", 0, 1, false);

              // Add image to paragraph
              P p = objectFactory.createP();
              R run = objectFactory.createR();
              p.getContent().add(run);
              Drawing drawing = objectFactory.createDrawing();
              run.getContent().add(drawing);
              drawing.getAnchorOrInline().add(inline);
              content.getContent().add(p);
            }
          }
        }
        addPageBreak(content);
      }
      doc.save(ous);
    } catch (Docx4JException | FileNotFoundException ex) {
      log.error("Error creating DOCX document", ex);
    } catch (IOException ex) {
      log.error("Error creating DOCX document", ex);
    } catch (Exception ex) {
      log.error("Error creating DOCX document", ex);
    }
  }
  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"));
  }
  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";
  }
  private WordprocessingMLPackage fetchComponents(
      WordprocessingMLPackage srcPackage, ContentAccessor contentAccessor) throws Docx4JException {

    // convert components to altChunk
    Map<Integer, CTAltChunk> replacements = new HashMap<Integer, CTAltChunk>();
    Integer index = 0;
    justGotAComponent = false;

    LinkedList<Integer> continuousBeforeIndex = new LinkedList<Integer>();
    List<Boolean> continuousBefore = new ArrayList<Boolean>();

    List<Boolean> continuousAfter = new ArrayList<Boolean>();

    for (Object block : contentAccessor.getContent()) {

      // Object ublock = XmlUtils.unwrap(block);
      if (block instanceof org.docx4j.wml.SdtBlock) {

        org.docx4j.wml.SdtBlock sdt = (org.docx4j.wml.SdtBlock) block;

        Tag tag = getSdtPr(sdt).getTag();

        if (tag == null) {
          List<Object> newContent = new ArrayList<Object>();
          newContent.add(sdt);
          continue;
        }

        log.info(tag.getVal());

        HashMap<String, String> map = QueryString.parseQueryString(tag.getVal(), true);

        String componentId = map.get(BINDING_ROLE_COMPONENT);
        if (componentId == null) continue;

        // Convert the sdt to a w:altChunk
        // .. get the IRI
        String iri = ComponentsPart.getComponentById(components, componentId).getIri();
        log.debug("Fetching " + iri);

        if (docxFetcher == null) {
          log.error("You need a docxFetcher (and the MergeDocx extension) to fetch components");
          return srcPackage;
        }

        // .. create the part
        AlternativeFormatInputPart afiPart =
            new AlternativeFormatInputPart(
                getNewPartName(
                    "/chunk", ".docx", srcPackage.getMainDocumentPart().getRelationshipsPart()));
        afiPart.setBinaryData(docxFetcher.getDocxFromIRI(iri));

        afiPart.setContentType(
            new ContentType(
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")); // docx

        Relationship altChunkRel = srcPackage.getMainDocumentPart().addTargetPart(afiPart);
        CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk();
        ac.setId(altChunkRel.getId());

        replacements.put(index, ac);

        /*
         * 2011 12 11 TODO.  Rethink support for
         * od:continuousBefore and od:continuousAfter.
         */

        // This is handled in this class
        if (map.get(BINDING_ROLE_COMPONENT_BEFORE) != null
            && map.get(BINDING_ROLE_COMPONENT_BEFORE).equals("true")) {
          continuousBefore.add(Boolean.TRUE);
          continuousBeforeIndex.addFirst(index);
          log.info("ctsBefore index: " + index);
        } else {
          continuousBefore.add(Boolean.FALSE);
          continuousBeforeIndex.addFirst(index);
        }

        // The following is handled in ProcessAltChunk
        if (map.get(BINDING_ROLE_COMPONENT_AFTER) != null
            && map.get(BINDING_ROLE_COMPONENT_AFTER).equals("true")) {
          continuousAfter.add(Boolean.TRUE);
        } else {
          continuousAfter.add(Boolean.TRUE);
        }

        justGotAComponent = true;
      }
      index++;
    }

    if (!justGotAComponent) {
      return srcPackage;
    }

    // Now replace in list
    for (Integer key : replacements.keySet()) {
      contentAccessor.getContent().set(key, replacements.get(key));
    }

    // Go through docx in reverse order
    List<Object> bodyChildren = contentAccessor.getContent();
    int i = 0;
    for (Integer indexIntoBody : continuousBeforeIndex) {

      if (continuousBefore.get(i)) {
        // Element before the w:altChunk
        if (indexIntoBody == 0) {
          // // Insert a sectPr right at the beginning of the docx?
          // // TODO check this isn't necessary
          // SectPr newSectPr =
          // Context.getWmlObjectFactory().createSectPr();
          // SectPr.Type type =
          // Context.getWmlObjectFactory().createSectPrType();
          // type.setVal("continuous");
          // newSectPr.setType( type );
          //
          // bodyChildren.add(0, newSectPr);

        } else {
          Object block = bodyChildren.get(indexIntoBody.intValue() - 1);
          if (block instanceof P
              && ((P) block).getPPr() != null
              && ((P) block).getPPr().getSectPr() != null) {
            makeContinuous(((P) block).getPPr().getSectPr());
          } else if (block instanceof P) {
            // More likely
            PPr ppr = ((P) block).getPPr();
            if (ppr == null) {
              ppr = Context.getWmlObjectFactory().createPPr();
              ((P) block).setPPr(ppr);
            }
            SectPr newSectPr = Context.getWmlObjectFactory().createSectPr();
            SectPr.Type type = Context.getWmlObjectFactory().createSectPrType();
            type.setVal("continuous");
            newSectPr.setType(type);

            ppr.setSectPr(newSectPr);
          } else {
            // Equally likely - its a table or something, so add a p
            P newP = Context.getWmlObjectFactory().createP();
            PPr ppr = Context.getWmlObjectFactory().createPPr();
            newP.setPPr(ppr);

            SectPr newSectPr = Context.getWmlObjectFactory().createSectPr();
            SectPr.Type type = Context.getWmlObjectFactory().createSectPrType();
            type.setVal("continuous");
            newSectPr.setType(type);
            ppr.setSectPr(newSectPr);

            bodyChildren.add(indexIntoBody.intValue(), newP); // add
            // before
            // altChunk
          }
        }
      }
      // else nothing specified, so go with normal MergeDocx behaviour

      i++;
    }

    // process altChunk
    try {
      // Use reflection, so docx4j can be built
      // by users who don't have the MergeDocx utility
      Class<?> documentBuilder = Class.forName("com.plutext.merge.ProcessAltChunk");
      // Method method = documentBuilder.getMethod("merge",
      // wmlPkgList.getClass());
      Method[] methods = documentBuilder.getMethods();
      Method processMethod = null;
      for (int j = 0; j < methods.length; j++) {
        log.debug(methods[j].getName());
        if (methods[j].getName().equals("process")) {
          processMethod = methods[j];
        }
      }
      if (processMethod == null) throw new NoSuchMethodException();
      return (WordprocessingMLPackage) processMethod.invoke(null, srcPackage);

    } catch (ClassNotFoundException e) {
      extensionMissing(e);
      justGotAComponent = false;
      return srcPackage;
      // throw new Docx4JException("Problem processing w:altChunk", e);
    } catch (NoSuchMethodException e) {
      // Degrade gracefully
      extensionMissing(e);
      justGotAComponent = false;
      return srcPackage;
      // throw new Docx4JException("Problem processing w:altChunk", e);
    } catch (Exception e) {
      throw new Docx4JException("Problem processing w:altChunk", e);
    }
  }