fixed compatibility issues with OpenOffice 3.0 and Excel 2008 Mac sp2, see Bugzilla #46419 and #47559
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@797350 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
32d0c7213e
commit
0f1f7d1d48
@ -22,10 +22,6 @@
|
||||
<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>
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
<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>
|
||||
|
@ -136,7 +136,7 @@ public final class PackageRelationship {
|
||||
|
||||
/* Getters */
|
||||
|
||||
public URI getContainerPartRelationship() {
|
||||
public static URI getContainerPartRelationship() {
|
||||
return containerRelationshipPart;
|
||||
}
|
||||
|
||||
|
@ -259,11 +259,14 @@ public final class PackagingURIHelper {
|
||||
* 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);
|
||||
@ -283,6 +286,15 @@ public final class PackagingURIHelper {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -358,6 +370,21 @@ public final class PackagingURIHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -163,7 +163,7 @@ public final class ZipPartMarshaller implements PartMarshaller {
|
||||
} else {
|
||||
URI targetURI = rel.getTargetURI();
|
||||
targetValue = PackagingURIHelper.relativizeURI(
|
||||
sourcePartURI, targetURI).getPath();
|
||||
sourcePartURI, targetURI, true).getPath();
|
||||
if (targetURI.getRawFragment() != null) {
|
||||
targetValue += "#" + targetURI.getRawFragment();
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import javax.xml.namespace.QName;
|
||||
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;
|
||||
@ -228,6 +229,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
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());
|
||||
|
||||
|
@ -23,6 +23,7 @@ import java.util.*;
|
||||
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;
|
||||
@ -187,6 +188,9 @@ public class XWPFDocument extends POIXMLDocument {
|
||||
|
||||
ctDocument = CTDocument1.Factory.newInstance();
|
||||
ctDocument.addNewBody();
|
||||
|
||||
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
|
||||
expProps.getUnderlyingProperties().setApplication("Microsoft Office Word");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -36,11 +37,14 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
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");
|
||||
@ -195,6 +199,7 @@ public final class TestPackage extends TestCase {
|
||||
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);
|
||||
@ -205,6 +210,26 @@ public final class TestPackage extends TestCase {
|
||||
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) != '/');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,6 @@ public class TestPackagingURIHelper extends TestCase {
|
||||
|
||||
/**
|
||||
* Test relativizePartName() method.
|
||||
*
|
||||
* TODO: fix and unable
|
||||
*/
|
||||
public void testRelativizeURI() throws Exception {
|
||||
URI uri1 = new URI("/word/document.xml");
|
||||
@ -54,22 +52,14 @@ public class TestPackagingURIHelper extends TestCase {
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,6 +260,8 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
|
||||
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);
|
||||
@ -269,6 +271,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
|
||||
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());
|
||||
|
@ -21,6 +21,7 @@ import java.io.File;
|
||||
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;
|
||||
@ -119,4 +120,12 @@ public class TestXWPFDocument extends TestCase {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user