improved API for OOXML custom properties
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@821496 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a6ced5bc25
commit
bee594dc5e
@ -47,23 +47,14 @@ public class WorkbookProperties {
|
||||
ext.getUnderlyingProperties().setTemplate("XSSF");
|
||||
|
||||
/**
|
||||
* Custom properties enable users to define custom metadata properties
|
||||
* through a set of well-defined data types. For example, a custom
|
||||
* OLE Editor property of type string can be defined as follows:
|
||||
*
|
||||
* <property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="Editor">
|
||||
* <vt:lpwstr>John Smith</vt:lpwstr>
|
||||
* </property>
|
||||
* Custom properties enable users to define custom metadata properties.
|
||||
*/
|
||||
|
||||
POIXMLProperties.CustomProperties cust = props.getCustomProperties();
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
|
||||
property = cust.getUnderlyingProperties().addNewProperty();
|
||||
|
||||
property.setFmtid("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
|
||||
property.setPid(2);
|
||||
property.setName("Editor");
|
||||
property.setLpwstr("John Smith");
|
||||
cust.addProperty("Author", "John Smith");
|
||||
cust.addProperty("Year", 2009);
|
||||
cust.addProperty("Price", 45.50);
|
||||
cust.addProperty("Available", true);
|
||||
|
||||
FileOutputStream out = new FileOutputStream("workbook.xlsx");
|
||||
workbook.write(out);
|
||||
|
@ -34,6 +34,7 @@ import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.util.Nullable;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
|
||||
|
||||
/**
|
||||
* Wrapper around the two different kinds of OOXML properties
|
||||
@ -150,8 +151,14 @@ public class POIXMLProperties {
|
||||
out.close();
|
||||
}
|
||||
if(custPart != null){
|
||||
XmlOptions xmlOptions = new XmlOptions(POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt");
|
||||
xmlOptions.setSaveSuggestedPrefixes(map);
|
||||
|
||||
OutputStream out = custPart.getOutputStream();
|
||||
cust.props.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
|
||||
cust.props.save(out, xmlOptions);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@ -274,6 +281,12 @@ public class POIXMLProperties {
|
||||
* Custom document properties
|
||||
*/
|
||||
public class CustomProperties {
|
||||
/**
|
||||
* Each custom property element contains an fmtid attribute
|
||||
* with the same GUID value ({D5CDD505-2E9C-101B-9397-08002B2CF9AE}).
|
||||
*/
|
||||
public static final String FORMAT_ID = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";
|
||||
|
||||
private org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props;
|
||||
private CustomProperties(org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props) {
|
||||
this.props = props;
|
||||
@ -282,5 +295,91 @@ public class POIXMLProperties {
|
||||
public org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties getUnderlyingProperties() {
|
||||
return props.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new property
|
||||
*
|
||||
* @param name the property name
|
||||
* @throws IllegalArgumentException if a property with this name already exists
|
||||
*/
|
||||
private CTProperty add(String name) {
|
||||
if(contains(name)) {
|
||||
throw new IllegalArgumentException("A property with this name " +
|
||||
"already exists in the custom properties");
|
||||
}
|
||||
|
||||
CTProperty p = props.getProperties().addNewProperty();
|
||||
int pid = nextPid();
|
||||
p.setPid(pid);
|
||||
p.setFmtid(FORMAT_ID);
|
||||
p.setName(name);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new string property
|
||||
*
|
||||
* @throws IllegalArgumentException if a property with this name already exists
|
||||
*/
|
||||
public void addProperty(String name, String value){
|
||||
CTProperty p = add(name);
|
||||
p.setLpwstr(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new double property
|
||||
*
|
||||
* @throws IllegalArgumentException if a property with this name already exists
|
||||
*/
|
||||
public void addProperty(String name, double value){
|
||||
CTProperty p = add(name);
|
||||
p.setR8(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new integer property
|
||||
*
|
||||
* @throws IllegalArgumentException if a property with this name already exists
|
||||
*/
|
||||
public void addProperty(String name, int value){
|
||||
CTProperty p = add(name);
|
||||
p.setI4(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new boolean property
|
||||
*
|
||||
* @throws IllegalArgumentException if a property with this name already exists
|
||||
*/
|
||||
public void addProperty(String name, boolean value){
|
||||
CTProperty p = add(name);
|
||||
p.setBool(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate next id that uniquely relates a custom property
|
||||
*
|
||||
* @return next property id starting with 2
|
||||
*/
|
||||
protected int nextPid(){
|
||||
int propid = 1;
|
||||
for(CTProperty p : props.getProperties().getPropertyArray()){
|
||||
if(p.getPid() > propid) propid = p.getPid();
|
||||
}
|
||||
return propid + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a property with this name already exists in the collection of custom properties
|
||||
*
|
||||
* @param name the name to check
|
||||
* @return whether a property with the given name exists in the custom properties
|
||||
*/
|
||||
public boolean contains(String name){
|
||||
for(CTProperty p : props.getProperties().getPropertyArray()){
|
||||
if(p.getName().equals(name)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xwpf.XWPFTestDataSamples;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties;
|
||||
|
||||
/**
|
||||
* Test setting extended and custom OOXML properties
|
||||
@ -85,66 +86,54 @@ public final class TestPOIXMLProperties extends TestCase {
|
||||
}
|
||||
|
||||
|
||||
public void testWorkbookCustomProperties() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
POIXMLProperties props = workbook.getProperties();
|
||||
assertNotNull(props);
|
||||
/**
|
||||
* Test usermodel API for setting custom properties
|
||||
*/
|
||||
public void testCustomProperties() {
|
||||
POIXMLDocument wb = new XSSFWorkbook();
|
||||
|
||||
org.apache.poi.POIXMLProperties.CustomProperties properties =
|
||||
props.getCustomProperties();
|
||||
POIXMLProperties.CustomProperties customProps = wb.getProperties().getCustomProperties();
|
||||
customProps.addProperty("test-1", "string val");
|
||||
customProps.addProperty("test-2", 1974);
|
||||
customProps.addProperty("test-3", 36.6);
|
||||
//adding a duplicate
|
||||
try {
|
||||
customProps.addProperty("test-3", 36.6);
|
||||
fail("expected exception");
|
||||
} catch(IllegalArgumentException e){
|
||||
assertEquals("A property with this name already exists in the custom properties", e.getMessage());
|
||||
}
|
||||
customProps.addProperty("test-4", true);
|
||||
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
|
||||
ctProps = properties.getUnderlyingProperties();
|
||||
wb = XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)wb);
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties ctProps =
|
||||
wb.getProperties().getCustomProperties().getUnderlyingProperties();
|
||||
assertEquals(4, ctProps.sizeOfPropertyArray());
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty p;
|
||||
|
||||
p = ctProps.getPropertyArray(0);
|
||||
assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
|
||||
assertEquals("test-1", p.getName());
|
||||
assertEquals("string val", p.getLpwstr());
|
||||
assertEquals(2, p.getPid());
|
||||
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
|
||||
property = ctProps.addNewProperty();
|
||||
|
||||
|
||||
String fmtid =
|
||||
"{A1A1A1A1A1A1A1A1-A1A1A1A1-A1A1A1A1-A1A1A1A1-A1A1A1A1A1A1A1A1}";
|
||||
int pId = 1;
|
||||
String name = "testProperty";
|
||||
String stringValue = "testValue";
|
||||
|
||||
|
||||
property.setFmtid(fmtid);
|
||||
property.setPid(pId);
|
||||
property.setName(name);
|
||||
property.setBstr(stringValue);
|
||||
|
||||
|
||||
property = null;
|
||||
ctProps = null;
|
||||
properties = null;
|
||||
props = null;
|
||||
|
||||
XSSFWorkbook newWorkbook =
|
||||
XSSFTestDataSamples.writeOutAndReadBack(workbook);
|
||||
|
||||
assertTrue(workbook != newWorkbook);
|
||||
|
||||
|
||||
POIXMLProperties newProps = newWorkbook.getProperties();
|
||||
assertNotNull(newProps);
|
||||
org.apache.poi.POIXMLProperties.CustomProperties newProperties =
|
||||
newProps.getCustomProperties();
|
||||
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
|
||||
newCtProps = newProperties.getUnderlyingProperties();
|
||||
|
||||
assertEquals(1, newCtProps.getPropertyArray().length);
|
||||
|
||||
|
||||
org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
|
||||
newpProperty = newCtProps.getPropertyArray()[0];
|
||||
|
||||
assertEquals(fmtid, newpProperty.getFmtid());
|
||||
assertEquals(pId, newpProperty.getPid());
|
||||
assertEquals(name, newpProperty.getName());
|
||||
assertEquals(stringValue, newpProperty.getBstr());
|
||||
p = ctProps.getPropertyArray(1);
|
||||
assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
|
||||
assertEquals("test-2", p.getName());
|
||||
assertEquals(1974, p.getI4());
|
||||
assertEquals(3, p.getPid());
|
||||
|
||||
p = ctProps.getPropertyArray(2);
|
||||
assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
|
||||
assertEquals("test-3", p.getName());
|
||||
assertEquals(36.6, p.getR8());
|
||||
assertEquals(4, p.getPid());
|
||||
|
||||
p = ctProps.getPropertyArray(3);
|
||||
assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
|
||||
assertEquals("test-4", p.getName());
|
||||
assertEquals(true, p.getBool());
|
||||
assertEquals(5, p.getPid());
|
||||
}
|
||||
|
||||
public void testDocumentProperties() {
|
||||
|
Loading…
Reference in New Issue
Block a user