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! -->
|
||||
<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">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>
|
||||
|
@ -34,6 +34,7 @@
|
||||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<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">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>
|
||||
|
@ -108,7 +108,10 @@ public class EmbeddedObjectRefSubRecord
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -55,36 +55,72 @@ public class HSSFObjectData
|
||||
this.record = record;
|
||||
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.
|
||||
* @throws IOException if there was an error reading the data.
|
||||
*/
|
||||
public DirectoryEntry getDirectory() throws IOException
|
||||
{
|
||||
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);
|
||||
public DirectoryEntry getDirectory() throws IOException {
|
||||
EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
|
||||
|
||||
Entry entry = poifs.getRoot().getEntry(streamName);
|
||||
if (entry instanceof DirectoryEntry)
|
||||
{
|
||||
return (DirectoryEntry) entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Stream " + streamName + " was not an OLE2 directory");
|
||||
}
|
||||
int streamId = ((EmbeddedObjectRefSubRecord) subRecord).getStreamId();
|
||||
String streamName = "MBD" + HexDump.toHex(streamId);
|
||||
|
||||
Entry entry = poifs.getRoot().getEntry(streamName);
|
||||
if (entry instanceof DirectoryEntry) {
|
||||
return (DirectoryEntry) entry;
|
||||
} else {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -18,14 +18,17 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
import org.apache.poi.util.TempFile;
|
||||
|
||||
@ -950,4 +953,40 @@ public final class TestBugs extends TestCase {
|
||||
writeOutAndReadBack(wb);
|
||||
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