1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
- package org.apache.poi.xwpf.usermodel;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Map;
-
- import javax.xml.namespace.QName;
-
- import org.apache.poi.POIXMLDocument;
- import org.apache.poi.POIXMLDocumentPart;
- import org.apache.poi.POIXMLException;
- import org.apache.poi.POIXMLProperties;
- import org.apache.poi.POIXMLRelation;
- import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
- import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
- import org.apache.poi.openxml4j.opc.OPCPackage;
- import org.apache.poi.openxml4j.opc.PackagePart;
- import org.apache.poi.openxml4j.opc.PackagePartName;
- import org.apache.poi.openxml4j.opc.PackageRelationship;
- import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
- import org.apache.poi.openxml4j.opc.PackagingURIHelper;
- import org.apache.poi.openxml4j.opc.TargetMode;
- import org.apache.poi.poifs.crypt.HashAlgorithm;
- import org.apache.poi.util.IOUtils;
- import org.apache.poi.util.IdentifierManager;
- import org.apache.poi.util.Internal;
- import org.apache.poi.util.PackageHelper;
- import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
- import org.apache.xmlbeans.XmlCursor;
- import org.apache.xmlbeans.XmlException;
- import org.apache.xmlbeans.XmlObject;
- import org.apache.xmlbeans.XmlOptions;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.CommentsDocument;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.EndnotesDocument;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect;
- import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
-
- /**
- * <p>High(ish) level class for working with .docx files.</p>
- *
- * <p>This class tries to hide some of the complexity
- * of the underlying file format, but as it's not a
- * mature and stable API yet, certain parts of the
- * XML structure come through. You'll therefore almost
- * certainly need to refer to the OOXML specifications
- * from
- * http://www.ecma-international.org/publications/standards/Ecma-376.htm
- * at some point in your use.</p>
- */
- public class XWPFDocument extends POIXMLDocument implements Document, IBody {
- private CTDocument1 ctDocument;
- private XWPFSettings settings;
- /**
- * Keeps track on all id-values used in this document and included parts, like headers, footers, etc.
- */
- private IdentifierManager drawingIdManager = new IdentifierManager(1L,4294967295L);
- protected List<XWPFFooter> footers = new ArrayList<XWPFFooter>();
- protected List<XWPFHeader> headers = new ArrayList<XWPFHeader>();
- protected List<XWPFComment> comments = new ArrayList<XWPFComment>();
- protected List<XWPFHyperlink> hyperlinks = new ArrayList<XWPFHyperlink>();
- protected List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
- protected List<XWPFTable> tables = new ArrayList<XWPFTable>();
- protected List<XWPFSDT> contentControls = new ArrayList<XWPFSDT>();
- protected List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
- protected List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
- protected Map<Long, List<XWPFPictureData>> packagePictures = new HashMap<Long, List<XWPFPictureData>>();
- protected Map<Integer, XWPFFootnote> endnotes = new HashMap<Integer, XWPFFootnote>();
- protected XWPFNumbering numbering;
- protected XWPFStyles styles;
- protected XWPFFootnotes footnotes;
-
- /** Handles the joy of different headers/footers for different pages */
- private XWPFHeaderFooterPolicy headerFooterPolicy;
-
- public XWPFDocument(OPCPackage pkg) throws IOException {
- super(pkg);
-
- //build a tree of POIXMLDocumentParts, this document being the root
- load(XWPFFactory.getInstance());
- }
-
- public XWPFDocument(InputStream is) throws IOException {
- super(PackageHelper.open(is));
-
- //build a tree of POIXMLDocumentParts, this workbook being the root
- load(XWPFFactory.getInstance());
- }
-
- public XWPFDocument(){
- super(newPackage());
- onDocumentCreate();
- }
-
- @Override
- protected void onDocumentRead() throws IOException {
- try {
- DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream());
- ctDocument = doc.getDocument();
-
- initFootnotes();
-
- // parse the document with cursor and add
- // the XmlObject to its lists
- XmlCursor cursor = ctDocument.getBody().newCursor();
- cursor.selectPath("./*");
- while (cursor.toNextSelection()) {
- XmlObject o = cursor.getObject();
- if (o instanceof CTP) {
- XWPFParagraph p = new XWPFParagraph((CTP) o, this);
- bodyElements.add(p);
- paragraphs.add(p);
- } else if (o instanceof CTTbl) {
- XWPFTable t = new XWPFTable((CTTbl) o, this);
- bodyElements.add(t);
- tables.add(t);
- } else if (o instanceof CTSdtBlock){
- XWPFSDT c = new XWPFSDT((CTSdtBlock)o, this);
- bodyElements.add(c);
- contentControls.add(c);
- }
- }
- cursor.dispose();
-
- // Sort out headers and footers
- if (doc.getDocument().getBody().getSectPr() != null)
- headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
-
- // Create for each XML-part in the Package a PartClass
- for (POIXMLDocumentPart p : getRelations()) {
- String relation = p.getPackageRelationship().getRelationshipType();
- if (relation.equals(XWPFRelation.STYLES.getRelation())) {
- this.styles = (XWPFStyles) p;
- this.styles.onDocumentRead();
- } else if (relation.equals(XWPFRelation.NUMBERING.getRelation())) {
- this.numbering = (XWPFNumbering) p;
- this.numbering.onDocumentRead();
- } else if (relation.equals(XWPFRelation.FOOTER.getRelation())) {
- XWPFFooter footer = (XWPFFooter) p;
- footers.add(footer);
- footer.onDocumentRead();
- } else if (relation.equals(XWPFRelation.HEADER.getRelation())) {
- XWPFHeader header = (XWPFHeader) p;
- headers.add(header);
- header.onDocumentRead();
- } else if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
- // TODO Create according XWPFComment class, extending POIXMLDocumentPart
- CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
- for (CTComment ctcomment : cmntdoc.getComments().getCommentArray()) {
- comments.add(new XWPFComment(ctcomment, this));
- }
- } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) {
- settings = (XWPFSettings) p;
- settings.onDocumentRead();
- } else if (relation.equals(XWPFRelation.IMAGES.getRelation())) {
- XWPFPictureData picData = (XWPFPictureData) p;
- picData.onDocumentRead();
- registerPackagePictureData(picData);
- pictures.add(picData);
- } else if (relation.equals(XWPFRelation.GLOSSARY_DOCUMENT.getRelation())) {
- // We don't currently process the glossary itself
- // Until we do, we do need to load the glossary child parts of it
- for (POIXMLDocumentPart gp : p.getRelations()) {
- // Trigger the onDocumentRead for all the child parts
- // Otherwise we'll hit issues on Styles, Settings etc on save
- try {
- Method onDocumentRead = gp.getClass().getDeclaredMethod("onDocumentRead");
- onDocumentRead.setAccessible(true);
- onDocumentRead.invoke(gp);
- } catch(Exception e) {
- throw new POIXMLException(e);
- }
- }
- }
- }
- initHyperlinks();
- } catch (XmlException e) {
- throw new POIXMLException(e);
- }
- }
-
- private void initHyperlinks(){
- // Get the hyperlinks
- // TODO: make me optional/separated in private function
- try {
- Iterator<PackageRelationship> relIter =
- getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
- while(relIter.hasNext()) {
- PackageRelationship rel = relIter.next();
- hyperlinks.add(new XWPFHyperlink(rel.getId(), rel.getTargetURI().toString()));
- }
- } catch (InvalidFormatException e){
- throw new POIXMLException(e);
- }
- }
-
- @SuppressWarnings("deprecation")
- private void initFootnotes() throws XmlException, IOException {
- for(POIXMLDocumentPart p : getRelations()){
- String relation = p.getPackageRelationship().getRelationshipType();
- if (relation.equals(XWPFRelation.FOOTNOTE.getRelation())) {
- this.footnotes = (XWPFFootnotes)p;
- this.footnotes.onDocumentRead();
- } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){
- EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream());
-
- for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteArray()) {
- endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn));
- }
- }
- }
- }
-
- /**
- * Create a new WordProcessingML package and setup the default minimal content
- */
- protected static OPCPackage newPackage() {
- try {
- OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
- // Main part
- PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
- // Create main part relationship
- pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
- // Create main document part
- pkg.createPart(corePartName, XWPFRelation.DOCUMENT.getContentType());
-
- pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
-
- return pkg;
- } catch (Exception e){
- throw new POIXMLException(e);
- }
- }
-
- /**
- * Create a new CTWorkbook with all values set to default
- */
- @Override
- protected void onDocumentCreate() {
- ctDocument = CTDocument1.Factory.newInstance();
- ctDocument.addNewBody();
-
- settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS,XWPFFactory.getInstance());
-
- POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
- expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
- }
-
- /**
- * Returns the low level document base object
- */
- @Internal
- public CTDocument1 getDocument() {
- return ctDocument;
- }
-
- IdentifierManager getDrawingIdManager() {
- return drawingIdManager;
- }
-
- /**
- * returns an Iterator with paragraphs and tables
- * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
- */
- @Override
- public List<IBodyElement> getBodyElements() {
- return Collections.unmodifiableList(bodyElements);
- }
-
- public Iterator<IBodyElement> getBodyElementsIterator() {
- return bodyElements.iterator();
- }
-
- /**
- * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs()
- */
- @Override
- public List<XWPFParagraph> getParagraphs(){
- return Collections.unmodifiableList(paragraphs);
- }
-
- /**
- * @see org.apache.poi.xwpf.usermodel.IBody#getTables()
- */
- @Override
- public List<XWPFTable> getTables(){
- return Collections.unmodifiableList(tables);
- }
-
- /**
- * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
- */
- @Override
- public XWPFTable getTableArray(int pos) {
- if (pos > 0 && pos < tables.size()){
- return tables.get(pos);
- }
- return null;
- }
-
- /**
- *
- * @return the list of footers
- */
- public List<XWPFFooter> getFooterList(){
- return Collections.unmodifiableList(footers);
- }
-
- public XWPFFooter getFooterArray(int pos){
- return footers.get(pos);
- }
-
- /**
- *
- * @return the list of headers
- */
- public List<XWPFHeader> getHeaderList(){
- return Collections.unmodifiableList(headers);
- }
-
- public XWPFHeader getHeaderArray(int pos){
- return headers.get(pos);
- }
-
- public String getTblStyle(XWPFTable table){
- return table.getStyleID();
- }
-
- public XWPFHyperlink getHyperlinkByID(String id) {
- for (XWPFHyperlink link : hyperlinks) {
- if (link.getId().equals(id))
- return link;
- }
-
- return null;
- }
-
- public XWPFFootnote getFootnoteByID(int id) {
- if(footnotes == null) return null;
- return footnotes.getFootnoteById(id);
- }
-
- public XWPFFootnote getEndnoteByID(int id) {
- if(endnotes == null) return null;
- return endnotes.get(id);
- }
-
- public List<XWPFFootnote> getFootnotes() {
- if(footnotes == null) {
- return Collections.emptyList();
- }
- return footnotes.getFootnotesList();
- }
-
- public XWPFHyperlink[] getHyperlinks() {
- return hyperlinks.toArray(new XWPFHyperlink[hyperlinks.size()]);
- }
-
- public XWPFComment getCommentByID(String id) {
- for (XWPFComment comment : comments) {
- if (comment.getId().equals(id))
- return comment;
- }
-
- return null;
- }
-
- public XWPFComment[] getComments() {
- return comments.toArray(new XWPFComment[comments.size()]);
- }
-
- /**
- * Get the document part that's defined as the
- * given relationship of the core document.
- */
- public PackagePart getPartById(String id) {
- try {
- PackagePart corePart = getCorePart();
- return corePart.getRelatedPart(corePart.getRelationship(id));
- } catch (InvalidFormatException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * Returns the policy on headers and footers, which
- * also provides a way to get at them.
- */
- public XWPFHeaderFooterPolicy getHeaderFooterPolicy() {
- return headerFooterPolicy;
- }
-
- /**
- * Returns the styles object used
- */
- @Internal
- public CTStyles getStyle() throws XmlException, IOException {
- PackagePart[] parts;
- try {
- parts = getRelatedByType(XWPFRelation.STYLES.getRelation());
- } catch(InvalidFormatException e) {
- throw new IllegalStateException(e);
- }
- if(parts.length != 1) {
- throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length);
- }
-
- StylesDocument sd = StylesDocument.Factory.parse(parts[0].getInputStream());
- return sd.getStyles();
- }
-
- /**
- * Get the document's embedded files.
- */
- @Override
- public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
- List<PackagePart> embedds = new LinkedList<PackagePart>();
-
- // Get the embeddings for the workbook
- PackagePart part = getPackagePart();
- for (PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) {
- embedds.add(part.getRelatedPart(rel));
- }
-
- for (PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) {
- embedds.add(part.getRelatedPart(rel));
- }
-
- return embedds;
- }
-
- /**
- * Finds that for example the 2nd entry in the body list is the 1st paragraph
- */
- private int getBodyElementSpecificPos(int pos, List<? extends IBodyElement> list) {
- // If there's nothing to find, skip it
- if(list.size() == 0) {
- return -1;
- }
-
- if(pos >= 0 && pos < bodyElements.size()) {
- // Ensure the type is correct
- IBodyElement needle = bodyElements.get(pos);
- if(needle.getElementType() != list.get(0).getElementType()) {
- // Wrong type
- return -1;
- }
-
- // Work back until we find it
- int startPos = Math.min(pos, list.size()-1);
- for(int i=startPos; i>=0; i--) {
- if(list.get(i) == needle) {
- return i;
- }
- }
- }
-
- // Couldn't be found
- return -1;
- }
-
- /**
- * Look up the paragraph at the specified position in the body elements list
- * and return this paragraphs position in the paragraphs list
- *
- * @param pos
- * The position of the relevant paragraph in the body elements
- * list
- * @return the position of the paragraph in the paragraphs list, if there is
- * a paragraph at the position in the bodyelements list. Else it
- * will return -1
- *
- */
- public int getParagraphPos(int pos) {
- return getBodyElementSpecificPos(pos, paragraphs);
- }
-
- /**
- * get with the position of a table in the bodyelement array list
- * the position of this table in the table array list
- * @param pos position of the table in the bodyelement array list
- * @return if there is a table at the position in the bodyelement array list,
- * else it will return null.
- */
- public int getTablePos(int pos) {
- return getBodyElementSpecificPos(pos, tables);
- }
-
- /**
- * Add a new paragraph at position of the cursor. The cursor must be on the
- * {@link org.apache.xmlbeans.XmlCursor.TokenType#START} tag of an subelement
- * of the documents body. When this method is done, the cursor passed as
- * parameter points to the {@link org.apache.xmlbeans.XmlCursor.TokenType#END}
- * of the newly inserted paragraph.
- *
- * @param cursor
- * @return the {@link XWPFParagraph} object representing the newly inserted
- * CTP object
- */
- @Override
- public XWPFParagraph insertNewParagraph(XmlCursor cursor) {
- if (isCursorInBody(cursor)) {
- String uri = CTP.type.getName().getNamespaceURI();
- /*
- * TODO DO not use a coded constant, find the constant in the OOXML
- * classes instead, as the child of type CT_Paragraph is defined in the
- * OOXML schema as 'p'
- */
- String localPart = "p";
- // creates a new Paragraph, cursor is positioned inside the new
- // element
- cursor.beginElement(localPart, uri);
- // move the cursor to the START token to the paragraph just created
- cursor.toParent();
- CTP p = (CTP) cursor.getObject();
- XWPFParagraph newP = new XWPFParagraph(p, this);
- XmlObject o = null;
- /*
- * move the cursor to the previous element until a) the next
- * paragraph is found or b) all elements have been passed
- */
- while (!(o instanceof CTP) && (cursor.toPrevSibling())) {
- o = cursor.getObject();
- }
- /*
- * if the object that has been found is a) not a paragraph or b) is
- * the paragraph that has just been inserted, as the cursor in the
- * while loop above was not moved as there were no other siblings,
- * then the paragraph that was just inserted is the first paragraph
- * in the body. Otherwise, take the previous paragraph and calculate
- * the new index for the new paragraph.
- */
- if ((!(o instanceof CTP)) || (CTP) o == p) {
- paragraphs.add(0, newP);
- } else {
- int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;
- paragraphs.add(pos, newP);
- }
-
- /*
- * create a new cursor, that points to the START token of the just
- * inserted paragraph
- */
- XmlCursor newParaPos = p.newCursor();
- try {
- /*
- * Calculate the paragraphs index in the list of all body
- * elements
- */
- int i = 0;
- cursor.toCursor(newParaPos);
- while (cursor.toPrevSibling()) {
- o = cursor.getObject();
- if (o instanceof CTP || o instanceof CTTbl)
- i++;
- }
- bodyElements.add(i, newP);
- cursor.toCursor(newParaPos);
- cursor.toEndToken();
- return newP;
- } finally {
- newParaPos.dispose();
- }
- }
- return null;
- }
-
- @Override
- public XWPFTable insertNewTbl(XmlCursor cursor) {
- if (isCursorInBody(cursor)) {
- String uri = CTTbl.type.getName().getNamespaceURI();
- String localPart = "tbl";
- cursor.beginElement(localPart, uri);
- cursor.toParent();
- CTTbl t = (CTTbl) cursor.getObject();
- XWPFTable newT = new XWPFTable(t, this);
- XmlObject o = null;
- while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) {
- o = cursor.getObject();
- }
- if (!(o instanceof CTTbl)) {
- tables.add(0, newT);
- } else {
- int pos = tables.indexOf(getTable((CTTbl) o)) + 1;
- tables.add(pos, newT);
- }
- int i = 0;
- XmlCursor tableCursor = t.newCursor();
- try {
- cursor.toCursor(tableCursor);
- while (cursor.toPrevSibling()) {
- o = cursor.getObject();
- if (o instanceof CTP || o instanceof CTTbl)
- i++;
- }
- bodyElements.add(i, newT);
- cursor.toCursor(tableCursor);
- cursor.toEndToken();
- return newT;
- }
- finally {
- tableCursor.dispose();
- }
- }
- return null;
- }
-
- /**
- * verifies that cursor is on the right position
- * @param cursor
- */
- private boolean isCursorInBody(XmlCursor cursor) {
- XmlCursor verify = cursor.newCursor();
- verify.toParent();
- try {
- return (verify.getObject() == this.ctDocument.getBody());
- } finally {
- verify.dispose();
- }
- }
-
- private int getPosOfBodyElement(IBodyElement needle) {
- BodyElementType type = needle.getElementType();
- IBodyElement current;
- for(int i=0; i<bodyElements.size(); i++) {
- current = bodyElements.get(i);
- if(current.getElementType() == type) {
- if(current.equals(needle)) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
- * Get the position of the paragraph, within the list
- * of all the body elements.
- * @param p The paragraph to find
- * @return The location, or -1 if the paragraph couldn't be found
- */
- public int getPosOfParagraph(XWPFParagraph p){
- return getPosOfBodyElement(p);
- }
-
- /**
- * Get the position of the table, within the list of
- * all the body elements.
- * @param t The table to find
- * @return The location, or -1 if the table couldn't be found
- */
- public int getPosOfTable(XWPFTable t){
- return getPosOfBodyElement(t);
- }
-
- /**
- * commit and saves the document
- */
- @Override
- protected void commit() throws IOException {
- XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
- xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDocument1.type.getName().getNamespaceURI(), "document"));
- Map<String, String> map = new HashMap<String, String>();
- map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
- map.put("urn:schemas-microsoft-com:office:office", "o");
- map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
- map.put("urn:schemas-microsoft-com:vml", "v");
- map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
- map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
- map.put("urn:schemas-microsoft-com:office:word", "w10");
- map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
- map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
- xmlOptions.setSaveSuggestedPrefixes(map);
-
- PackagePart part = getPackagePart();
- OutputStream out = part.getOutputStream();
- ctDocument.save(out, xmlOptions);
- out.close();
- }
-
- /**
- * Gets the index of the relation we're trying to create
- * @param relation
- * @return i
- */
- private int getRelationIndex(XWPFRelation relation) {
- List<POIXMLDocumentPart> relations = getRelations();
- int i = 1;
- for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext() ; ) {
- POIXMLDocumentPart item = it.next();
- if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
- i++;
- }
- }
- return i;
- }
-
- /**
- * Appends a new paragraph to this document
- * @return a new paragraph
- */
- public XWPFParagraph createParagraph() {
- XWPFParagraph p = new XWPFParagraph(ctDocument.getBody().addNewP(), this);
- bodyElements.add(p);
- paragraphs.add(p);
- return p;
- }
-
- /**
- * Creates an empty numbering if one does not already exist and sets the numbering member
- * @return numbering
- */
- public XWPFNumbering createNumbering() {
- if(numbering == null) {
- NumberingDocument numberingDoc = NumberingDocument.Factory.newInstance();
-
- XWPFRelation relation = XWPFRelation.NUMBERING;
- int i = getRelationIndex(relation);
-
- XWPFNumbering wrapper = (XWPFNumbering)createRelationship(relation, XWPFFactory.getInstance(), i);
- wrapper.setNumbering(numberingDoc.addNewNumbering());
- numbering = wrapper;
- }
-
- return numbering;
- }
-
- /**
- * Creates an empty styles for the document if one does not already exist
- * @return styles
- */
- public XWPFStyles createStyles() {
- if(styles == null) {
- StylesDocument stylesDoc = StylesDocument.Factory.newInstance();
-
- XWPFRelation relation = XWPFRelation.STYLES;
- int i = getRelationIndex(relation);
-
- XWPFStyles wrapper = (XWPFStyles)createRelationship(relation, XWPFFactory.getInstance(), i);
- wrapper.setStyles(stylesDoc.addNewStyles());
- styles = wrapper;
- }
-
- return styles;
- }
-
- /**
- * Creates an empty footnotes element for the document if one does not already exist
- * @return footnotes
- */
- public XWPFFootnotes createFootnotes() {
- if(footnotes == null) {
- FootnotesDocument footnotesDoc = FootnotesDocument.Factory.newInstance();
-
- XWPFRelation relation = XWPFRelation.FOOTNOTE;
- int i = getRelationIndex(relation);
-
- XWPFFootnotes wrapper = (XWPFFootnotes)createRelationship(relation, XWPFFactory.getInstance(), i);
- wrapper.setFootnotes(footnotesDoc.addNewFootnotes());
- footnotes = wrapper;
- }
-
- return footnotes;
- }
-
- public XWPFFootnote addFootnote(CTFtnEdn note) {
- return footnotes.addFootnote(note);
- }
-
- public XWPFFootnote addEndnote(CTFtnEdn note) {
- XWPFFootnote endnote = new XWPFFootnote(this, note);
- endnotes.put(note.getId().intValue(), endnote);
- return endnote;
- }
-
- /**
- * remove a BodyElement from bodyElements array list
- * @param pos
- * @return true if removing was successfully, else return false
- */
- public boolean removeBodyElement(int pos) {
- if (pos >= 0 && pos < bodyElements.size()) {
- BodyElementType type = bodyElements.get(pos).getElementType();
- if (type == BodyElementType.TABLE){
- int tablePos = getTablePos(pos);
- tables.remove(tablePos);
- ctDocument.getBody().removeTbl(tablePos);
- }
- if (type == BodyElementType.PARAGRAPH) {
- int paraPos = getParagraphPos(pos);
- paragraphs.remove(paraPos);
- ctDocument.getBody().removeP(paraPos);
- }
- bodyElements.remove(pos);
- return true;
- }
- return false;
- }
-
- /**
- * copies content of a paragraph to a existing paragraph in the list paragraphs at position pos
- * @param paragraph
- * @param pos
- */
- public void setParagraph(XWPFParagraph paragraph, int pos) {
- paragraphs.set(pos, paragraph);
- ctDocument.getBody().setPArray(pos, paragraph.getCTP());
- /* TODO update body element, update xwpf element, verify that
- * incoming paragraph belongs to this document or if not, XML was
- * copied properly (namespace-abbreviations, etc.)
- */
- }
-
- /**
- * @return the LastParagraph of the document
- */
- public XWPFParagraph getLastParagraph() {
- int lastPos = paragraphs.toArray().length - 1;
- return paragraphs.get(lastPos);
- }
-
- /**
- * Create an empty table with one row and one column as default.
- * @return a new table
- */
- public XWPFTable createTable() {
- XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this);
- bodyElements.add(table);
- tables.add(table);
- return table;
- }
-
- /**
- * Create an empty table with a number of rows and cols specified
- * @param rows
- * @param cols
- * @return table
- */
- public XWPFTable createTable(int rows, int cols) {
- XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols);
- bodyElements.add(table);
- tables.add(table);
- return table;
- }
-
- /**
- *
- */
- public void createTOC() {
- CTSdtBlock block = this.getDocument().getBody().addNewSdt();
- TOC toc = new TOC(block);
- for (XWPFParagraph par : paragraphs) {
- String parStyle = par.getStyle();
- if (parStyle != null && parStyle.startsWith("Heading")) {
- try {
- int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue();
- toc.addRow(level, par.getText(), 1, "112723803");
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- /**Replace content of table in array tables at position pos with a
- * @param pos
- * @param table
- */
- public void setTable(int pos, XWPFTable table) {
- tables.set(pos, table);
- ctDocument.getBody().setTblArray(pos, table.getCTTbl());
- }
-
- /**
- * Verifies that the documentProtection tag in settings.xml file <br/>
- * specifies that the protection is enforced (w:enforcement="1") <br/>
- * and that the kind of protection is readOnly (w:edit="readOnly")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
- * </pre>
- *
- * @return true if documentProtection is enforced with option readOnly
- */
- public boolean isEnforcedReadonlyProtection() {
- return settings.isEnforcedWith(STDocProtect.READ_ONLY);
- }
-
- /**
- * Verifies that the documentProtection tag in settings.xml file <br/>
- * specifies that the protection is enforced (w:enforcement="1") <br/>
- * and that the kind of protection is forms (w:edit="forms")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="forms" w:enforcement="1"/>
- * </pre>
- *
- * @return true if documentProtection is enforced with option forms
- */
- public boolean isEnforcedFillingFormsProtection() {
- return settings.isEnforcedWith(STDocProtect.FORMS);
- }
-
- /**
- * Verifies that the documentProtection tag in settings.xml file <br/>
- * specifies that the protection is enforced (w:enforcement="1") <br/>
- * and that the kind of protection is comments (w:edit="comments")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="comments" w:enforcement="1"/>
- * </pre>
- *
- * @return true if documentProtection is enforced with option comments
- */
- public boolean isEnforcedCommentsProtection() {
- return settings.isEnforcedWith(STDocProtect.COMMENTS);
- }
-
- /**
- * Verifies that the documentProtection tag in settings.xml file <br/>
- * specifies that the protection is enforced (w:enforcement="1") <br/>
- * and that the kind of protection is trackedChanges (w:edit="trackedChanges")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="trackedChanges" w:enforcement="1"/>
- * </pre>
- *
- * @return true if documentProtection is enforced with option trackedChanges
- */
- public boolean isEnforcedTrackedChangesProtection() {
- return settings.isEnforcedWith(STDocProtect.TRACKED_CHANGES);
- }
-
- public boolean isEnforcedUpdateFields() {
- return settings.isUpdateFields();
- }
-
- /**
- * Enforces the readOnly protection.<br/>
- * In the documentProtection tag inside settings.xml file, <br/>
- * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
- * and the value of edit to readOnly (w:edit="readOnly")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="readOnly" w:enforcement="1"/>
- * </pre>
- */
- public void enforceReadonlyProtection() {
- settings.setEnforcementEditValue(STDocProtect.READ_ONLY);
- }
-
- /**
- * Enforces the readOnly protection with a password.<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:documentProtection w:edit="readOnly" w:enforcement="1"
- * w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
- * w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
- * w:cryptSpinCount="100000" w:hash="..." w:salt="...."
- * />
- * </pre>
- *
- * @param password the plaintext password, if null no password will be applied
- * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
- * if null, it will default default to sha1
- */
- public void enforceReadonlyProtection(String password, HashAlgorithm hashAlgo) {
- settings.setEnforcementEditValue(STDocProtect.READ_ONLY, password, hashAlgo);
- }
-
- /**
- * Enforce the Filling Forms protection.<br/>
- * In the documentProtection tag inside settings.xml file, <br/>
- * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
- * and the value of edit to forms (w:edit="forms")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="forms" w:enforcement="1"/>
- * </pre>
- */
- public void enforceFillingFormsProtection() {
- settings.setEnforcementEditValue(STDocProtect.FORMS);
- }
-
- /**
- * Enforce the Filling Forms protection.<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:documentProtection w:edit="forms" w:enforcement="1"
- * w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
- * w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
- * w:cryptSpinCount="100000" w:hash="..." w:salt="...."
- * />
- * </pre>
- *
- * @param password the plaintext password, if null no password will be applied
- * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
- * if null, it will default default to sha1
- */
- public void enforceFillingFormsProtection(String password, HashAlgorithm hashAlgo) {
- settings.setEnforcementEditValue(STDocProtect.FORMS, password, hashAlgo);
- }
-
- /**
- * Enforce the Comments protection.<br/>
- * In the documentProtection tag inside settings.xml file,<br/>
- * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
- * and the value of edit to comments (w:edit="comments")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="comments" w:enforcement="1"/>
- * </pre>
- */
- public void enforceCommentsProtection() {
- settings.setEnforcementEditValue(STDocProtect.COMMENTS);
- }
-
- /**
- * Enforce the Comments protection.<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:documentProtection w:edit="comments" w:enforcement="1"
- * w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
- * w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
- * w:cryptSpinCount="100000" w:hash="..." w:salt="...."
- * />
- * </pre>
- *
- * @param password the plaintext password, if null no password will be applied
- * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
- * if null, it will default default to sha1
- */
- public void enforceCommentsProtection(String password, HashAlgorithm hashAlgo) {
- settings.setEnforcementEditValue(STDocProtect.COMMENTS, password, hashAlgo);
- }
-
- /**
- * Enforce the Tracked Changes protection.<br/>
- * In the documentProtection tag inside settings.xml file, <br/>
- * it sets the value of enforcement to "1" (w:enforcement="1") <br/>
- * and the value of edit to trackedChanges (w:edit="trackedChanges")<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:settings ... >
- * <w:documentProtection w:edit="trackedChanges" w:enforcement="1"/>
- * </pre>
- */
- public void enforceTrackedChangesProtection() {
- settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);
- }
-
- /**
- * Enforce the Tracked Changes protection.<br/>
- * <br/>
- * sample snippet from settings.xml
- * <pre>
- * <w:documentProtection w:edit="trackedChanges" w:enforcement="1"
- * w:cryptProviderType="rsaAES" w:cryptAlgorithmClass="hash"
- * w:cryptAlgorithmType="typeAny" w:cryptAlgorithmSid="14"
- * w:cryptSpinCount="100000" w:hash="..." w:salt="...."
- * />
- * </pre>
- *
- * @param password the plaintext password, if null no password will be applied
- * @param hashAlgo the hash algorithm - only md2, m5, sha1, sha256, sha384 and sha512 are supported.
- * if null, it will default default to sha1
- */
- public void enforceTrackedChangesProtection(String password, HashAlgorithm hashAlgo) {
- settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES, password, hashAlgo);
- }
-
- /**
- * Validates the existing password
- *
- * @param password
- * @return true, only if password was set and equals, false otherwise
- */
- public boolean validateProtectionPassword(String password) {
- return settings.validateProtectionPassword(password);
- }
-
- /**
- * Remove protection enforcement.<br/>
- * In the documentProtection tag inside settings.xml file <br/>
- * it sets the value of enforcement to "0" (w:enforcement="0") <br/>
- */
- public void removeProtectionEnforcement() {
- settings.removeEnforcement();
- }
-
- /**
- * Enforces fields update on document open (in Word).
- * In the settings.xml file <br/>
- * sets the updateSettings value to true (w:updateSettings w:val="true")
- *
- * NOTICES:
- * <ul>
- * <li>Causing Word to ask on open: "This document contains fields that may refer to other files. Do you want to update the fields in this document?"
- * (if "Update automatic links at open" is enabled)</li>
- * <li>Flag is removed after saving with changes in Word </li>
- * </ul>
- */
- public void enforceUpdateFields() {
- settings.setUpdateFields();
- }
-
- /**
- * Check if revision tracking is turned on.
- *
- * @return <code>true</code> if revision tracking is turned on
- */
- public boolean isTrackRevisions() {
- return settings.isTrackRevisions();
- }
-
- /**
- * Enable or disable revision tracking.
- *
- * @param enable <code>true</code> to turn on revision tracking, <code>false</code> to turn off revision tracking
- */
- public void setTrackRevisions(boolean enable) {
- settings.setTrackRevisions(enable);
- }
-
- /**
- * inserts an existing XWPFTable to the arrays bodyElements and tables
- * @param pos
- * @param table
- */
- @Override
- @SuppressWarnings("deprecation")
- public void insertTable(int pos, XWPFTable table) {
- bodyElements.add(pos, table);
- int i = 0;
- for (CTTbl tbl : ctDocument.getBody().getTblArray()) {
- if (tbl == table.getCTTbl()) {
- break;
- }
- i++;
- }
- tables.add(i, table);
- }
-
- /**
- * Returns all Pictures, which are referenced from the document itself.
- * @return a {@link List} of {@link XWPFPictureData}. The returned {@link List} is unmodifiable. Use #a
- */
- public List<XWPFPictureData> getAllPictures() {
- return Collections.unmodifiableList(pictures);
- }
-
- /**
- * @return all Pictures in this package
- */
- public List<XWPFPictureData> getAllPackagePictures() {
- List<XWPFPictureData> result = new ArrayList<XWPFPictureData>();
- Collection<List<XWPFPictureData>> values = packagePictures.values();
- for (List<XWPFPictureData> list : values) {
- result.addAll(list);
- }
- return Collections.unmodifiableList(result);
- }
-
- void registerPackagePictureData(XWPFPictureData picData) {
- List<XWPFPictureData> list = packagePictures.get(picData.getChecksum());
- if (list == null) {
- list = new ArrayList<XWPFPictureData>(1);
- packagePictures.put(picData.getChecksum(), list);
- }
- if (!list.contains(picData))
- {
- list.add(picData);
- }
- }
-
- XWPFPictureData findPackagePictureData(byte[] pictureData, int format)
- {
- long checksum = IOUtils.calculateChecksum(pictureData);
- XWPFPictureData xwpfPicData = null;
- /*
- * Try to find PictureData with this checksum. Create new, if none
- * exists.
- */
- List<XWPFPictureData> xwpfPicDataList = packagePictures.get(checksum);
- if (xwpfPicDataList != null) {
- Iterator<XWPFPictureData> iter = xwpfPicDataList.iterator();
- while (iter.hasNext() && xwpfPicData == null) {
- XWPFPictureData curElem = iter.next();
- if (Arrays.equals(pictureData, curElem.getData())) {
- xwpfPicData = curElem;
- }
- }
- }
- return xwpfPicData;
- }
-
- public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
- {
- XWPFPictureData xwpfPicData = findPackagePictureData(pictureData, format);
- POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
-
- if (xwpfPicData == null)
- {
- /* Part doesn't exist, create a new one */
- int idx = getNextPicNameNumber(format);
- xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
- /* write bytes to new part */
- PackagePart picDataPart = xwpfPicData.getPackagePart();
- OutputStream out = null;
- try {
- out = picDataPart.getOutputStream();
- out.write(pictureData);
- } catch (IOException e) {
- throw new POIXMLException(e);
- } finally {
- try {
- if (out != null) out.close();
- } catch (IOException e) {
- // ignore
- }
- }
-
- registerPackagePictureData(xwpfPicData);
- pictures.add(xwpfPicData);
-
- return getRelationId(xwpfPicData);
- }
- else if (!getRelations().contains(xwpfPicData))
- {
- /*
- * Part already existed, but was not related so far. Create
- * relationship to the already existing part and update
- * POIXMLDocumentPart data.
- */
- PackagePart picDataPart = xwpfPicData.getPackagePart();
- // TODO add support for TargetMode.EXTERNAL relations.
- TargetMode targetMode = TargetMode.INTERNAL;
- PackagePartName partName = picDataPart.getPartName();
- String relation = relDesc.getRelation();
- PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
- String id = relShip.getId();
- addRelation(id,xwpfPicData);
- pictures.add(xwpfPicData);
- return id;
- }
- else
- {
- /* Part already existed, get relation id and return it */
- return getRelationId(xwpfPicData);
- }
- }
-
- public String addPictureData(InputStream is,int format) throws InvalidFormatException
- {
- try {
- byte[] data = IOUtils.toByteArray(is);
- return addPictureData(data, format);
- } catch (IOException e) {
- throw new POIXMLException(e);
- }
- }
-
- /**
- * get the next free ImageNumber
- * @param format
- * @return the next free ImageNumber
- * @throws InvalidFormatException
- */
- public int getNextPicNameNumber(int format) throws InvalidFormatException {
- int img = getAllPackagePictures().size() + 1;
- String proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
- PackagePartName createPartName = PackagingURIHelper.createPartName(proposal);
- while (this.getPackage().getPart(createPartName) != null) {
- img++;
- proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
- createPartName = PackagingURIHelper.createPartName(proposal);
- }
- return img;
- }
-
- /**
- * returns the PictureData by blipID
- * @param blipID
- * @return XWPFPictureData of a specificID
- */
- public XWPFPictureData getPictureDataByID(String blipID) {
- POIXMLDocumentPart relatedPart = getRelationById(blipID);
- if (relatedPart instanceof XWPFPictureData) {
- XWPFPictureData xwpfPicData = (XWPFPictureData) relatedPart;
- return xwpfPicData;
- }
- return null;
- }
-
- /**
- * getNumbering
- * @return numbering
- */
- public XWPFNumbering getNumbering() {
- return numbering;
- }
-
- /**
- * get Styles
- * @return styles for this document
- */
- public XWPFStyles getStyles() {
- return styles;
- }
-
- /**
- * get the paragraph with the CTP class p
- *
- * @param p
- * @return the paragraph with the CTP class p
- */
- @Override
- public XWPFParagraph getParagraph(CTP p) {
- for (int i = 0; i < getParagraphs().size(); i++) {
- if (getParagraphs().get(i).getCTP() == p) {
- return getParagraphs().get(i);
- }
- }
- return null;
- }
-
- /**
- * get a table by its CTTbl-Object
- * @param ctTbl
- * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
- * @return a table by its CTTbl-Object or null
- */
- @Override
- public XWPFTable getTable(CTTbl ctTbl) {
- for (int i = 0; i < tables.size(); i++) {
- if (getTables().get(i).getCTTbl() == ctTbl) {
- return getTables().get(i);
- }
- }
- return null;
- }
-
- public Iterator<XWPFTable> getTablesIterator() {
- return tables.iterator();
- }
-
- public Iterator<XWPFParagraph> getParagraphsIterator() {
- return paragraphs.iterator();
- }
-
- /**
- * Returns the paragraph that of position pos
- * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)
- */
- @Override
- public XWPFParagraph getParagraphArray(int pos) {
- if (pos >= 0 && pos < paragraphs.size()) {
- return paragraphs.get(pos);
- }
- return null;
- }
-
- /**
- * returns the Part, to which the body belongs, which you need for adding relationship to other parts
- * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
- * belongs.
- * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
- */
- @Override
- public POIXMLDocumentPart getPart() {
- return this;
- }
-
-
- /**
- * get the PartType of the body, for example
- * DOCUMENT, HEADER, FOOTER, FOOTNOTE,
- *
- * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
- */
- @Override
- public BodyType getPartType() {
- return BodyType.DOCUMENT;
- }
-
- /**
- * get the TableCell which belongs to the TableCell
- * @param cell
- */
- @Override
- public XWPFTableCell getTableCell(CTTc cell) {
- XmlCursor cursor = cell.newCursor();
- cursor.toParent();
- XmlObject o = cursor.getObject();
- if(!(o instanceof CTRow)){
- return null;
- }
- CTRow row = (CTRow)o;
- cursor.toParent();
- o = cursor.getObject();
- cursor.dispose();
- if(! (o instanceof CTTbl)){
- return null;
- }
- CTTbl tbl = (CTTbl) o;
- XWPFTable table = getTable(tbl);
- if(table == null){
- return null;
- }
- XWPFTableRow tableRow = table.getRow(row);
- if (tableRow == null) {
- return null;
- }
- return tableRow.getTableCell(cell);
- }
-
- @Override
- public XWPFDocument getXWPFDocument() {
- return this;
- }
- }
|