#59717 POIXMLProperties helper methods for reading and changing OOXML document thumbnails
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1749528 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fdb7c7d1ff
commit
631ca92c16
@ -19,17 +19,20 @@ package org.apache.poi;
|
||||
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.ContentTypes;
|
||||
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.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.util.Nullable;
|
||||
@ -37,8 +40,9 @@ import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
|
||||
|
||||
/**
|
||||
* Wrapper around the two different kinds of OOXML properties
|
||||
* a document can have
|
||||
* Wrapper around the three different kinds of OOXML properties
|
||||
* and metadata a document can have (Core, Extended and Custom),
|
||||
* as well Thumbnails.
|
||||
*/
|
||||
public class POIXMLProperties {
|
||||
private OPCPackage pkg;
|
||||
@ -122,6 +126,69 @@ public class POIXMLProperties {
|
||||
return cust;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PackagePart} for the Document
|
||||
* Thumbnail, or <code>null</code> if there isn't one
|
||||
*
|
||||
* @return The Document Thumbnail part or null
|
||||
*/
|
||||
protected PackagePart getThumbnailPart() {
|
||||
PackageRelationshipCollection rels =
|
||||
pkg.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL);
|
||||
if(rels.size() == 1) {
|
||||
return pkg.getPart(rels.getRelationship(0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Returns the name of the Document thumbnail, eg
|
||||
* <code>thumbnail.jpeg</code>, or <code>null</code> if there
|
||||
* isn't one.
|
||||
*
|
||||
* @return The thumbnail filename, or null
|
||||
*/
|
||||
public String getThumbnailFilename() {
|
||||
PackagePart tPart = getThumbnailPart();
|
||||
if (tPart == null) return null;
|
||||
String name = tPart.getPartName().getName();
|
||||
return name.substring(name.lastIndexOf('/'));
|
||||
}
|
||||
/**
|
||||
* Returns the Document thumbnail image data, or
|
||||
* <code>null</code> if there isn't one.
|
||||
*
|
||||
* @return The thumbnail data, or null
|
||||
*/
|
||||
public InputStream getThumbnailImage() throws IOException {
|
||||
PackagePart tPart = getThumbnailPart();
|
||||
if (tPart == null) return null;
|
||||
return tPart.getInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Thumbnail for the document, replacing any existing
|
||||
* one.
|
||||
*
|
||||
* @param name The filename for the thumbnail image, eg <code>thumbnail.jpg</code>
|
||||
* @param imageData The inputstream to read the thumbnail image from
|
||||
*/
|
||||
public void setThumbnail(String filename, InputStream imageData) throws IOException {
|
||||
PackagePart tPart = getThumbnailPart();
|
||||
if (tPart == null) {
|
||||
// New thumbnail
|
||||
pkg.addThumbnail(filename, imageData);
|
||||
} else {
|
||||
// Change existing
|
||||
String newType = ContentTypes.getContentTypeFromFileExtension(filename);
|
||||
if (! newType.equals(tPart.getContentType())) {
|
||||
throw new IllegalArgumentException("Can't set a Thumbnail of type " +
|
||||
newType + " when existing one is of a different type " +
|
||||
tPart.getContentType());
|
||||
}
|
||||
StreamHelper.copyStream(imageData, tPart.getOutputStream());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit changes to the underlying OPC package
|
||||
*
|
||||
|
@ -474,18 +474,31 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
||||
* the addition of a thumbnail in a package. You can do the same work by
|
||||
* using the traditionnal relationship and part mechanism.
|
||||
*
|
||||
* @param path
|
||||
* The full path to the image file.
|
||||
* @param path The full path to the image file.
|
||||
*/
|
||||
public void addThumbnail(String path) throws IOException {
|
||||
// Check parameter
|
||||
if ("".equals(path)) {
|
||||
throw new IllegalArgumentException("path");
|
||||
}
|
||||
// Check parameter
|
||||
if (path == null || path.isEmpty()) {
|
||||
throw new IllegalArgumentException("path");
|
||||
}
|
||||
String name = path.substring(path.lastIndexOf(File.separatorChar) + 1);
|
||||
|
||||
// Get the filename from the path
|
||||
String filename = path
|
||||
.substring(path.lastIndexOf(File.separatorChar) + 1);
|
||||
FileInputStream is = new FileInputStream(path);
|
||||
addThumbnail(name, is);
|
||||
is.close();
|
||||
}
|
||||
/**
|
||||
* Add a thumbnail to the package. This method is provided to make easier
|
||||
* the addition of a thumbnail in a package. You can do the same work by
|
||||
* using the traditionnal relationship and part mechanism.
|
||||
*
|
||||
* @param path The full path to the image file.
|
||||
*/
|
||||
public void addThumbnail(String filename, InputStream data) throws IOException {
|
||||
// Check parameter
|
||||
if (filename == null || filename.isEmpty()) {
|
||||
throw new IllegalArgumentException("filename");
|
||||
}
|
||||
|
||||
// Create the thumbnail part name
|
||||
String contentType = ContentTypes
|
||||
@ -495,10 +508,10 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
||||
thumbnailPartName = PackagingURIHelper.createPartName("/docProps/"
|
||||
+ filename);
|
||||
} catch (InvalidFormatException e) {
|
||||
String partName = "/docProps/thumbnail" +
|
||||
filename.substring(filename.lastIndexOf(".") + 1);
|
||||
try {
|
||||
thumbnailPartName = PackagingURIHelper
|
||||
.createPartName("/docProps/thumbnail"
|
||||
+ path.substring(path.lastIndexOf(".") + 1));
|
||||
thumbnailPartName = PackagingURIHelper.createPartName(partName);
|
||||
} catch (InvalidFormatException e2) {
|
||||
throw new InvalidOperationException(
|
||||
"Can't add a thumbnail file named '" + filename + "'", e2);
|
||||
@ -519,10 +532,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
|
||||
PackageRelationshipTypes.THUMBNAIL);
|
||||
|
||||
// Copy file data to the newly created part
|
||||
FileInputStream is = new FileInputStream(path);
|
||||
StreamHelper.copyStream(is, thumbnailPart
|
||||
.getOutputStream());
|
||||
is.close();
|
||||
StreamHelper.copyStream(data, thumbnailPart.getOutputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,9 +19,11 @@ package org.apache.poi;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -42,12 +44,16 @@ import org.junit.Test;
|
||||
*/
|
||||
public final class TestPOIXMLProperties {
|
||||
private XWPFDocument sampleDoc;
|
||||
private XWPFDocument sampleNoThumb;
|
||||
private POIXMLProperties _props;
|
||||
private CoreProperties _coreProperties;
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx");
|
||||
sampleNoThumb = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
|
||||
assertNotNull(sampleDoc);
|
||||
assertNotNull(sampleNoThumb);
|
||||
_props = sampleDoc.getProperties();
|
||||
_coreProperties = _props.getCoreProperties();
|
||||
assertNotNull(_props);
|
||||
@ -56,6 +62,7 @@ public final class TestPOIXMLProperties {
|
||||
@After
|
||||
public void closeResources() throws Exception {
|
||||
sampleDoc.close();
|
||||
sampleNoThumb.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -215,6 +222,35 @@ public final class TestPOIXMLProperties {
|
||||
return utcString.equals(dateTimeUtcString);
|
||||
}
|
||||
|
||||
public void testThumbnails() throws Exception {
|
||||
POIXMLProperties noThumbProps = sampleNoThumb.getProperties();
|
||||
|
||||
assertNotNull(_props.getThumbnailPart());
|
||||
assertNull(noThumbProps.getThumbnailPart());
|
||||
|
||||
assertNotNull(_props.getThumbnailFilename());
|
||||
assertNull(noThumbProps.getThumbnailFilename());
|
||||
|
||||
assertNotNull(_props.getThumbnailImage());
|
||||
assertNull(noThumbProps.getThumbnailImage());
|
||||
|
||||
assertEquals("thumbnail.jpeg", _props.getThumbnailFilename());
|
||||
|
||||
|
||||
// Adding / changing
|
||||
noThumbProps.setThumbnail("Testing.png", new ByteArrayInputStream(new byte[1]));
|
||||
assertNotNull(noThumbProps.getThumbnailPart());
|
||||
assertEquals("Testing.png", noThumbProps.getThumbnailFilename());
|
||||
assertNotNull(noThumbProps.getThumbnailImage());
|
||||
assertEquals(1, noThumbProps.getThumbnailImage().available());
|
||||
|
||||
noThumbProps.setThumbnail("Testing2.png", new ByteArrayInputStream(new byte[2]));
|
||||
assertNotNull(noThumbProps.getThumbnailPart());
|
||||
assertEquals("Testing.png", noThumbProps.getThumbnailFilename());
|
||||
assertNotNull(noThumbProps.getThumbnailImage());
|
||||
assertEquals(2, noThumbProps.getThumbnailImage().available());
|
||||
}
|
||||
|
||||
private static String zeroPad(long i) {
|
||||
if (i >= 0 && i <=9) {
|
||||
return "0" + i;
|
||||
|
Loading…
Reference in New Issue
Block a user