mirror of https://github.com/apache/poi.git
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
This commit is contained in:
parent
d6d5250933
commit
91f1934fcc
|
@ -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>
|
||||
|
|
|
@ -281,5 +281,4 @@ public class POIXMLDocumentPart {
|
|||
protected void onDocumentRead() throws IOException{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Get any tables
|
||||
for(CTTbl table : body.getTblArray()) {
|
||||
tables.add(new XWPFTable(this, table));
|
||||
}
|
||||
|
||||
|
||||
// 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()]
|
||||
);
|
||||
}
|
||||
|
||||
public Iterator<XWPFTable> getTablesIterator()
|
||||
{
|
||||
return tables.iterator();
|
||||
|
||||
/**
|
||||
* @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs()
|
||||
*/
|
||||
public List<XWPFParagraph> getParagraphs(){
|
||||
return Collections.unmodifiableList(paragraphs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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) {
|
||||
super(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 {
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -16,22 +16,56 @@
|
|||
==================================================================== */
|
||||
package org.apache.poi.xwpf.usermodel;
|
||||
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
|
||||
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;
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
// }
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue