<document>
<header>
<title>Busy Developers' Guide to HSSF and XSSF Features</title>
- <authors>
- <person email="user@poi.apache.org" name="Glen Stampoultzis" id="CO"/>
- <person email="user@poi.apache.org" name="Yegor Kozlov" id="YK"/>
- </authors>
</header>
<body>
<section><title>Busy Developers' Guide to Features</title>
<changes>
<release version="3.5-beta7" date="2009-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">46419 - Fixed compatibility issue with OpenOffice 3.0</action>
+ <action dev="POI-DEVELOPERS" type="fix">47559 - Fixed compatibility issue with Excel 2008 Max sp2</action>
<action dev="POI-DEVELOPERS" type="fix">47540 - Fix for saving custom and extended OOXML properties</action>
<action dev="POI-DEVELOPERS" type="fix">47535 - Fixed WordExtractor to tolerate files with empty footnote block</action>
<action dev="POI-DEVELOPERS" type="fix">47517 - Fixed ExtractorFactory to support .xltx and .dotx files</action>
/* Getters */
- public URI getContainerPartRelationship() {
+ public static URI getContainerPartRelationship() {
return containerRelationshipPart;
}
* The source part URI.
* @param targetURI
* The target part URI.
+ * @param msCompatible if true then remove leading slash from the relativized URI.
+ * This flag violates [M1.4]: A part name shall start with a forward slash ('/') character, but
+ * allows generating URIs compatible with MS Office and OpenOffice.
* @return A fully relativize part name URI ('word/media/image1.gif',
* '/word/document.xml' => 'media/image1.gif') else
* <code>null</code>.
*/
- public static URI relativizeURI(URI sourceURI, URI targetURI) {
+ public static URI relativizeURI(URI sourceURI, URI targetURI, boolean msCompatible) {
StringBuilder retVal = new StringBuilder();
String[] segmentsSource = sourceURI.getPath().split("/", -1);
String[] segmentsTarget = targetURI.getPath().split("/", -1);
// If the source is the root, then the relativized
// form must actually be an absolute URI
if(sourceURI.toString().equals("/")) {
+ String path = targetURI.getPath();
+ if(msCompatible && path.charAt(0) == '/') {
+ try {
+ targetURI = new URI(path.substring(1));
+ } catch (Exception e) {
+ System.err.println(e);
+ return null;
+ }
+ }
return targetURI;
}
}
}
- /**
+ /**
+ * Fully relativize the source part URI against the target part URI.
+ *
+ * @param sourceURI
+ * The source part URI.
+ * @param targetURI
+ * The target part URI.
+ * @return A fully relativize part name URI ('word/media/image1.gif',
+ * '/word/document.xml' => 'media/image1.gif') else
+ * <code>null</code>.
+ */
+ public static URI relativizeURI(URI sourceURI, URI targetURI) {
+ return relativizeURI(sourceURI, targetURI, false);
+ }
+
+ /**
* Resolve a source uri against a target.
*
* @param sourcePartUri
} else {
URI targetURI = rel.getTargetURI();
targetValue = PackagingURIHelper.relativizeURI(
- sourcePartURI, targetURI).getPath();
+ sourcePartURI, targetURI, true).getPath();
if (targetURI.getRawFragment() != null) {
targetValue += "#" + targetURI.getRawFragment();
}
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
+import org.apache.poi.POIXMLProperties;
import org.apache.poi.hssf.record.formula.SheetNameFormatter;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
bv.setActiveTab(0);
workbook.addNewSheets();
+ //required by Excel 2008 Mac sp2, see Bugzilla #47559
+ POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
+ expProps.getUnderlyingProperties().setApplication("Microsoft Excel");
+
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLProperties;
import org.apache.poi.util.PackageHelper;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.xmlbeans.XmlException;
ctDocument = CTDocument1.Factory.newInstance();
ctDocument.addNewBody();
+
+ POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
+ expProps.getUnderlyingProperties().setApplication("Microsoft Office Word");
}
/**
import java.lang.reflect.Field;
import java.net.URI;
import java.util.TreeMap;
+import java.util.Iterator;
import junit.framework.TestCase;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.util.TempFile;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.POILogger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
+import org.dom4j.io.SAXReader;
public final class TestPackage extends TestCase {
private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");
// Save and re-load
pkg.close();
File tmp = TempFile.createTempFile("testCreatePackageWithCoreDocument", ".zip");
- FileOutputStream fout = new FileOutputStream(tmp);
+ FileOutputStream fout = new FileOutputStream(tmp);
fout.write(baos.toByteArray());
fout.close();
pkg = OPCPackage.open(tmp.getPath());
//tmp.delete();
-
+
// Check still right
coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
assertEquals(1, coreRels.size());
coreRel = coreRels.getRelationship(0);
+
assertEquals("/", coreRel.getSourceURI().toString());
assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());
corePart = pkg.getPart(coreRel);
rel = rels.getRelationship(0);
assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment());
+ assertMSCompatibility(pkg);
+ }
+
+ private void assertMSCompatibility(OPCPackage pkg) throws Exception {
+ PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship());
+ PackagePart relPart = pkg.getPart(relName);
+ SAXReader reader = new SAXReader();
+ Document xmlRelationshipsDoc = reader
+ .read(relPart.getInputStream());
+
+ Element root = xmlRelationshipsDoc.getRootElement();
+ for (Iterator i = root
+ .elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i
+ .hasNext();) {
+ Element element = (Element) i.next();
+ String value = element.attribute(
+ PackageRelationship.TARGET_ATTRIBUTE_NAME)
+ .getValue();
+ assertTrue("Root target must not start with a leadng slash ('/'): " + value, value.charAt(0) != '/');
+ }
}
- /**
+ /**
* Test package opening.
*/
public void testOpenPackage() throws Exception {
/**
* Test relativizePartName() method.
- *
- * TODO: fix and unable
*/
public void testRelativizeURI() throws Exception {
URI uri1 = new URI("/word/document.xml");
URI retURI2 = PackagingURIHelper.relativizeURI(uri1, uri1);
assertEquals("", retURI2.getPath());
- // Document and root totally different
- URI uri4 = new URI("/");
- try {
- PackagingURIHelper.relativizeURI(uri1, uri4);
- //TODO: figure oout why the assertion fails
- //fail("Must throw an exception ! Can't relativize with an empty URI");
- } catch (Exception e) {
- // Do nothing
- }
- try {
- PackagingURIHelper.relativizeURI(uri4, uri1);
- //TODO: figure oout why the assertion fails
- //fail("Must throw an exception ! Can't relativize with an empty URI");
- } catch (Exception e) {
- // Do nothing
- }
- }
+ // relativization against root
+ URI root = new URI("/");
+ uriRes = PackagingURIHelper.relativizeURI(root, uri1);
+ assertEquals("/word/document.xml", uriRes.toString());
+
+ //URI compatible with MS Office and OpenOffice: leading slash is removed
+ uriRes = PackagingURIHelper.relativizeURI(root, uri1, true);
+ assertEquals("word/document.xml", uriRes.toString());
+ }
/**
* Test createPartName(String, y)
XSSFWorkbook workbook = new XSSFWorkbook();
POIXMLProperties props = workbook.getProperties();
assertNotNull(props);
+ //the Application property must be set for new workbooks, see Bugzilla #47559
+ assertEquals("Microsoft Excel", props.getExtendedProperties().getUnderlyingProperties().getApplication());
PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties();
assertNotNull(opcProps);
opcProps.setCreatorProperty("poi-dev@poi.apache.org");
workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
+ assertEquals("Microsoft Excel", workbook.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
opcProps = workbook.getProperties().getCoreProperties().getUnderlyingProperties();
assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue());
assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue());
import junit.framework.TestCase;
import org.apache.poi.POIXMLDocument;
+import org.apache.poi.POIXMLProperties;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
}
+
+ public void testWorkbookProperties() throws Exception {
+ XWPFDocument doc = new XWPFDocument();
+ POIXMLProperties props = doc.getProperties();
+ assertNotNull(props);
+ assertEquals("Microsoft Office Word", props.getExtendedProperties().getUnderlyingProperties().getApplication());
+ }
+
}