/** * 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); }
/** * 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); }
/** * 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; }
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); }
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()
@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(); } } }
/** * 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; }
/** * 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; }
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; }
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; }
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 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); }
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); } }
@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 "1-3" \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 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; }
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); } }
@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; }