Help for bug #44840 - Improved handling of HSSFObjectData, especially for entries with data held not in POIFS
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@659575 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6eb311672a
commit
bdf210f9ee
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.1-final" date="2008-06-??">
|
<release version="3.1-final" date="2008-06-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add">44840 - Improved handling of HSSFObjectData, especially for entries with data held not in POIFS</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">45043 - Support for getting excel cell comments when extracting text</action>
|
<action dev="POI-DEVELOPERS" type="add">45043 - Support for getting excel cell comments when extracting text</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level</action>
|
<action dev="POI-DEVELOPERS" type="add">Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">45025 - improved FormulaParser parse error messages</action>
|
<action dev="POI-DEVELOPERS" type="fix">45025 - improved FormulaParser parse error messages</action>
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.1-final" date="2008-06-??">
|
<release version="3.1-final" date="2008-06-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add">44840 - Improved handling of HSSFObjectData, especially for entries with data held not in POIFS</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">45043 - Support for getting excel cell comments when extracting text</action>
|
<action dev="POI-DEVELOPERS" type="add">45043 - Support for getting excel cell comments when extracting text</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level</action>
|
<action dev="POI-DEVELOPERS" type="add">Extend the support for specifying a policy to HSSF on missing / blank cells when fetching, to be able to specify the policy at the HSSFWorkbook level</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">45025 - improved FormulaParser parse error messages</action>
|
<action dev="POI-DEVELOPERS" type="fix">45025 - improved FormulaParser parse error messages</action>
|
||||||
|
@ -108,7 +108,10 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
in.readByte(); // discard
|
in.readByte(); // discard
|
||||||
}
|
}
|
||||||
|
|
||||||
field_6_stream_id = in.readInt();
|
// Fetch the stream ID
|
||||||
|
field_6_stream_id = in.readInt();
|
||||||
|
|
||||||
|
// Store what's left
|
||||||
remainingBytes = in.readRemainder();
|
remainingBytes = in.readRemainder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,36 +55,72 @@ public class HSSFObjectData
|
|||||||
this.record = record;
|
this.record = record;
|
||||||
this.poifs = poifs;
|
this.poifs = poifs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the OLE2 Class Name of the object
|
||||||
|
*/
|
||||||
|
public String getOLE2ClassName() {
|
||||||
|
EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
|
||||||
|
return subRecord.field_5_ole_classname;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the object data.
|
* Gets the object data. Only call for ones that have
|
||||||
|
* data though. See {@link #hasDirectoryEntry()}
|
||||||
*
|
*
|
||||||
* @return the object data as an OLE2 directory.
|
* @return the object data as an OLE2 directory.
|
||||||
* @throws IOException if there was an error reading the data.
|
* @throws IOException if there was an error reading the data.
|
||||||
*/
|
*/
|
||||||
public DirectoryEntry getDirectory() throws IOException
|
public DirectoryEntry getDirectory() throws IOException {
|
||||||
{
|
EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
|
||||||
Iterator subRecordIter = record.getSubRecords().iterator();
|
|
||||||
while (subRecordIter.hasNext())
|
|
||||||
{
|
|
||||||
Object subRecord = subRecordIter.next();
|
|
||||||
if (subRecord instanceof EmbeddedObjectRefSubRecord)
|
|
||||||
{
|
|
||||||
int streamId = ((EmbeddedObjectRefSubRecord) subRecord).getStreamId();
|
|
||||||
String streamName = "MBD" + HexDump.toHex(streamId);
|
|
||||||
|
|
||||||
Entry entry = poifs.getRoot().getEntry(streamName);
|
int streamId = ((EmbeddedObjectRefSubRecord) subRecord).getStreamId();
|
||||||
if (entry instanceof DirectoryEntry)
|
String streamName = "MBD" + HexDump.toHex(streamId);
|
||||||
{
|
|
||||||
return (DirectoryEntry) entry;
|
Entry entry = poifs.getRoot().getEntry(streamName);
|
||||||
}
|
if (entry instanceof DirectoryEntry) {
|
||||||
else
|
return (DirectoryEntry) entry;
|
||||||
{
|
} else {
|
||||||
throw new IOException("Stream " + streamName + " was not an OLE2 directory");
|
throw new IOException("Stream " + streamName + " was not an OLE2 directory");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data portion, for an ObjectData
|
||||||
|
* that doesn't have an associated POIFS Directory
|
||||||
|
* Entry
|
||||||
|
*/
|
||||||
|
public byte[] getObjectData() {
|
||||||
|
EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
|
||||||
|
return subRecord.remainingBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this ObjectData have an associated POIFS
|
||||||
|
* Directory Entry?
|
||||||
|
* (Not all do, those that don't have a data portion)
|
||||||
|
*/
|
||||||
|
public boolean hasDirectoryEntry() {
|
||||||
|
EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
|
||||||
|
|
||||||
|
// Field 6 tells you
|
||||||
|
return (subRecord.field_6_stream_id != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the EmbeddedObjectRefSubRecord, or throws an
|
||||||
|
* Exception if there wasn't one
|
||||||
|
*/
|
||||||
|
protected EmbeddedObjectRefSubRecord findObjectRecord() {
|
||||||
|
Iterator subRecordIter = record.getSubRecords().iterator();
|
||||||
|
|
||||||
|
while (subRecordIter.hasNext()) {
|
||||||
|
Object subRecord = subRecordIter.next();
|
||||||
|
if (subRecord instanceof EmbeddedObjectRefSubRecord) {
|
||||||
|
return (EmbeddedObjectRefSubRecord)subRecord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalStateException("Object data does not contain a reference to an embedded object OLE2 directory");
|
throw new IllegalStateException("Object data does not contain a reference to an embedded object OLE2 directory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,17 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
||||||
import org.apache.poi.hssf.util.Region;
|
import org.apache.poi.hssf.util.Region;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.util.TempFile;
|
||||||
|
|
||||||
@ -950,4 +953,40 @@ public final class TestBugs extends TestCase {
|
|||||||
writeOutAndReadBack(wb);
|
writeOutAndReadBack(wb);
|
||||||
assertTrue("no errors writing sample xls", true);
|
assertTrue("no errors writing sample xls", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Problems with extracting check boxes from
|
||||||
|
* HSSFObjectData
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void test44840() throws Exception {
|
||||||
|
HSSFWorkbook wb = openSample("WithCheckBoxes.xls");
|
||||||
|
|
||||||
|
// Take a look at the embeded objects
|
||||||
|
List objects = wb.getAllEmbeddedObjects();
|
||||||
|
assertEquals(1, objects.size());
|
||||||
|
|
||||||
|
HSSFObjectData obj = (HSSFObjectData)objects.get(0);
|
||||||
|
assertNotNull(obj);
|
||||||
|
|
||||||
|
// Peek inside the underlying record
|
||||||
|
EmbeddedObjectRefSubRecord rec = obj.findObjectRecord();
|
||||||
|
assertNotNull(rec);
|
||||||
|
|
||||||
|
assertEquals(32, rec.field_1_stream_id_offset);
|
||||||
|
assertEquals(0, rec.field_6_stream_id); // WRONG!
|
||||||
|
assertEquals("Forms.CheckBox.1", rec.field_5_ole_classname);
|
||||||
|
assertEquals(12, rec.remainingBytes.length);
|
||||||
|
|
||||||
|
// Doesn't have a directory
|
||||||
|
assertFalse(obj.hasDirectoryEntry());
|
||||||
|
assertNotNull(obj.getObjectData());
|
||||||
|
assertEquals(12, obj.getObjectData().length);
|
||||||
|
assertEquals("Forms.CheckBox.1", obj.getOLE2ClassName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
obj.getDirectory();
|
||||||
|
fail();
|
||||||
|
} catch(FileNotFoundException e) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user