bug 51265: Enhanced Handling of Picture Parts in XWPF

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1130120 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2011-06-01 12:07:16 +00:00
parent 3d7cd947fd
commit b988ca3855
57 changed files with 2962 additions and 2012 deletions

View File

@ -34,10 +34,11 @@
<changes> <changes>
<release version="3.8-beta4" date="2011-??-??"> <release version="3.8-beta4" date="2011-??-??">
<action dev="poi-developers" type="add">51265 - Enhanced Handling of Picture Parts in XWPF</action>
<action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action> <action dev="poi-developers" type="add">51292 - Additional HWPF Table Cell Descriptor values</action>
</release> </release>
<release version="3.8-beta3" date="2011-??-??"> <release version="3.8-beta3" date="2011-06-06">
<action dev="poi-developers" type="fix">51098 - Correct calculate image width/height, if image fits into one cell</action> <action dev="poi-developers" type="fix">51098 - Correctly calculate image width/height, if image fits into one cell</action>
<action dev="poi-developers" type="fix">47147 - Correct extra paragraphs from XWPF Table Cells</action> <action dev="poi-developers" type="fix">47147 - Correct extra paragraphs from XWPF Table Cells</action>
<action dev="poi-developers" type="add">51188 - Support for getting and setting XPWF zoom settings</action> <action dev="poi-developers" type="add">51188 - Support for getting and setting XPWF zoom settings</action>
<action dev="poi-developers" type="add">51134 - Support for adding Numbering and Styles to a XWPF document that doesn't already have them</action> <action dev="poi-developers" type="add">51134 - Support for adding Numbering and Styles to a XWPF document that doesn't already have them</action>

View File

@ -23,6 +23,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
public final class IOUtils { public final class IOUtils {
private IOUtils() { private IOUtils() {
@ -129,4 +131,10 @@ public final class IOUtils {
} }
} }
} }
public static long calculateChecksum(byte[] data) {
Checksum sum = new CRC32();
sum.update(data, 0, data.length);
return sum.getValue();
}
} }

View File

@ -30,10 +30,8 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; 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.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
@ -80,33 +78,6 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
return getPackagePart(); return getPackagePart();
} }
/**
* Get the PackagePart that is the target of a relationship.
*
* @param rel The relationship
* @return The target part
* @throws InvalidFormatException
*/
protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException {
return getTargetPart(getPackage(), rel);
}
/**
* Get the PackagePart that is the target of a relationship.
*
* @param rel The relationship
* @param pkg The package to fetch from
* @return The target part
* @throws InvalidFormatException
*/
protected static PackagePart getTargetPart(OPCPackage pkg, PackageRelationship rel) throws InvalidFormatException {
PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
PackagePart part = pkg.getPart(relName);
if (part == null) {
throw new IllegalArgumentException("No part found for relationship " + rel);
}
return part;
}
/** /**
* Retrieves all the PackageParts which are defined as * Retrieves all the PackageParts which are defined as
* relationships of the base document with the * relationships of the base document with the
@ -125,8 +96,6 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
return parts; return parts;
} }
/** /**
* Checks that the supplied InputStream (which MUST * Checks that the supplied InputStream (which MUST
* support mark and reset, or be a PushbackInputStream) * support mark and reset, or be a PushbackInputStream)

View File

@ -17,15 +17,23 @@
package org.apache.poi; package org.apache.poi;
import java.io.IOException; import java.io.IOException;
import java.util.*;
import java.net.URI; import java.net.URI;
import java.util.*;
import java.util.Map.Entry;
import org.apache.xmlbeans.XmlOptions;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.*; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
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.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlOptions;
/** /**
* Represents an entry of a OOXML package. * Represents an entry of a OOXML package.
@ -47,19 +55,55 @@ public class POIXMLDocumentPart {
DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces(); DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();
} }
private PackagePart packagePart; private PackagePart packagePart;
private PackageRelationship packageRel; private PackageRelationship packageRel;
private POIXMLDocumentPart parent; private POIXMLDocumentPart parent;
private List<POIXMLDocumentPart> relations; private Map<String,POIXMLDocumentPart> relations = new LinkedHashMap<String,POIXMLDocumentPart>();
/**
* Get the PackagePart that is the target of a relationship.
*
* @param rel The relationship
* @param pkg The package to fetch from
* @return The target part
* @throws InvalidFormatException
*/
protected static PackagePart getTargetPart(OPCPackage pkg, PackageRelationship rel)
throws InvalidFormatException {
PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
PackagePart part = pkg.getPart(relName);
if (part == null) {
throw new IllegalArgumentException("No part found for relationship " + rel);
}
return part;
}
/**
* Counter that provides the amount of incoming relations from other parts
* to this part.
*/
private int relationCounter = 0;
int incrementRelationCounter() {
relationCounter++;
return relationCounter;
}
int decrementRelationCounter() {
relationCounter--;
return relationCounter;
}
int getRelationCounter() {
return relationCounter;
}
/** /**
* Construct POIXMLDocumentPart representing a "core document" package part. * Construct POIXMLDocumentPart representing a "core document" package part.
*/ */
public POIXMLDocumentPart(OPCPackage pkg) { public POIXMLDocumentPart(OPCPackage pkg) {
PackageRelationship coreRel = pkg.getRelationshipsByType( PackageRelationship coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);
PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);
this.relations = new LinkedList<POIXMLDocumentPart>();
this.packagePart = pkg.getPart(coreRel); this.packagePart = pkg.getPart(coreRel);
this.packageRel = coreRel; this.packageRel = coreRel;
} }
@ -70,7 +114,6 @@ public class POIXMLDocumentPart {
* @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean) * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)
*/ */
public POIXMLDocumentPart(){ public POIXMLDocumentPart(){
this.relations = new LinkedList<POIXMLDocumentPart>();
} }
/** /**
@ -82,7 +125,6 @@ public class POIXMLDocumentPart {
* @see #read(POIXMLFactory, java.util.Map) * @see #read(POIXMLFactory, java.util.Map)
*/ */
public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){ public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){
this.relations = new LinkedList<POIXMLDocumentPart>();
this.packagePart = part; this.packagePart = part;
this.packageRel = rel; this.packageRel = rel;
} }
@ -97,7 +139,6 @@ public class POIXMLDocumentPart {
* @see #read(POIXMLFactory, java.util.Map) * @see #read(POIXMLFactory, java.util.Map)
*/ */
public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel){ public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel){
this.relations = new LinkedList<POIXMLDocumentPart>();
this.packagePart = part; this.packagePart = part;
this.packageRel = rel; this.packageRel = rel;
this.parent = parent; this.parent = parent;
@ -145,7 +186,46 @@ public class POIXMLDocumentPart {
* @return child relations * @return child relations
*/ */
public final List<POIXMLDocumentPart> getRelations(){ public final List<POIXMLDocumentPart> getRelations(){
return relations; return Collections.unmodifiableList(new ArrayList<POIXMLDocumentPart>(relations.values()));
}
/**
* Returns the target {@link POIXMLDocumentPart}, where a
* {@link PackageRelationship} is set from the {@link PackagePart} of this
* {@link POIXMLDocumentPart} to the {@link PackagePart} of the target
* {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()}
* matching the given parameter value.
*
* @param id
* The relation id to look for
* @return the target part of the relation, or null, if none exists
*/
public final POIXMLDocumentPart getRelationById(String id) {
return relations.get(id);
}
/**
* Returns the {@link PackageRelationship#getId()} of the
* {@link PackageRelationship}, that sources from the {@link PackagePart} of
* this {@link POIXMLDocumentPart} to the {@link PackagePart} of the given
* parameter value.
*
* @param part
* The {@link POIXMLDocumentPart} for which the according
* relation-id shall be found.
* @return The value of the {@link PackageRelationship#getId()} or null, if
* parts are not related.
*/
public final String getRelationId(POIXMLDocumentPart part) {
Iterator<Entry<String, POIXMLDocumentPart>> iter = relations.entrySet().iterator();
while (iter.hasNext())
{
Entry<String, POIXMLDocumentPart> entry = iter.next();
if (entry.getValue() == part) {
return entry.getKey();
}
}
return null;
} }
/** /**
@ -153,17 +233,54 @@ public class POIXMLDocumentPart {
* *
* @param part the child to add * @param part the child to add
*/ */
protected final void addRelation(POIXMLDocumentPart part){ protected final void addRelation(String id,POIXMLDocumentPart part){
relations.add(part); relations.put(id,part);
part.incrementRelationCounter();
} }
/** /**
* Remove the specified part in this package. * Remove the relation to the specified part in this package and remove the
* part, if it is no longer needed.
*/ */
public final void removeRelation(POIXMLDocumentPart part){ protected final void removeRelation(POIXMLDocumentPart part){
getPackagePart().removeRelationship(part.getPackageRelationship().getId()); removeRelation(part,true);
}
/**
* Remove the relation to the specified part in this package and remove the
* part, if it is no longer needed and flag is set to true.
*
* @param part
* The related part, to which the relation shall be removed.
* @param removeUnusedParts
* true, if the part shall be removed from the package if not
* needed any longer.
*/
protected final boolean removeRelation(POIXMLDocumentPart part, boolean removeUnusedParts){
String id = getRelationId(part);
if (id == null) {
// part is not related with this POIXMLDocumentPart
return false;
}
/* decrement usage counter */
part.decrementRelationCounter();
/* remove packagepart relationship */
getPackagePart().removeRelationship(id);
/* remove POIXMLDocument from relations */
relations.remove(id);
if (removeUnusedParts) {
/* if last relation to target part was removed, delete according target part */
if (part.getRelationCounter() == 0) {
try {
part.onDocumentRemove();
} catch (IOException e) {
throw new POIXMLException(e);
}
getPackagePart().getPackage().removePart(part.getPackagePart()); getPackagePart().getPackage().removePart(part.getPackagePart());
relations.remove(part); }
}
return true;
} }
/** /**
@ -211,7 +328,7 @@ public class POIXMLDocumentPart {
protected final void onSave(Set<PackagePart> alreadySaved) throws IOException{ protected final void onSave(Set<PackagePart> alreadySaved) throws IOException{
commit(); commit();
alreadySaved.add(this.getPackagePart()); alreadySaved.add(this.getPackagePart());
for(POIXMLDocumentPart p : relations){ for(POIXMLDocumentPart p : relations.values()){
if (!alreadySaved.contains(p.getPackagePart())) { if (!alreadySaved.contains(p.getPackagePart())) {
p.onSave(alreadySaved); p.onSave(alreadySaved);
} }
@ -246,15 +363,19 @@ public class POIXMLDocumentPart {
try { try {
PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx)); PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
PackageRelationship rel = null; PackageRelationship rel = null;
PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
if(!noRelation) { if(!noRelation) {
/* only add to relations, if according relationship is being created. */
rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation()); rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
} }
PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
POIXMLDocumentPart doc = factory.newDocumentPart(descriptor); POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);
doc.packageRel = rel; doc.packageRel = rel;
doc.packagePart = part; doc.packagePart = part;
doc.parent = this; doc.parent = this;
addRelation(doc); if(!noRelation) {
/* only add to relations, if according relationship is being created. */
addRelation(rel.getId(),doc);
}
return doc; return doc;
} catch (Exception e){ } catch (Exception e){
throw new POIXMLException(e); throw new POIXMLException(e);
@ -292,14 +413,14 @@ public class POIXMLDocumentPart {
if (!context.containsKey(p)) { if (!context.containsKey(p)) {
POIXMLDocumentPart childPart = factory.createDocumentPart(this, rel, p); POIXMLDocumentPart childPart = factory.createDocumentPart(this, rel, p);
childPart.parent = this; childPart.parent = this;
addRelation(childPart); addRelation(rel.getId(),childPart);
if(p != null){ if(p != null){
context.put(p, childPart); context.put(p, childPart);
if(p.hasRelationships()) childPart.read(factory, context); if(p.hasRelationships()) childPart.read(factory, context);
} }
} }
else { else {
addRelation(context.get(p)); addRelation(rel.getId(),context.get(p));
} }
} }
} }
@ -315,7 +436,25 @@ public class POIXMLDocumentPart {
/** /**
* Fired when a package part is read * Fired when a package part is read
*/ */
protected void onDocumentRead() throws IOException{ protected void onDocumentRead() throws IOException {
}
/**
* Get the PackagePart that is the target of a relationship.
*
* @param rel The relationship
* @return The target part
* @throws InvalidFormatException
*/
protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException {
return getTargetPart(getPackagePart().getPackage(), rel);
}
/**
* Fired when a package part is about to be removed from the package
*/
protected void onDocumentRemove() throws IOException {
} }
} }

View File

@ -31,7 +31,10 @@ import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
@ -553,6 +556,25 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
return retArr; return retArr;
} }
/**
* @return
*/
public List<PackagePart> getPartsByName(final Pattern namePattern) {
if (namePattern == null) {
throw new IllegalArgumentException("name pattern must not be null");
}
ArrayList<PackagePart> result = new ArrayList<PackagePart>();
for (PackagePart part : partList.values()) {
PackagePartName partName = part.getPartName();
String name = partName.getName();
Matcher matcher = namePattern.matcher(name);
if (matcher.matches()) {
result.add(part);
}
}
return result;
}
/** /**
* Get the target part from the specified relationship. * Get the target part from the specified relationship.
* *

View File

@ -22,7 +22,7 @@ import java.io.OutputStream;
import java.text.ParsePosition; import java.text.ParsePosition;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

View File

@ -0,0 +1,268 @@
/* ====================================================================
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.util;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* <p>
* 24.08.2009<br>
* </p>
*
* @author Stefan Stern<br>
*/
public class IdentifierManager {
public static final long MAX_ID = Long.MAX_VALUE - 1;
public static final long MIN_ID = 0L;
/**
*
*/
private final long upperbound;
/**
*
*/
private final long lowerbound;
/**
* List of segments of available identifiers
*/
private LinkedList<Segment> segments;
/**
* @param lowerbound the lower limit of the id-range to manage. Must be greater than or equal to {@link #MIN_ID}.
* @param upperbound the upper limit of the id-range to manage. Must be less then or equal {@link #MAX_ID}.
*/
public IdentifierManager(long lowerbound, long upperbound) {
if (lowerbound > upperbound) {
String message = "lowerbound must not be greater than upperbound";
throw new IllegalArgumentException(message);
}
else if (lowerbound < MIN_ID) {
String message = "lowerbound must be greater than or equal to " + Long.toString(MIN_ID);
throw new IllegalArgumentException(message);
}
else if (upperbound > MAX_ID) {
/*
* while MAX_ID is Long.MAX_VALUE, this check is pointless. But if
* someone subclasses / tweaks the limits, this check if fine.
*/
String message = "upperbound must be less thean or equal " + Long.toString(MAX_ID);
throw new IllegalArgumentException(message);
}
this.lowerbound = lowerbound;
this.upperbound = upperbound;
this.segments = new LinkedList<Segment>();
segments.add(new Segment(lowerbound, upperbound));
}
public long reserve(long id) {
if (id < lowerbound || id > upperbound) {
throw new IllegalArgumentException("Value for parameter 'id' was out of bounds");
}
verifyIdentifiersLeft();
if (id == upperbound) {
Segment lastSegment = segments.getLast();
if (lastSegment.end == upperbound) {
lastSegment.end = upperbound - 1;
if (lastSegment.start > lastSegment.end) {
segments.removeLast();
}
return id;
}
return reserveNew();
}
if (id == lowerbound) {
Segment firstSegment = segments.getFirst();
if (firstSegment.start == lowerbound) {
firstSegment.start = lowerbound + 1;
if (firstSegment.end < firstSegment.start) {
segments.removeFirst();
}
return id;
}
return reserveNew();
}
ListIterator<Segment> iter = segments.listIterator();
while (iter.hasNext()) {
Segment segment = iter.next();
if (segment.end < id) {
continue;
}
else if (segment.start > id) {
break;
}
else if (segment.start == id) {
segment.start = id + 1;
if (segment.end < segment.start) {
iter.remove();
}
return id;
}
else if (segment.end == id) {
segment.end = id - 1;
if (segment.start > segment.end) {
iter.remove();
}
return id;
}
else {
iter.add(new Segment(id + 1, segment.end));
segment.end = id - 1;
return id;
}
}
return reserveNew();
}
/**
* @return a new identifier.
* @throws IllegalStateException if no more identifiers are available, then an Exception is raised.
*/
public long reserveNew() {
verifyIdentifiersLeft();
Segment segment = segments.getFirst();
long result = segment.start;
segment.start += 1;
if (segment.start > segment.end) {
segments.removeFirst();
}
return result;
}
/**
* @param id
* the identifier to release. Must be greater than or equal to
* {@link #lowerbound} and must be less than or equal to {@link #upperbound}
* @return true, if the identifier was reserved and has been successfully
* released, false, if the identifier was not reserved.
*/
public boolean release(long id) {
if (id < lowerbound || id > upperbound) {
throw new IllegalArgumentException("Value for parameter 'id' was out of bounds");
}
if (id == upperbound) {
Segment lastSegment = segments.getLast();
if (lastSegment.end == upperbound - 1) {
lastSegment.end = upperbound;
return true;
} else if (lastSegment.end == upperbound) {
return false;
} else {
segments.add(new Segment(upperbound, upperbound));
return true;
}
}
if (id == lowerbound) {
Segment firstSegment = segments.getFirst();
if (firstSegment.start == lowerbound + 1) {
firstSegment.start = lowerbound;
return true;
} else if (firstSegment.start == lowerbound) {
return false;
} else {
segments.addFirst(new Segment(lowerbound, lowerbound));
return true;
}
}
long higher = id + 1;
long lower = id - 1;
ListIterator<Segment> iter = segments.listIterator();
while (iter.hasNext()) {
Segment segment = iter.next();
if (segment.end < lower) {
continue;
}
if (segment.start > higher) {
iter.previous();
iter.add(new Segment(id, id));
return true;
}
if (segment.start == higher) {
segment.start = id;
return true;
}
else if (segment.end == lower) {
segment.end = id;
/* check if releasing this elements glues two segments into one */
if (iter.hasNext()) {
Segment next = iter.next();
if (next.start == segment.end + 1) {
segment.end = next.end;
iter.remove();
}
}
return true;
}
else {
/* id was not reserved, return false */
break;
}
}
return false;
}
public long getRemainingIdentifiers() {
long result = 0;
for (Segment segment : segments) {
result = result - segment.start;
result = result + segment.end + 1;
}
return result;
}
/**
*
*/
private void verifyIdentifiersLeft() {
if (segments.isEmpty()) {
throw new IllegalStateException("No identifiers left");
}
}
private static class Segment {
public Segment(long start, long end) {
this.start = start;
this.end = end;
}
public long start;
public long end;
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return "[" + start + "; " + end + "]";
}
}
}

View File

@ -213,7 +213,7 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing {
XSSFPictureData data = wb.getAllPictures().get(pictureIndex); XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
PackagePartName ppName = data.getPackagePart().getPartName(); PackagePartName ppName = data.getPackagePart().getPartName();
PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation()); PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
addRelation(new XSSFPictureData(data.getPackagePart(), rel)); addRelation(rel.getId(),new XSSFPictureData(data.getPackagePart(), rel));
return rel; return rel;
} }

View File

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFactory; import org.apache.poi.xwpf.usermodel.XWPFFactory;
import org.apache.poi.xwpf.usermodel.XWPFFooter; import org.apache.poi.xwpf.usermodel.XWPFFooter;
@ -106,16 +105,11 @@ public class XWPFHeaderFooterPolicy {
for(int i=0; i<sectPr.sizeOfHeaderReferenceArray(); i++) { for(int i=0; i<sectPr.sizeOfHeaderReferenceArray(); i++) {
// Get the header // Get the header
CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i); CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
PackagePart hdrPart = doc.getPartById(ref.getId()); POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId());
XWPFHeader hdr = null; XWPFHeader hdr = null;
if (relatedPart != null && relatedPart instanceof XWPFHeader) {
for (POIXMLDocumentPart part : doc.getRelations()) { hdr = (XWPFHeader) relatedPart;
if (part.getPackagePart().getPartName().equals(hdrPart.getPartName())) {
hdr = (XWPFHeader) part;
} }
}
// Assign it // Assign it
Enum type = ref.getType(); Enum type = ref.getType();
assignHeader(hdr, type); assignHeader(hdr, type);
@ -123,17 +117,18 @@ public class XWPFHeaderFooterPolicy {
for(int i=0; i<sectPr.sizeOfFooterReferenceArray(); i++) { for(int i=0; i<sectPr.sizeOfFooterReferenceArray(); i++) {
// Get the footer // Get the footer
CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i); CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i);
PackagePart ftrPart = doc.getPartById(ref.getId()); POIXMLDocumentPart relatedPart = doc.getRelationById(ref.getId());
XWPFFooter ftr = new XWPFFooter(doc, XWPFFooter ftr = null;
FtrDocument.Factory.parse(ftrPart.getInputStream()).getFtr()); if (relatedPart != null && relatedPart instanceof XWPFFooter)
{
ftr = (XWPFFooter) relatedPart;
}
// Assign it // Assign it
Enum type = ref.getType(); Enum type = ref.getType();
assignFooter(ftr, type); assignFooter(ftr, type);
} }
} }
private void assignFooter(XWPFFooter ftr, Enum type) { private void assignFooter(XWPFFooter ftr, Enum type) {
if(type == STHdrFtr.FIRST) { if(type == STHdrFtr.FIRST) {
firstPageFooter = ftr; firstPageFooter = ftr;
@ -144,7 +139,6 @@ public class XWPFHeaderFooterPolicy {
} }
} }
private void assignHeader(XWPFHeader hdr, Enum type) { private void assignHeader(XWPFHeader hdr, Enum type) {
if(type == STHdrFtr.FIRST) { if(type == STHdrFtr.FIRST) {
firstPageHeader = hdr; firstPageHeader = hdr;
@ -180,8 +174,6 @@ public class XWPFHeaderFooterPolicy {
return wrapper; return wrapper;
} }
public XWPFFooter createFooter(Enum type) throws IOException { public XWPFFooter createFooter(Enum type) throws IOException {
return createFooter(type, null); return createFooter(type, null);
} }
@ -207,7 +199,6 @@ public class XWPFHeaderFooterPolicy {
return wrapper; return wrapper;
} }
private int getRelationIndex(XWPFRelation relation) { private int getRelationIndex(XWPFRelation relation) {
List<POIXMLDocumentPart> relations = doc.getRelations(); List<POIXMLDocumentPart> relations = doc.getRelations();
int i = 1; int i = 1;
@ -220,7 +211,6 @@ public class XWPFHeaderFooterPolicy {
return i; return i;
} }
private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) { private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) {
//CTHdrFtr ftr = buildHdrFtr(pStyle, pars); // MB 24 May 2010 //CTHdrFtr ftr = buildHdrFtr(pStyle, pars); // MB 24 May 2010
CTHdrFtr ftr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010 CTHdrFtr ftr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010
@ -228,7 +218,6 @@ public class XWPFHeaderFooterPolicy {
return ftr; return ftr;
} }
private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) { private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) {
//CTHdrFtr hdr = buildHdrFtr(pStyle, pars); // MB 24 May 2010 //CTHdrFtr hdr = buildHdrFtr(pStyle, pars); // MB 24 May 2010
CTHdrFtr hdr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010 CTHdrFtr hdr = buildHdrFtr(pStyle, pars, wrapper); // MB 24 May 2010
@ -382,7 +371,6 @@ public class XWPFHeaderFooterPolicy {
return defaultFooter; return defaultFooter;
} }
public void createWatermark(String text) { public void createWatermark(String text) {
XWPFParagraph[] pars = new XWPFParagraph[1]; XWPFParagraph[] pars = new XWPFParagraph[1];
try { try {
@ -398,7 +386,6 @@ public class XWPFHeaderFooterPolicy {
} }
} }
/* /*
* This is the default Watermark paragraph; the only variable is the text message * This is the default Watermark paragraph; the only variable is the text message
* TODO: manage all the other variables * TODO: manage all the other variables

View File

@ -19,6 +19,7 @@ package org.apache.poi.xwpf.usermodel;
import java.util.List; import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
@ -42,7 +43,7 @@ public interface IBody {
* belongs. * belongs.
* @return the Part, to which the body belongs * @return the Part, to which the body belongs
*/ */
IBody getPart(); POIXMLDocumentPart getPart();
/** /**
* get the PartType of the body, for example * get the PartType of the body, for example

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import org.apache.poi.POIXMLDocumentPart;
/** /**
* 9 Jan 2010 * 9 Jan 2010
@ -24,7 +25,8 @@ package org.apache.poi.xwpf.usermodel;
* *
*/ */
public interface IBodyElement{ public interface IBodyElement{
IBody getPart(); IBody getBody();
POIXMLDocumentPart getPart();
BodyType getPartType(); BodyType getPartType();
BodyElementType getElementType(); BodyElementType getElementType();
} }

View File

@ -16,12 +16,12 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -36,6 +36,7 @@ import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLProperties; import org.apache.poi.POIXMLProperties;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
@ -46,6 +47,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.IdentifierManager;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.PackageHelper; import org.apache.poi.util.PackageHelper;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
@ -85,16 +87,21 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
private CTDocument1 ctDocument; private CTDocument1 ctDocument;
private XWPFSettings settings; private XWPFSettings settings;
protected List<XWPFFooter> footers; /**
protected List <XWPFHeader> headers; * Keeps track on all id-values used in this document and included parts, like headers, footers, etc.
protected List<XWPFComment> comments; */
protected List<XWPFHyperlink> hyperlinks; private IdentifierManager drawingIdManager = new IdentifierManager(1L,4294967295L);
protected List<XWPFParagraph> paragraphs; protected List<XWPFFooter> footers = new ArrayList<XWPFFooter>();
protected List<XWPFTable> tables; protected List<XWPFHeader> headers = new ArrayList<XWPFHeader>();
protected List<IBodyElement> bodyElements; protected List<XWPFComment> comments = new ArrayList<XWPFComment>();
protected List<XWPFPictureData> pictures; protected List<XWPFHyperlink> hyperlinks = new ArrayList<XWPFHyperlink>();
protected Map<Integer, XWPFFootnote> footnotes; protected List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
protected Map<Integer, XWPFFootnote> endnotes; protected List<XWPFTable> tables = new ArrayList<XWPFTable>();
protected List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
protected List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
protected Map<Long, List<XWPFPictureData>> packagePictures = new HashMap<Long, List<XWPFPictureData>>();
protected Map<Integer, XWPFFootnote> footnotes = new HashMap<Integer, XWPFFootnote>();
protected Map<Integer, XWPFFootnote> endnotes = new HashMap<Integer, XWPFFootnote>();
protected XWPFNumbering numbering; protected XWPFNumbering numbering;
protected XWPFStyles styles; protected XWPFStyles styles;
@ -122,23 +129,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
@Override @Override
protected void onDocumentRead() throws IOException { protected void onDocumentRead() throws IOException {
hyperlinks = new ArrayList<XWPFHyperlink>();
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>();
try { try {
DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream()); DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream());
ctDocument = doc.getDocument(); ctDocument = doc.getDocument();
initFootnotes(); initFootnotes();
// parse the document with cursor and add // parse the document with cursor and add
// the XmlObject to its lists // the XmlObject to its lists
XmlCursor cursor = ctDocument.getBody().newCursor(); XmlCursor cursor = ctDocument.getBody().newCursor();
@ -146,12 +142,11 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
while (cursor.toNextSelection()) { while (cursor.toNextSelection()) {
XmlObject o = cursor.getObject(); XmlObject o = cursor.getObject();
if (o instanceof CTP) { if (o instanceof CTP) {
XWPFParagraph p = new XWPFParagraph((CTP)o, this); XWPFParagraph p = new XWPFParagraph((CTP) o, this);
bodyElements.add(p); bodyElements.add(p);
paragraphs.add(p); paragraphs.add(p);
} } else if (o instanceof CTTbl) {
if (o instanceof CTTbl) { XWPFTable t = new XWPFTable((CTTbl) o, this);
XWPFTable t = new XWPFTable((CTTbl)o, this);
bodyElements.add(t); bodyElements.add(t);
tables.add(t); tables.add(t);
} }
@ -163,39 +158,49 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
headerFooterPolicy = new XWPFHeaderFooterPolicy(this); headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
// Create for each XML-part in the Package a PartClass // Create for each XML-part in the Package a PartClass
for(POIXMLDocumentPart p : getRelations()){ for (POIXMLDocumentPart p : getRelations()) {
String relation = p.getPackageRelationship().getRelationshipType(); String relation = p.getPackageRelationship().getRelationshipType();
if(relation.equals(XWPFRelation.STYLES.getRelation())){ if (relation.equals(XWPFRelation.STYLES.getRelation())) {
this.styles = (XWPFStyles) p; this.styles = (XWPFStyles) p;
} else if (relation.equals(XWPFRelation.NUMBERING.getRelation())){ this.styles.onDocumentRead();
} else if (relation.equals(XWPFRelation.NUMBERING.getRelation())) {
this.numbering = (XWPFNumbering) p; this.numbering = (XWPFNumbering) p;
} else if (relation.equals(XWPFRelation.FOOTER.getRelation())){ this.numbering.onDocumentRead();
footers.add((XWPFFooter)p); } else if (relation.equals(XWPFRelation.FOOTER.getRelation())) {
} else if (relation.equals(XWPFRelation.HEADER.getRelation())){ XWPFFooter footer = (XWPFFooter) p;
headers.add((XWPFHeader)p); footers.add(footer);
} else if (relation.equals(XWPFRelation.COMMENT.getRelation())){ footer.onDocumentRead();
} else if (relation.equals(XWPFRelation.HEADER.getRelation())) {
XWPFHeader header = (XWPFHeader) p;
headers.add(header);
header.onDocumentRead();
} else if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
// TODO Create according XWPFComment class, extending POIXMLDocumentPart
CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream()); CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
for(CTComment ctcomment : cmntdoc.getComments().getCommentList()) { for (CTComment ctcomment : cmntdoc.getComments().getCommentList()) {
comments.add(new XWPFComment(ctcomment, this)); comments.add(new XWPFComment(ctcomment, this));
} }
} else if (relation.equals(XWPFRelation.SETTINGS.getRelation())){ } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) {
settings = (XWPFSettings)p; settings = (XWPFSettings) p;
settings.onDocumentRead();
} else if (relation.equals(XWPFRelation.IMAGES.getRelation())) {
XWPFPictureData picData = (XWPFPictureData) p;
picData.onDocumentRead();
registerPackagePictureData(picData);
pictures.add(picData);
} }
} }
initHyperlinks(); initHyperlinks();
} catch (XmlException e) { } catch (XmlException e) {
throw new POIXMLException(e); throw new POIXMLException(e);
} }
// create for every Graphic-Part in Package a new XWPFGraphic
getAllPictures();
} }
private void initHyperlinks(){ private void initHyperlinks(){
// Get the hyperlinks // Get the hyperlinks
// TODO: make me optional/separated in private function // TODO: make me optional/separated in private function
try { try {
Iterator <PackageRelationship> relIter = Iterator<PackageRelationship> relIter =
getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator(); getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
while(relIter.hasNext()) { while(relIter.hasNext()) {
PackageRelationship rel = relIter.next(); PackageRelationship rel = relIter.next();
@ -251,20 +256,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
*/ */
@Override @Override
protected void onDocumentCreate() { protected void onDocumentCreate() {
hyperlinks = new ArrayList<XWPFHyperlink>();
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>();
ctDocument = CTDocument1.Factory.newInstance(); ctDocument = CTDocument1.Factory.newInstance();
ctDocument.addNewBody(); ctDocument.addNewBody();
settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS, XWPFFactory.getInstance()); settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS,XWPFFactory.getInstance());
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties(); POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR); expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
@ -278,6 +273,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return ctDocument; return ctDocument;
} }
IdentifierManager getDrawingIdManager() {
return drawingIdManager;
}
/** /**
* returns an Iterator with paragraphs and tables * returns an Iterator with paragraphs and tables
* @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements() * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
@ -340,8 +339,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public XWPFHyperlink getHyperlinkByID(String id) { public XWPFHyperlink getHyperlinkByID(String id) {
Iterator<XWPFHyperlink> iter = hyperlinks.iterator(); Iterator<XWPFHyperlink> iter = hyperlinks.iterator();
while(iter.hasNext()) while (iter.hasNext()) {
{
XWPFHyperlink link = iter.next(); XWPFHyperlink link = iter.next();
if(link.getId().equals(id)) if(link.getId().equals(id))
return link; return link;
@ -363,15 +361,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
} }
public XWPFHyperlink[] getHyperlinks() { public XWPFHyperlink[] getHyperlinks() {
return hyperlinks.toArray( return hyperlinks.toArray(new XWPFHyperlink[hyperlinks.size()]);
new XWPFHyperlink[hyperlinks.size()]
);
} }
public XWPFComment getCommentByID(String id) { public XWPFComment getCommentByID(String id) {
Iterator<XWPFComment> iter = comments.iterator(); Iterator<XWPFComment> iter = comments.iterator();
while(iter.hasNext()) while (iter.hasNext()) {
{
XWPFComment comment = iter.next(); XWPFComment comment = iter.next();
if(comment.getId().equals(id)) if(comment.getId().equals(id))
return comment; return comment;
@ -379,10 +374,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return null; return null;
} }
public XWPFComment[] getComments() { public XWPFComment[] getComments() {
return comments.toArray( return comments.toArray(new XWPFComment[comments.size()]);
new XWPFComment[comments.size()]
);
} }
/** /**
@ -391,10 +385,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
*/ */
public PackagePart getPartById(String id) { public PackagePart getPartById(String id) {
try { try {
return getTargetPart( return getTargetPart(getCorePart().getRelationship(id));
getCorePart().getRelationship(id) } catch (InvalidFormatException e) {
);
} catch(InvalidFormatException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
} }
@ -422,8 +414,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length); throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length);
} }
StylesDocument sd = StylesDocument sd = StylesDocument.Factory.parse(parts[0].getInputStream());
StylesDocument.Factory.parse(parts[0].getInputStream());
return sd.getStyles(); return sd.getStyles();
} }
@ -435,11 +426,13 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
List<PackagePart> embedds = new LinkedList<PackagePart>(); List<PackagePart> embedds = new LinkedList<PackagePart>();
// Get the embeddings for the workbook // Get the embeddings for the workbook
for(PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) for (PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) {
embedds.add(getTargetPart(rel)); embedds.add(getTargetPart(rel));
}
for(PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) for (PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) {
embedds.add(getTargetPart(rel)); embedds.add(getTargetPart(rel));
}
return embedds; return embedds;
} }
@ -475,14 +468,18 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
} }
/** /**
* get with the position of a Paragraph in the bodyelement array list * Look up the paragraph at the specified position in the body elemnts list
* the position of this paragraph in the paragraph array list * and return this paragraphs position in the paragraphs 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, * @param pos
* else it will return -1 * The position of the relevant paragraph in the body elements
* list
* @return the position of the paragraph in the paragraphs list, if there is
* a paragraph at the position in the bodyelements list. Else it
* will return -1
* *
*/ */
public int getParagraphPos(int pos){ public int getParagraphPos(int pos) {
return getBodyElementSpecificPos(pos, paragraphs); return getBodyElementSpecificPos(pos, paragraphs);
} }
@ -493,73 +490,111 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @return if there is a table at the position in the bodyelement array list, * @return if there is a table at the position in the bodyelement array list,
* else it will return null. * else it will return null.
*/ */
public int getTablePos(int pos){ public int getTablePos(int pos) {
return getBodyElementSpecificPos(pos, tables); return getBodyElementSpecificPos(pos, tables);
} }
/** /**
* add a new paragraph at position of the cursor * add a new paragraph at position of the cursor. The cursor must be on the
* {@link TokenType#START} tag of an subelement of the documents body. When
* this method is done, the cursor passed as parameter points to the
* {@link TokenType#END} of the newly inserted paragraph.
*
* @param cursor * @param cursor
* @return the {@link XWPFParagraph} object representing the newly inserted
* CTP object
*/ */
public XWPFParagraph insertNewParagraph(XmlCursor cursor){ public XWPFParagraph insertNewParagraph(XmlCursor cursor) {
if(isCursorInBody(cursor)){ if (isCursorInBody(cursor)) {
String uri = CTP.type.getName().getNamespaceURI(); String uri = CTP.type.getName().getNamespaceURI();
/*
* TODO DO not use a coded constant, find the constant in the OOXML
* classes instead, as the child of type CT_Paragraph is defined in the
* OOXML schema as 'p'
*/
String localPart = "p"; String localPart = "p";
cursor.beginElement(localPart,uri); // creates a new Paragraph, cursor is positioned inside the new
// element
cursor.beginElement(localPart, uri);
// move the cursor to the START token to the paragraph just created
cursor.toParent(); cursor.toParent();
CTP p = (CTP)cursor.getObject(); CTP p = (CTP) cursor.getObject();
XWPFParagraph newP = new XWPFParagraph(p, this); XWPFParagraph newP = new XWPFParagraph(p, this);
XmlObject o = null; XmlObject o = null;
while(!(o instanceof CTP)&&(cursor.toPrevSibling())){ /*
* move the cursor to the previous element until a) the next
* paragraph is found or b) all elements have been passed
*/
while (!(o instanceof CTP) && (cursor.toPrevSibling())) {
o = cursor.getObject(); o = cursor.getObject();
} }
if((!(o instanceof CTP)) || (CTP)o == p){ /*
* if the object that has been found is a) not a paragraph or b) is
* the paragraph that has just been inserted, as the cursor in the
* while loop above was not moved as there were no other siblings,
* then the paragraph that was just inserted is the first paragraph
* in the body. Otherwise, take the previous paragraph and calculate
* the new index for the new paragraph.
*/
if ((!(o instanceof CTP)) || (CTP) o == p) {
paragraphs.add(0, newP); paragraphs.add(0, newP);
} else {
int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;
paragraphs.add(pos, newP);
} }
else{
int pos = paragraphs.indexOf(getParagraph((CTP)o))+1; /*
paragraphs.add(pos,newP); * create a new cursor, that points to the START token of the just
} * inserted paragraph
int i=0; */
cursor.toCursor(p.newCursor()); XmlCursor newParaPos = p.newCursor();
while(cursor.toPrevSibling()){ try {
o =cursor.getObject(); /*
if(o instanceof CTP || o instanceof CTTbl) * Calculate the paragraphs index in the list of all body
* elements
*/
int i = 0;
cursor.toCursor(newParaPos);
while (cursor.toPrevSibling()) {
o = cursor.getObject();
if (o instanceof CTP || o instanceof CTTbl)
i++; i++;
} }
bodyElements.add(i, newP); bodyElements.add(i, newP);
cursor.toCursor(p.newCursor()); cursor.toCursor(newParaPos);
cursor.toEndToken(); cursor.toEndToken();
return newP; return newP;
} finally {
newParaPos.dispose();
}
} }
return null; return null;
} }
public XWPFTable insertNewTbl(XmlCursor cursor) { public XWPFTable insertNewTbl(XmlCursor cursor) {
if(isCursorInBody(cursor)){ if (isCursorInBody(cursor)) {
String uri = CTTbl.type.getName().getNamespaceURI(); String uri = CTTbl.type.getName().getNamespaceURI();
String localPart ="tbl"; String localPart = "tbl";
cursor.beginElement(localPart,uri); cursor.beginElement(localPart, uri);
cursor.toParent(); cursor.toParent();
CTTbl t = (CTTbl)cursor.getObject(); CTTbl t = (CTTbl) cursor.getObject();
XWPFTable newT = new XWPFTable(t, this); XWPFTable newT = new XWPFTable(t, this);
cursor.removeXmlContents(); cursor.removeXmlContents();
XmlObject o = null; XmlObject o = null;
while(!(o instanceof CTTbl)&&(cursor.toPrevSibling())){ while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) {
o = cursor.getObject(); o = cursor.getObject();
} }
if(!(o instanceof CTTbl)){ if (!(o instanceof CTTbl)) {
tables.add(0, newT); tables.add(0, newT);
} else {
int pos = tables.indexOf(getTable((CTTbl) o)) + 1;
tables.add(pos, newT);
} }
else{ int i = 0;
int pos = tables.indexOf(getTable((CTTbl)o))+1;
tables.add(pos,newT);
}
int i=0;
cursor = t.newCursor(); cursor = t.newCursor();
while(cursor.toPrevSibling()){ while (cursor.toPrevSibling()) {
o =cursor.getObject(); o = cursor.getObject();
if(o instanceof CTP || o instanceof CTTbl) if (o instanceof CTP || o instanceof CTTbl)
i++; i++;
} }
bodyElements.add(i, newT); bodyElements.add(i, newT);
@ -577,12 +612,11 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
private boolean isCursorInBody(XmlCursor cursor) { private boolean isCursorInBody(XmlCursor cursor) {
XmlCursor verify = cursor.newCursor(); XmlCursor verify = cursor.newCursor();
verify.toParent(); verify.toParent();
if(verify.getObject() == this.ctDocument.getBody()){ try {
return true; return (verify.getObject() == this.ctDocument.getBody());
} finally {
verify.dispose();
} }
XmlObject o = verify.getObject();
return false;
} }
private int getPosOfBodyElement(IBodyElement needle) { private int getPosOfBodyElement(IBodyElement needle) {
@ -666,7 +700,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* Appends a new paragraph to this document * Appends a new paragraph to this document
* @return a new paragraph * @return a new paragraph
*/ */
public XWPFParagraph createParagraph(){ public XWPFParagraph createParagraph() {
XWPFParagraph p = new XWPFParagraph(ctDocument.getBody().addNewP(), this); XWPFParagraph p = new XWPFParagraph(ctDocument.getBody().addNewP(), this);
bodyElements.add(p); bodyElements.add(p);
paragraphs.add(p); paragraphs.add(p);
@ -753,15 +787,19 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @param paragraph * @param paragraph
* @param pos * @param pos
*/ */
public void setParagraph(XWPFParagraph paragraph, int pos){ public void setParagraph(XWPFParagraph paragraph, int pos) {
paragraphs.set(pos, paragraph); paragraphs.set(pos, paragraph);
ctDocument.getBody().setPArray(pos, paragraph.getCTP()); ctDocument.getBody().setPArray(pos, paragraph.getCTP());
/* TODO update body element, update xwpf element, verify that
* incoming paragraph belongs to this document or if not, XML was
* copied properly (namespace-abbreviations, etc.)
*/
} }
/** /**
* @return the LastParagraph of the document * @return the LastParagraph of the document
*/ */
public XWPFParagraph getLastParagraph(){ public XWPFParagraph getLastParagraph() {
int lastPos = paragraphs.toArray().length - 1; int lastPos = paragraphs.toArray().length - 1;
return paragraphs.get(lastPos); return paragraphs.get(lastPos);
} }
@ -770,7 +808,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* Create an empty table with one row and one column as default. * Create an empty table with one row and one column as default.
* @return a new table * @return a new table
*/ */
public XWPFTable createTable(){ public XWPFTable createTable() {
XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this); XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this);
bodyElements.add(table); bodyElements.add(table);
tables.add(table); tables.add(table);
@ -790,21 +828,19 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return table; return table;
} }
/** /**
* *
*/ */
public void createTOC() { public void createTOC() {
CTSdtBlock block = this.getDocument().getBody().addNewSdt(); CTSdtBlock block = this.getDocument().getBody().addNewSdt();
TOC toc = new TOC(block); TOC toc = new TOC(block);
for (XWPFParagraph par: paragraphs ) { for (XWPFParagraph par : paragraphs) {
String parStyle = par.getStyle(); String parStyle = par.getStyle();
if (parStyle != null && parStyle.substring(0, 7).equals("Heading")) { if (parStyle != null && parStyle.substring(0, 7).equals("Heading")) {
try { try {
int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue(); int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue();
toc.addRow(level, par.getText(), 1, "112723803"); toc.addRow(level, par.getText(), 1, "112723803");
} } catch (NumberFormatException e) {
catch (NumberFormatException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -815,7 +851,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @param pos * @param pos
* @param table * @param table
*/ */
public void setTable(int pos, XWPFTable table){ public void setTable(int pos, XWPFTable table) {
tables.set(pos, table); tables.set(pos, table);
ctDocument.getBody().setTblArray(pos, table.getCTTbl()); ctDocument.getBody().setTblArray(pos, table.getCTTbl());
} }
@ -961,20 +997,6 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
settings.removeEnforcement(); settings.removeEnforcement();
} }
/**
* Return the zoom level, as a percentage
*/
public long getZoomPercent() {
return settings.getZoomPercent();
}
/**
* Sets the zoom level, as a percentage
*/
public void setZoomPercent(long zoomPercent) {
settings.setZoomPercent(zoomPercent);
}
/** /**
* inserts an existing XWPFTable to the arrays bodyElements and tables * inserts an existing XWPFTable to the arrays bodyElements and tables
* @param pos * @param pos
@ -985,75 +1007,128 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
int i; int i;
for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) { for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) {
CTTbl tbl = ctDocument.getBody().getTblArray(i); CTTbl tbl = ctDocument.getBody().getTblArray(i);
if(tbl == table.getCTTbl()){ if (tbl == table.getCTTbl()) {
break; break;
} }
} }
tables.add(i, table); tables.add(i, table);
} }
/**
* Returns all Pictures, which are referenced from the document itself.
* @return a {@link List} of {@link XWPFPictureData}. The returned {@link List} is unmodifiable. Use #a
*/
public List<XWPFPictureData> getAllPictures() { public List<XWPFPictureData> getAllPictures() {
if(pictures == null){ return Collections.unmodifiableList(pictures);
pictures = new ArrayList<XWPFPictureData>();
for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
if(poixmlDocumentPart instanceof XWPFPictureData){
pictures.add((XWPFPictureData)poixmlDocumentPart);
}
}
}
return pictures;
} }
/** /**
* @return all Pictures in this package * @return all Pictures in this package
*/ */
public List<XWPFPictureData> getAllPackagePictures(){ public List<XWPFPictureData> getAllPackagePictures() {
List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>(); List<XWPFPictureData> result = new ArrayList<XWPFPictureData>();
pkgpictures.addAll(getAllPictures()); Collection<List<XWPFPictureData>> values = packagePictures.values();
for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){ for (List<XWPFPictureData> list : values) {
if(poixmlDocumentPart instanceof XWPFHeaderFooter){ result.addAll(list);
pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
} }
} return Collections.unmodifiableList(result);
return pkgpictures;
} }
/** void registerPackagePictureData(XWPFPictureData picData) {
* Adds a picture to the document. Users should normally call List<XWPFPictureData> list = packagePictures.get(picData.getChecksum());
* {@link XWPFRun#addPicture(InputStream, int)} if (list == null) {
* list = new ArrayList<XWPFPictureData>(1);
* packagePictures.put(picData.getChecksum(), list);
* @param is The stream to read image from }
* @param format The format of the picture, eg {@link Document#PICTURE_TYPE_JPEG} if (!list.contains(picData))
{
list.add(picData);
}
}
* XWPFPictureData findPackagePictureData(byte[] pictureData, int format)
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . {
* @throws InvalidFormatException long checksum = IOUtils.calculateChecksum(pictureData);
XWPFPictureData xwpfPicData = null;
/*
* Try to find PictureData with this checksum. Create new, if none
* exists.
*/ */
public int addPicture(InputStream is, int format) throws IOException, InvalidFormatException { List<XWPFPictureData> xwpfPicDataList = packagePictures.get(checksum);
int imageNumber = getNextPicNameNumber(format); if (xwpfPicDataList != null) {
XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); Iterator<XWPFPictureData> iter = xwpfPicDataList.iterator();
OutputStream out = img.getPackagePart().getOutputStream(); while (iter.hasNext() && xwpfPicData == null) {
IOUtils.copy(is, out); XWPFPictureData curElem = iter.next();
out.close(); if (Arrays.equals(pictureData, curElem.getData())) {
pictures.add(img); xwpfPicData = curElem;
return getAllPictures().size()-1; }
}
}
return xwpfPicData;
} }
/** public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
* Adds a picture to the document. Users should normally call {
* {@link XWPFRun#addPicture(InputStream, int)} XWPFPictureData xwpfPicData = findPackagePictureData(pictureData, format);
* POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
* @param pictureData The bytes to read image from
* @param format The format of the picture, eg {@link Document#PICTURE_TYPE_JPEG} if (xwpfPicData == null)
* {
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . /* Part doesn't exist, create a new one */
* @throws InvalidFormatException int idx = getNextPicNameNumber(format);
*/ xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
public int addPicture(byte[] pictureData, int format) throws InvalidFormatException { /* write bytes to new part */
PackagePart picDataPart = xwpfPicData.getPackagePart();
OutputStream out = null;
try { try {
return addPicture(new ByteArrayInputStream(pictureData), format); out = picDataPart.getOutputStream();
} catch (IOException e){ out.write(pictureData);
} catch (IOException e) {
throw new POIXMLException(e);
} finally {
try {
out.close();
} catch (IOException e) {
// ignore
}
}
registerPackagePictureData(xwpfPicData);
pictures.add(xwpfPicData);
return getRelationId(xwpfPicData);
}
else if (!getRelations().contains(xwpfPicData))
{
/*
* Part already existed, but was not related so far. Create
* relationship to the already existing part and update
* POIXMLDocumentPart data.
*/
PackagePart picDataPart = xwpfPicData.getPackagePart();
// TODO add support for TargetMode.EXTERNAL relations.
TargetMode targetMode = TargetMode.INTERNAL;
PackagePartName partName = picDataPart.getPartName();
String relation = relDesc.getRelation();
PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
String id = relShip.getId();
addRelation(id,xwpfPicData);
pictures.add(xwpfPicData);
return id;
}
else
{
/* Part already existed, get relation id and return it */
return getRelationId(xwpfPicData);
}
}
public String addPictureData(InputStream is,int format) throws InvalidFormatException
{
try {
byte[] data = IOUtils.toByteArray(is);
return addPictureData(data, format);
} catch (IOException e) {
throw new POIXMLException(e); throw new POIXMLException(e);
} }
} }
@ -1064,11 +1139,11 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @return the next free ImageNumber * @return the next free ImageNumber
* @throws InvalidFormatException * @throws InvalidFormatException
*/ */
public int getNextPicNameNumber(int format) throws InvalidFormatException{ public int getNextPicNameNumber(int format) throws InvalidFormatException {
int img = getAllPackagePictures().size()+1; int img = getAllPackagePictures().size() + 1;
String proposal = XWPFPictureData.RELATIONS[format].getFileName(img); String proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
PackagePartName createPartName = PackagingURIHelper.createPartName(proposal); PackagePartName createPartName = PackagingURIHelper.createPartName(proposal);
while (this.getPackage().getPart(createPartName)!= null){ while (this.getPackage().getPart(createPartName) != null) {
img++; img++;
proposal = XWPFPictureData.RELATIONS[format].getFileName(img); proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
createPartName = PackagingURIHelper.createPartName(proposal); createPartName = PackagingURIHelper.createPartName(proposal);
@ -1080,17 +1155,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* returns the PictureData by blipID * returns the PictureData by blipID
* @param blipID * @param blipID
* @return XWPFPictureData of a specificID * @return XWPFPictureData of a specificID
* @throws Exception
*/ */
public XWPFPictureData getPictureDataByID(String blipID) { public XWPFPictureData getPictureDataByID(String blipID) {
for(POIXMLDocumentPart part: getRelations()){ POIXMLDocumentPart relatedPart = getRelationById(blipID);
if(part.getPackageRelationship() != null){ if (relatedPart instanceof XWPFPictureData) {
if(part.getPackageRelationship().getId() != null){ XWPFPictureData xwpfPicData = (XWPFPictureData) relatedPart;
if(part.getPackageRelationship().getId().equals(blipID)){ return xwpfPicData;
return (XWPFPictureData)part;
}
}
}
} }
return null; return null;
} }
@ -1099,7 +1169,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* getNumbering * getNumbering
* @return numbering * @return numbering
*/ */
public XWPFNumbering getNumbering(){ public XWPFNumbering getNumbering() {
return numbering; return numbering;
} }
@ -1107,7 +1177,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* get Styles * get Styles
* @return styles for this document * @return styles for this document
*/ */
public XWPFStyles getStyles(){ public XWPFStyles getStyles() {
return styles; return styles;
} }
@ -1117,9 +1187,11 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @param p * @param p
* @return the paragraph with the CTP class p * @return the paragraph with the CTP class p
*/ */
public XWPFParagraph getParagraph(CTP p){ public XWPFParagraph getParagraph(CTP p) {
for(int i=0; i<getParagraphs().size(); i++){ for (int i = 0; i < getParagraphs().size(); i++) {
if(getParagraphs().get(i).getCTP() == p) return getParagraphs().get(i); if (getParagraphs().get(i).getCTP() == p) {
return getParagraphs().get(i);
}
} }
return null; return null;
} }
@ -1131,8 +1203,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @return a table by its CTTbl-Object or null * @return a table by its CTTbl-Object or null
*/ */
public XWPFTable getTable(CTTbl ctTbl) { public XWPFTable getTable(CTTbl ctTbl) {
for(int i=0; i<tables.size(); i++){ for (int i = 0; i < tables.size(); i++) {
if(getTables().get(i).getCTTbl() == ctTbl) return getTables().get(i); if (getTables().get(i).getCTTbl() == ctTbl) {
return getTables().get(i);
}
} }
return null; return null;
} }
@ -1157,18 +1231,17 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return null; return null;
} }
/** /**
* returns the Part, to which the body belongs, which you need for adding relationship to other parts * 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 * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
* belongs. * belongs.
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/ */
public IBody getPart() { public POIXMLDocumentPart getPart() {
return this; return this;
} }
/** /**
* get the PartType of the body, for example * get the PartType of the body, for example
* DOCUMENT, HEADER, FOOTER, FOOTNOTE, * DOCUMENT, HEADER, FOOTER, FOOTNOTE,
@ -1212,4 +1285,4 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public XWPFDocument getXWPFDocument() { public XWPFDocument getXWPFDocument() {
return this; return this;
} }
}//end class } // end class

View File

@ -19,17 +19,16 @@ package org.apache.poi.xwpf.usermodel;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
@ -48,9 +47,6 @@ public class XWPFFooter extends XWPFHeaderFooter {
public XWPFFooter(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException { public XWPFFooter(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException {
super(doc, hdrFtr); super(doc, hdrFtr);
bodyElements = new ArrayList<IBodyElement>();
paragraphs = new ArrayList<XWPFParagraph>();
tables = new ArrayList<XWPFTable>();
XmlCursor cursor = headerFooter.newCursor(); XmlCursor cursor = headerFooter.newCursor();
cursor.selectPath("./*"); cursor.selectPath("./*");
while (cursor.toNextSelection()) { while (cursor.toNextSelection()) {
@ -67,7 +63,6 @@ public class XWPFFooter extends XWPFHeaderFooter {
} }
} }
cursor.dispose(); cursor.dispose();
getAllPictures();
} }
public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
@ -99,10 +94,8 @@ public class XWPFFooter extends XWPFHeaderFooter {
} }
@Override @Override
protected void onDocumentRead(){ protected void onDocumentRead() throws IOException{
bodyElements = new ArrayList<IBodyElement>(); super.onDocumentRead();
paragraphs = new ArrayList<XWPFParagraph>();
tables= new ArrayList<XWPFTable>();
FtrDocument ftrDocument = null; FtrDocument ftrDocument = null;
InputStream is; InputStream is;
try { try {
@ -127,22 +120,10 @@ public class XWPFFooter extends XWPFHeaderFooter {
} }
} }
cursor.dispose(); cursor.dispose();
getAllPictures(); } catch (Exception e) {
} catch (IOException e) { throw new POIXMLException(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()
*/
public IBody getPart() {
return this;
}
/** /**
* get the PartType of the body * get the PartType of the body

View File

@ -19,13 +19,13 @@ package org.apache.poi.xwpf.usermodel;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
@ -50,10 +50,8 @@ public class XWPFHeader extends XWPFHeaderFooter {
super(parent, part, rel); super(parent, part, rel);
} }
public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException { public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) {
super(doc, hdrFtr); super(doc, hdrFtr);
paragraphs = new ArrayList<XWPFParagraph>();
tables = new ArrayList<XWPFTable>();
XmlCursor cursor = headerFooter.newCursor(); XmlCursor cursor = headerFooter.newCursor();
cursor.selectPath("./*"); cursor.selectPath("./*");
while (cursor.toNextSelection()) { while (cursor.toNextSelection()) {
@ -68,13 +66,6 @@ public class XWPFHeader extends XWPFHeaderFooter {
} }
} }
cursor.dispose(); cursor.dispose();
getAllPictures();
}
/**
public XWPFHeader(PackagePart part, PackageRelationship rel)
throws IOException {
super(part, rel);
} }
/** /**
@ -103,12 +94,11 @@ public class XWPFHeader extends XWPFHeaderFooter {
/** /**
* reads the document * reads the document
* @throws IOException
*/ */
@Override @Override
protected void onDocumentRead(){ protected void onDocumentRead() throws IOException {
bodyElements = new ArrayList<IBodyElement>(); super.onDocumentRead();
paragraphs = new ArrayList<XWPFParagraph>();
tables= new ArrayList<XWPFTable>();
HdrDocument hdrDocument = null; HdrDocument hdrDocument = null;
InputStream is; InputStream is;
try { try {
@ -133,23 +123,11 @@ public class XWPFHeader extends XWPFHeaderFooter {
} }
} }
cursor.dispose(); cursor.dispose();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlException e) { } catch (XmlException e) {
// TODO Auto-generated catch block throw new POIXMLException(e);
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()
*/
public IBody getPart() {
return this;
}
/** /**
* get the PartType of the body * get the PartType of the body
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType() * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
@ -157,6 +135,4 @@ public class XWPFHeader extends XWPFHeaderFooter {
public BodyType getPartType() { public BodyType getPartType() {
return BodyType.HEADER; return BodyType.HEADER;
} }
}//end class }//end class

View File

@ -25,11 +25,12 @@ import java.util.List;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
@ -43,15 +44,16 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
/** /**
* Parent of XWPF headers and footers * Parent of XWPF headers and footers
*/ */
public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody{ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody {
protected CTHdrFtr headerFooter; List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>(1);
protected List<XWPFParagraph> paragraphs; List<XWPFTable> tables= new ArrayList<XWPFTable>(1);
protected List<XWPFTable> tables; List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
protected List<XWPFPictureData> pictures; List<IBodyElement> bodyElements = new ArrayList<IBodyElement>(1);
protected XWPFDocument document;
protected List<IBodyElement> bodyElements;
protected XWPFHeaderFooter(XWPFDocument doc, CTHdrFtr hdrFtr){ CTHdrFtr headerFooter;
XWPFDocument document;
XWPFHeaderFooter(XWPFDocument doc, CTHdrFtr hdrFtr){
if (doc==null) { if (doc==null) {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -66,7 +68,6 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
readHdrFtr(); readHdrFtr();
} }
public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
super(parent, part, rel); super(parent, part, rel);
this.document = (XWPFDocument)getParent(); this.document = (XWPFDocument)getParent();
@ -74,8 +75,17 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
if (this.document==null) { if (this.document==null) {
throw new NullPointerException(); throw new NullPointerException();
} }
}
onDocumentRead(); @Override
protected void onDocumentRead() throws IOException {
for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
if(poixmlDocumentPart instanceof XWPFPictureData){
XWPFPictureData xwpfPicData = (XWPFPictureData) poixmlDocumentPart;
pictures.add(xwpfPicData);
document.registerPackagePictureData(xwpfPicData);
}
}
} }
@Internal @Internal
@ -201,15 +211,7 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
} }
public List<XWPFPictureData> getAllPictures() { public List<XWPFPictureData> getAllPictures() {
if(pictures == null){ return Collections.unmodifiableList(pictures);
pictures = new ArrayList<XWPFPictureData>();
for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
if(poixmlDocumentPart instanceof XWPFPictureData){
pictures.add((XWPFPictureData)poixmlDocumentPart);
}
}
}
return pictures;
} }
/** /**
@ -217,14 +219,8 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
* @return all Pictures in this package * @return all Pictures in this package
*/ */
public List<XWPFPictureData> getAllPackagePictures(){ public List<XWPFPictureData> getAllPackagePictures(){
List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>(); return document.getAllPackagePictures();
pkgpictures.addAll(getAllPictures());
for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
if(poixmlDocumentPart instanceof XWPFHeaderFooter){
pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
}
}
return pkgpictures;
} }
/** /**
@ -234,61 +230,76 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
* @param format The format of the picture. * @param format The format of the picture.
* *
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . * @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 { public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
int imageNumber = getNextPicNameNumber(format); {
XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true); XWPFPictureData xwpfPicData = document.findPackagePictureData(pictureData, format);
OutputStream out = img.getPackagePart().getOutputStream(); POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
IOUtils.copy(is, out);
out.close();
pictures.add(img);
return getAllPictures().size()-1;
if (xwpfPicData == null)
{
/* Part doesn't exist, create a new one */
int idx = document.getNextPicNameNumber(format);
xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
/* write bytes to new part */
PackagePart picDataPart = xwpfPicData.getPackagePart();
OutputStream out = null;
try {
out = picDataPart.getOutputStream();
out.write(pictureData);
} catch (IOException e) {
throw new POIXMLException(e);
} finally {
try {
out.close();
} catch (IOException e) {
// ignore
}
}
document.registerPackagePictureData(xwpfPicData);
pictures.add(xwpfPicData);
return getRelationId(xwpfPicData);
}
else if (!getRelations().contains(xwpfPicData))
{
/*
* Part already existed, but was not related so far. Create
* relationship to the already existing part and update
* POIXMLDocumentPart data.
*/
PackagePart picDataPart = xwpfPicData.getPackagePart();
// TODO add support for TargetMode.EXTERNAL relations.
TargetMode targetMode = TargetMode.INTERNAL;
PackagePartName partName = picDataPart.getPartName();
String relation = relDesc.getRelation();
PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
String id = relShip.getId();
addRelation(id,xwpfPicData);
pictures.add(xwpfPicData);
return id;
}
else
{
/* Part already existed, get relation id and return it */
return getRelationId(xwpfPicData);
}
} }
/** /**
* Adds a picture to the document. * Adds a picture to the document.
* *
* @param pictureData The picture bytes * @param is The stream to read image from
* @param format The format of the picture. * @param format The format of the picture.
* *
* @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} . * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
* @throws InvalidFormatException
* @throws IOException
*/ */
public int addPicture(byte[] pictureData, int format) { public String addPictureData(InputStream is, int format) throws InvalidFormatException,IOException {
int imageNumber = getNextPicNameNumber(format); byte[] data = IOUtils.toByteArray(is);
XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); return addPictureData(data,format);
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 the next free ImageNumber
*/
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;
} }
/** /**
@ -298,63 +309,13 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
* @throws Exception * @throws Exception
*/ */
public XWPFPictureData getPictureDataByID(String blipID) { public XWPFPictureData getPictureDataByID(String blipID) {
for(POIXMLDocumentPart part: getRelations()){ POIXMLDocumentPart relatedPart = getRelationById(blipID);
if(part.getPackageRelationship() != null){ if (relatedPart != null && relatedPart instanceof XWPFPictureData) {
if(part.getPackageRelationship().getId() != null){ return (XWPFPictureData) relatedPart;
if(part.getPackageRelationship().getId().equals(blipID)){
return (XWPFPictureData)part;
}
}
}
} }
return null; return null;
} }
/**
* Add the picture to drawing relations
*
* @param pictureData the picture bytes
* @param format the picture format
*/
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 is the stream to read picture data from
*/
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 * add a new paragraph at position of the cursor
* @param cursor * @param cursor
@ -505,7 +466,6 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
} }
} }
cursor.dispose(); cursor.dispose();
getAllPictures();
} }
/** /**
@ -545,4 +505,12 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
return (XWPFDocument)getParent(); return (XWPFDocument)getParent();
} }
} }
/**
* 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()
*/
public POIXMLDocumentPart getPart() {
return this;
}
}//end class }//end class

View File

@ -44,10 +44,11 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
* *
*/ */
public class XWPFNumbering extends POIXMLDocumentPart { public class XWPFNumbering extends POIXMLDocumentPart {
protected List<XWPFAbstractNum> abstractNums = new ArrayList<XWPFAbstractNum>();
protected List<XWPFNum> nums = new ArrayList<XWPFNum>();
private CTNumbering ctNumbering; private CTNumbering ctNumbering;
protected List<XWPFAbstractNum> abstractNums; boolean isNew;
protected List<XWPFNum> nums;
protected boolean isNew;
/** /**
*create a new styles object with an existing document *create a new styles object with an existing document
@ -55,7 +56,6 @@ public class XWPFNumbering extends POIXMLDocumentPart {
public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{ public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
super(part, rel); super(part, rel);
isNew = true; isNew = true;
onDocumentRead();
} }
/** /**
@ -72,8 +72,6 @@ public class XWPFNumbering extends POIXMLDocumentPart {
*/ */
@Override @Override
protected void onDocumentRead() throws IOException{ protected void onDocumentRead() throws IOException{
abstractNums = new ArrayList<XWPFAbstractNum>();
nums = new ArrayList<XWPFNum>();
NumberingDocument numberingDoc = null; NumberingDocument numberingDoc = null;
InputStream is; InputStream is;
is = getPackagePart().getInputStream(); is = getPackagePart().getInputStream();
@ -100,7 +98,7 @@ public class XWPFNumbering extends POIXMLDocumentPart {
protected void commit() throws IOException { protected void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering")); xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering"));
Map map = new HashMap(); Map<String,String> map = new HashMap<String,String>();
map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve"); map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
map.put("urn:schemas-microsoft-com:office:office", "o"); 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/relationships", "r");

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
@ -50,11 +51,10 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
/** /**
* Sketch of XWPF paragraph class * Sketch of XWPF paragraph class
*/ */
public class XWPFParagraph implements IBodyElement{ public class XWPFParagraph implements IBodyElement {
private final CTP paragraph; private final CTP paragraph;
protected IBody part; protected IBody part;
/** For access to the document's hyperlink, comments, tables etc */ /** For access to the document's hyperlink, comments, tables etc */
@ -260,9 +260,9 @@ public class XWPFParagraph implements IBodyElement{
* @return a new text run * @return a new text run
*/ */
public XWPFRun createRun() { public XWPFRun createRun() {
XWPFRun run = new XWPFRun(paragraph.addNewR(), this); XWPFRun xwpfRun = new XWPFRun(paragraph.addNewR(), this);
runs.add(run); runs.add(xwpfRun);
return run; return xwpfRun;
} }
/** /**
@ -1241,11 +1241,17 @@ public class XWPFParagraph implements IBodyElement{
return BodyElementType.PARAGRAPH; return BodyElementType.PARAGRAPH;
} }
@Override
public IBody getBody()
{
return part;
}
/** /**
* returns the part of the bodyElement * returns the part of the bodyElement
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/ */
public IBody getPart() { public POIXMLDocumentPart getPart() {
if(part != null){ if(part != null){
return part.getPart(); return part.getPart();
} }
@ -1254,6 +1260,7 @@ public class XWPFParagraph implements IBodyElement{
/** /**
* returns the partType of the bodyPart which owns the bodyElement * returns the partType of the bodyPart which owns the bodyElement
*
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType() * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
*/ */
public BodyType getPartType() { public BodyType getPartType() {
@ -1262,24 +1269,29 @@ public class XWPFParagraph implements IBodyElement{
/** /**
* adds a new Run to the Paragraph * adds a new Run to the Paragraph
*
* @param r
* @return
*/ */
public void addRun(XWPFRun r){ public void addRun(XWPFRun r) {
if (!runs.contains(r)) {
runs.add(r); runs.add(r);
} }
}
/** /**
* return the XWPFRun-Element which owns the CTR run-Element * return the XWPFRun-Element which owns the CTR run-Element
*
* @param r
* @return
*/ */
public XWPFRun getRun(CTR r){ public XWPFRun getRun(CTR r) {
for(int i=0; i < getRuns().size(); i++){ for (int i = 0; i < getRuns().size(); i++) {
if(getRuns().get(i).getCTR() == r) return getRuns().get(i); if (getRuns().get(i).getCTR() == r) {
return getRuns().get(i);
}
} }
return null; return null;
} }
}//end class }//end class

View File

@ -25,16 +25,13 @@ import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
* @author Philipp Epp * @author Philipp Epp
*/ */
public class XWPFPicture { public class XWPFPicture {
protected XWPFParagraph paragraph;
private CTPicture ctPic; private CTPicture ctPic;
private String description; private String description;
private XWPFRun run;
public XWPFParagraph getParagraph(){ public XWPFPicture(CTPicture ctPic, XWPFRun run){
return paragraph; this.run = run;
}
public XWPFPicture(CTPicture ctPic, XWPFParagraph paragraph){
this.paragraph = paragraph;
this.ctPic = ctPic; this.ctPic = ctPic;
description = ctPic.getNvPicPr().getCNvPr().getDescr(); description = ctPic.getNvPicPr().getCNvPr().getDescr();
} }
@ -62,9 +59,12 @@ public class XWPFPicture {
*/ */
public XWPFPictureData getPictureData(){ public XWPFPictureData getPictureData(){
String blipId = ctPic.getBlipFill().getBlip().getEmbed(); String blipId = ctPic.getBlipFill().getBlip().getEmbed();
for(POIXMLDocumentPart part: ((POIXMLDocumentPart) paragraph.getPart()).getRelations()){ POIXMLDocumentPart part = run.getParagraph().getPart();
if(part.getPackageRelationship().getId().equals(blipId)){ if (part != null)
return (XWPFPictureData)part; {
POIXMLDocumentPart relatedPart = part.getRelationById(blipId);
if (relatedPart instanceof XWPFPictureData) {
return (XWPFPictureData) relatedPart;
} }
} }
return null; return null;

View File

@ -18,9 +18,13 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation; import org.apache.poi.POIXMLRelation;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
@ -32,7 +36,6 @@ import org.apache.poi.util.IOUtils;
/** /**
* @author Philipp Epp * @author Philipp Epp
*
*/ */
public class XWPFPictureData extends POIXMLDocumentPart { public class XWPFPictureData extends POIXMLDocumentPart {
@ -50,6 +53,9 @@ public class XWPFPictureData extends POIXMLDocumentPart {
RELATIONS[Document.PICTURE_TYPE_DIB] = XWPFRelation.IMAGE_DIB; RELATIONS[Document.PICTURE_TYPE_DIB] = XWPFRelation.IMAGE_DIB;
RELATIONS[Document.PICTURE_TYPE_GIF] = XWPFRelation.IMAGE_GIF; RELATIONS[Document.PICTURE_TYPE_GIF] = XWPFRelation.IMAGE_GIF;
} }
private Long checksum = null;
/** /**
* Create a new XWPFGraphicData node * Create a new XWPFGraphicData node
* *
@ -65,11 +71,15 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* @param rel the package relationship holding this drawing, * @param rel the package relationship holding this drawing,
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
*/ */
public XWPFPictureData(PackagePart part, PackageRelationship rel) { public XWPFPictureData(PackagePart part, PackageRelationship rel) {
super(part, rel); super(part, rel);
} }
@Override
protected void onDocumentRead() throws IOException {
super.onDocumentRead();
}
/** /**
* Gets the picture data as a byte array. * Gets the picture data as a byte array.
* <p> * <p>
@ -80,34 +90,30 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* InputStream is = getPackagePart().getInputStream(); * InputStream is = getPackagePart().getInputStream();
* </code> * </code>
* </p> * </p>
*
* @return the Picture data. * @return the Picture data.
*/ */
public byte[] getData() { public byte[] getData() {
try { try {
return IOUtils.toByteArray(getPackagePart().getInputStream()); return IOUtils.toByteArray(getPackagePart().getInputStream());
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block throw new POIXMLException(e);
e.printStackTrace();
} }
return null;
} }
/** /**
* Returns the file name of the image, eg image7.jpg . * Returns the file name of the image, eg image7.jpg . The original filename
* The original filename isn't always available, but if it * isn't always available, but if it can be found it's likely to be in the
* can be found it's likely to be in the CTDrawing * CTDrawing
*/ */
public String getFileName() { public String getFileName() {
String name = getPackagePart().getPartName().getName(); String name = getPackagePart().getPartName().getName();
if(name == null) if (name == null)
return null; return null;
return name.substring(name.lastIndexOf('/') + 1); return name.substring(name.lastIndexOf('/') + 1);
} }
/** /**
* Suggests a file extension for this image. * Suggests a file extension for this image.
*
* @return the file extension. * @return the file extension.
*/ */
public String suggestFileExtension() { public String suggestFileExtension() {
@ -125,15 +131,103 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
* @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB
*/ */
public int getPictureType(){ public int getPictureType() {
String contentType = getPackagePart().getContentType(); String contentType = getPackagePart().getContentType();
for (int i = 0; i < RELATIONS.length; i++) { for (int i = 0; i < RELATIONS.length; i++) {
if(RELATIONS[i] == null) continue; if (RELATIONS[i] == null) {
continue;
}
if(RELATIONS[i].getContentType().equals(contentType)){ if (RELATIONS[i].getContentType().equals(contentType)) {
return i; return i;
} }
} }
return 0; return 0;
} }
public Long getChecksum() {
if (this.checksum == null) {
InputStream is = null;
byte[] data;
try {
is = getPackagePart().getInputStream();
data = IOUtils.toByteArray(is);
} catch (IOException e) {
throw new POIXMLException(e);
} finally {
try {
is.close();
} catch (IOException e) {
throw new POIXMLException(e);
}
}
this.checksum = IOUtils.calculateChecksum(data);
}
return this.checksum;
}
@Override
public boolean equals(Object obj) {
/**
* In case two objects ARE equal, but its not the same instance, this
* implementation will always run through the whole
* byte-array-comparison before returning true. If this will turn into a
* performance issue, two possible approaches are available:<br>
* a) Use the checksum only and take the risk that two images might have
* the same CRC32 sum, although they are not the same.<br>
* b) Use a second (or third) checksum algorithm to minimise the chance
* that two images have the same checksums but are not equal (e.g.
* CRC32, MD5 and SHA-1 checksums, additionally compare the
* data-byte-array lengths).
*/
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof XWPFPictureData)) {
return false;
}
XWPFPictureData picData = (XWPFPictureData) obj;
PackagePart foreignPackagePart = picData.getPackagePart();
PackagePart ownPackagePart = this.getPackagePart();
if ((foreignPackagePart != null && ownPackagePart == null)
|| (foreignPackagePart == null && ownPackagePart != null)) {
return false;
}
if (ownPackagePart != null) {
OPCPackage foreignPackage = foreignPackagePart.getPackage();
OPCPackage ownPackage = ownPackagePart.getPackage();
if ((foreignPackage != null && ownPackage == null)
|| (foreignPackage == null && ownPackage != null)) {
return false;
}
if (ownPackage != null) {
if (!ownPackage.equals(foreignPackage)) {
return false;
}
}
}
Long foreignChecksum = picData.getChecksum();
Long localChecksum = getChecksum();
if (!(localChecksum.equals(foreignChecksum))) {
return false;
}
return Arrays.equals(this.getData(), picData.getData());
}
@Override
public int hashCode() {
return getChecksum().hashCode();
}
} }

View File

@ -45,6 +45,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
@ -88,14 +89,33 @@ public class XWPFRun {
this.run = r; this.run = r;
this.paragraph = p; this.paragraph = p;
/**
* reserve already occupied drawing ids, so reserving new ids later will
* not corrupt the document
*/
List<CTDrawing> drawingList = r.getDrawingList();
for (CTDrawing ctDrawing : drawingList) {
List<CTAnchor> anchorList = ctDrawing.getAnchorList();
for (CTAnchor anchor : anchorList) {
if (anchor.getDocPr() != null) {
getDocument().getDrawingIdManager().reserve(anchor.getDocPr().getId());
}
}
List<CTInline> inlineList = ctDrawing.getInlineList();
for (CTInline inline : inlineList) {
if (inline.getDocPr() != null) {
getDocument().getDrawingIdManager().reserve(inline.getDocPr().getId());
}
}
}
// Look for any text in any of our pictures or drawings // Look for any text in any of our pictures or drawings
StringBuffer text = new StringBuffer(); StringBuffer text = new StringBuffer();
List<XmlObject> pictTextObjs = new ArrayList<XmlObject>(); List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();
pictTextObjs.addAll(r.getPictList()); pictTextObjs.addAll(r.getPictList());
pictTextObjs.addAll(r.getDrawingList()); pictTextObjs.addAll(drawingList);
for(XmlObject o : pictTextObjs) { for(XmlObject o : pictTextObjs) {
XmlObject[] t = o XmlObject[] t = o.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
for (int m = 0; m < t.length; m++) { for (int m = 0; m < t.length; m++) {
NodeList kids = t[m].getDomNode().getChildNodes(); NodeList kids = t[m].getDomNode().getChildNodes();
for (int n = 0; n < kids.getLength(); n++) { for (int n = 0; n < kids.getLength(); n++) {
@ -114,7 +134,7 @@ public class XWPFRun {
pictures = new ArrayList<XWPFPicture>(); pictures = new ArrayList<XWPFPicture>();
for(XmlObject o : pictTextObjs) { for(XmlObject o : pictTextObjs) {
for(CTPicture pict : getCTPictures(o)) { for(CTPicture pict : getCTPictures(o)) {
XWPFPicture picture = new XWPFPicture( pict, p ); XWPFPicture picture = new XWPFPicture(pict, this);
pictures.add(picture); pictures.add(picture);
} }
} }
@ -156,6 +176,17 @@ public class XWPFRun {
return paragraph; return paragraph;
} }
/**
* @return The {@link XWPFDocument} instance, this run belongs to, or
* <code>null</code> if parent structure (paragraph > document) is not properly set.
*/
public XWPFDocument getDocument() {
if (paragraph != null) {
return paragraph.getDocument();
}
return null;
}
/** /**
* For isBold, isItalic etc * For isBold, isItalic etc
*/ */
@ -177,8 +208,9 @@ public class XWPFRun {
*/ */
public boolean isBold() { public boolean isBold() {
CTRPr pr = run.getRPr(); CTRPr pr = run.getRPr();
if(pr == null || !pr.isSetB()) if(pr == null || !pr.isSetB()) {
return false; return false;
}
return isCTOnOff(pr.getB()); return isCTOnOff(pr.getB());
} }
@ -251,7 +283,6 @@ public class XWPFRun {
preserveSpaces(t); preserveSpaces(t);
} }
/** /**
* Whether the italic property should be applied to all non-complex script * Whether the italic property should be applied to all non-complex script
* characters in the contents of this run when displayed in a document. * characters in the contents of this run when displayed in a document.
@ -384,8 +415,7 @@ public class XWPFRun {
*/ */
public VerticalAlign getSubscript() { public VerticalAlign getSubscript() {
CTRPr pr = run.getRPr(); CTRPr pr = run.getRPr();
return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr.getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE;
.getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE;
} }
/** /**
@ -546,7 +576,6 @@ public class XWPFRun {
br.setType(STBrType.Enum.forInt(type.getValue())); br.setType(STBrType.Enum.forInt(type.getValue()));
} }
/** /**
* Specifies that a break shall be placed at the current location in the run * Specifies that a break shall be placed at the current location in the run
* content. A break is a special character which is used to override the * content. A break is a special character which is used to override the
@ -607,8 +636,8 @@ public class XWPFRun {
XWPFDocument doc = paragraph.document; XWPFDocument doc = paragraph.document;
// Add the picture + relationship // Add the picture + relationship
int picNumber = doc.addPicture(pictureData, pictureType); String relationId = doc.addPictureData(pictureData, pictureType);
XWPFPictureData picData = doc.getAllPackagePictures().get(picNumber); XWPFPictureData picData = (XWPFPictureData) doc.getRelationById(relationId);
// Create the drawing entry for it // Create the drawing entry for it
try { try {
@ -632,8 +661,10 @@ public class XWPFRun {
inline.setDistL(0); inline.setDistL(0);
CTNonVisualDrawingProps docPr = inline.addNewDocPr(); CTNonVisualDrawingProps docPr = inline.addNewDocPr();
docPr.setId(picNumber); long id = getParagraph().document.getDrawingIdManager().reserveNew();
docPr.setName("Picture " + picNumber); docPr.setId(id);
/* This name is not visible in Word 2010 anywhere. */
docPr.setName("Drawing " + id);
docPr.setDescr(filename); docPr.setDescr(filename);
CTPositiveSize2D extent = inline.addNewExtent(); CTPositiveSize2D extent = inline.addNewExtent();
@ -649,8 +680,10 @@ public class XWPFRun {
CTPictureNonVisual nvPicPr = pic.addNewNvPicPr(); CTPictureNonVisual nvPicPr = pic.addNewNvPicPr();
CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr(); CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr();
cNvPr.setId(picNumber); /* use "0" for the id. See ECM-576, 20.2.2.3 */
cNvPr.setName("Picture " + picNumber); cNvPr.setId(0L);
/* This name is not visible in Word 2010 anywhere */
cNvPr.setName("Picture " + id);
cNvPr.setDescr(filename); cNvPr.setDescr(filename);
CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr(); CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr();
@ -677,7 +710,7 @@ public class XWPFRun {
prstGeom.addNewAvLst(); prstGeom.addNewAvLst();
// Finish up // Finish up
XWPFPicture xwpfPicture = new XWPFPicture(pic, paragraph); XWPFPicture xwpfPicture = new XWPFPicture(pic, this);
pictures.add(xwpfPicture); pictures.add(xwpfPicture);
return xwpfPicture; return xwpfPicture;
} catch(XmlException e) { } catch(XmlException e) {

View File

@ -42,7 +42,6 @@ public class XWPFSettings extends POIXMLDocumentPart {
public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException { public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException {
super(part, rel); super(part, rel);
readFrom(part.getInputStream());
} }
public XWPFSettings() { public XWPFSettings() {
@ -50,6 +49,13 @@ public class XWPFSettings extends POIXMLDocumentPart {
ctSettings = CTSettings.Factory.newInstance(); ctSettings = CTSettings.Factory.newInstance();
} }
@Override
protected void onDocumentRead() throws IOException
{
super.onDocumentRead();
readFrom(getPackagePart().getInputStream());
}
/** /**
* Set zoom.<br/> * Set zoom.<br/>
* In the zoom tag inside settings.xml file <br/> * In the zoom tag inside settings.xml file <br/>

View File

@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.lang.String;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
@ -49,9 +48,10 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;
* *
*/ */
public class XWPFStyles extends POIXMLDocumentPart{ public class XWPFStyles extends POIXMLDocumentPart{
private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();
private CTStyles ctStyles; private CTStyles ctStyles;
protected XWPFLatentStyles latentStyles; XWPFLatentStyles latentStyles;
protected List<XWPFStyle> listStyle;
/** /**
* Construct XWPFStyles from a package part * Construct XWPFStyles from a package part
@ -62,14 +62,12 @@ public class XWPFStyles extends POIXMLDocumentPart{
public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{ public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
super(part, rel); super(part, rel);
onDocumentRead();
} }
/** /**
* Construct XWPFStyles from scratch for a new document. * Construct XWPFStyles from scratch for a new document.
*/ */
public XWPFStyles() { public XWPFStyles() {
listStyle = new ArrayList<XWPFStyle>();
} }
/** /**
@ -77,7 +75,6 @@ public class XWPFStyles extends POIXMLDocumentPart{
*/ */
@Override @Override
protected void onDocumentRead ()throws IOException{ protected void onDocumentRead ()throws IOException{
listStyle = new ArrayList<XWPFStyle>();
StylesDocument stylesDoc; StylesDocument stylesDoc;
try { try {
InputStream is = getPackagePart().getInputStream(); InputStream is = getPackagePart().getInputStream();
@ -98,7 +95,7 @@ public class XWPFStyles extends POIXMLDocumentPart{
protected void commit() throws IOException { protected void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles")); xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
Map map = new HashMap(); Map<String,String> map = new HashMap<String,String>();
map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r"); map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w"); map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
xmlOptions.setSaveSuggestedPrefixes(map); xmlOptions.setSaveSuggestedPrefixes(map);

View File

@ -20,6 +20,7 @@ import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
@ -58,7 +59,6 @@ public class XWPFTable implements IBodyElement{
} }
} }
public XWPFTable(CTTbl table, IBody part){ public XWPFTable(CTTbl table, IBody part){
this.part = part; this.part = part;
this.ctTbl = table; this.ctTbl = table;
@ -131,17 +131,17 @@ public class XWPFTable implements IBodyElement{
return text.toString(); return text.toString();
} }
public void addNewRowBetween(int start, int end) { public void addNewRowBetween(int start, int end) {
// TODO // TODO
} }
/** /**
* add a new column for each row in this table * add a new column for each row in this table
*/ */
public void addNewCol() { public void addNewCol() {
if (ctTbl.sizeOfTrArray() == 0) createRow(); if (ctTbl.sizeOfTrArray() == 0) {
createRow();
}
for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) { for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) {
XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this); XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this);
tabRow.createCell(); tabRow.createCell();
@ -268,7 +268,7 @@ public class XWPFTable implements IBodyElement{
* @param pos position the Row in the Table * @param pos position the Row in the Table
*/ */
public boolean removeRow(int pos) throws IndexOutOfBoundsException { public boolean removeRow(int pos) throws IndexOutOfBoundsException {
if(pos > 0 && pos < tableRows.size()){ if (pos >= 0 && pos < tableRows.size()) {
ctTbl.removeTr(pos); ctTbl.removeTr(pos);
tableRows.remove(pos); tableRows.remove(pos);
return true; return true;
@ -289,25 +289,29 @@ public class XWPFTable implements IBodyElement{
return BodyElementType.TABLE; return BodyElementType.TABLE;
} }
@Override
public IBody getBody()
{
return part;
}
/** /**
* returns the part of the bodyElement * returns the part of the bodyElement
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/ */
public IBody getPart() { public POIXMLDocumentPart getPart() {
if(part != null){ if(part != null){
return part.getPart(); return part.getPart();
} }
return null; return null;
} }
/** /**
* returns the partType of the bodyPart which owns the bodyElement * returns the partType of the bodyPart which owns the bodyElement
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType() * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
*/ */
public BodyType getPartType() { public BodyType getPartType() {
return ((IBody)part).getPartType(); return part.getPartType();
} }
/** /**

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
@ -248,14 +249,12 @@ public class XWPFTableCell implements IBody {
return null; return null;
} }
/** /**
* get the to which the TableCell belongs * get the to which the TableCell belongs
*
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/ */
public IBody getPart() { public POIXMLDocumentPart getPart() {
return tableRow.getTable().getPart(); return tableRow.getTable().getPart();
} }

View File

@ -52,7 +52,7 @@ public class XWPFTableRow {
* @return the newly created XWPFTableCell * @return the newly created XWPFTableCell
*/ */
public XWPFTableCell createCell() { public XWPFTableCell createCell() {
XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getPart()); XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody());
tableCells.add(tableCell); tableCells.add(tableCell);
return tableCell; return tableCell;
} }
@ -69,7 +69,7 @@ public class XWPFTableRow {
*/ */
public XWPFTableCell addNewTableCell(){ public XWPFTableCell addNewTableCell(){
CTTc cell = ctRow.addNewTc(); CTTc cell = ctRow.addNewTc();
XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getPart()); XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody());
tableCells.add(tableCell); tableCells.add(tableCell);
return tableCell; return tableCell;
} }
@ -123,7 +123,7 @@ public class XWPFTableRow {
if(tableCells == null){ if(tableCells == null){
List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>(); List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
for (CTTc tableCell : ctRow.getTcList()) { for (CTTc tableCell : ctRow.getTcList()) {
cells.add(new XWPFTableCell(tableCell, this, table.getPart())); cells.add(new XWPFTableCell(tableCell, this, table.getBody()));
} }
this.tableCells = cells; this.tableCells = cells;
} }

View File

@ -141,4 +141,15 @@ public final class TestPOIXMLDocument extends TestCase {
PackageHelper.open(POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx")) PackageHelper.open(POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx"))
); );
} }
public void testRelationOrder() throws Exception {
OPCPackage pkg = PackageHelper.open(POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx"));
OPCParser doc = new OPCParser(pkg);
doc.parse(new TestFactory());
for(POIXMLDocumentPart rel : doc.getRelations()){
System.out.println(rel);
}
}
} }

View File

@ -0,0 +1,144 @@
/* ====================================================================
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;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import junit.framework.TestCase;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.util.TempFile;
import org.apache.poi.util.PackageHelper;
/**
* Test recursive read and write of OPC packages
*/
public final class TestPOIXMLDocumentPart extends TestCase {
private static class OPCParser extends POIXMLDocument {
public OPCParser(OPCPackage pkg) {
super(pkg);
}
public List<PackagePart> getAllEmbedds() {
throw new RuntimeException("not supported");
}
public void parse(POIXMLFactory factory) throws IOException{
load(factory);
}
}
private static final class TestFactory extends POIXMLFactory {
public TestFactory() {
//
}
public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){
return new POIXMLDocumentPart(part, rel);
}
public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
throw new RuntimeException("not supported");
}
}
/**
* Recursively traverse a OOXML document and assert that same logical parts have the same physical instances
*/
private static void traverse(POIXMLDocumentPart part, HashMap<String,POIXMLDocumentPart> context) throws IOException{
context.put(part.getPackageRelationship().getTargetURI().toString(), part);
for(POIXMLDocumentPart p : part.getRelations()){
String uri = p.getPackageRelationship().getTargetURI().toString();
if (!context.containsKey(uri)) {
traverse(p, context);
} else {
POIXMLDocumentPart prev = context.get(uri);
assertSame("Duplicate POIXMLDocumentPart instance for targetURI=" + uri, prev, p);
}
}
}
public void assertReadWrite(OPCPackage pkg1) throws Exception {
OPCParser doc = new OPCParser(pkg1);
doc.parse(new TestFactory());
HashMap<String,POIXMLDocumentPart> context = new HashMap<String,POIXMLDocumentPart>();
traverse(doc, context);
context.clear();
File tmp = TempFile.createTempFile("poi-ooxml", ".tmp");
FileOutputStream out = new FileOutputStream(tmp);
doc.write(out);
out.close();
OPCPackage pkg2 = OPCPackage.open(tmp.getAbsolutePath());
doc = new OPCParser(pkg1);
doc.parse(new TestFactory());
context = new HashMap<String,POIXMLDocumentPart>();
traverse(doc, context);
context.clear();
assertEquals(pkg1.getRelationships().size(), pkg2.getRelationships().size());
ArrayList<PackagePart> l1 = pkg1.getParts();
ArrayList<PackagePart> l2 = pkg2.getParts();
assertEquals(l1.size(), l2.size());
for (int i=0; i < l1.size(); i++){
PackagePart p1 = l1.get(i);
PackagePart p2 = l2.get(i);
assertEquals(p1.getContentType(), p2.getContentType());
assertEquals(p1.hasRelationships(), p2.hasRelationships());
if(p1.hasRelationships()){
assertEquals(p1.getRelationships().size(), p2.getRelationships().size());
}
assertEquals(p1.getPartName(), p2.getPartName());
}
}
public void testPPTX() throws Exception {
assertReadWrite(
PackageHelper.open(POIDataSamples.getSlideShowInstance().openResourceAsStream("PPTWithAttachments.pptm"))
);
}
public void testXLSX() throws Exception {
assertReadWrite(
PackageHelper.open(POIDataSamples.getSpreadSheetInstance().openResourceAsStream("ExcelWithAttachments.xlsm"))
);
}
public void testDOCX() throws Exception {
assertReadWrite(
PackageHelper.open(POIDataSamples.getDocumentInstance().openResourceAsStream("WordWithAttachments.docx"))
);
}
}

View File

@ -17,16 +17,21 @@
package org.apache.poi; package org.apache.poi;
import java.util.*; import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.POIXMLProperties.CoreProperties;
import org.apache.poi.openxml4j.util.Nullable;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.openxml4j.util.Nullable;
/** /**
* Test setting extended and custom OOXML properties * Test setting extended and custom OOXML properties
@ -35,7 +40,7 @@ public final class TestPOIXMLProperties extends TestCase {
private POIXMLProperties _props; private POIXMLProperties _props;
private CoreProperties _coreProperties; private CoreProperties _coreProperties;
public void setUp() { public void setUp() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx");
_props = sampleDoc.getProperties(); _props = sampleDoc.getProperties();
_coreProperties = _props.getCoreProperties(); _coreProperties = _props.getCoreProperties();
@ -152,7 +157,7 @@ public final class TestPOIXMLProperties extends TestCase {
assertEquals("Hello World", title); assertEquals("Hello World", title);
} }
public void testTransitiveSetters() { public void testTransitiveSetters() throws IOException {
XWPFDocument doc = new XWPFDocument(); XWPFDocument doc = new XWPFDocument();
CoreProperties cp = doc.getProperties().getCoreProperties(); CoreProperties cp = doc.getProperties().getCoreProperties();

View File

@ -25,8 +25,8 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URI; import java.net.URI;
import java.util.TreeMap; import java.util.*;
import java.util.Iterator; import java.util.regex.Pattern;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -509,4 +509,23 @@ public final class TestPackage extends TestCase {
f.setAccessible(true); f.setAccessible(true);
return (ContentTypeManager)f.get(pkg); return (ContentTypeManager)f.get(pkg);
} }
public void testGetPartsByName() throws Exception {
String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ_WRITE);
List<PackagePart> rs = pkg.getPartsByName(Pattern.compile("/word/.*?\\.xml"));
HashMap<String, PackagePart> selected = new HashMap<String, PackagePart>();
for(PackagePart p : rs)
selected.put(p.getPartName().getName(), p);
assertEquals(6, selected.size());
assertTrue(selected.containsKey("/word/document.xml"));
assertTrue(selected.containsKey("/word/fontTable.xml"));
assertTrue(selected.containsKey("/word/settings.xml"));
assertTrue(selected.containsKey("/word/styles.xml"));
assertTrue(selected.containsKey("/word/theme/theme1.xml"));
assertTrue(selected.containsKey("/word/webSettings.xml"));
}
} }

View File

@ -0,0 +1,113 @@
package org.apache.poi.util;
import junit.framework.TestCase;
public class TestIdentifierManager extends TestCase
{
public void testBasic()
{
IdentifierManager manager = new IdentifierManager(0L,100L);
assertEquals(101L,manager.getRemainingIdentifiers());
assertEquals(0L,manager.reserveNew());
assertEquals(100L,manager.getRemainingIdentifiers());
assertEquals(1L,manager.reserve(0L));
assertEquals(99L,manager.getRemainingIdentifiers());
}
public void testLongLimits()
{
long min = IdentifierManager.MIN_ID;
long max = IdentifierManager.MAX_ID;
IdentifierManager manager = new IdentifierManager(min,max);
assertTrue("Limits lead to a long variable overflow", max - min + 1 > 0);
assertTrue("Limits lead to a long variable overflow", manager.getRemainingIdentifiers() > 0);
assertEquals(min,manager.reserveNew());
assertEquals(max,manager.reserve(max));
assertEquals(max - min -1, manager.getRemainingIdentifiers());
manager.release(max);
manager.release(min);
}
public void testReserve()
{
IdentifierManager manager = new IdentifierManager(10L,30L);
assertEquals(12L,manager.reserve(12L));
long reserve = manager.reserve(12L);
assertFalse("Same id must be reserved twice!",reserve == 12L);
assertTrue(manager.release(12L));
assertTrue(manager.release(reserve));
assertFalse(manager.release(12L));
assertFalse(manager.release(reserve));
manager = new IdentifierManager(0L,2L);
assertEquals(0L,manager.reserve(0L));
assertEquals(1L,manager.reserve(1L));
assertEquals(2L,manager.reserve(2L));
try
{
manager.reserve(0L);
fail("Exception expected");
}
catch(IllegalStateException e)
{
// expected
}
try
{
manager.reserve(1L);
fail("Exception expected");
}
catch(IllegalStateException e)
{
// expected
}
try
{
manager.reserve(2L);
fail("Exception expected");
}
catch(IllegalStateException e)
{
// expected
}
}
public void testReserveNew()
{
IdentifierManager manager = new IdentifierManager(10L,12L);
assertSame(10L,manager.reserveNew());
assertSame(11L,manager.reserveNew());
assertSame(12L,manager.reserveNew());
try {
manager.reserveNew();
fail("IllegalStateException expected");
}
catch (IllegalStateException e)
{
// expected
}
}
public void testRelease() {
IdentifierManager manager = new IdentifierManager(10L,20L);
assertEquals(10L,manager.reserve(10L));
assertEquals(11L,manager.reserve(11L));
assertEquals(12L,manager.reserve(12L));
assertEquals(13L,manager.reserve(13L));
assertEquals(14L,manager.reserve(14L));
assertTrue(manager.release(10L));
assertEquals(10L,manager.reserve(10L));
assertTrue(manager.release(10L));
assertTrue(manager.release(11L));
assertEquals(11L,manager.reserve(11L));
assertTrue(manager.release(11L));
assertFalse(manager.release(11L));
assertFalse(manager.release(10L));
assertEquals(10L,manager.reserve(10L));
assertEquals(11L,manager.reserve(11L));
assertTrue(manager.release(12L));
}
}

View File

@ -22,6 +22,7 @@ import junit.framework.TestSuite;
import org.apache.poi.xwpf.extractor.TestXWPFWordExtractor; import org.apache.poi.xwpf.extractor.TestXWPFWordExtractor;
import org.apache.poi.xwpf.model.TestXWPFHeaderFooterPolicy; import org.apache.poi.xwpf.model.TestXWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.TestXWPFDocument;
import org.apache.poi.xwpf.usermodel.TestXWPFHeader; import org.apache.poi.xwpf.usermodel.TestXWPFHeader;
import org.apache.poi.xwpf.usermodel.TestXWPFHeadings; import org.apache.poi.xwpf.usermodel.TestXWPFHeadings;
import org.apache.poi.xwpf.usermodel.TestXWPFNumbering; import org.apache.poi.xwpf.usermodel.TestXWPFNumbering;

View File

@ -17,6 +17,8 @@
package org.apache.poi.xwpf; package org.apache.poi.xwpf;
import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.POIXMLProperties.CoreProperties;
@ -41,7 +43,7 @@ import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.CTVect
* *
*/ */
public final class TestAllExtendedProperties extends TestCase { public final class TestAllExtendedProperties extends TestCase {
public void testGetAllExtendedProperties() { public void testGetAllExtendedProperties() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");
CTProperties ctProps = doc.getProperties().getExtendedProperties().getUnderlyingProperties(); CTProperties ctProps = doc.getProperties().getExtendedProperties().getUnderlyingProperties();
assertEquals("Microsoft Office Word",ctProps.getApplication()); assertEquals("Microsoft Office Word",ctProps.getApplication());

View File

@ -17,6 +17,8 @@
package org.apache.poi.xwpf; package org.apache.poi.xwpf;
import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.POIXMLProperties.CoreProperties;
@ -37,7 +39,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
* *
*/ */
public final class TestPackageCorePropertiesGetKeywords extends TestCase { public final class TestPackageCorePropertiesGetKeywords extends TestCase {
public void testGetSetKeywords() { public void testGetSetKeywords() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestPoiXMLDocumentCorePropertiesGetKeywords.docx");
String keywords = doc.getProperties().getCoreProperties().getKeywords(); String keywords = doc.getProperties().getCoreProperties().getKeywords();
assertEquals("extractor, test, rdf", keywords); assertEquals("extractor, test, rdf", keywords);

View File

@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.PackageHelper;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
/** /**
@ -29,23 +31,21 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
*/ */
public class XWPFTestDataSamples { public class XWPFTestDataSamples {
public static XWPFDocument openSampleDocument(String sampleName) { public static XWPFDocument openSampleDocument(String sampleName) throws IOException {
InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream(sampleName); InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream(sampleName);
try {
return new XWPFDocument(is); return new XWPFDocument(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
public static XWPFDocument writeOutAndReadBack(XWPFDocument doc) { public static XWPFDocument writeOutAndReadBack(XWPFDocument doc) throws IOException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
doc.write(baos); doc.write(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return new XWPFDocument(bais); return new XWPFDocument(bais);
} catch (IOException e) {
throw new RuntimeException(e);
} }
public static byte[] getImage(String filename) throws IOException {
InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream(filename);
byte[] result = IOUtils.toByteArray(is);
return result;
} }
} }

View File

@ -17,6 +17,8 @@
package org.apache.poi.xwpf.extractor; package org.apache.poi.xwpf.extractor;
import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.XWPFTestDataSamples;
@ -29,8 +31,9 @@ public class TestXWPFWordExtractor extends TestCase {
/** /**
* Get text out of the simple file * Get text out of the simple file
* @throws IOException
*/ */
public void testGetSimpleText() { public void testGetSimpleText() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -58,8 +61,9 @@ public class TestXWPFWordExtractor extends TestCase {
/** /**
* Tests getting the text out of a complex file * Tests getting the text out of a complex file
* @throws IOException
*/ */
public void testGetComplexText() { public void testGetComplexText() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -91,7 +95,7 @@ public class TestXWPFWordExtractor extends TestCase {
assertEquals(134, ps); assertEquals(134, ps);
} }
public void testGetWithHyperlinks() { public void testGetWithHyperlinks() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -116,7 +120,7 @@ public class TestXWPFWordExtractor extends TestCase {
); );
} }
public void testHeadersFooters() { public void testHeadersFooters() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ThreeColHeadFoot.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ThreeColHeadFoot.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -159,7 +163,7 @@ public class TestXWPFWordExtractor extends TestCase {
); );
} }
public void testFootnotes() { public void testFootnotes() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("footnotes.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("footnotes.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -167,14 +171,14 @@ public class TestXWPFWordExtractor extends TestCase {
} }
public void testTableFootnotes() { public void testTableFootnotes() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("table_footnotes.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("table_footnotes.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
assertTrue(extractor.getText().contains("snoska")); assertTrue(extractor.getText().contains("snoska"));
} }
public void testFormFootnotes() { public void testFormFootnotes() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("form_footnotes.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("form_footnotes.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -183,14 +187,14 @@ public class TestXWPFWordExtractor extends TestCase {
assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase")); assertTrue("Unable to find expected word in text\n" + text, text.contains("test phrase"));
} }
public void testEndnotes() { public void testEndnotes() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("endnotes.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("endnotes.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
assertTrue(extractor.getText().contains("XXX")); assertTrue(extractor.getText().contains("XXX"));
} }
public void testInsertedDeletedText() { public void testInsertedDeletedText() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("delins.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("delins.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -198,7 +202,7 @@ public class TestXWPFWordExtractor extends TestCase {
assertTrue(extractor.getText().contains("extremely well")); assertTrue(extractor.getText().contains("extremely well"));
} }
public void testParagraphHeader() { public void testParagraphHeader() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Headers.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Headers.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -210,8 +214,9 @@ public class TestXWPFWordExtractor extends TestCase {
/** /**
* Test that we can open and process .docm * Test that we can open and process .docm
* (macro enabled) docx files (bug #45690) * (macro enabled) docx files (bug #45690)
* @throws IOException
*/ */
public void testDOCMFiles() { public void testDOCMFiles() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("45690.docm"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("45690.docm");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -224,8 +229,9 @@ public class TestXWPFWordExtractor extends TestCase {
* Test that we handle things like tabs and * Test that we handle things like tabs and
* carriage returns properly in the text that * carriage returns properly in the text that
* we're extracting (bug #49189) * we're extracting (bug #49189)
* @throws IOException
*/ */
public void testDocTabs() { public void testDocTabs() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithTabs.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithTabs.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
@ -241,8 +247,9 @@ public class TestXWPFWordExtractor extends TestCase {
/** /**
* The output should not contain field codes, e.g. those specified in the * The output should not contain field codes, e.g. those specified in the
* w:instrText tag (spec sec. 17.16.23) * w:instrText tag (spec sec. 17.16.23)
* @throws IOException
*/ */
public void testNoFieldCodes() { public void testNoFieldCodes() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FieldCodes.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FieldCodes.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
String text = extractor.getText(); String text = extractor.getText();
@ -254,8 +261,9 @@ public class TestXWPFWordExtractor extends TestCase {
/** /**
* The output should contain the values of simple fields, those specified * The output should contain the values of simple fields, those specified
* with the fldSimple element (spec sec. 17.16.19) * with the fldSimple element (spec sec. 17.16.19)
* @throws IOException
*/ */
public void testFldSimpleContent() { public void testFldSimpleContent() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FldSimple.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("FldSimple.docx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc); XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
String text = extractor.getText(); String text = extractor.getText();

View File

@ -17,6 +17,8 @@
package org.apache.poi.xwpf.model; package org.apache.poi.xwpf.model;
import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.XWPFTestDataSamples;
@ -32,7 +34,7 @@ public class TestXWPFDecorators extends TestCase {
private XWPFDocument hyperlink; private XWPFDocument hyperlink;
private XWPFDocument comments; private XWPFDocument comments;
protected void setUp() { protected void setUp() throws IOException {
simple = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); simple = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
hyperlink = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); hyperlink = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
comments = XWPFTestDataSamples.openSampleDocument("WordWithAttachments.docx"); comments = XWPFTestDataSamples.openSampleDocument("WordWithAttachments.docx");

View File

@ -17,6 +17,8 @@
package org.apache.poi.xwpf.model; package org.apache.poi.xwpf.model;
import java.io.IOException;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.XWPFTestDataSamples;
@ -33,7 +35,7 @@ public class TestXWPFHeaderFooterPolicy extends TestCase {
private XWPFDocument oddEven; private XWPFDocument oddEven;
private XWPFDocument diffFirst; private XWPFDocument diffFirst;
protected void setUp() { protected void setUp() throws IOException {
noHeader = XWPFTestDataSamples.openSampleDocument("NoHeadFoot.docx"); noHeader = XWPFTestDataSamples.openSampleDocument("NoHeadFoot.docx");
header = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); header = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");

View File

@ -15,9 +15,11 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.xwpf; package org.apache.poi.xwpf.usermodel;
import java.util.ArrayList; import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -27,10 +29,11 @@ import org.apache.poi.POIXMLProperties;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.xwpf.usermodel.XWPFPictureData; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.xwpf.usermodel.XWPFRelation; import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
@ -70,7 +73,7 @@ public final class TestXWPFDocument extends TestCase {
assertNotNull(xml.getStyle()); assertNotNull(xml.getStyle());
} }
public void testMetadataBasics() { public void testMetadataBasics() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx"); XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertNotNull(xml.getProperties().getCoreProperties()); assertNotNull(xml.getProperties().getCoreProperties());
assertNotNull(xml.getProperties().getExtendedProperties()); assertNotNull(xml.getProperties().getExtendedProperties());
@ -83,7 +86,7 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue()); assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
} }
public void testMetadataComplex() { public void testMetadataComplex() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx"); XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
assertNotNull(xml.getProperties().getCoreProperties()); assertNotNull(xml.getProperties().getCoreProperties());
assertNotNull(xml.getProperties().getExtendedProperties()); assertNotNull(xml.getProperties().getExtendedProperties());
@ -103,7 +106,7 @@ public final class TestXWPFDocument extends TestCase {
assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication()); assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
} }
public void testAddParagraph(){ public void testAddParagraph() throws IOException{
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertEquals(3, doc.getParagraphs().size()); assertEquals(3, doc.getParagraphs().size());
@ -123,23 +126,21 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(5, doc.getParagraphs().size()); assertEquals(5, doc.getParagraphs().size());
} }
public void testAddPicture(){ public void testAddPicture() throws IOException, InvalidFormatException
{
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
byte[] jpeg = "This is a jpeg".getBytes(); byte[] jpeg = XWPFTestDataSamples.getImage("nature1.jpg");
try { String relationId = doc.addPictureData(jpeg,XWPFDocument.PICTURE_TYPE_JPEG);
int jpegNum = doc.addPicture(jpeg, XWPFDocument.PICTURE_TYPE_JPEG);
byte[] newJpeg = doc.getAllPictures().get(jpegNum).getData(); byte[] newJpeg = ((XWPFPictureData) doc.getRelationById(relationId)).getData();
assertEquals(newJpeg.length, jpeg.length); assertEquals(newJpeg.length,jpeg.length);
for(int i = 0 ; i < jpeg.length; i++){ for (int i = 0 ; i < jpeg.length ; i++)
assertEquals(newJpeg[i], jpeg[i]); {
} assertEquals(newJpeg[i],jpeg[i]);
} catch (InvalidFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }
public void testRemoveBodyElement() { public void testRemoveBodyElement() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertEquals(3, doc.getParagraphs().size()); assertEquals(3, doc.getParagraphs().size());
assertEquals(3, doc.getBodyElements().size()); assertEquals(3, doc.getBodyElements().size());
@ -200,46 +201,119 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(p3, doc.getParagraphs().get(0)); assertEquals(p3, doc.getParagraphs().get(0));
} }
public void testSettings() throws Exception { public void testRegisterPackagePictureData() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithGIF.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
assertEquals(120, doc.getZoomPercent());
assertEquals(false, doc.isEnforcedCommentsProtection());
assertEquals(false, doc.isEnforcedFillingFormsProtection());
assertEquals(false, doc.isEnforcedReadonlyProtection());
assertEquals(false, doc.isEnforcedTrackedChangesProtection());
doc.setZoomPercent(124); /* manually assemble a new image package part*/
OPCPackage opcPckg = doc.getPackage();
XWPFRelation jpgRelation = XWPFRelation.IMAGE_JPEG;
PackagePartName partName = PackagingURIHelper.createPartName(jpgRelation.getDefaultFileName().replace('#', '2'));
PackagePart newImagePart = opcPckg.createPart(partName, jpgRelation.getContentType());
byte[] nature1 = XWPFTestDataSamples.getImage("abstract4.jpg");
OutputStream os = newImagePart.getOutputStream();
os.write(nature1);
os.close();
XWPFHeader xwpfHeader = doc.getHeaderList().get(0);
PackageRelationship relationship = xwpfHeader.getPackagePart().addRelationship(partName, TargetMode.INTERNAL, jpgRelation.getRelation());
XWPFPictureData newPicData = new XWPFPictureData(newImagePart,relationship);
/* new part is now ready to rumble */
// Only one enforcement allowed, last one wins! assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
doc.enforceFillingFormsProtection(); assertFalse(doc.getAllPictures().contains(newPicData));
doc.enforceReadonlyProtection(); assertFalse(doc.getAllPackagePictures().contains(newPicData));
doc = XWPFTestDataSamples.writeOutAndReadBack(doc); doc.registerPackagePictureData(newPicData);
assertEquals(124, doc.getZoomPercent()); assertFalse(xwpfHeader.getAllPictures().contains(newPicData));
assertEquals(false, doc.isEnforcedCommentsProtection()); assertFalse(doc.getAllPictures().contains(newPicData));
assertEquals(false, doc.isEnforcedFillingFormsProtection()); assertTrue(doc.getAllPackagePictures().contains(newPicData));
assertEquals(true, doc.isEnforcedReadonlyProtection());
assertEquals(false, doc.isEnforcedTrackedChangesProtection()); doc.getPackage().revert();
} }
public void testGIFSupport() throws Exception { public void testFindPackagePictureData() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("WithGIF.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
ArrayList<PackagePart> gifParts = doc.getPackage().getPartsByContentType(XWPFRelation.IMAGE_GIF.getContentType()); byte[] nature1 = XWPFTestDataSamples.getImage("nature1.gif");
assertEquals("Expected exactly one GIF part in package.",1,gifParts.size()); XWPFPictureData part = doc.findPackagePictureData(nature1, Document.PICTURE_TYPE_GIF);
PackagePart gifPart = gifParts.get(0); assertNotNull(part);
assertTrue(doc.getAllPictures().contains(part));
assertTrue(doc.getAllPackagePictures().contains(part));
doc.getPackage().revert();
}
List<POIXMLDocumentPart> relations = doc.getRelations(); public void testGetAllPictures() throws IOException {
POIXMLDocumentPart gifDocPart = null; XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
for (POIXMLDocumentPart docPart : relations) List<XWPFPictureData> allPictures = doc.getAllPictures();
{ List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
if (gifPart == docPart.getPackagePart())
{ assertNotNull(allPictures);
assertNull("More than one POIXMLDocumentPart for GIF PackagePart.",gifDocPart); assertEquals(3,allPictures.size());
gifDocPart = docPart; for (XWPFPictureData xwpfPictureData : allPictures) {
assertTrue(allPackagePictures.contains(xwpfPictureData));
} }
try {
allPictures.add(allPictures.get(0));
fail("This list must be unmodifiable!");
} catch (UnsupportedOperationException e) {
// all ok
} }
assertNotNull("GIF part not related to document.xml PackagePart",gifDocPart);
assertTrue("XWPFRelation for GIF image was not recognized properly, as the POIXMLDocumentPart created was of a wrong type.",XWPFRelation.IMAGE_GIF.getRelationClass().isInstance(gifDocPart)); doc.getPackage().revert();
}
public void testGetAllPackagePictures() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
assertNotNull(allPackagePictures);
assertEquals(5,allPackagePictures.size());
try {
allPackagePictures.add(allPackagePictures.get(0));
fail("This list must be unmodifiable!");
} catch (UnsupportedOperationException e) {
// all ok
}
doc.getPackage().revert();
}
public void testPictureHandlingSimpleFile() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
assertEquals(1,doc.getAllPackagePictures().size());
byte[] newPic = XWPFTestDataSamples.getImage("abstract4.jpg");
String id1 = doc.addPictureData(newPic, Document.PICTURE_TYPE_JPEG);
assertEquals(2,doc.getAllPackagePictures().size());
/* copy data, to avoid instance-equality */
byte[] newPicCopy = Arrays.copyOf(newPic, newPic.length);
String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG);
assertEquals(id1,id2);
doc.getPackage().revert();
}
public void testPictureHandlingHeaderDocumentImages() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx");
assertEquals(1,doc.getAllPictures().size());
assertEquals(1,doc.getAllPackagePictures().size());
assertEquals(1,doc.getHeaderList().get(0).getAllPictures().size());
doc.getPackage().revert();
}
public void testPictureHandlingComplex() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
XWPFHeader xwpfHeader = doc.getHeaderList().get(0);
assertEquals(3,doc.getAllPictures().size());
assertEquals(3,xwpfHeader.getAllPictures().size());
assertEquals(5,doc.getAllPackagePictures().size());
byte[] nature1 = XWPFTestDataSamples.getImage("nature1.jpg");
String id = doc.addPictureData(nature1, Document.PICTURE_TYPE_JPEG);
POIXMLDocumentPart part1 = xwpfHeader.getRelationById("rId1");
XWPFPictureData part2 = (XWPFPictureData) doc.getRelationById(id);
assertSame(part1,part2);
doc.getPackage().revert();
} }
} }

View File

@ -29,7 +29,7 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
public final class TestXWPFHeader extends TestCase { public final class TestXWPFHeader extends TestCase {
public void testSimpleHeader() { public void testSimpleHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerFooter.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerFooter.docx");
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
@ -40,7 +40,7 @@ public final class TestXWPFHeader extends TestCase {
assertNotNull(footer); assertNotNull(footer);
} }
public void testImageInHeader() { public void testImageInHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
@ -122,7 +122,7 @@ public final class TestXWPFHeader extends TestCase {
assertEquals("Second paragraph for the footer", paras[1].getText()); assertEquals("Second paragraph for the footer", paras[1].getText());
} }
public void testSetWatermark() { public void testSetWatermark() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
// no header is set (yet) // no header is set (yet)
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
@ -136,4 +136,20 @@ public final class TestXWPFHeader extends TestCase {
assertNotNull(policy.getFirstPageHeader()); assertNotNull(policy.getFirstPageHeader());
assertNotNull(policy.getEvenPageHeader()); assertNotNull(policy.getEvenPageHeader());
} }
public void testAddPictureData() {
}
public void testGetAllPictures() {
}
public void testGetAllPackagePictures() {
}
public void testGetPictureDataById() {
}
} }

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -25,7 +26,7 @@ import org.apache.poi.xwpf.XWPFTestDataSamples;
public class TestXWPFNumbering extends TestCase { public class TestXWPFNumbering extends TestCase {
public void testCompareAbstractNum(){ public void testCompareAbstractNum() throws IOException{
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
XWPFNumbering numbering = doc.getNumbering(); XWPFNumbering numbering = doc.getNumbering();
BigInteger numId = BigInteger.valueOf(1); BigInteger numId = BigInteger.valueOf(1);

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.List; import java.util.List;
@ -49,8 +50,9 @@ public final class TestXWPFParagraph extends TestCase {
/** /**
* Check that we get the right paragraph from the header * Check that we get the right paragraph from the header
* @throws IOException
*/ */
public void disabled_testHeaderParagraph() { public void disabled_testHeaderParagraph() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader(); XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader();
@ -67,8 +69,9 @@ public final class TestXWPFParagraph extends TestCase {
/** /**
* Check that we get the right paragraphs from the document * Check that we get the right paragraphs from the document
* @throws IOException
*/ */
public void disabled_testDocumentParagraph() { public void disabled_testDocumentParagraph() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx"); XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
List<XWPFParagraph> ps = xml.getParagraphs(); List<XWPFParagraph> ps = xml.getParagraphs();
assertEquals(10, ps.size()); assertEquals(10, ps.size());
@ -231,7 +234,7 @@ public final class TestXWPFParagraph extends TestCase {
assertEquals(STOnOff.TRUE, ppr.getPageBreakBefore().getVal()); assertEquals(STOnOff.TRUE, ppr.getPageBreakBefore().getVal());
} }
public void testBookmarks() { public void testBookmarks() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx");
XWPFParagraph paragraph = doc.getParagraphs().get(0); XWPFParagraph paragraph = doc.getParagraphs().get(0);
assertEquals("Sample Word Document", paragraph.getText()); assertEquals("Sample Word Document", paragraph.getText());

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -29,98 +30,103 @@ import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
public class TestXWPFPictureData extends TestCase { public class TestXWPFPictureData extends TestCase {
public void testRead(){
public void testRead() throws InvalidFormatException, IOException
{
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
List<XWPFPictureData> pictures = sampleDoc.getAllPictures(); List<XWPFPictureData> pictures = sampleDoc.getAllPictures();
assertSame(pictures, sampleDoc.getAllPictures());
assertEquals(5, pictures.size()); assertEquals(5,pictures.size());
String[] ext = {"wmf", "png", "emf", "emf", "jpeg"}; String[] ext = {"wmf","png","emf","emf","jpeg"};
for (int i = 0; i < pictures.size(); i++) { for (int i = 0 ; i < pictures.size() ; i++)
assertEquals(ext[i], pictures.get(i).suggestFileExtension()); {
assertEquals(ext[i],pictures.get(i).suggestFileExtension());
} }
int num = pictures.size(); int num = pictures.size();
byte[] pictureData = {0xA, 0xB, 0XC, 0xD, 0xE, 0xF}; byte[] pictureData = XWPFTestDataSamples.getImage("nature1.jpg");
int idx; String relationId = sampleDoc.addPictureData(pictureData,XWPFDocument.PICTURE_TYPE_JPEG);
try { // picture list was updated
idx = sampleDoc.addPicture(pictureData, XWPFDocument.PICTURE_TYPE_JPEG); assertEquals(num + 1,pictures.size());
assertEquals(num + 1, pictures.size()); XWPFPictureData pict = (XWPFPictureData) sampleDoc.getRelationById(relationId);
//idx is 0-based index in the #pictures array assertEquals("jpeg",pict.suggestFileExtension());
assertEquals(pictures.size() - 1, idx); assertTrue(Arrays.equals(pictureData,pict.getData()));
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 testPictureInHeader() { public void testPictureInHeader() throws IOException
{
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
XWPFHeader header = policy.getDefaultHeader(); XWPFHeader header = policy.getDefaultHeader();
List<XWPFPictureData> pictures = header.getAllPictures(); List<XWPFPictureData> pictures = header.getAllPictures();
assertEquals(1, pictures.size()); assertEquals(1,pictures.size());
} }
public void testNew() throws Exception { public void testNew() throws InvalidFormatException, IOException
{
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx");
byte[] jpegData = "test jpeg data".getBytes(); byte[] jpegData = XWPFTestDataSamples.getImage("nature1.jpg");
byte[] wmfData = "test wmf data".getBytes(); byte[] gifData = XWPFTestDataSamples.getImage("nature1.gif");
byte[] pngData = "test png data".getBytes(); byte[] pngData = XWPFTestDataSamples.getImage("nature1.png");
List<XWPFPictureData> pictures = doc.getAllPictures(); List<XWPFPictureData> pictures = doc.getAllPictures();
assertEquals(0, pictures.size()); assertEquals(0,pictures.size());
// Document shouldn't have any image relationships // Document shouldn't have any image relationships
assertEquals(13, doc.getPackagePart().getRelationships().size()); assertEquals(13,doc.getPackagePart().getRelationships().size());
for(PackageRelationship rel : doc.getPackagePart().getRelationships()) { for (PackageRelationship rel : doc.getPackagePart().getRelationships())
if(rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation())) { {
if (rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation()))
{
fail("Shouldn't have JPEG yet"); fail("Shouldn't have JPEG yet");
} }
} }
// Add the image // Add the image
int jpegIdx; String relationId = doc.addPictureData(jpegData,XWPFDocument.PICTURE_TYPE_JPEG);
assertEquals(1,pictures.size());
jpegIdx = doc.addPicture(jpegData, XWPFDocument.PICTURE_TYPE_JPEG); XWPFPictureData jpgPicData = (XWPFPictureData) doc.getRelationById(relationId);
assertEquals(1, pictures.size()); assertEquals("jpeg",jpgPicData.suggestFileExtension());
assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); assertTrue(Arrays.equals(jpegData,jpgPicData.getData()));
assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData()));
// Ensure it now has one // Ensure it now has one
assertEquals(14, doc.getPackagePart().getRelationships().size()); assertEquals(14,doc.getPackagePart().getRelationships().size());
PackageRelationship jpegRel = null; PackageRelationship jpegRel = null;
for(PackageRelationship rel : doc.getPackagePart().getRelationships()) { for (PackageRelationship rel : doc.getPackagePart().getRelationships())
if(rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation())) { {
if(jpegRel != null) if (rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation()))
{
if (jpegRel != null)
fail("Found 2 jpegs!"); fail("Found 2 jpegs!");
jpegRel = rel; jpegRel = rel;
} }
} }
assertNotNull("JPEG Relationship not found", jpegRel); assertNotNull("JPEG Relationship not found",jpegRel);
// Check the details // Check the details
assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(), jpegRel.getRelationshipType()); assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(),jpegRel.getRelationshipType());
assertEquals("/word/document.xml", jpegRel.getSource().getPartName().toString()); assertEquals("/word/document.xml",jpegRel.getSource().getPartName().toString());
assertEquals("/word/media/image1.jpeg", jpegRel.getTargetURI().getPath()); assertEquals("/word/media/image1.jpeg",jpegRel.getTargetURI().getPath());
XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId()); XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId());
byte [] newJPEGData = pictureDataByID.getData(); byte[] newJPEGData = pictureDataByID.getData();
assertEquals(newJPEGData.length, jpegData.length); assertEquals(newJPEGData.length,jpegData.length);
for(int i = 0; i < newJPEGData.length; i++){ for (int i = 0 ; i < newJPEGData.length ; i++)
assertEquals(newJPEGData[i], jpegData[i]); {
assertEquals(newJPEGData[i],jpegData[i]);
} }
// Save an re-load, check it appears // Save an re-load, check it appears
doc = XWPFTestDataSamples.writeOutAndReadBack(doc); doc = XWPFTestDataSamples.writeOutAndReadBack(doc);
assertEquals(1, doc.getAllPictures().size()); assertEquals(1,doc.getAllPictures().size());
assertEquals(1, doc.getAllPackagePictures().size()); assertEquals(1,doc.getAllPackagePictures().size());
}
public void testGetChecksum() {
} }
} }

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.List; import java.util.List;
@ -198,8 +199,9 @@ public class TestXWPFRun extends TestCase {
/** /**
* Test that on an existing document, we do the * Test that on an existing document, we do the
* right thing with it * right thing with it
* @throws IOException
*/ */
public void testExisting() { public void testExisting() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx"); XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
XWPFParagraph p; XWPFParagraph p;
XWPFRun run; XWPFRun run;
@ -330,7 +332,7 @@ public class TestXWPFRun extends TestCase {
assertEquals(null, run.getCTR().getRPr()); assertEquals(null, run.getCTR().getRPr());
} }
public void testPictureInHeader() { public void testPictureInHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy(); XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();

View File

@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,7 +31,7 @@ public class TestXWPFStyles extends TestCase {
// super.setUp(); // super.setUp();
// } // }
public void testGetUsedStyles(){ public void testGetUsedStyles() throws IOException{
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx"); XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx");
List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>(); List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>();
XWPFStyles styles = sampleDoc.getStyles(); XWPFStyles styles = sampleDoc.getStyles();

BIN
test-data/document/abstract1.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
test-data/document/abstract2.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
test-data/document/abstract3.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
test-data/document/abstract4.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test-data/document/nature1.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

BIN
test-data/document/nature1.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
test-data/document/nature1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
test-data/document/nature2.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
test-data/document/nature3.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
test-data/document/nature4.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB