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:
Nick Burch 2010-06-11 14:37:58 +00:00
parent d6d5250933
commit 91f1934fcc
40 changed files with 4073 additions and 254 deletions

View File

@ -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>

View File

@ -281,5 +281,4 @@ public class POIXMLDocumentPart {
protected void onDocumentRead() throws IOException{
}
}

View File

@ -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);
}
}

View File

@ -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,
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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>();

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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");

View File

@ -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);
}
}

View File

@ -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());

View File

@ -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();
}
}
}

View File

@ -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();
// }
}

View File

@ -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());

View File

@ -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();
}
}