aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Burch <nick@apache.org>2010-06-11 14:37:58 +0000
committerNick Burch <nick@apache.org>2010-06-11 14:37:58 +0000
commit91f1934fcc0fbcbf3e0c015fbe92adfa8d938a8d (patch)
treeaaf69ad071ca7977396dc446addd393ea809c1df
parentd6d52509337a02ef5e46b0fcc80d0335de0fea1a (diff)
downloadpoi-91f1934fcc0fbcbf3e0c015fbe92adfa8d938a8d.tar.gz
poi-91f1934fcc0fbcbf3e0c015fbe92adfa8d938a8d.zip
Apply (with slight tweaks) patch from Phillip Epp from bug #48574 - further XWPF support for tables, paragraphs, including enhanced support for adding new ones
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@953704 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/documentation/content/xdocs/status.xml1
-rw-r--r--src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java1
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java7
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java34
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java37
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java38
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java131
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java31
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java65
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java2
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java98
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java59
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java743
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java117
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java8
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java131
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java478
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java48
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java65
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java249
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java475
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java74
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java128
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java61
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java5
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java143
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java201
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java151
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java316
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java69
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java9
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java36
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java13
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java40
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java50
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java89
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java54
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java14
-rw-r--r--src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java46
40 files changed, 4069 insertions, 250 deletions
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 92474f0aa5..9bf39c78e8 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -34,6 +34,7 @@
<changes>
<release version="3.7-SNAPSHOT" date="2010-??-??">
+ <action dev="POI-DEVELOPERS" type="add">48574 - further XWPF support for tables, paragraphs, including enhanced support for adding new ones</action>
<action dev="POI-DEVELOPERS" type="add">48245 - tweak HWPF table cell detection to work across more files</action>
<action dev="POI-DEVELOPERS" type="add">48996 - initial support for External Name References in HSSF formula evaluation</action>
<action dev="POI-DEVELOPERS" type="fix">46664 - fix up Tab IDs when adding new sheets, so that print areas don't end up invalid</action>
diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
index 0aeba7450b..c129b0a793 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
@@ -281,5 +281,4 @@ public class POIXMLDocumentPart {
protected void onDocumentRead() throws IOException{
}
-
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
index 11c934f99e..7c90a59baa 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
@@ -120,8 +120,7 @@ public class XWPFHeaderFooterPolicy {
CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i);
PackagePart ftrPart = doc.getPartById(ref.getId());
XWPFFooter ftr = new XWPFFooter(
- FtrDocument.Factory.parse(ftrPart.getInputStream()).getFtr()
- );
+ FtrDocument.Factory.parse(ftrPart.getInputStream()).getFtr());
// Assign it
Enum type = ref.getType();
@@ -163,6 +162,7 @@ public class XWPFHeaderFooterPolicy {
XWPFHeader wrapper = (XWPFHeader)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars);
+ wrapper.setHeaderFooter(hdr);
OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
hdrDoc.setHdr(hdr);
@@ -189,6 +189,7 @@ public class XWPFHeaderFooterPolicy {
XWPFFooter wrapper = (XWPFFooter)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);
+ wrapper.setHeaderFooter(ftr);
OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
ftrDoc.setFtr(ftr);
@@ -459,6 +460,6 @@ public class XWPFHeaderFooterPolicy {
shapeTextPath.setString(text);
pict.set(group);
// end watermark paragraph
- return new XWPFParagraph(p);
+ return new XWPFParagraph(p, null);
}
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
new file mode 100644
index 0000000000..3df31061a4
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
@@ -0,0 +1,34 @@
+/* ====================================================================
+ 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;
+
+/**
+ * <p>
+ * 9 Jan 2010
+ * </p>
+ * <p>
+ * // TODO insert Javadoc here!
+ * </p>
+ * @author epp
+ *
+ */
+public enum BodyElementType {
+ PARAGRAPH,
+ TABLE,
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java
new file mode 100644
index 0000000000..10ba6e94a5
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java
@@ -0,0 +1,37 @@
+/* ====================================================================
+ 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;
+
+/**
+ * <p>
+ * 9 Jan 2010
+ * </p>
+ * <p>
+ * // TODO insert Javadoc here!
+ * </p>
+ * @author epp
+ *
+ */
+public enum BodyType {
+ DOCUMENT,
+ HEADER,
+ FOOTER,
+ FOOTNOTE,
+ TABLECELL
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
new file mode 100644
index 0000000000..2c3d4f732a
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
@@ -0,0 +1,38 @@
+/* ====================================================================
+ 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;
+
+public interface Document {
+ /** Extended windows meta file */
+ public static final int PICTURE_TYPE_EMF = 2;
+
+ /** Windows Meta File */
+ public static final int PICTURE_TYPE_WMF = 3;
+
+ /** Mac PICT format */
+ public static final int PICTURE_TYPE_PICT = 4;
+
+ /** JPEG format */
+ public static final int PICTURE_TYPE_JPEG = 5;
+
+ /** PNG format */
+ public static final int PICTURE_TYPE_PNG = 6;
+
+ /** Device independent bitmap */
+ public static final int PICTURE_TYPE_DIB = 7;
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
new file mode 100644
index 0000000000..35ebffd91e
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
@@ -0,0 +1,131 @@
+/* ====================================================================
+ 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.util.List;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.xmlbeans.XmlCursor;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
+
+
+
+/**
+ * <p>
+ * 8 Jan 2010
+ * </p>
+ * <p>
+ * // This Interface represents an object, which is able to have a collection of paragraphs and tables
+ * this can be XWFPDocument, XWPFHeader, XWPFFooter, XWPFTableCell
+ * </p>
+ * @author Philipp Epp
+ *
+ */
+public interface IBody {
+ /**
+ * 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.
+ * @return
+ */
+ IBody getPart();
+
+ /**
+ * get the PartType of the body, for example
+ * DOCUMENT, HEADER, FOOTER, FOOTNOTE,
+ * @return
+ */
+ BodyType getPartType();
+ /**
+ * Returns the paragraph(s) that holds
+ * the text of the header or footer.
+ */
+ public List<XWPFParagraph> getParagraphs();
+
+
+ /**
+ * Return the table(s) that holds the text
+ * of the IBodyPart, for complex cases
+ * where a paragraph isn't used.
+ */
+ public List<XWPFTable> getTables();
+
+ /**
+ * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer
+ * the method will return this paragraph
+ * if there is no corresponding {@link XWPFParagraph} the method will return null
+ * @param p is instance of CTP and is searching for an XWPFParagraph
+ * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer
+ * XWPFParagraph with the correspondig CTP p
+ */
+ public XWPFParagraph getParagraph(CTP p);
+
+ /**
+ * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header
+ * the method will return this table
+ * if there is no corresponding {@link XWPFTable} the method will return null
+ * @param ctTable
+ * @return
+ */
+ public XWPFTable getTable(CTTbl ctTable);
+
+ /**
+ * Returns the paragraph that of position pos
+ */
+ public XWPFParagraph getParagraphArray(int pos);
+
+ /**
+ * Returns the table at position pos
+ */
+ public XWPFTable getTableArray(int pos);
+
+ /**
+ *inserts a new paragraph at position of the cursor
+ * @param cursor
+ * @return
+ */
+ public XWPFParagraph insertNewParagraph(XmlCursor cursor);
+
+ /**
+ * inserts a new Table at the cursor position.
+ * @param cursor
+ * @return
+ */
+ public XWPFTable insertNewTbl(XmlCursor cursor);
+
+ /**
+ * inserts a new Table at position pos
+ * @param pos
+ * @param table
+ */
+ void insertTable(int pos, XWPFTable table);
+
+ /**
+ * returns the TableCell to which the Table belongs
+ * @param cell
+ * @return
+ */
+ XWPFTableCell getTableCell(CTTc cell);
+
+
+
+
+}
+
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
new file mode 100644
index 0000000000..03d133b37f
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
@@ -0,0 +1,31 @@
+/* ====================================================================
+ 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 org.apache.poi.POIXMLDocumentPart;
+
+/**
+ * 9 Jan 2010
+ * @author Philipp Epp
+ *
+ */
+public interface IBodyElement{
+ IBody getPart();
+ BodyType getPartType();
+ BodyElementType getElementType();
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
index 503aeca8e3..2fd6acade0 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
@@ -17,8 +17,8 @@
package org.apache.poi.xwpf.usermodel;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
/**
* Specifies all types of alignment which are available to be applied to objects in a
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
new file mode 100644
index 0000000000..5e387e7f8c
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
@@ -0,0 +1,65 @@
+/* ====================================================================
+ 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;
+
+
+/**
+ * postion of a character in a paragrapho
+* 1st RunPositon
+* 2nd TextPosition
+* 3rd CharacterPosition
+*
+*
+*/
+public class PositionInParagraph {
+ private int posRun = 0, posText = 0, posChar = 0;
+
+ public PositionInParagraph(){
+ }
+
+ public PositionInParagraph(int posRun, int posText, int posChar){
+ this.posRun=posRun;
+ this.posChar=posChar;
+ this.posText= posText;
+ }
+
+ public int getRun() {
+ return posRun;
+ }
+
+ public void setRun(int beginRun) {
+ this.posRun = beginRun;
+ }
+
+ public int getText() {
+ return posText;
+ }
+
+ public void setText(int beginText) {
+ this.posText = beginText;
+ }
+
+ public int getChar() {
+ return posChar;
+ }
+
+ public void setChar(int beginChar) {
+ this.posChar = beginChar;
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
index 60c5386957..f144e624d8 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
@@ -18,8 +18,8 @@ package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
-import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space;
import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
new file mode 100644
index 0000000000..23aa158081
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
@@ -0,0 +1,98 @@
+/* ====================================================================
+ 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;
+
+
+/**
+ * saves the begin and end position of a text in a Paragraph
+*/
+public class TextSegement {
+ private PositionInParagraph beginPos;
+ private PositionInParagraph endPos;
+
+ public TextSegement(){
+ this.beginPos = new PositionInParagraph();
+ this. endPos = new PositionInParagraph();
+ }
+
+ public TextSegement(int beginRun, int endRun, int beginText, int endText, int beginChar, int endChar){
+ PositionInParagraph beginPos = new PositionInParagraph(beginRun, beginText, beginChar);
+ PositionInParagraph endPos = new PositionInParagraph(endRun, endText, endChar);
+ this.beginPos = beginPos;
+ this.endPos = endPos;
+ }
+
+ public TextSegement(PositionInParagraph beginPos, PositionInParagraph endPos){
+ this.beginPos = beginPos;
+ this.endPos = endPos;
+ }
+
+ public PositionInParagraph getBeginPos(){
+ return beginPos;
+ }
+
+ public PositionInParagraph getEndPos(){
+ return endPos;
+ }
+
+ public int getBeginRun(){
+ return beginPos.getRun();
+ }
+
+ public void setBeginRun(int beginRun){
+ beginPos.setRun(beginRun);
+ }
+
+ public int getBeginText(){
+ return beginPos.getText();
+ }
+
+ public void setBeginText(int beginText){
+ beginPos.setText(beginText);
+ }
+
+ public int getBeginChar(){
+ return beginPos.getChar();
+ }
+
+ public void setBeginChar(int beginChar){
+ beginPos.setChar(beginChar);
+ }
+ public int getEndRun(){
+ return endPos.getRun();
+ }
+
+ public void setEndRun(int endRun){
+ endPos.setRun(endRun);
+ }
+
+ public int getEndText(){
+ return endPos.getText();
+ }
+
+ public void setEndText(int endText){
+ endPos.setText(endText);
+ }
+
+ public int getEndChar(){
+ return endPos.getChar();
+ }
+
+ public void setEndChar(int endChar){
+ endPos.setChar(endChar);
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
new file mode 100644
index 0000000000..12d2d3a02c
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
@@ -0,0 +1,59 @@
+/* ====================================================================
+ 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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFAbstractNum {
+ private CTAbstractNum ctAbstractNum;
+ protected XWPFNumbering numbering;
+
+ protected XWPFAbstractNum() {
+ this.ctAbstractNum = null;
+ this.numbering = null;
+
+ }
+ public XWPFAbstractNum(CTAbstractNum abstractNum){
+ this.ctAbstractNum = abstractNum;
+ }
+
+ public XWPFAbstractNum(CTAbstractNum ctAbstractNum, XWPFNumbering numbering){
+ this.ctAbstractNum = ctAbstractNum;
+ this.numbering = numbering;
+ }
+ public CTAbstractNum getAbstractNum(){
+ return ctAbstractNum;
+ }
+
+ public XWPFNumbering getNumbering(){
+ return numbering;
+ }
+
+ public CTAbstractNum getCTAbstractNum(){
+ return ctAbstractNum;
+ }
+
+ public void setNumbering(XWPFNumbering numbering){
+ this.numbering = numbering;
+ }
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index 2959317bfb..d7a7851963 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -43,19 +44,24 @@ 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.util.PackageHelper;
+import org.apache.poi.util.IOUtils;
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.CTBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
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;
@@ -67,23 +73,29 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
* Experimental class to do low level processing
* of docx files.
*
- * If you are using these low level classes, then you
+ * If you're using these low level classes, then you
* will almost certainly need to refer to the OOXML
* specifications from
* http://www.ecma-international.org/publications/standards/Ecma-376.htm
*
* WARNING - APIs expected to change rapidly
*/
-public class XWPFDocument extends POIXMLDocument {
+public class XWPFDocument extends POIXMLDocument implements Document, IBody {
private CTDocument1 ctDocument;
private XWPFSettings settings;
+ protected List<XWPFFooter> footers;
+ protected List <XWPFHeader> headers;
protected List<XWPFComment> comments;
protected List<XWPFHyperlink> hyperlinks;
protected List<XWPFParagraph> paragraphs;
protected List<XWPFTable> tables;
+ protected List<IBodyElement> bodyElements;
+ protected List<XWPFPictureData> pictures;
protected Map<Integer, XWPFFootnote> footnotes;
protected Map<Integer, XWPFFootnote> endnotes;
+ protected XWPFNumbering numbering;
+ protected XWPFStyles styles;
/** Handles the joy of different headers/footers for different pages */
private XWPFHeaderFooterPolicy headerFooterPolicy;
@@ -113,6 +125,9 @@ public class XWPFDocument extends POIXMLDocument {
comments = new ArrayList<XWPFComment>();
paragraphs = new ArrayList<XWPFParagraph>();
tables= new ArrayList<XWPFTable>();
+ bodyElements = new ArrayList<IBodyElement>();
+ footers = new ArrayList<XWPFFooter>();
+ headers = new ArrayList<XWPFHeader>();
footnotes = new HashMap<Integer, XWPFFootnote>();
endnotes = new HashMap<Integer, XWPFFootnote>();
@@ -120,27 +135,49 @@ public class XWPFDocument extends POIXMLDocument {
DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream());
ctDocument = doc.getDocument();
- CTBody body = ctDocument.getBody();
-
initFootnotes();
-
- // filling paragraph list
- for (CTP p : body.getPArray()) {
- paragraphs.add(new XWPFParagraph(p, this));
- }
-
- // Get any tables
- for(CTTbl table : body.getTblArray()) {
- tables.add(new XWPFTable(this, table));
+
+
+ // 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);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ bodyElements.add(t);
+ tables.add(t);
+ }
}
-
+
// 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.COMMENT.getRelation())){
+ if(relation.equals(XWPFRelation.STYLES.getRelation())){
+ this.styles = (XWPFStyles) p;
+ }
+ else if(relation.equals(XWPFRelation.NUMBERING.getRelation())){
+ this.numbering = (XWPFNumbering) p;
+
+ }
+ else if(relation.equals(XWPFRelation.FOOTER.getRelation())){
+ footers.add((XWPFFooter)p);
+ }
+ else if(relation.equals(XWPFRelation.HEADER.getRelation())){
+ headers.add((XWPFHeader)p);
+ }
+
+ else if(relation.equals(XWPFRelation.COMMENT.getRelation())){
CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
for(CTComment ctcomment : cmntdoc.getComments().getCommentArray()) {
comments.add(new XWPFComment(ctcomment));
@@ -155,12 +192,14 @@ public class XWPFDocument extends POIXMLDocument {
} catch (XmlException e) {
throw new POIXMLException(e);
}
+ // create for every Graphic-Part in Package a new XWPFGraphic
+ getAllPictures();
}
private void initHyperlinks(){
// Get the hyperlinks
// TODO: make me optional/separated in private function
- try {
+ try {
Iterator <PackageRelationship> relIter =
getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
while(relIter.hasNext()) {
@@ -192,10 +231,10 @@ public class XWPFDocument extends POIXMLDocument {
}
/**
- * Create a new SpreadsheetML package and setup the default minimal content
+ * Create a new WordProcessingML package and setup the default minimal content
*/
protected static OPCPackage newPackage() {
- try {
+ try {
OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
// Main part
PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
@@ -237,21 +276,90 @@ public class XWPFDocument extends POIXMLDocument {
public CTDocument1 getDocument() {
return ctDocument;
}
-
- public Iterator<XWPFParagraph> getParagraphsIterator() {
- return paragraphs.iterator();
+
+ /**
+ * returns an Iterator with paragraphs and tables
+ * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
+ * @return
+ */
+ public List<IBodyElement> getBodyElements(){
+ return Collections.unmodifiableList(bodyElements);
}
- public XWPFParagraph[] getParagraphs() {
- return paragraphs.toArray(
- new XWPFParagraph[paragraphs.size()]
- );
+
+ /**
+ * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs()
+ */
+ public List<XWPFParagraph> getParagraphs(){
+ return Collections.unmodifiableList(paragraphs);
}
-
- public Iterator<XWPFTable> getTablesIterator()
- {
- return tables.iterator();
+
+ /**
+ * @see org.apache.poi.xwpf.usermodel.IBody#getTables()
+ * @return
+ */
+ 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
+ */
+ public List<XWPFFooter> getFooterList(){
+ return Collections.unmodifiableList(footers);
+ }
+
+ /**
+ *
+ * @param pos
+ * @return
+ */
+ public XWPFFooter getFooterArray(int pos){
+ return footers.get(pos);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public List<XWPFHeader> getHeaderList(){
+ return Collections.unmodifiableList(headers);
+ }
+
+ /**
+ *
+ * @param pos
+ * @return
+ */
+ public XWPFHeader getHeaderArray(int pos){
+ return headers.get(pos);
+ }
+
+ /**
+ *
+ * @param table
+ * @return
+ */
+ public String getTblStyle(XWPFTable table){
+ return table.getStyleID();
}
+ /**
+ *
+ * @param id
+ * @return
+ */
public XWPFHyperlink getHyperlinkByID(String id) {
Iterator<XWPFHyperlink> iter = hyperlinks.iterator();
while(iter.hasNext())
@@ -264,18 +372,36 @@ public class XWPFDocument extends POIXMLDocument {
return null;
}
+ /**
+ *
+ * @param id
+ * @return
+ */
public XWPFFootnote getFootnoteByID(int id) {
return footnotes.get(id);
}
+ /**
+ *
+ * @param id
+ * @return
+ */
public XWPFFootnote getEndnoteByID(int id) {
return endnotes.get(id);
}
+ /**
+ *
+ * @return
+ */
public Collection<XWPFFootnote> getFootnotes() {
- return footnotes == null ? new ArrayList<XWPFFootnote>() : footnotes.values();
+ return Collections.unmodifiableCollection(footnotes == null ? new ArrayList<XWPFFootnote>() : footnotes.values());
}
+ /**
+ *
+ * @return
+ */
public XWPFHyperlink[] getHyperlinks() {
return hyperlinks.toArray(
new XWPFHyperlink[hyperlinks.size()]
@@ -356,7 +482,198 @@ public class XWPFDocument extends POIXMLDocument {
return embedds;
}
+
+ /**
+ * get with the position of a Paragraph in the bodyelement array list
+ * the position of this paragraph in the paragraph array list
+ * @param pos position of the paragraph in the bodyelement array list
+ * @return if there is a paragraph at the position in the bodyelement array list,
+ * else it will return -1
+ *
+ */
+ public int getParagraphPos(int pos){
+ if(pos >= 0 && pos < bodyElements.size()){
+ if(bodyElements.get(pos).getElementType() == BodyElementType.PARAGRAPH){
+ int startPos;
+ //find the startpoint for searching
+ if(pos < paragraphs.size()){
+ startPos = pos;
+ }
+ else{
+ startPos = (paragraphs.size());
+ }
+ for(int i = startPos; i < 0; i--){
+ if(paragraphs.get(i) == bodyElements.get(pos))
+ return i;
+ }
+ }
+ }
+ if(paragraphs.size() == 0){
+ return 0;
+ }
+ return -1;
+ }
+
+ /**
+ * 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){
+ if(pos >= 0 && pos < bodyElements.size()){
+ if(bodyElements.get(pos).getElementType() == BodyElementType.TABLE){
+ int startPos;
+ //find the startpoint for searching
+ if(pos < tables.size()){
+ startPos = pos;
+ }
+ else{
+ startPos = (tables.size());
+ }
+ for(int i = startPos; i > 0; i--){
+ if(tables.get(i) == bodyElements.get(pos))
+ return i;
+ }
+ }
+ }
+ if(tables.size() == 0){
+ return 0;
+ }
+ else
+ return -1;
+ }
+
+ /**
+ * add a new paragraph at position of the cursor
+ * @param cursor
+ * @return
+ */
+ public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+ if(isCursorInBody(cursor)){
+ String uri = CTP.type.getName().getNamespaceURI();
+ String localPart = "p";
+ cursor.beginElement(localPart,uri);
+ cursor.toParent();
+ CTP p = (CTP)cursor.getObject();
+ XWPFParagraph newP = new XWPFParagraph(p, this);
+ XmlObject o = null;
+ while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
+ o = cursor.getObject();
+ }
+ if((!(o instanceof CTP)) || (CTP)o == p){
+ paragraphs.add(0, newP);
+ }
+ else{
+ int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
+ paragraphs.add(pos,newP);
+ }
+ int i=0;
+ cursor.toCursor(p.newCursor());
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newP);
+ cursor.toCursor(p.newCursor());
+ cursor.toEndToken();
+ return newP;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param cursor
+ * @return
+ */
+ 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);
+ cursor.removeXmlContents();
+ 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;
+ cursor = t.newCursor();
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newT);
+ cursor = t.newCursor();
+ cursor.toEndToken();
+ return newT;
+ }
+ return null;
+ }
+
+ /**
+ * verifies that cursor is on the right position
+ * @param cursor
+ * @return
+ */
+ private boolean isCursorInBody(XmlCursor cursor) {
+ XmlCursor verify = cursor.newCursor();
+ verify.toParent();
+ if(verify.getObject() == this.ctDocument.getBody()){
+ return true;
+ }
+ XmlObject o = verify.getObject();
+ return false;
+
+ }
+
+ /**
+ * get position of the paragraph
+ * @param p
+ * @return
+ */
+ public Integer getPosOfParagraph(XWPFParagraph p){
+ int i, pos = 0;
+ for (i = 0 ; i < bodyElements.size() ; i++) {
+ if (bodyElements.get(i) instanceof XWPFParagraph){
+ if (bodyElements.get(i).equals(p)){
+ return pos;
+ }
+ pos++;
+ }
+ }
+ return null;
+ }
+
+ public Integer getPosOfTable(XWPFTable t){
+ int i, pos = 0;
+ for(i = 0; i < bodyElements.size(); i++){
+ if(bodyElements.get(i).getElementType() == BodyElementType.TABLE){
+ if (bodyElements.get(i) == t){
+ return pos;
+ }
+ pos++;
+ }
+ }
+ return null;
+ }
+ /**
+ * commit and saves the document
+ */
@Override
protected void commit() throws IOException {
@@ -382,20 +699,62 @@ public class XWPFDocument extends POIXMLDocument {
/**
* Appends a new paragraph to this document
- *
* @return a new paragraph
*/
public XWPFParagraph createParagraph(){
return new XWPFParagraph(ctDocument.getBody().addNewP(), this);
}
+
+ /**
+ * 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()){
+ if(bodyElements.get(pos).getElementType() == BodyElementType.TABLE){
+ bodyElements.remove(pos);
+ Integer tablePos = getTablePos(pos);
+ tables.remove(tablePos);
+ ctDocument.getBody().removeTbl(tablePos);
+ return true;
+ }
+ if(bodyElements.get(pos).getElementType() == BodyElementType.PARAGRAPH){
+ bodyElements.remove(pos);
+ Integer paraPos = getParagraphPos(pos);
+ paragraphs.remove(paraPos);
+ ctDocument.getBody().removeP(paraPos);
+ 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());
+ }
+
+ /**
+ * get the LastParagraph of the document
+ * @return
+ */
+ 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(){
- return new XWPFTable(this, ctDocument.getBody().addNewTbl());
+ return new XWPFTable(ctDocument.getBody().addNewTbl(), this);
}
/**
@@ -405,15 +764,17 @@ public class XWPFDocument extends POIXMLDocument {
* @return table
*/
public XWPFTable createTable(int rows, int cols) {
- return new XWPFTable(this, ctDocument.getBody().addNewTbl(), rows, cols);
+ return new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols);
}
-
+
+
+ /**
+ *
+ */
public void createTOC() {
CTSdtBlock block = this.getDocument().getBody().addNewSdt();
TOC toc = new TOC(block);
- int i = 1;
- for (Iterator<XWPFParagraph> iterator = getParagraphsIterator() ; iterator.hasNext() ; ) {
- XWPFParagraph par = iterator.next();
+ for (XWPFParagraph par: paragraphs ) {
String parStyle = par.getStyle();
if (parStyle != null && parStyle.substring(0, 7).equals("Heading")) {
try {
@@ -426,7 +787,15 @@ public class XWPFDocument extends POIXMLDocument {
}
}
}
-
+
+ /**Replace content of table in array tables at position pos with a
+ * @param pos, 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/>
@@ -568,4 +937,292 @@ public class XWPFDocument extends POIXMLDocument {
settings.removeEnforcement();
}
-}
+ /**
+ * inserts an existing XWPFTable to the arrays bodyElements and tables
+ * @param i
+ * @param table
+ */
+ @Override
+ public void insertTable(int pos, XWPFTable table) {
+ bodyElements.add(pos, table);
+ int i;
+ for (i = 0; i < ctDocument.getBody().getTblArray().length; i++) {
+ CTTbl tbl = ctDocument.getBody().getTblArray(i);
+ if(tbl == table.getCTTbl()){
+ break;
+ }
+ }
+ tables.add(i, table);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public List<XWPFPictureData> getAllPictures() {
+ if(pictures == null){
+ pictures = new ArrayList<XWPFPictureData>();
+ for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+ if(poixmlDocumentPart instanceof XWPFPictureData){
+ pictures.add((XWPFPictureData)poixmlDocumentPart);
+ }
+ }
+ }
+ return pictures;
+ }
+
+ /**
+ * get all Pictures in this package
+ * @return
+ */
+ public List<XWPFPictureData> getAllPackagePictures(){
+ List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>();
+ pkgpictures.addAll(getAllPictures());
+ for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+ if(poixmlDocumentPart instanceof XWPFHeaderFooter){
+ pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
+ }
+ }
+ return pkgpictures;
+ }
+
+ /**
+ * Adds a picture to the document.
+ *
+ * @param is The stream to read image from
+ * @param format The format of the picture.
+ *
+ * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+ * @throws InvalidFormatException
+ */
+ public int addPicture(InputStream is, int format) throws IOException, InvalidFormatException {
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true);
+ OutputStream out = img.getPackagePart().getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ pictures.add(img);
+ return getAllPictures().size()-1;
+
+ }
+
+ /**
+ * Adds a picture to the document.
+ *
+ * @param is The stream to read image from
+ * @param format The format of the picture.
+ *
+ * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+ * @throws InvalidFormatException
+ */
+ public int addPicture(byte[] pictureData, int format) throws InvalidFormatException {
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ try {
+ OutputStream out = img.getPackagePart().getOutputStream();
+ out.write(pictureData);
+ out.close();
+ } catch (IOException e){
+ throw new POIXMLException(e);
+ }
+
+ pictures.add(img);
+ return getAllPictures().size()-1;
+ }
+
+ /**
+ * get the next free ImageNumber
+ * @param format
+ * @return
+ * @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
+ * @throws Exception
+ */
+ public XWPFPictureData getPictureDataByID(String blipID) {
+ for(POIXMLDocumentPart part: getRelations()){
+ if(part.getPackageRelationship() != null){
+ if(part.getPackageRelationship().getId() != null){
+ if(part.getPackageRelationship().getId().equals(blipID)){
+ return (XWPFPictureData)part;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add the picture to drawing relations
+ *
+ * @param img the PictureData of the Picture,
+ * @throws InvalidFormatException
+ */
+ public PackageRelationship addPictureReference(byte[] pictureData, int format) throws InvalidFormatException{
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ PackageRelationship rel = null;
+ try {
+ OutputStream out = img.getPackagePart().getOutputStream();
+ out.write(pictureData);
+ out.close();
+ rel = img.getPackageRelationship();
+ pictures.add(img);
+ } catch (IOException e){
+ throw new POIXMLException(e);
+ }
+ return rel;
+ }
+
+ /**
+ * Add the picture to drawing relations
+ *
+ * @param img the PictureData of the Picture,
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public PackageRelationship addPictureReference(InputStream is, int format) throws InvalidFormatException, IOException{
+
+ PackageRelationship rel = null;
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ OutputStream out = img.getPackagePart().getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ rel = img.getPackageRelationship();
+ pictures.add(img);
+ return rel;
+ }
+
+ /**
+ * getNumbering
+ * @return numbering
+ */
+ public XWPFNumbering getNumbering(){
+ return numbering;
+ }
+
+ /**
+ * get Styles
+ * @return
+ */
+ public XWPFStyles getStyles(){
+ return styles;
+ }
+
+ /**
+ * get the paragraph with the CTP class p
+ * @param p
+ * @return
+ */
+ 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
+ */
+ 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 IBody getPart() {
+ return this;
+ }
+
+ /**
+ * get the PartType of the body, for example
+ * DOCUMENT, HEADER, FOOTER, FOOTNOTE,
+ * @return
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return BodyType.DOCUMENT;
+ }
+
+ /**
+ * get the TableCell which belongs to the TableCell
+ * @param o
+ * @return
+ */
+ @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();
+ 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(row == null){
+ return null;
+ }
+ return tableRow.getTableCell(cell);
+ }
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
index e0b4ed9a22..4b95ad1c5b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
@@ -17,10 +17,25 @@
package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+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.CTHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument;
/**
* Sketch of XWPF footer class
@@ -29,12 +44,112 @@ public class XWPFFooter extends XWPFHeaderFooter {
public XWPFFooter() {
super();
}
- public XWPFFooter(CTHdrFtr hdrFtr) {
+
+
+ public XWPFFooter(CTHdrFtr hdrFtr) throws IOException {
super(hdrFtr);
+ bodyElements = new ArrayList<IBodyElement>();
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables = new ArrayList<XWPFTable>();
+ XmlCursor cursor = headerFooter.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+ paragraphs.add(p);
+ bodyElements.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
+ }
+ }
+ getAllPictures();
}
public XWPFFooter(PackagePart part, PackageRelationship rel) throws IOException {
super(part, rel);
}
+ /**
+ * save and commit footer
+ */
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "ftr"));
+ Map map = new HashMap();
+ map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+ map.put("urn:schemas-microsoft-com:office:office", "o");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+ map.put("urn:schemas-microsoft-com:vml", "v");
+ map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+ map.put("urn:schemas-microsoft-com:office:word", "w10");
+ map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+ map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ super._getHdrFtr().save(out, xmlOptions);
+ out.close();
+ }
+
+ @Override
+ protected void onDocumentRead(){
+ bodyElements = new ArrayList<IBodyElement>();
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables= new ArrayList<XWPFTable>();
+ FtrDocument ftrDocument = null;
+ InputStream is;
+ try {
+ is = getPackagePart().getInputStream();
+ ftrDocument = FtrDocument.Factory.parse(is);
+ headerFooter = ftrDocument.getFtr();
+ // parse the document with cursor and add
+ // the XmlObject to its lists
+ XmlCursor cursor = headerFooter.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+ paragraphs.add(p);
+ bodyElements.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
+ }
+ }
+ getAllPictures();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (XmlException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ /**
+ * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ @Override
+ public IBody getPart() {
+ return this;
+ }
+
+ /**
+ * get the PartType of the body
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return BodyType.FOOTER;
+ }
+
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
index 8ee834d486..b3e30b8e0f 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
@@ -16,12 +16,12 @@
==================================================================== */
package org.apache.poi.xwpf.usermodel;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
-
-import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
+
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
public class XWPFFootnote implements Iterable<XWPFParagraph> {
private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
index 69dc84dec8..c78dc05e5e 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
@@ -17,24 +17,149 @@
package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+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.CTHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument;
/**
* Sketch of XWPF header class
*/
public class XWPFHeader extends XWPFHeaderFooter {
+
public XWPFHeader() {
super();
}
- public XWPFHeader(CTHdrFtr hdrFtr) {
+
+ public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
+ super(part, rel);
+ }
+
+ public XWPFHeader(CTHdrFtr hdrFtr) throws IOException {
super(hdrFtr);
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables = new ArrayList<XWPFTable>();
+ XmlCursor cursor = headerFooter.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP) o, this);
+ paragraphs.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl) o, this);
+ tables.add(t);
+ }
+ }
+ getAllPictures();
}
- public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
+ /**
+ public XWPFHeader(PackagePart part, PackageRelationship rel)
+ throws IOException {
super(part, rel);
}
-}
+ /**
+ * save and commit footer
+ */
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "hdr"));
+ Map map = new HashMap();
+ map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+ map.put("urn:schemas-microsoft-com:office:office", "o");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+ map.put("urn:schemas-microsoft-com:vml", "v");
+ map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+ map.put("urn:schemas-microsoft-com:office:word", "w10");
+ map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+ map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ super._getHdrFtr().save(out, xmlOptions);
+ out.close();
+ }
+
+ /**
+ * reads the document
+ * @overide onDocumentRead of class {@link POIXMLDocumentPart}
+ */
+ @Override
+ protected void onDocumentRead(){
+ bodyElements = new ArrayList<IBodyElement>();
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables= new ArrayList<XWPFTable>();
+ HdrDocument hdrDocument = null;
+ InputStream is;
+ try {
+ is = getPackagePart().getInputStream();
+ hdrDocument = HdrDocument.Factory.parse(is);
+ headerFooter = hdrDocument.getHdr();
+ // parse the document with cursor and add
+ // the XmlObject to its lists
+ XmlCursor cursor = headerFooter.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+ paragraphs.add(p);
+ bodyElements.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
+ }
+ }
+ getAllPictures();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (XmlException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ @Override
+ public IBody getPart() {
+ return this;
+ }
+
+ /**
+ * get the PartType of the body
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return BodyType.HEADER;
+ }
+
+
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
index 367242ee5c..2b11d733a7 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
@@ -17,28 +17,52 @@
package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.util.Internal;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.PackagingURIHelper;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
/**
* Parent of XWPF headers and footers
*/
-public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
+public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody{
protected CTHdrFtr headerFooter;
+ protected List<XWPFParagraph> paragraphs;
+ protected List<XWPFTable> tables;
+ protected List<XWPFPictureData> pictures;
+ protected XWPFDocument document;
+ protected List<IBodyElement> bodyElements;
- protected XWPFHeaderFooter(CTHdrFtr hdrFtr) {
+ protected XWPFHeaderFooter(CTHdrFtr hdrFtr){
headerFooter = hdrFtr;
+ readHdrFtr();
}
protected XWPFHeaderFooter() {
- headerFooter = CTHdrFtr.Factory.newInstance();
+ this(CTHdrFtr.Factory.newInstance());
}
public XWPFHeaderFooter(PackagePart part, PackageRelationship rel) throws IOException {
super(part, rel);
+ this.document = (XWPFDocument)getParent();
+ onDocumentRead();
}
@Internal
@@ -53,16 +77,11 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
* there could be more in certain cases, or
* a table.
*/
- public XWPFParagraph[] getParagraphs() {
- XWPFParagraph[] paras =
- new XWPFParagraph[headerFooter.getPArray().length];
- for(int i=0; i<paras.length; i++) {
- paras[i] = new XWPFParagraph(
- headerFooter.getPArray(i), null
- );
- }
- return paras;
- }
+ public List<XWPFParagraph> getParagraphs() {
+ return Collections.unmodifiableList(paragraphs);
+ }
+
+
/**
* Return the table(s) that holds the text
* of the header or footer, for complex cases
@@ -71,17 +90,11 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
* complex headers/footers have a table or two
* in addition.
*/
- public XWPFTable[] getTables() {
- XWPFTable[] tables =
- new XWPFTable[headerFooter.getTblArray().length];
- for(int i=0; i<tables.length; i++) {
- tables[i] = new XWPFTable(
- null,
- headerFooter.getTblArray(i)
- );
- }
- return tables;
- }
+ public List<XWPFTable> getTables()throws ArrayIndexOutOfBoundsException {
+ return Collections.unmodifiableList(tables);
+ }
+
+
/**
* Returns the textual content of the header/footer,
@@ -90,10 +103,9 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
public String getText() {
StringBuffer t = new StringBuffer();
- XWPFParagraph[] paras = getParagraphs();
- for(int i=0; i<paras.length; i++) {
- if(! paras[i].isEmpty()) {
- String text = paras[i].getText();
+ for(int i=0; i<paragraphs.size(); i++) {
+ if(! paragraphs.get(i).isEmpty()) {
+ String text = paragraphs.get(i).getText();
if(text != null && text.length() > 0) {
t.append(text);
t.append('\n');
@@ -101,9 +113,9 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
}
}
- XWPFTable[] tables = getTables();
- for(int i=0; i<tables.length; i++) {
- String text = tables[i].getText();
+ List<XWPFTable> tables = getTables();
+ for(int i=0; i<tables.size(); i++) {
+ String text = tables.get(i).getText();
if(text != null && text.length() > 0) {
t.append(text);
t.append('\n');
@@ -112,4 +124,404 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
return t.toString();
}
-}
+
+ /**
+ * set a new headerFooter
+ */
+ public void setHeaderFooter(CTHdrFtr headerFooter){
+ this.headerFooter = headerFooter;
+ readHdrFtr();
+ }
+
+ /**
+ * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header
+ * the method will return this table
+ * if there is no corresponding {@link XWPFTable} the method will return null
+ * @param ctTable
+ * @return
+ */
+ public XWPFTable getTable(CTTbl ctTable){
+ for (XWPFTable table : tables) {
+ if(table==null)
+ return null;
+ if(table.getCTTbl().equals(ctTable))
+ return table;
+ }
+ return null;
+ }
+
+ /**
+ * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer
+ * the method will return this paragraph
+ * if there is no corresponding {@link XWPFParagraph} the method will return null
+ * @param p is instance of CTP and is searching for an XWPFParagraph
+ * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer
+ * XWPFParagraph with the correspondig CTP p
+ */
+ public XWPFParagraph getParagraph(CTP p){
+ for (XWPFParagraph paragraph : paragraphs) {
+ if(paragraph.getCTP().equals(p))
+ return paragraph;
+ }
+ return null;
+
+ }
+
+ /**
+ * Returns the paragraph that holds
+ * the text of the header or footer.
+ */
+ public XWPFParagraph getParagraphArray(int pos) {
+
+ return paragraphs.get(pos);
+ }
+
+ /**
+ * get a List of all Paragraphs
+ * @return a list of {@link XWPFParagraph}
+ */
+ public List<XWPFParagraph> getListParagraph(){
+ return paragraphs;
+ }
+
+ public List<XWPFPictureData> getAllPictures() {
+ if(pictures == null){
+ pictures = new ArrayList<XWPFPictureData>();
+ for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+ if(poixmlDocumentPart instanceof XWPFPictureData){
+ pictures.add((XWPFPictureData)poixmlDocumentPart);
+ }
+ }
+ }
+ return pictures;
+ }
+
+ /**
+ * get all Pictures in this package
+ * @return
+ */
+ public List<XWPFPictureData> getAllPackagePictures(){
+ List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>();
+ pkgpictures.addAll(getAllPictures());
+ for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+ if(poixmlDocumentPart instanceof XWPFHeaderFooter){
+ pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
+ }
+ }
+ return pkgpictures;
+ }
+
+ /**
+ * Adds a picture to the document.
+ *
+ * @param is The stream to read image from
+ * @param format The format of the picture.
+ *
+ * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+ */
+ public int addPicture(InputStream is, int format) throws IOException {
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true);
+ OutputStream out = img.getPackagePart().getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ pictures.add(img);
+ return getAllPictures().size()-1;
+
+ }
+
+ /**
+ * Adds a picture to the document.
+ *
+ * @param is The stream to read image from
+ * @param format The format of the picture.
+ *
+ * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+ */
+ public int addPicture(byte[] pictureData, int format) {
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ try {
+ OutputStream out = img.getPackagePart().getOutputStream();
+ out.write(pictureData);
+ out.close();
+ } catch (IOException e){
+ throw new POIXMLException(e);
+ }
+
+ pictures.add(img);
+ return getAllPictures().size()-1;
+ }
+
+ /**
+ * get the next free ImageNumber
+ * @param format
+ * @return
+ */
+ public int getNextPicNameNumber(int format){
+ int img = getAllPackagePictures().size()+1;
+ String proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+ try {
+ PackagePartName createPartName = PackagingURIHelper.createPartName(proposal);
+ while (this.getPackagePart().getPackage().getPart(createPartName)!= null){
+ img++;
+ proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+ createPartName = PackagingURIHelper.createPartName(proposal);
+ }
+ } catch (InvalidFormatException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return img;
+ }
+
+ /**
+ * returns the PictureData by blipID
+ * @param blipID
+ * @return XWPFPictureData of a specificID
+ * @throws Exception
+ */
+ public XWPFPictureData getPictureDataByID(String blipID) {
+ for(POIXMLDocumentPart part: getRelations()){
+ if(part.getPackageRelationship() != null){
+ if(part.getPackageRelationship().getId() != null){
+ if(part.getPackageRelationship().getId().equals(blipID)){
+ return (XWPFPictureData)part;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add the picture to drawing relations
+ *
+ * @param img the PictureData of the Picture,
+ */
+ public PackageRelationship addPictureReference(byte[] pictureData, int format){
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ PackageRelationship rel = null;
+ try {
+ OutputStream out = img.getPackagePart().getOutputStream();
+ out.write(pictureData);
+ out.close();
+ rel = img.getPackageRelationship();
+ pictures.add(img);
+ } catch (IOException e){
+ throw new POIXMLException(e);
+ }
+ return rel;
+ }
+
+ /**
+ * Add the picture to drawing relations
+ *
+ * @param img the PictureData of the Picture,
+ */
+ public PackageRelationship addPictureReference(InputStream is, int format){
+
+ PackageRelationship rel = null;
+ try {
+ int imageNumber = getNextPicNameNumber(format);
+ XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+ OutputStream out = img.getPackagePart().getOutputStream();
+ IOUtils.copy(is, out);
+ out.close();
+ rel = img.getPackageRelationship();
+ pictures.add(img);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return rel;
+ }
+
+ /**
+ * add a new paragraph at position of the cursor
+ * @param cursor
+ * @return
+ */
+ public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+ if(isCursorInHdrF(cursor)){
+ String uri = CTP.type.getName().getNamespaceURI();
+ String localPart = "p";
+ cursor.beginElement(localPart,uri);
+ cursor.toParent();
+ CTP p = (CTP)cursor.getObject();
+ XWPFParagraph newP = new XWPFParagraph(p, this);
+ XmlObject o = null;
+ while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
+ o = cursor.getObject();
+ }
+ if((!(o instanceof CTP)) || (CTP)o == p){
+ paragraphs.add(0, newP);
+ }
+ else{
+ int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
+ paragraphs.add(pos,newP);
+ }
+ int i=0;
+ cursor.toCursor(p.newCursor());
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newP);
+ cursor.toCursor(p.newCursor());
+ cursor.toEndToken();
+ return newP;
+ }
+ return null;
+ }
+
+
+ /**
+ *
+ * @param cursor
+ * @return
+ */
+ public XWPFTable insertNewTbl(XmlCursor cursor) {
+ if(isCursorInHdrF(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);
+ cursor.removeXmlContents();
+ 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;
+ cursor = t.newCursor();
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newT);
+ cursor = t.newCursor();
+ cursor.toEndToken();
+ return newT;
+ }
+ return null;
+ }
+
+ /**
+ * verifies that cursor is on the right position
+ * @param cursor
+ * @return
+ */
+ private boolean isCursorInHdrF(XmlCursor cursor) {
+ XmlCursor verify = cursor.newCursor();
+ verify.toParent();
+ if(verify.getObject() == this.headerFooter){
+ return true;
+ }
+ return false;
+ }
+
+
+ public POIXMLDocumentPart getOwner(){
+ return this;
+ }
+
+ /**
+ * Returns the table at position pos
+ * @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;
+ }
+
+ /**
+ * inserts an existing XWPFTable to the arrays bodyElements and tables
+ * @param i
+ * @param table
+ */
+ @Override
+ public void insertTable(int pos, XWPFTable table) {
+ bodyElements.add(pos, table);
+ int i;
+ for (i = 0; i < headerFooter.getTblArray().length; i++) {
+ CTTbl tbl = headerFooter.getTblArray(i);
+ if(tbl == table.getCTTbl()){
+ break;
+ }
+ }
+ tables.add(i, table);
+
+ }
+
+ public void readHdrFtr(){
+ bodyElements = new ArrayList<IBodyElement>();
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables= new ArrayList<XWPFTable>();
+ // parse the document with cursor and add
+ // the XmlObject to its lists
+ XmlCursor cursor = headerFooter.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+ paragraphs.add(p);
+ bodyElements.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
+ }
+ }
+ getAllPictures();
+ }
+
+ /**
+ * get the TableCell which belongs to the TableCell
+ * @param o
+ * @return
+ */
+ 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();
+ 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(row == null){
+ return null;
+ }
+ return tableRow.getTableCell(cell);
+ }
+
+
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
new file mode 100644
index 0000000000..e04dc914f4
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
@@ -0,0 +1,48 @@
+/* ====================================================================
+ 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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;
+
+public class XWPFLatentStyles {
+ private CTLatentStyles latentStyles;
+ protected XWPFStyles styles; //LatentStyle shall know styles
+
+ protected XWPFLatentStyles(){
+ }
+
+ protected XWPFLatentStyles(CTLatentStyles latentStyles){
+ this(latentStyles,null);
+ }
+
+ protected XWPFLatentStyles(CTLatentStyles latentStyles, XWPFStyles styles) {
+ this.latentStyles=latentStyles;
+ this.styles=styles;
+ }
+
+ /**
+ * checks wheter specific LatentStyleID is a latentStyle
+ */
+ protected boolean isLatentStyle(String latentStyleID){
+ for ( CTLsdException lsd: latentStyles.getLsdExceptionArray()) {
+ if(lsd.getName().equals(latentStyleID));
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
new file mode 100644
index 0000000000..300936d2a0
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
@@ -0,0 +1,65 @@
+/* ====================================================================
+ 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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFNum {
+ private CTNum ctNum;
+ protected XWPFNumbering numbering;
+
+ public XWPFNum(){
+ this.ctNum = null;
+ this.numbering = null;
+ }
+
+ public XWPFNum(CTNum ctNum){
+ this.ctNum = ctNum;
+ this.numbering = null;
+ }
+
+ public XWPFNum(XWPFNumbering numbering){
+ this.ctNum = null;
+ this.numbering = numbering;
+ }
+
+ public XWPFNum(CTNum ctNum, XWPFNumbering numbering){
+ this.ctNum = ctNum;
+ this.numbering = numbering;
+ }
+
+ public XWPFNumbering getNumbering(){
+ return numbering;
+ }
+
+ public CTNum getCTNum(){
+ return ctNum;
+ }
+
+ public void setNumbering(XWPFNumbering numbering){
+ this.numbering = numbering;
+ }
+
+ public void setCTNum(CTNum ctNum){
+ this.ctNum = ctNum;
+ }
+} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
new file mode 100644
index 0000000000..267491ff9e
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
@@ -0,0 +1,249 @@
+/* ====================================================================
+ 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFNumbering extends POIXMLDocumentPart {
+ private CTNumbering ctNumbering;
+ protected List<XWPFAbstractNum> abstractNums;
+ protected List<XWPFNum> nums;
+ protected boolean isNew;
+
+ /**
+ *create a new styles object with an existing document
+ */
+ public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
+ super(part, rel);
+ isNew = true;
+ onDocumentRead();
+ }
+
+ /**
+ * read numbering form an existing package
+ */
+ @Override
+ protected void onDocumentRead() throws IOException{
+ abstractNums = new ArrayList<XWPFAbstractNum>();
+ nums = new ArrayList<XWPFNum>();
+ NumberingDocument numberingDoc = null;
+ InputStream is;
+ is = getPackagePart().getInputStream();
+ try {
+ numberingDoc = NumberingDocument.Factory.parse(is);
+ ctNumbering = numberingDoc.getNumbering();
+ //get any Nums
+ for(CTNum ctNum : ctNumbering.getNumArray()) {
+ nums.add(new XWPFNum(ctNum, this));
+ }
+ for(CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()){
+ abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this));
+ }
+ isNew = false;
+ } catch (XmlException e) {
+ throw new POIXMLException();
+ }
+ }
+
+ /**
+ * save and commit numbering
+ */
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering"));
+ Map map = new HashMap();
+ map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+ map.put("urn:schemas-microsoft-com:office:office", "o");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+ map.put("urn:schemas-microsoft-com:vml", "v");
+ map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+ map.put("urn:schemas-microsoft-com:office:word", "w10");
+ map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+ map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ ctNumbering.save(out, xmlOptions);
+ out.close();
+ }
+
+
+
+ /**
+ * Checks whether number with numID exists
+ * @param numID
+ * @return boolean true if num exist, false if num not exist
+ */
+ public boolean numExist(BigInteger numID){
+ for (XWPFNum num : nums) {
+ if (num.getCTNum().getNumId().equals(numID))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * add a new number to the numbering document
+ * @param num
+ */
+ public BigInteger addNum(XWPFNum num){
+ ctNumbering.addNewNum();
+ int pos = (ctNumbering.getNumArray().length) - 1;
+ ctNumbering.setNumArray(pos, num.getCTNum());
+ nums.add(num);
+ return num.getCTNum().getNumId();
+ }
+
+ /**
+ * Add a new num with an abstractNumID
+ * @return return NumId of the added num
+ */
+ public BigInteger addNum(BigInteger abstractNumID){
+ CTNum ctNum = this.ctNumbering.addNewNum();
+ ctNum.addNewAbstractNumId();
+ ctNum.getAbstractNumId().setVal(abstractNumID);
+ ctNum.setNumId(BigInteger.valueOf(nums.size()+1));
+ XWPFNum num = new XWPFNum(ctNum, this);
+ nums.add(num);
+ return ctNum.getNumId();
+ }
+
+
+ /**
+ * get Num by NumID
+ * @param numID
+ * @return abstractNum with NumId if no Num exists with that NumID
+ * null will be returned
+ */
+ public XWPFNum getNum(BigInteger numID){
+ for(XWPFNum num: nums){
+ if(num.getCTNum().getNumId().equals(numID))
+ return num;
+ }
+ return null;
+ }
+ /**
+ * get AbstractNum by abstractNumID
+ * @param abstractNumID
+ * @return abstractNum with abstractNumId if no abstractNum exists with that abstractNumID
+ * null will be returned
+ */
+ public XWPFAbstractNum getAbstractNum(BigInteger abstractNumID){
+ for(XWPFAbstractNum abstractNum: abstractNums){
+ if(abstractNum.getAbstractNum().getAbstractNumId().equals(abstractNumID)){
+ return abstractNum;
+ }
+ }
+ return null;
+ }
+ /**
+ * Compare AbstractNum with abstractNums of this numbering document.
+ * If the content of abstractNum equals with an abstractNum of the List in numbering
+ * the BigInteger Value of it will be returned.
+ * If no equal abstractNum is existing null will be returned
+ *
+ * @param abstractNum
+ * @return BigInteger
+ */
+ public BigInteger getIdOfAbstractNum(XWPFAbstractNum abstractNum){
+ CTAbstractNum copy = (CTAbstractNum) abstractNum.getCTAbstractNum().copy();
+ XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(copy, this);
+ int i;
+ for (i = 0; i < abstractNums.size(); i++) {
+ newAbstractNum.getCTAbstractNum().setAbstractNumId(BigInteger.valueOf(i));
+ newAbstractNum.setNumbering(this);
+ if(newAbstractNum.getCTAbstractNum().valueEquals(abstractNums.get(i).getCTAbstractNum())){
+ return newAbstractNum.getCTAbstractNum().getAbstractNumId();
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * add a new AbstractNum and return its AbstractNumID
+ * @param abstractNum
+ */
+ public BigInteger addAbstractNum(XWPFAbstractNum abstractNum){
+ int pos = abstractNums.size();
+ ctNumbering.addNewAbstractNum();
+ abstractNum.getAbstractNum().setAbstractNumId(BigInteger.valueOf(pos));
+ ctNumbering.setAbstractNumArray(pos, abstractNum.getAbstractNum());
+ abstractNums.add(abstractNum);
+ return abstractNum.getCTAbstractNum().getAbstractNumId();
+ }
+
+ /**
+ * remove an existing abstractNum
+ * @param abstractNumID
+ * @return true if abstractNum with abstractNumID exists in NumberingArray,
+ * false if abstractNum with abstractNumID not exists
+ */
+ public boolean removeAbstractNum(BigInteger abstractNumID){
+ if(abstractNumID.byteValue()<abstractNums.size()){
+ ctNumbering.removeAbstractNum(abstractNumID.byteValue());
+ abstractNums.remove(abstractNumID.byteValue());
+ return true;
+ }
+ return false;
+ }
+ /**
+ *return the abstractNumID
+ *If the AbstractNumID not exists
+ *return null
+ * @param num
+ * @return abstractNumID
+ */
+ public BigInteger getAbstractNumID(BigInteger numID){
+ XWPFNum num = getNum(numID);
+ if(num == null)
+ return null;
+ if (num.getCTNum() == null)
+ return null;
+ if (num.getCTNum().getAbstractNumId() == null)
+ return null;
+ return num.getCTNum().getAbstractNumId().getVal();
+ }
+}
+
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
index bf8202dad1..1e2fd408f4 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
@@ -19,10 +19,14 @@ package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
-import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef;
@@ -34,12 +38,15 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPicture;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTProofErr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRunTrackChange;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
@@ -54,11 +61,13 @@ import org.w3c.dom.Text;
/**
* Sketch of XWPF paragraph class
*/
-public class XWPFParagraph {
+public class XWPFParagraph implements IBodyElement{
private CTP paragraph;
- protected XWPFDocument document; // XXX: we'd like to have access to
- // document's hyperlink, comments and
- // other tables
+ protected IBody part;
+ /** For access to the document's hyperlink, comments, tables etc */
+ protected XWPFDocument document;
+ protected List<XWPFRun> runs;
+
/**
* TODO - replace with RichText String
*/
@@ -72,107 +81,137 @@ public class XWPFParagraph {
}
- protected XWPFParagraph(CTP prgrph, XWPFDocument docRef) {
+ public XWPFParagraph(CTP prgrph, IBody part) {
this.paragraph = prgrph;
- this.document = docRef;
+ this.part = part;
+
+ // We only care about the document (for comments,
+ // hyperlinks etc) if we're attached to the
+ // core document
+ if(part instanceof XWPFDocument) {
+ this.document = (XWPFDocument)part;
+ }
+
+ runs = new ArrayList<XWPFRun>();
+ if (prgrph.getRList().size() > 0) {
+ for(CTR ctRun : prgrph.getRList()) {
+ runs.add(new XWPFRun(ctRun, this));
+ }
+ }
if (!isEmpty()) {
- // All the runs to loop over
- // TODO - replace this with some sort of XPath expression
- // to directly find all the CTRs, in the right order
- ArrayList<CTR> rs = new ArrayList<CTR>();
- rs.addAll(Arrays.asList(paragraph.getRArray()));
-
- for (CTSdtRun sdt : paragraph.getSdtArray()) {
- CTSdtContentRun run = sdt.getSdtContent();
- rs.addAll(Arrays.asList(run.getRArray()));
- }
- for (CTRunTrackChange c : paragraph.getDelArray()) {
- rs.addAll(Arrays.asList(c.getRArray()));
- }
-
- for (CTRunTrackChange c : paragraph.getInsArray()) {
- rs.addAll(Arrays.asList(c.getRArray()));
- }
-
- // Get text of the paragraph
- for (int j = 0; j < rs.size(); j++) {
- // Grab the text and tabs of the paragraph
- // Do so in a way that preserves the ordering
- XmlCursor c = rs.get(j).newCursor();
- c.selectPath("./*");
- while (c.toNextSelection()) {
- XmlObject o = c.getObject();
- if (o instanceof CTText) {
- text.append(((CTText) o).getStringValue());
- }
- if (o instanceof CTPTab) {
- text.append("\t");
- }
- if (o instanceof CTEmpty) {
- // Some inline text elements get returned not as
- // themselves, but as CTEmpty, owing to some odd
- // definitions around line 5642 of the XSDs
- String tagName = o.getDomNode().getNodeName();
- if ("w:tab".equals(tagName)) {
- text.append("\t");
- }
- if ("w:cr".equals(tagName)) {
- text.append("\n");
- }
- }
- //got a reference to a footnote
- if (o instanceof CTFtnEdnRef) {
- CTFtnEdnRef ftn = (CTFtnEdnRef) o;
- footnoteText.append("[").append(ftn.getId()).append(": ");
- XWPFFootnote footnote =
- ftn.getDomNode().getLocalName().equals("footnoteReference") ?
- document.getFootnoteByID(ftn.getId().intValue()) :
- document.getEndnoteByID(ftn.getId().intValue());
-
- boolean first = true;
- for (XWPFParagraph p : footnote.getParagraphs()) {
- if (!first) {
- footnoteText.append("\n");
- first = false;
- }
- footnoteText.append(p.getText());
- }
-
- footnoteText.append("]");
- }
- }
-
- // Loop over pictures inside our
- // paragraph, looking for text in them
- CTPicture[] picts = rs.get(j).getPictArray();
- for (int k = 0; k < picts.length; k++) {
- XmlObject[] t = picts[k]
- .selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
- for (int m = 0; m < t.length; m++) {
- NodeList kids = t[m].getDomNode().getChildNodes();
- for (int n = 0; n < kids.getLength(); n++) {
- if (kids.item(n) instanceof Text) {
- pictureText.append("\n");
- pictureText.append(kids.item(n).getNodeValue());
- }
- }
- }
- }
- }
+ readNewText();
}
}
+
+ protected String readNewText() {
+ StringBuffer text = new StringBuffer();
+
+ // All the runs to loop over
+ // TODO - replace this with some sort of XPath expression
+ // to directly find all the CTRs, in the right order
+ ArrayList<CTR> rs = new ArrayList<CTR>();
+ rs.addAll( paragraph.getRList() );
+
+ for (CTSdtRun sdt : paragraph.getSdtList()) {
+ CTSdtContentRun run = sdt.getSdtContent();
+ rs.addAll( run.getRList() );
+ }
+ for (CTRunTrackChange c : paragraph.getDelList()) {
+ rs.addAll( c.getRList() );
+ }
+ for (CTRunTrackChange c : paragraph.getInsList()) {
+ rs.addAll( c.getRList() );
+ }
+
+ // Get text of the paragraph
+ for (int j = 0; j < rs.size(); j++) {
+ // Grab the text and tabs of the paragraph
+ // Do so in a way that preserves the ordering
+ XmlCursor c = rs.get(j).newCursor();
+ c.selectPath("./*");
+ while (c.toNextSelection()) {
+ XmlObject o = c.getObject();
+ if (o instanceof CTText) {
+ text.append(((CTText) o).getStringValue());
+ }
+ if (o instanceof CTPTab) {
+ text.append("\t");
+ }
+ if (o instanceof CTEmpty) {
+ // Some inline text elements get returned not as
+ // themselves, but as CTEmpty, owing to some odd
+ // definitions around line 5642 of the XSDs
+ String tagName = o.getDomNode().getNodeName();
+ if ("w:tab".equals(tagName)) {
+ text.append("\t");
+ }
+ if ("w:cr".equals(tagName)) {
+ text.append("\n");
+ }
+ }
+
+ // Check for bits that only apply when
+ // attached to a core document
+ if(document != null) {
+ //got a reference to a footnote
+ if (o instanceof CTFtnEdnRef) {
+ CTFtnEdnRef ftn = (CTFtnEdnRef) o;
+ footnoteText.append("[").append(ftn.getId()).append(": ");
+ XWPFFootnote footnote =
+ ftn.getDomNode().getLocalName().equals("footnoteReference") ?
+ document.getFootnoteByID(ftn.getId().intValue()) :
+ document.getEndnoteByID(ftn.getId().intValue());
+
+ boolean first = true;
+ for (XWPFParagraph p : footnote.getParagraphs()) {
+ if (!first) {
+ footnoteText.append("\n");
+ first = false;
+ }
+ footnoteText.append(p.getText());
+ }
+
+ footnoteText.append("]");
+ }
+ }
+ }
+
+ // Loop over pictures inside our
+ // paragraph, looking for text in them
+ for(CTPicture pict : rs.get(j).getPictList()) {
+ XmlObject[] t = pict
+ .selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
+ for (int m = 0; m < t.length; m++) {
+ NodeList kids = t[m].getDomNode().getChildNodes();
+ for (int n = 0; n < kids.getLength(); n++) {
+ if (kids.item(n) instanceof Text) {
+ pictureText.append("\n");
+ pictureText.append(kids.item(n).getNodeValue());
+ }
+ }
+ }
+ }
+ }
+
+ this.text = text;
+ return text.toString();
+ }
@Internal
public CTP getCTP() {
return paragraph;
}
- public boolean isEmpty() {
+ public List<XWPFRun> getRuns(){
+ return Collections.unmodifiableList(runs);
+ }
+
+ public boolean isEmpty(){
return !paragraph.getDomNode().hasChildNodes();
}
- public XWPFDocument getDocument() {
+ public XWPFDocument getDocument(){
return document;
}
@@ -185,6 +224,51 @@ public class XWPFParagraph {
out.append(text).append(footnoteText).append(pictureText);
return out.toString();
}
+
+ /**
+ * Return styleID of the paragraph if style exist for this paragraph
+ * if not, null will be returned
+ * @return styleID as String
+ */
+ public String getStyleID(){
+ if (paragraph.getPPr() != null){
+ if(paragraph.getPPr().getPStyle()!= null){
+ if (paragraph.getPPr().getPStyle().getVal()!= null)
+ return paragraph.getPPr().getPStyle().getVal();
+ }
+ }
+ return null;
+ }
+ /**
+ * If style exist for this paragraph
+ * NumId of the paragraph will be returned.
+ * If style not exist null will be returned
+ * @return NumID as BigInteger
+ */
+ public BigInteger getNumID(){
+ if(paragraph.getPPr()!=null){
+ if(paragraph.getPPr().getNumPr()!=null){
+ if(paragraph.getPPr().getNumPr().getNumId()!=null)
+ return paragraph.getPPr().getNumPr().getNumId().getVal();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * setNumID of Paragraph
+ * @param numPos
+ */
+ public void setNumID(BigInteger numPos) {
+ if(paragraph.getPPr()==null)
+ paragraph.addNewPPr();
+ if(paragraph.getPPr().getNumPr()==null)
+ paragraph.getPPr().addNewNumPr();
+ if(paragraph.getPPr().getNumPr().getNumId()==null){
+ paragraph.getPPr().getNumPr().addNewNumId();
+ }
+ paragraph.getPPr().getNumPr().getNumId().setVal(numPos);
+ }
/**
* Returns the text of the paragraph, but not of any objects in the
@@ -1040,5 +1124,210 @@ public class XWPFParagraph {
: paragraph.getPPr();
return pr;
}
+
+
+ /**
+ * add a new run at the end of the position of
+ * the content of parameter run
+ * @param run
+ */
+ protected void addRun(CTR run){
+ int pos;
+ pos = paragraph.getRArray().length;
+ paragraph.addNewR();
+ paragraph.setRArray(pos, run);
+ for (CTText ctText: paragraph.getRArray(pos).getTArray()) {
+ this.text.append(ctText.getStringValue());
+ }
+ }
+
+ /**
+ * this methods parse the paragraph and search for the string searched.
+ * If it finds the string, it will return true and the position of the String
+ * will be saved in the parameter startPos.
+ * @param searched
+ * @param pos
+ * @return
+ */
+ public TextSegement searchText(String searched,PositionInParagraph startPos){
+
+ int startRun = startPos.getRun(),
+ startText = startPos.getText(),
+ startChar = startPos.getChar();
+ int beginRunPos = 0, candCharPos = 0;
+ boolean newList = false;
+ for (int runPos=startRun; runPos<paragraph.getRArray().length; runPos++) {
+ int beginTextPos = 0,beginCharPos = 0, textPos = 0, charPos = 0;
+ CTR ctRun = paragraph.getRArray(runPos);
+ XmlCursor c = ctRun.newCursor();
+ c.selectPath("./*");
+ while(c.toNextSelection()){
+ XmlObject o = c.getObject();
+ if(o instanceof CTText){
+ if(textPos>=startText){
+ String candidate = ((CTText)o).getStringValue();
+ if(runPos==startRun)
+ charPos= startChar;
+ else
+ charPos = 0;
+ for(; charPos<candidate.length(); charPos++){
+ if((candidate.charAt(charPos)==searched.charAt(0))&&(candCharPos==0)){
+ beginTextPos = textPos;
+ beginCharPos = charPos;
+ beginRunPos = runPos;
+ newList = true;
+ }
+ if(candidate.charAt(charPos)==searched.charAt(candCharPos)){
+ if(candCharPos+1<searched.length())
+ candCharPos++;
+ else if(newList){
+ TextSegement segement = new TextSegement();
+ segement.setBeginRun(beginRunPos);
+ segement.setBeginText(beginTextPos);
+ segement.setBeginChar(beginCharPos);
+ segement.setEndRun(runPos);
+ segement.setEndText(textPos);
+ segement.setEndChar(charPos);
+ return segement;
+ }
+ }
+ else
+ candCharPos=0;
+ }
+ }
+ textPos++;
+ }
+ else if(o instanceof CTProofErr){
+ c.removeXml();
+ }
+ else if(o instanceof CTRPr);
+ //do nothing
+ else
+ candCharPos=0;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * insert a new Run in RunArray
+ * @param pos
+ * @return
+ */
+ public XWPFRun insertNewRun(int pos){
+ if (pos >= 0 && pos <= paragraph.sizeOfRArray()) {
+ CTR ctRun = paragraph.insertNewR(pos);
+ XWPFRun newRun = new XWPFRun(ctRun, this);
+ runs.add(newRun);
+ return newRun;
+ }
+ return null;
+ }
+
+
+
+ /**
+ * get a Text
+ * @param posList
+ * @return
+ */
+ public String getText(TextSegement segment){
+ int runBegin = segment.getBeginRun();
+ int textBegin = segment.getBeginText();
+ int charBegin = segment.getBeginChar();
+ int runEnd = segment.getEndRun();
+ int textEnd = segment.getEndText();
+ int charEnd = segment.getEndChar();
+ StringBuffer out = new StringBuffer();
+ for(int i=runBegin; i<=runEnd;i++){
+ int startText=0, endText = paragraph.getRArray(i).getTArray().length-1;
+ if(i==runBegin)
+ startText=textBegin;
+ if(i==runEnd)
+ endText = textEnd;
+ for(int j=startText;j<=endText;j++){
+ String tmpText = paragraph.getRArray(i).getTArray(j).getStringValue();
+ int startChar=0, endChar = tmpText.length()-1;
+ if((j==textBegin)&&(i==runBegin))
+ startChar=charBegin;
+ if((j==textEnd)&&(i==runEnd)){
+ endChar = charEnd;
+ }
+ out.append(tmpText.substring(startChar, endChar+1));
+
+ }
+ }
+ return out.toString();
+ }
+
+ /**
+ * removes a Run at the position pos in the paragraph
+ * @param pos
+ * @return
+ */
+ public boolean removeRun(int pos){
+ if (pos >= 0 && pos < paragraph.sizeOfRArray()){
+ getCTP().removeR(pos);
+ runs.remove(pos);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * returns the type of the BodyElement Paragraph
+ * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
+ */
+ @Override
+ public BodyElementType getElementType() {
+ return BodyElementType.PARAGRAPH;
+ }
+
+ /**
+ * returns the part of the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ @Override
+ public IBody getPart() {
+ if(part != null){
+ return part.getPart();
+ }
+ return null;
+ }
+
+ /**
+ * returns the partType of the bodyPart which owns the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return part.getPartType();
+ }
+
+ /**
+ * adds a new Run to the Paragraph
+ * @param r
+ * @return
+ */
+ public void addRun(XWPFRun r){
+ runs.add(r);
+ }
+
+ /**
+ * return the XWPFRun-Element which owns the CTR run-Element
+ * @param r
+ * @return
+ */
+ public XWPFRun getRun(CTR r){
+ for(int i=0; i < getRuns().size(); i++){
+ if(getRuns().get(i).getCTR() == r) return getRuns().get(i);
+ }
+ return null;
+ }
+
+
+
+}//end class
+
+
-}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
new file mode 100644
index 0000000000..4b1cea3fc3
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
@@ -0,0 +1,74 @@
+/* ====================================================================
+ 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 org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
+
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFPicture {
+ private static final POILogger logger = POILogFactory.getLogger(XWPFPicture.class);
+ protected XWPFParagraph paragraph;
+ private CTPicture ctPic;
+
+
+ public XWPFParagraph getParagraph(){
+ return paragraph;
+ }
+
+ public XWPFPicture(CTPicture ctPic, XWPFParagraph paragraph){
+ this.paragraph = paragraph;
+ this.ctPic = ctPic;
+ }
+ /**
+ * Link Picture with PictureData
+ * @param rel
+ */
+ public void setPictureReference(PackageRelationship rel){
+ ctPic.getBlipFill().getBlip().setEmbed(rel.getId());
+ }
+
+ /**
+ * Return the underlying CTPicture bean that holds all properties for this picture
+ *
+ * @return the underlying CTPicture bean
+ */
+ public CTPicture getCTPicture(){
+ return ctPic;
+ }
+ /**
+ * Get the PictureData of the Picture
+ * @return
+ */
+ public XWPFPictureData getPictureData(){
+ String blipId = ctPic.getBlipFill().getBlip().getEmbed();
+ for(POIXMLDocumentPart part: paragraph.getDocument().getRelations()){
+ if(part.getPackageRelationship().getId().equals(blipId)){
+ return (XWPFPictureData)part;
+ }
+ }
+ return null;
+ }
+
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
new file mode 100644
index 0000000000..5094763f73
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
@@ -0,0 +1,128 @@
+/* ====================================================================
+ 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.IOException;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.IOUtils;
+
+/**
+ * Raw picture data, normally attached to a WordprocessingML Drawing.
+ * As a rule, pictures are stored in the /word/media/ part of a WordprocessingML package.
+ */
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFPictureData extends POIXMLDocumentPart {
+
+ /**
+ * Relationships for each known picture type
+ */
+ protected static final POIXMLRelation[] RELATIONS;
+ static {
+ RELATIONS = new POIXMLRelation[8];
+ RELATIONS[Document.PICTURE_TYPE_EMF] = XWPFRelation.IMAGE_EMF;
+ RELATIONS[Document.PICTURE_TYPE_WMF] = XWPFRelation.IMAGE_WMF;
+ RELATIONS[Document.PICTURE_TYPE_PICT] = XWPFRelation.IMAGE_PICT;
+ RELATIONS[Document.PICTURE_TYPE_JPEG] = XWPFRelation.IMAGE_JPEG;
+ RELATIONS[Document.PICTURE_TYPE_PNG] = XWPFRelation.IMAGE_PNG;
+ RELATIONS[Document.PICTURE_TYPE_DIB] = XWPFRelation.IMAGE_DIB;
+ }
+ /**
+ * Create a new XWPFGraphicData node
+ *
+ */
+ protected XWPFPictureData() {
+ super();
+ }
+
+ /**
+ * Construct XWPFPictureData from a package part
+ *
+ * @param part the package part holding the drawing data,
+ * @param rel the package relationship holding this drawing,
+ * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
+ */
+
+ public XWPFPictureData(PackagePart part, PackageRelationship rel) {
+ super(part, rel);
+ }
+
+ /**
+ * Gets the picture data as a byte array.
+ * <p>
+ * Note, that this call might be expensive since all the picture data is copied into a temporary byte array.
+ * You can grab the picture data directly from the underlying package part as follows:
+ * <br/>
+ * <code>
+ * InputStream is = getPackagePart().getInputStream();
+ * </code>
+ * </p>
+ *
+ * @return the Picture data.
+ */
+ public byte[] getData() {
+ try {
+ return IOUtils.toByteArray(getPackagePart().getInputStream());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Suggests a file extension for this image.
+ *
+ * @return the file extension.
+ */
+ public String suggestFileExtension() {
+ return getPackagePart().getPartName().getExtension();
+ }
+
+ /**
+ * Return an integer constant that specifies type of this picture
+ *
+ * @return an integer constant that specifies type of this picture
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
+ * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB
+ */
+ public int getPictureType(){
+ String contentType = getPackagePart().getContentType();
+ for (int i = 0; i < RELATIONS.length; i++) {
+ if(RELATIONS[i] == null) continue;
+
+ if(RELATIONS[i].getContentType().equals(contentType)){
+ return i;
+ }
+ }
+ return 0;
+ }
+
+
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
index c5accb89f9..83d2282099 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
@@ -17,11 +17,11 @@
package org.apache.poi.xwpf.usermodel;
-import org.apache.poi.POIXMLRelation;
-import org.apache.poi.POIXMLDocumentPart;
-
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLRelation;
/**
* @author Yegor Kozlov
@@ -58,6 +58,13 @@ public final class XWPFRelation extends POIXMLRelation {
"/word/document.xml",
null
);
+
+ public static final XWPFRelation NUMBERING = new XWPFRelation(
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
+ "/word/numbering.xml",
+ XWPFNumbering.class
+ );
public static final XWPFRelation FONT_TABLE = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
@@ -74,7 +81,7 @@ public final class XWPFRelation extends POIXMLRelation {
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
"/word/styles.xml",
- null
+ XWPFStyles.class
);
public static final XWPFRelation WEB_SETTINGS = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
@@ -118,6 +125,50 @@ public final class XWPFRelation extends POIXMLRelation {
null,
null
);
+
+ public static final XWPFRelation IMAGE_EMF = new XWPFRelation(
+ "image/x-emf",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.emf",
+ XWPFPictureData.class
+ );
+ public static final XWPFRelation IMAGE_WMF = new XWPFRelation(
+ "image/x-wmf",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.wmf",
+ XWPFPictureData.class
+ );
+ public static final XWPFRelation IMAGE_PICT = new XWPFRelation(
+ "image/pict",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.pict",
+ XWPFPictureData.class
+ );
+ public static final XWPFRelation IMAGE_JPEG = new XWPFRelation(
+ "image/jpeg",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.jpeg",
+ XWPFPictureData.class
+ );
+ public static final XWPFRelation IMAGE_PNG = new XWPFRelation(
+ "image/png",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.png",
+ XWPFPictureData.class
+ );
+ public static final XWPFRelation IMAGE_DIB = new XWPFRelation(
+ "image/dib",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ "/word/media/image#.dib",
+ XWPFPictureData.class
+ );
+
+ public static final XWPFRelation IMAGES = new XWPFRelation(
+ null,
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ null,
+ null
+ );
private XWPFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
index 93dd9c8f16..c041030e8d 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
@@ -18,6 +18,7 @@ package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
+import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
@@ -33,7 +34,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;
-import org.apache.poi.util.Internal;
/**
* XWPFRun object defines a region of text with a common set of properties
@@ -48,7 +48,7 @@ public class XWPFRun {
* @param r the CTR bean which holds the run attributes
* @param p the parent paragraph
*/
- protected XWPFRun(CTR r, XWPFParagraph p) {
+ public XWPFRun(CTR r, XWPFParagraph p) {
this.run = r;
this.paragraph = p;
}
@@ -471,5 +471,6 @@ public class XWPFRun {
public void removeCarriageReturn() {
//TODO
}
+
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
new file mode 100644
index 0000000000..9de4eecdad
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
@@ -0,0 +1,143 @@
+/* ====================================================================
+ 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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFStyle {
+
+ private CTStyle ctStyle;
+ protected XWPFStyles styles;
+
+ /**
+ * constructor
+ * @param style
+ */
+ public XWPFStyle(CTStyle style){
+ this(style,null);
+ }
+ /**
+ * constructor
+ * @param style
+ * @param styles
+ */
+ public XWPFStyle(CTStyle style, XWPFStyles styles){
+ this.ctStyle = style;
+ this.styles = styles;
+ }
+
+ /**
+ * get StyleID of the style
+ * @return styleID StyleID of the style
+ */
+ public String getStyleId(){
+ return ctStyle.getStyleId();
+ }
+
+ /**
+ * get Type of the Style
+ * @return ctType
+ */
+ public STStyleType.Enum getType(){
+ return ctStyle.getType();
+ }
+
+ /**
+ * set style
+ * @param style
+ */
+ public void setStyle(CTStyle style){
+ this.ctStyle = style;
+ }
+ /**
+ * get ctStyle
+ * @return ctStyle
+ */
+ public CTStyle getCTStyle(){
+ return this.ctStyle;
+ }
+ /**
+ * set styleID
+ * @param styleId
+ */
+ public void setStyleId(String styleId){
+ ctStyle.setStyleId(styleId);
+ }
+
+ /**
+ * set styleType
+ * @param type
+ */
+ public void setType(STStyleType.Enum type){
+ ctStyle.setType(type);
+ }
+ /**
+ * get styles
+ * @return styles the styles to which this style belongs
+ */
+ public XWPFStyles getStyles(){
+ return styles;
+ }
+
+ public String getBasisStyleID(){
+ if(ctStyle.getBasedOn()!=null)
+ return ctStyle.getBasedOn().getVal();
+ else
+ return null;
+ }
+
+
+ /**
+ * get StyleID of the linked Style
+ * @return
+ */
+ public String getLinkStyleID(){
+ if (ctStyle.getLink()!=null)
+ return ctStyle.getLink().getVal();
+ else
+ return null;
+ }
+
+ /**
+ * get StyleID of the next style
+ * @return
+ */
+ public String getNextStyleID(){
+ if(ctStyle.getNext()!=null)
+ return ctStyle.getNext().getVal();
+ else
+ return null;
+ }
+
+ /**
+ * compares the names of the Styles
+ * @param compStyle
+ * @return
+ */
+ public boolean hasSameName(XWPFStyle compStyle){
+ CTStyle ctCompStyle = compStyle.getCTStyle();
+ String name = ctCompStyle.getName().getVal();
+ return name.equals(ctStyle.getName().getVal());
+ }
+
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
new file mode 100644
index 0000000000..f2328824c9
--- /dev/null
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
@@ -0,0 +1,201 @@
+/* ====================================================================
+ 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFStyles extends POIXMLDocumentPart{
+ private CTStyles ctStyles;
+ protected XWPFLatentStyles latentStyles;
+ protected List<XWPFStyle> listStyle;
+
+ /**
+ * Construct XWPFStyles from a package part
+ *
+ * @param part the package part holding the data of the styles,
+ * @param rel the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
+ */
+
+ public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
+ super(part, rel);
+ onDocumentRead();
+ }
+ /**
+ * Read document
+ */
+ @Override
+ protected void onDocumentRead ()throws IOException{
+ listStyle = new ArrayList<XWPFStyle>();
+ StylesDocument stylesDoc;
+ try {
+ InputStream is = getPackagePart().getInputStream();
+ stylesDoc = StylesDocument.Factory.parse(is);
+ ctStyles = stylesDoc.getStyles();
+ latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this);
+
+ } catch (XmlException e) {
+ throw new POIXMLException();
+ }
+ //get any Style
+ for(CTStyle style : ctStyles.getStyleArray()) {
+ listStyle.add(new XWPFStyle(style, this));
+ }
+ }
+
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+ xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
+ Map map = new HashMap();
+ map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+ map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ ctStyles.save(out, xmlOptions);
+ out.close();
+ }
+
+
+
+
+ /**
+ * checks whether style with styleID exist
+ * @param styleID styleID of the Style in the style-Document
+ * @return true if style exist, false if style not exist
+ */
+ public boolean styleExist(String styleID){
+ for (XWPFStyle style : listStyle) {
+ if (style.getStyleId().equals(styleID))
+ return true;
+ }
+ return false;
+ }
+ /**
+ * add a style to the document
+ * @param style
+ * @throws IOException
+ */
+ public void addStyle(XWPFStyle style){
+ listStyle.add(style);
+ ctStyles.addNewStyle();
+ int pos = (ctStyles.getStyleArray().length) - 1;
+ ctStyles.setStyleArray(pos, style.getCTStyle());
+ }
+ /**
+ *get style by a styleID
+ * @param styleID styleID of the searched style
+ * @return style
+ */
+ public XWPFStyle getStyle(String styleID){
+ for (XWPFStyle style : listStyle) {
+ if(style.getStyleId().equals(styleID))
+ return style;
+ }
+ return null;
+ }
+
+ /**
+ * get the styles which are related to the parameter style and their relatives
+ * this method can be used to copy all styles from one document to another document
+ * @param style
+ * @return a list of all styles which were used by this method
+ */
+ public List<XWPFStyle> getUsedStyleList(XWPFStyle style){
+ List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();
+ usedStyleList.add(style);
+ return getUsedStyleList(style, usedStyleList);
+ }
+
+ /**
+ * get the styles which are related to parameter style
+ * @param style
+ * @return all Styles of the parameterList
+ */
+ private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList){
+ String basisStyleID = style.getBasisStyleID();
+ XWPFStyle basisStyle = getStyle(basisStyleID);
+ if((basisStyle!=null)&&(!usedStyleList.contains(basisStyle))){
+ usedStyleList.add(basisStyle);
+ getUsedStyleList(basisStyle, usedStyleList);
+ }
+ String linkStyleID = style.getLinkStyleID();
+ XWPFStyle linkStyle = getStyle(linkStyleID);
+ if((linkStyle!=null)&&(!usedStyleList.contains(linkStyle))){
+ usedStyleList.add(linkStyle);
+ getUsedStyleList(linkStyle, usedStyleList);
+ }
+
+ String nextStyleID = style.getNextStyleID();
+ XWPFStyle nextStyle = getStyle(nextStyleID);
+ if((nextStyle!=null)&&(!usedStyleList.contains(nextStyle))){
+ usedStyleList.add(linkStyle);
+ getUsedStyleList(linkStyle, usedStyleList);
+ }
+ return usedStyleList;
+ }
+
+
+
+ /**
+ * get latentstyles
+ * @return
+ */
+ public XWPFLatentStyles getLatentStyles() {
+ return latentStyles;
+ }
+
+ /**
+ * get the style with the same name
+ * if this style is not existing, return null
+ * @param style
+ * @return
+ */
+ public XWPFStyle getStyleWithSameName(XWPFStyle style){
+ for (XWPFStyle ownStyle : listStyle) {
+ if(ownStyle.hasSameName(style)){
+ return ownStyle;
+ }
+ }
+ return null;
+
+ }
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
index 61a1f11fd0..b12cce2c12 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
@@ -17,7 +17,10 @@
package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
@@ -27,7 +30,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
-import org.apache.poi.util.Internal;
/**
* Sketch of XWPFTable class. Only table's text is being hold.
@@ -37,16 +39,20 @@ import org.apache.poi.util.Internal;
*
* @author Yury Batrakov (batrakov at gmail.com)
*/
-public class XWPFTable {
+public class XWPFTable implements IBodyElement{
protected StringBuffer text = new StringBuffer();
private CTTbl ctTbl;
+ protected List<XWPFTableRow> tableRows;
+ protected List<String> styleIDs;
+ protected IBody part;
+ private XWPFDocument document;
-
- public XWPFTable(XWPFDocument doc, CTTbl table, int row, int col) {
- this(doc, table);
+ public XWPFTable(CTTbl table, IBody part, int row, int col) {
+ this(table, part);
for (int i = 0; i < row; i++) {
XWPFTableRow tabRow = (getRow(i) == null) ? createRow() : getRow(i);
+ tableRows.add(tabRow);
for (int k = 0; k < col; k++) {
XWPFTableCell tabCell = (tabRow.getCell(k) == null) ? tabRow
.createCell() : null;
@@ -55,8 +61,11 @@ public class XWPFTable {
}
- public XWPFTable(XWPFDocument doc, CTTbl table) {
+ public XWPFTable(CTTbl table, IBody part){
+ this.part = part;
this.ctTbl = table;
+
+ tableRows = new ArrayList<XWPFTableRow>();
// is an empty table: I add one row and one column as default
if (table.sizeOfTrArray() == 0)
@@ -64,9 +73,11 @@ public class XWPFTable {
for (CTRow row : table.getTrArray()) {
StringBuffer rowText = new StringBuffer();
+ XWPFTableRow tabRow = new XWPFTableRow(row, this);
+ tableRows.add(tabRow);
for (CTTc cell : row.getTcArray()) {
for (CTP ctp : cell.getPArray()) {
- XWPFParagraph p = new XWPFParagraph(ctp, doc);
+ XWPFParagraph p = new XWPFParagraph(ctp, part);
if (rowText.length() > 0) {
rowText.append('\t');
}
@@ -104,7 +115,7 @@ public class XWPFTable {
* CTTblGrid tblgrid=table.addNewTblGrid();
* tblgrid.addNewGridCol().setW(new BigInteger("2000"));
*/
-
+ getRows();
}
/**
@@ -134,7 +145,7 @@ public class XWPFTable {
public void addNewCol() {
if (ctTbl.sizeOfTrArray() == 0) createRow();
for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) {
- XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i));
+ XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this);
tabRow.createCell();
}
}
@@ -147,7 +158,7 @@ public class XWPFTable {
public XWPFTableRow createRow() {
int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(0)
.sizeOfTcArray() : 0;
- XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr());
+ XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), this);
addColumn(tabRow, sizeCol);
return tabRow;
}
@@ -158,7 +169,8 @@ public class XWPFTable {
*/
public XWPFTableRow getRow(int pos) {
if (pos >= 0 && pos < ctTbl.sizeOfTrArray()) {
- return new XWPFTableRow(ctTbl.getTrArray(pos));
+ //return new XWPFTableRow(ctTbl.getTrArray(pos));
+ return getRows().get(pos);
}
return null;
}
@@ -201,5 +213,122 @@ public class XWPFTable {
}
}
}
+
+ /**
+ * get the StyleID of the table
+ * @return style-ID of the table
+ */
+ public String getStyleID(){
+ return ctTbl.getTblPr().getTblStyle().getVal();
+ }
+
+ /**
+ * add a new Row to the table
+ *
+ * @param row the row which should be added
+ */
+ public void addRow(XWPFTableRow row){
+ ctTbl.addNewTr();
+ ctTbl.setTrArray(getNumberOfRows()-1, row.getCtRow());
+ tableRows.add(row);
+ }
+
+ /**
+ * add a new Row to the table
+ * at position pos
+ * @param row the row which should be added
+ */
+ public boolean addRow(XWPFTableRow row, int pos){
+ if(pos >= 0 && pos <= tableRows.size()){
+ ctTbl.insertNewTr(pos);
+ ctTbl.setTrArray(pos,row.getCtRow());
+ tableRows.add(pos, row);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * inserts a new tablerow
+ * @param pos
+ * @return
+ */
+ public XWPFTableRow insertNewTableRow(int pos){
+ if(pos >= 0 && pos <= tableRows.size()){
+ CTRow row = ctTbl.insertNewTr(pos);
+ XWPFTableRow tableRow = new XWPFTableRow(row, this);
+ tableRows.add(pos, tableRow);
+ return tableRow;
+ }
+ return null;
+ }
+
+
+ /**
+ * Remove a row at position pos from the table
+ * @param pos position the Row in the Table
+ */
+ public boolean removeRow(int pos) throws IndexOutOfBoundsException {
+ if(pos > 0 && pos < tableRows.size()){
+ ctTbl.removeTr(pos);
+ tableRows.remove(pos);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param pos
+ * @return
+ */
+ public List<XWPFTableRow> getRows() {
+ return tableRows;
+ }
+
+ /**
+ * returns the type of the BodyElement Table
+ * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
+ */
+ @Override
+ public BodyElementType getElementType() {
+ return BodyElementType.TABLE;
+ }
+
+
+ /**
+ * returns the part of the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ @Override
+ public IBody getPart() {
+ if(part != null){
+ return part.getPart();
+ }
+ return null;
+ }
+
+
+ /**
+ * returns the partType of the bodyPart which owns the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return ((IBody)part).getPartType();
+ }
+
+ /**
+ * returns the XWPFRow which belongs to the CTRow row
+ * if this row is not existing in the table null will be returned
+ * @param row
+ * @return
+ */
+ public XWPFTableRow getRow(CTRow row) {
+ for(int i=0; i<getRows().size(); i++){
+ if(getRows().get(i).getCtRow()== row) return getRow(i);
+ }
+ return null;
+ }
}// end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
index 7d56df42e3..f6b3659389 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
@@ -16,22 +16,56 @@
==================================================================== */
package org.apache.poi.xwpf.usermodel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
-import org.apache.poi.util.Internal;
-public class XWPFTableCell {
+public class XWPFTableCell implements IBody {
private CTTc ctTc;
-
+ protected List<XWPFParagraph> paragraphs = null;
+ protected List<XWPFTable> tables = null;
+ protected List<IBodyElement> bodyElements = null;
+ protected IBody part;
+ private XWPFTableRow tableRow = null;
/**
* If a table cell does not include at least one block-level element, then this document shall be considered corrupt
*/
- public XWPFTableCell(CTTc cell) {
+ public XWPFTableCell(CTTc cell, XWPFTableRow tableRow, IBody part) {
this.ctTc = cell;
+ this.part = part;
+ this.tableRow = tableRow;
// NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt.
- cell.addNewP();
+ if(cell.getPArray().length<1)
+ cell.addNewP();
+ bodyElements = new ArrayList<IBodyElement>();
+ paragraphs = new ArrayList<XWPFParagraph>();
+ tables = new ArrayList<XWPFTable>();
+
+ XmlCursor cursor = ctTc.newCursor();
+ cursor.selectPath("./*");
+ while (cursor.toNextSelection()) {
+ XmlObject o = cursor.getObject();
+ if (o instanceof CTP) {
+ XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+ paragraphs.add(p);
+ bodyElements.add(p);
+ }
+ if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
+ }
+ }
}
@@ -47,21 +81,275 @@ public class XWPFTableCell {
ctTc.setPArray(0, p.getCTP());
}
- public XWPFParagraph getParagraph() {
- return ctTc.sizeOfPArray() == 0 ? null : new XWPFParagraph(ctTc.getPArray(0));
+ /**
+ * returns a list of paragraphs
+ * @return
+ */
+ public List<XWPFParagraph> getParagraphs(){
+ return paragraphs;
}
-
-
+
+ /**
+ * add a Paragraph to this TableCell
+ * @param p the paragaph which has to be added
+ */
+ public void addParagraph(XWPFParagraph p){
+ paragraphs.add(p);
+ }
+
+ /**
+ * removes a paragraph of this tablecell
+ * @param pos
+ */
+ public void removeParagraph(int pos){
+ paragraphs.remove(pos);
+ ctTc.removeP(pos);
+ }
+
+ /**
+ * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this table
+ * the method will return this paragraph
+ * if there is no corresponding {@link XWPFParagraph} the method will return null
+ * @param p is instance of CTP and is searching for an XWPFParagraph
+ * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this table
+ * XWPFParagraph with the correspondig CTP p
+ */
+ @Override
+ public XWPFParagraph getParagraph(CTP p){
+ for (XWPFParagraph paragraph : paragraphs) {
+ if(p.equals(paragraph.getCTP())){
+ return paragraph;
+ }
+ }
+ return null;
+ }
+
public void setText(String text) {
CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);
- XWPFParagraph par = new XWPFParagraph(ctP);
+ XWPFParagraph par = new XWPFParagraph(ctP, this);
par.createRun().setText(text);
}
-
- public String getText() {
- //TODO
- return null;
+
+ public XWPFTableRow getTableRow(){
+ return tableRow;
+ }
+
+ /**
+ * add a new paragraph at position of the cursor
+ * @param cursor
+ * @return
+ */
+ public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+ if(!isCursorInTableCell(cursor))
+ return null;
+
+ String uri = CTP.type.getName().getNamespaceURI();
+ String localPart = "p";
+ cursor.beginElement(localPart,uri);
+ cursor.toParent();
+ CTP p = (CTP)cursor.getObject();
+ XWPFParagraph newP = new XWPFParagraph(p, this);
+ XmlObject o = null;
+ while(!(o instanceof CTP)&&(cursor.toPrevSibling())){
+ o = cursor.getObject();
+ }
+ if((!(o instanceof CTP)) || (CTP)o == p){
+ paragraphs.add(0, newP);
+ }
+ else{
+ int pos = paragraphs.indexOf(getParagraph((CTP)o))+1;
+ paragraphs.add(pos,newP);
+ }
+ int i=0;
+ cursor.toCursor(p.newCursor());
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newP);
+ cursor.toCursor(p.newCursor());
+ cursor.toEndToken();
+ return newP;
}
+ /**
+ *
+ * @param cursor
+ * @return
+ */
+ public XWPFTable insertNewTbl(XmlCursor cursor) {
+ if(isCursorInTableCell(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);
+ cursor.removeXmlContents();
+ 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;
+ cursor = t.newCursor();
+ while(cursor.toPrevSibling()){
+ o =cursor.getObject();
+ if(o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newT);
+ cursor = t.newCursor();
+ cursor.toEndToken();
+ return newT;
+ }
+ return null;
+ }
+
+ /**
+ * verifies that cursor is on the right position
+ * @param cursor
+ * @return
+ */
+ private boolean isCursorInTableCell(XmlCursor cursor) {
+ XmlCursor verify = cursor.newCursor();
+ verify.toParent();
+ if(verify.getObject() == this.ctTc){
+ return true;
+ }
+ return false;
+ }
+
+
+
+ /**
+ * @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;
+ }
+
+
+
+
+ /**
+ * get the to which the TableCell belongs
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ @Override
+ public IBody getPart() {
+ return (IBody) tableRow.getTable().getPart();
+ }
+
+
+ /**
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ @Override
+ public BodyType getPartType() {
+ return BodyType.TABLECELL;
+ }
+
+
+ /**
+ * get a table by its CTTbl-Object
+ * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
+ */
+ @Override
+ public XWPFTable getTable(CTTbl ctTable) {
+ for(int i=0; i<tables.size(); i++){
+ if(getTables().get(i).getCTTbl() == ctTable) return getTables().get(i);
+ }
+ return null;
+ }
+
+
+ /**
+ * @see org.apache.poi.xwpf.usermodel.IBodyPart#getTableArray(int)
+ */
+ @Override
+ public XWPFTable getTableArray(int pos) {
+ if(pos > 0 && pos < tables.size()){
+ return tables.get(pos);
+ }
+ return null;
+ }
+
+
+ /**
+ * @see org.apache.poi.xwpf.usermodel.IBodyPart#getTables()
+ */
+ @Override
+ public List<XWPFTable> getTables() {
+ return Collections.unmodifiableList(tables);
+ }
+
+
+ /**
+ * inserts an existing XWPFTable to the arrays bodyElements and tables
+ * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable)
+ */
+ @Override
+ public void insertTable(int pos, XWPFTable table) {
+ bodyElements.add(pos, table);
+ int i;
+ for (i = 0; i < ctTc.getTblArray().length; i++) {
+ CTTbl tbl = ctTc.getTblArray(i);
+ if(tbl == table.getCTTbl()){
+ break;
+ }
+ }
+ tables.add(i, table);
+ }
+
+ public String getText(){
+ StringBuffer text = new StringBuffer();
+ for (XWPFParagraph p : paragraphs) {
+ text.append(p.readNewText());
+ }
+ return text.toString();
+ }
+
+ /**
+ * get the TableCell which belongs to the TableCell
+ * @param o
+ * @return
+ */
+ @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();
+ 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(row == null){
+ return null;
+ }
+ return tableRow.getTableCell(cell);
+ }
}// end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
index 6794808efd..4ac301476f 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
@@ -17,11 +17,14 @@
package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
-import org.apache.poi.util.Internal;
/**
@@ -30,9 +33,13 @@ import org.apache.poi.util.Internal;
public class XWPFTableRow {
private CTRow ctRow;
+ private XWPFTable table;
+ private List<XWPFTableCell> tableCells;
- public XWPFTableRow(CTRow row) {
+ public XWPFTableRow(CTRow row, XWPFTable table) {
+ this.table = table;
this.ctRow = row;
+ getTableCells();
}
@Internal
@@ -40,17 +47,37 @@ public class XWPFTableRow {
return ctRow;
}
-
+ /**
+ * create a new XWPFTableCell and add it to the tableCell-list of this tableRow
+ * @return the newly created XWPFTableCell
+ */
public XWPFTableCell createCell() {
- return new XWPFTableCell(ctRow.addNewTc());
+ XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getPart());
+ tableCells.add(tableCell);
+ return tableCell;
}
+ /**
+ * @param pos
+ * @return
+ */
public XWPFTableCell getCell(int pos) {
if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {
- return new XWPFTableCell(ctRow.getTcArray(pos));
+ return getTableCells().get(pos);
}
return null;
}
+
+ /**
+ * adds a new TableCell at the end of this tableRow
+ * @return
+ */
+ public XWPFTableCell addNewTableCell(){
+ CTTc cell = ctRow.addNewTc();
+ XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getPart());
+ tableCells.add(tableCell);
+ return tableCell;
+ }
/**
* This element specifies the height of the current table row within the
@@ -87,6 +114,38 @@ public class XWPFTableRow {
private CTTrPr getTrPr() {
return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr();
}
+
+ public XWPFTable getTable(){
+ return table;
+ }
+
+ /**
+ * create and return a list of all XWPFTableCell
+ * who belongs to this row
+ * @return a list of {@link XWPFTableCell}
+ */
+ public List<XWPFTableCell> getTableCells(){
+ if(tableCells == null){
+ List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
+ for (CTTc tableCell : ctRow.getTcArray()) {
+ cells.add(new XWPFTableCell(tableCell, this, table.getPart()));
+ }
+ this.tableCells = cells;
+ }
+ return tableCells;
+ }
+ /**
+ * returns the XWPFTableCell which belongs to the CTTC cell
+ * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned
+ * @param cell
+ * @return
+ */
+ public XWPFTableCell getTableCell(CTTc cell) {
+ for(int i=0; i<tableCells.size(); i++){
+ if(tableCells.get(i).getCTTc() == cell) return tableCells.get(i);
+ }
+ return null;
+ }
}// end class
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java b/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
index 17786326ac..f8c4e116b0 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
@@ -24,9 +24,13 @@ import org.apache.poi.xwpf.extractor.TestXWPFWordExtractor;
import org.apache.poi.xwpf.model.TestXWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.TestXWPFHeader;
import org.apache.poi.xwpf.usermodel.TestXWPFHeadings;
+import org.apache.poi.xwpf.usermodel.TestXWPFNumbering;
import org.apache.poi.xwpf.usermodel.TestXWPFParagraph;
+import org.apache.poi.xwpf.usermodel.TestXWPFPictureData;
import org.apache.poi.xwpf.usermodel.TestXWPFRun;
+import org.apache.poi.xwpf.usermodel.TestXWPFStyles;
import org.apache.poi.xwpf.usermodel.TestXWPFTable;
+import org.apache.poi.xwpf.usermodel.TestXWPFTableRow;
/**
* Collects all tests for <tt>org.apache.poi.xwpf</tt> and sub-packages.
@@ -45,8 +49,11 @@ public final class AllXWPFTests {
result.addTestSuite(TestXWPFParagraph.class);
result.addTestSuite(TestXWPFRun.class);
result.addTestSuite(TestXWPFTable.class);
+ result.addTestSuite(TestXWPFStyles.class);
+ result.addTestSuite(TestXWPFPictureData.class);
+ result.addTestSuite(TestXWPFNumbering.class);
result.addTestSuite(TestAllExtendedProperties.class);
result.addTestSuite(TestPackageCorePropertiesGetKeywords.class);
- return result;
+ return result;
}
}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java
index 1a7be43790..88d0823741 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java
@@ -20,10 +20,15 @@ package org.apache.poi.xwpf;
import junit.framework.TestCase;
import org.apache.poi.POIXMLProperties;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
+import org.apache.xmlbeans.XmlCursor;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
public final class TestXWPFDocument extends TestCase {
@@ -93,4 +98,35 @@ public final class TestXWPFDocument extends TestCase {
assertNotNull(props);
assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
}
+
+// public void testAddParagraph(){
+// XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+// int pLength = doc.getParagraphs().length;
+// XWPFParagraph p = doc.insertNewParagraph(3);
+// assertTrue(p == doc.getParagraphs()[3]);
+// assertTrue(++pLength == doc.getParagraphs().length);
+// CTP ctp = p.getCTP();
+// XWPFParagraph newP = doc.getParagraph(ctp);
+// assertSame(p, newP);
+// XmlCursor cursor = doc.getDocument().getBody().getPArray(0).newCursor();
+// XWPFParagraph cP = doc.insertNewParagraph(cursor);
+// assertSame(cP, doc.getParagraphs()[0]);
+// assertTrue(++pLength == doc.getParagraphs().length);
+// }
+
+ public void testAddPicture(){
+ XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+ byte[] jpeg = "This is a jpeg".getBytes();
+ try {
+ int jpegNum = doc.addPicture(jpeg, XWPFDocument.PICTURE_TYPE_JPEG);
+ byte[] newJpeg = doc.getAllPictures().get(jpegNum).getData();
+ assertEquals(newJpeg.length, jpeg.length);
+ for(int i = 0 ; i < jpeg.length; i++){
+ assertEquals(newJpeg[i], jpeg[i]);
+ }
+ } catch (InvalidFormatException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
index 4ee379f992..4747910c7a 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
@@ -18,6 +18,7 @@
package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
+import java.util.Arrays;
import junit.framework.TestCase;
@@ -81,7 +82,7 @@ public final class TestXWPFHeader extends TestCase {
pars[0] = p1;
XWPFParagraph p2 = new XWPFParagraph(ctP2);
- XWPFParagraph p3 = new XWPFParagraph(ctP3);
+ XWPFParagraph p3 = new XWPFParagraph(ctP3, null);
XWPFParagraph[] pars2 = new XWPFParagraph[2];
pars2[0] = p2;
pars2[1] = p3;
@@ -96,16 +97,20 @@ public final class TestXWPFHeader extends TestCase {
assertNotNull(policy.getDefaultHeader());
assertNotNull(policy.getFirstPageHeader());
assertNotNull(policy.getDefaultFooter());
- // ....and that the footer object captrued above contains two
+ // ....and that the footer object captured above contains two
// paragraphs of text.
- assertEquals(footer.getParagraphs().length, 2);
+ assertEquals(footer.getParagraphs().size(), 2);
// As an additional check, recover the defauls footer and
// make sure that it contains two paragraphs of text and that
// both do hold what is expected.
footer = policy.getDefaultFooter();
- XWPFParagraph[] paras = footer.getParagraphs();
+ XWPFParagraph[] paras = new XWPFParagraph[footer.getParagraphs().size()];
+ int i=0;
+ for(XWPFParagraph p : footer.getParagraphs()) {
+ paras[i++] = p;
+ }
assertEquals(paras.length, 2);
assertEquals(paras[0].getText(), "First paragraph for the footer");
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
new file mode 100644
index 0000000000..7990cd70d6
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
@@ -0,0 +1,40 @@
+/* ====================================================================
+ 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.math.BigInteger;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+public class TestXWPFNumbering extends TestCase {
+
+ public void testCompareAbstractNum(){
+ XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
+ XWPFNumbering numbering = doc.getNumbering();
+ BigInteger numId = BigInteger.valueOf(1);
+ assertTrue(numbering.numExist(numId));
+ XWPFNum num = numbering.getNum(numId);
+ BigInteger abstrNumId = num.getCTNum().getAbstractNumId().getVal();
+ XWPFAbstractNum abstractNum = numbering.getAbstractNum(abstrNumId);
+ BigInteger compareAbstractNum = numbering.getIdOfAbstractNum(abstractNum);
+ assertEquals(abstrNumId, compareAbstractNum);
+ }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
index 73f66927fd..3444c246e4 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
@@ -18,12 +18,26 @@
package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger;
-import java.io.File;
+import java.util.List;
import junit.framework.TestCase;
import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
/**
* Tests for XWPF Paragraphs
@@ -39,9 +53,9 @@ public final class TestXWPFParagraph extends TestCase {
XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader();
assertNotNull(hdr);
- XWPFParagraph[] ps = hdr.getParagraphs();
- assertEquals(1, ps.length);
- XWPFParagraph p = ps[0];
+ List<XWPFParagraph> ps = hdr.getParagraphs();
+ assertEquals(1, ps.size());
+ XWPFParagraph p = ps.get(0);
assertEquals(5, p.getCTP().getRArray().length);
assertEquals("First header column!\tMid header\tRight header!", p
@@ -53,25 +67,25 @@ public final class TestXWPFParagraph extends TestCase {
*/
public void disabled_testDocumentParagraph() {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
- XWPFParagraph[] ps = xml.getParagraphs();
- assertEquals(10, ps.length);
+ List<XWPFParagraph> ps = xml.getParagraphs();
+ assertEquals(10, ps.size());
- assertFalse(ps[0].isEmpty());
+ assertFalse(ps.get(0).isEmpty());
assertEquals(
"This is a sample word document. It has two pages. It has a three column heading, but no footer.",
- ps[0].getText());
+ ps.get(0).getText());
- assertTrue(ps[1].isEmpty());
- assertEquals("", ps[1].getText());
+ assertTrue(ps.get(1).isEmpty());
+ assertEquals("", ps.get(1).getText());
- assertFalse(ps[2].isEmpty());
- assertEquals("HEADING TEXT", ps[2].getText());
+ assertFalse(ps.get(2).isEmpty());
+ assertEquals("HEADING TEXT", ps.get(2).getText());
- assertTrue(ps[3].isEmpty());
- assertEquals("", ps[3].getText());
+ assertTrue(ps.get(3).isEmpty());
+ assertEquals("", ps.get(3).getText());
- assertFalse(ps[4].isEmpty());
- assertEquals("More on page one", ps[4].getText());
+ assertFalse(ps.get(4).isEmpty());
+ assertEquals("More on page one", ps.get(4).getText());
}
public void testSetGetBorderTop() {
@@ -216,7 +230,7 @@ public final class TestXWPFParagraph extends TestCase {
public void testBookmarks() {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx");
- XWPFParagraph paragraph = doc.getParagraphs()[0];
+ XWPFParagraph paragraph = doc.getParagraphs().get(0);
assertEquals("Sample Word Document", paragraph.getText());
assertEquals(1, paragraph.getCTP().sizeOfBookmarkStartArray());
assertEquals(0, paragraph.getCTP().sizeOfBookmarkEndArray());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
new file mode 100644
index 0000000000..87be3b2c8d
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
@@ -0,0 +1,89 @@
+/* ====================================================================
+ 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.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.hslf.usermodel.PictureData;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+
+import junit.framework.TestCase;
+
+public class TestXWPFPictureData extends TestCase {
+ public void testRead(){
+ XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
+ List<XWPFPictureData> pictures = sampleDoc.getAllPictures();
+ assertSame(pictures, sampleDoc.getAllPictures());
+
+ assertEquals(5, pictures.size());
+ String[] ext = {"wmf", "png", "emf", "emf", "jpeg"};
+ for (int i = 0; i < pictures.size(); i++) {
+ assertEquals(ext[i], pictures.get(i).suggestFileExtension());
+ }
+
+ int num = pictures.size();
+
+ byte[] pictureData = {0xA, 0xB, 0XC, 0xD, 0xE, 0xF};
+
+ int idx;
+ try {
+ idx = sampleDoc.addPicture(pictureData, XWPFDocument.PICTURE_TYPE_JPEG);
+ assertEquals(num + 1, pictures.size());
+ //idx is 0-based index in the #pictures array
+ assertEquals(pictures.size() - 1, idx);
+ XWPFPictureData pict = pictures.get(idx);
+ assertEquals("jpeg", pict.suggestFileExtension());
+ assertTrue(Arrays.equals(pictureData, pict.getData()));
+ } catch (InvalidFormatException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void testNew(){
+ XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx");
+ byte[] jpegData = "test jpeg data".getBytes();
+ byte[] wmfData = "test wmf data".getBytes();
+ byte[] pngData = "test png data".getBytes();
+ List<XWPFPictureData> pictures = doc.getAllPictures();
+ assertEquals(0, pictures.size());
+ int jpegIdx;
+ try {
+ jpegIdx = doc.addPicture(jpegData, XWPFDocument.PICTURE_TYPE_JPEG);
+ assertEquals(1, pictures.size());
+ assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
+ assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData()));
+
+ PackageRelationship addPictureReference = doc.addPictureReference(jpegData, Document.PICTURE_TYPE_JPEG );
+ XWPFPictureData pictureDataByID = doc.getPictureDataByID(addPictureReference.getId());
+ byte [] newJPEGData = pictureDataByID.getData();
+ assertEquals(newJPEGData.length, jpegData.length);
+ for(int i = 0; i < newJPEGData.length; i++){
+ assertEquals(newJPEGData[i], jpegData[i]);
+ }
+ } catch (InvalidFormatException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
new file mode 100644
index 0000000000..6c4a722035
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
@@ -0,0 +1,54 @@
+/* ====================================================================
+ 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.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+import junit.framework.TestCase;
+
+public class TestXWPFStyles extends TestCase {
+
+// protected void setUp() throws Exception {
+// super.setUp();
+// }
+
+ public void testGetUsedStyles(){
+ XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx");
+ List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>();
+ XWPFStyles styles = sampleDoc.getStyles();
+ XWPFStyle style = styles.getStyle("berschrift1");
+ testUsedStyleList.add(style);
+ testUsedStyleList.add(styles.getStyle("Standard"));
+ testUsedStyleList.add(styles.getStyle("berschrift1Zchn"));
+ testUsedStyleList.add(styles.getStyle("Absatz-Standardschriftart"));
+ style.hasSameName(style);
+
+ List<XWPFStyle> usedStyleList = styles.getUsedStyleList(style);
+ assertEquals(usedStyleList, testUsedStyleList);
+
+
+ }
+
+// protected void tearDown() throws Exception {
+// super.tearDown();
+// }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
index d7a831757e..6e8fe1e8ea 100644
--- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
@@ -43,14 +43,14 @@ public class TestXWPFTable extends TestCase {
public void testConstructor() {
CTTbl ctTable = CTTbl.Factory.newInstance();
- XWPFTable xtab = new XWPFTable(null, ctTable);
+ XWPFTable xtab = new XWPFTable(ctTable, null);
assertNotNull(xtab);
assertEquals(1, ctTable.sizeOfTrArray());
assertEquals(1, ctTable.getTrArray(0).sizeOfTcArray());
assertNotNull(ctTable.getTrArray(0).getTcArray(0).getPArray(0));
ctTable = CTTbl.Factory.newInstance();
- xtab = new XWPFTable(null, ctTable, 3, 2);
+ xtab = new XWPFTable(ctTable, null, 3, 2);
assertNotNull(xtab);
assertEquals(3, ctTable.sizeOfTrArray());
assertEquals(2, ctTable.getTrArray(0).sizeOfTcArray());
@@ -67,7 +67,7 @@ public class TestXWPFTable extends TestCase {
CTText text = run.addNewT();
text.setStringValue("finally I can write!");
- XWPFTable xtab = new XWPFTable(null, table);
+ XWPFTable xtab = new XWPFTable(table, null);
assertEquals("finally I can write!\n", xtab.getText());
}
@@ -84,7 +84,7 @@ public class TestXWPFTable extends TestCase {
r3.addNewTc().addNewP();
r3.addNewTc().addNewP();
- XWPFTable xtab = new XWPFTable(null, table);
+ XWPFTable xtab = new XWPFTable(table, null);
assertEquals(3, xtab.getNumberOfRows());
assertNotNull(xtab.getRow(2));
@@ -95,7 +95,7 @@ public class TestXWPFTable extends TestCase {
assertEquals(2, table.getTrArray(0).sizeOfTcArray());
//check creation of first row
- xtab = new XWPFTable(null, CTTbl.Factory.newInstance());
+ xtab = new XWPFTable(CTTbl.Factory.newInstance(), null);
assertEquals(1, xtab.getCTTbl().getTrArray(0).sizeOfTcArray());
}
@@ -104,7 +104,7 @@ public class TestXWPFTable extends TestCase {
CTTbl table = CTTbl.Factory.newInstance();
table.addNewTblPr().addNewTblW().setW(new BigInteger("1000"));
- XWPFTable xtab = new XWPFTable(null, table);
+ XWPFTable xtab = new XWPFTable(table, null);
assertEquals(1000, xtab.getWidth());
@@ -115,7 +115,7 @@ public class TestXWPFTable extends TestCase {
public void testSetGetHeight() {
CTTbl table = CTTbl.Factory.newInstance();
- XWPFTable xtab = new XWPFTable(null, table);
+ XWPFTable xtab = new XWPFTable(table, null);
XWPFTableRow row = xtab.createRow();
row.setHeight(20);
assertEquals(20, row.getHeight());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
new file mode 100644
index 0000000000..0844b507ba
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
@@ -0,0 +1,46 @@
+/* ====================================================================
+ 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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+
+import junit.framework.TestCase;
+
+public class TestXWPFTableRow extends TestCase {
+
+
+
+ @Override
+ protected void setUp() throws Exception {
+ // TODO Auto-generated method stub
+ super.setUp();
+ }
+
+ public void testSomething() throws Exception {
+
+ CTRow ctRow = CTRow.Factory.newInstance();
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // TODO Auto-generated method stub
+ super.tearDown();
+ }
+
+}