57482 Handle XSLX files with no shared strings table in read-only mode

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1653825 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2015-01-22 12:15:59 +00:00
parent 61e7dc447a
commit 0bd3a6df26
3 changed files with 41 additions and 4 deletions

View File

@ -44,6 +44,7 @@ import org.apache.poi.POIXMLProperties;
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;
import org.apache.poi.openxml4j.opc.PackageAccess;
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;
@ -343,17 +344,26 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
elIdMap.put(p.getPackageRelationship().getId(), (ExternalLinksTable)p); elIdMap.put(p.getPackageRelationship().getId(), (ExternalLinksTable)p);
} }
} }
boolean packageReadOnly = (getPackage().getPackageAccess() == PackageAccess.READ);
if (stylesSource == null) { if (stylesSource == null) {
// Create Styles if it is missing // Create Styles if it is missing
if (packageReadOnly) {
stylesSource = new StylesTable();
} else {
stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance()); stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());
} }
}
stylesSource.setTheme(theme); stylesSource.setTheme(theme);
if (sharedStringSource == null) { if (sharedStringSource == null) {
// Create SST if it is missing // Create SST if it is missing
if (packageReadOnly) {
sharedStringSource = new SharedStringsTable();
} else {
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance()); sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
} }
}
// Load individual sheets. The order of sheets is defined by the order // Load individual sheets. The order of sheets is defined by the order
// of CTSheet elements in the workbook // of CTSheet elements in the workbook

View File

@ -43,6 +43,7 @@ import org.apache.poi.POIXMLProperties;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
@ -2083,7 +2084,6 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
* A .xlsx file with no Shared Strings table should open fine * A .xlsx file with no Shared Strings table should open fine
* in read-only mode * in read-only mode
*/ */
@Ignore
@Test @Test
public void bug57482() throws Exception { public void bug57482() throws Exception {
for (PackageAccess access : new PackageAccess[] { for (PackageAccess access : new PackageAccess[] {
@ -2092,6 +2092,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
File file = HSSFTestDataSamples.getSampleFile("57482-OnlyNumeric.xlsx"); File file = HSSFTestDataSamples.getSampleFile("57482-OnlyNumeric.xlsx");
OPCPackage pkg = OPCPackage.open(file, access); OPCPackage pkg = OPCPackage.open(file, access);
try { try {
// Try to open it and read the contents
XSSFWorkbook wb = new XSSFWorkbook(pkg); XSSFWorkbook wb = new XSSFWorkbook(pkg);
assertNotNull(wb.getSharedStringSource()); assertNotNull(wb.getSharedStringSource());
assertEquals(0, wb.getSharedStringSource().getCount()); assertEquals(0, wb.getSharedStringSource().getCount());
@ -2101,8 +2102,34 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0))); assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0)));
assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1))); assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0))); assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0)));
// Add a text cell
s.getRow(0).createCell(3).setCellValue("Testing");
assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3)));
// Try to write-out and read again, should only work
// in read-write mode, not read-only mode
try {
wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
if (access == PackageAccess.READ)
fail("Shouln't be able to write from read-only mode");
} catch (InvalidOperationException e) {
if (access == PackageAccess.READ) {
// Expected
} else {
// Shouldn't occur in write-mode
throw e;
}
}
// Check again
s = wb.getSheetAt(0);
assertEquals("1", fmt.formatCellValue(s.getRow(0).getCell(0)));
assertEquals("11", fmt.formatCellValue(s.getRow(0).getCell(1)));
assertEquals("5", fmt.formatCellValue(s.getRow(4).getCell(0)));
assertEquals("Testing", fmt.formatCellValue(s.getRow(0).getCell(3)));
} finally { } finally {
pkg.close(); pkg.revert();
} }
} }
} }