PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352845 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew C. Oliver 2002-09-16 18:14:31 +00:00
parent fb52b027c9
commit c530fb5920
7 changed files with 158 additions and 32 deletions

View File

@ -465,8 +465,8 @@ public int getShort (byte[] rec)
<td>-2</td>
</tr>
<tr>
<td>UK11</td>
<td>Unknown Constant</td>
<td>SBAT_Block_Count</td>
<td>Number of big blocks holding the SBAT</td>
<td>0x0040</td>
<td>Integer</td>
<td>1</td>

View File

@ -64,6 +64,10 @@ import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.util.POILogger;
import java.io.ByteArrayInputStream;
@ -72,6 +76,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
/**
* High level representation of a workbook. This is the first object most users
@ -117,6 +122,18 @@ public class HSSFWorkbook
*/
private ArrayList names;
/**
* holds whether or not to preserve other nodes in the POIFS. Used
* for macros and embedded objects.
*/
private boolean preserveNodes;
/**
* if you do preserve the nodes, you'll need to hold the whole POIFS in
* memory.
*/
private POIFSFileSystem poifs;
private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
@ -132,18 +149,31 @@ public class HSSFWorkbook
names = new ArrayList(INITIAL_CAPACITY);
}
public HSSFWorkbook(POIFSFileSystem fs) throws IOException {
this(fs,true);
}
/**
* given a POI POIFSFileSystem object, read in its Workbook and populate the high and
* low level models. If you're reading in a workbook...start here.
*
* @param fs the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
* @exception IOException if the stream cannot be read
*/
public HSSFWorkbook(POIFSFileSystem fs)
public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
throws IOException
{
this.preserveNodes = preserveNodes;
if (preserveNodes) {
this.poifs = fs;
}
sheets = new ArrayList(INITIAL_CAPACITY);
names = new ArrayList(INITIAL_CAPACITY);
@ -175,20 +205,27 @@ public class HSSFWorkbook
}
}
public HSSFWorkbook(InputStream s) throws IOException {
this(s,true);
}
/**
* Companion to HSSFWorkbook(POIFSFileSystem), this constructs the POI filesystem around your
* inputstream.
*
* @param s the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
* @see #HSSFWorkbook(POIFSFileSystem)
* @exception IOException if the stream cannot be read
*/
public HSSFWorkbook(InputStream s)
public HSSFWorkbook(InputStream s, boolean preserveNodes)
throws IOException
{
this((new POIFSFileSystem(s)));
this(new POIFSFileSystem(s), preserveNodes);
}
/**
@ -515,9 +552,16 @@ public class HSSFWorkbook
{
byte[] bytes = getBytes();
POIFSFileSystem fs = new POIFSFileSystem();
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
if (preserveNodes) {
List excepts = new ArrayList(1);
excepts.add("Workbook");
copyNodes(this.poifs,fs,excepts);
}
fs.writeFilesystem(stream);
//poifs.writeFilesystem(stream);
}
/**
@ -548,12 +592,12 @@ public class HSSFWorkbook
// sheetbytes.add((( HSSFSheet ) sheets.get(k)).getSheet().getSize());
totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize();
}
if (totalsize < 4096)
/* if (totalsize < 4096)
{
totalsize = 4096;
}
byte[] data = new byte[totalsize];
int pos = workbook.serialize(0, data);
}*/
byte[] retval = new byte[totalsize];
int pos = workbook.serialize(0, retval);
// System.arraycopy(wb, 0, retval, 0, wb.length);
for (int k = 0; k < sheets.size(); k++)
@ -562,13 +606,13 @@ public class HSSFWorkbook
// byte[] sb = (byte[])sheetbytes.get(k);
// System.arraycopy(sb, 0, retval, pos, sb.length);
pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
data); // sb.length;
retval); // sb.length;
}
for (int k = pos; k < totalsize; k++)
/* for (int k = pos; k < totalsize; k++)
{
data[k] = 0;
}
return data;
retval[k] = 0;
}*/
return retval;
}
public int addSSTString(String string)
@ -677,5 +721,57 @@ public class HSSFWorkbook
removeName(index);
}
/**
* Copies nodes from one POIFS to the other minus the excepts
* @param source is the source POIFS to copy from
* @param target is the target POIFS to copy to
* @param excepts is a list of Strings specifying what nodes NOT to copy
*/
private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
List excepts) throws IOException {
//System.err.println("CopyNodes called");
DirectoryEntry root = source.getRoot();
DirectoryEntry newRoot = target.getRoot();
Iterator entries = root.getEntries();
while (entries.hasNext()) {
Entry entry = (Entry)entries.next();
if (!isInList(entry.getName(), excepts)) {
copyNodeRecursively(entry,newRoot);
}
}
}
private boolean isInList(String entry, List list) {
for (int k = 0; k < list.size(); k++) {
if (((String)list.get(k)).equals(entry)) {
return true;
}
}
return false;
}
private void copyNodeRecursively(Entry entry, DirectoryEntry target)
throws IOException {
//System.err.println("copyNodeRecursively called with "+entry.getName()+
// ","+target.getName());
DirectoryEntry newTarget = null;
if (entry.isDirectoryEntry()) {
newTarget = target.createDirectory(entry.getName());
Iterator entries = ((DirectoryEntry)entry).getEntries();
while (entries.hasNext()) {
copyNodeRecursively((Entry)entries.next(),newTarget);
}
} else {
DocumentEntry dentry = (DocumentEntry)entry;
DocumentInputStream dstream = new DocumentInputStream(dentry);
target.createDocument(dentry.getName(),dstream);
dstream.close();
}
}
}

View File

@ -269,6 +269,9 @@ public class POIFSFileSystem
// set the small block allocation table start block
header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock());
// set the small block allocation table block count
header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount());
// the header is now properly initialized. Make a list of
// writers (the header block, followed by the documents, the
// property table, the small block store, the small block

View File

@ -70,18 +70,19 @@ import org.apache.poi.util.ShortField;
public interface HeaderBlockConstants
{
public static final long _signature = 0xE11AB1A1E011CFD0L;
public static final int _bat_array_offset = 0x4c;
public static final int _max_bats_in_header =
public static final long _signature = 0xE11AB1A1E011CFD0L;
public static final int _bat_array_offset = 0x4c;
public static final int _max_bats_in_header =
(POIFSConstants.BIG_BLOCK_SIZE - _bat_array_offset)
/ LittleEndianConsts.INT_SIZE;
// useful offsets
public static final int _signature_offset = 0;
public static final int _bat_count_offset = 0x2C;
public static final int _property_start_offset = 0x30;
public static final int _sbat_start_offset = 0x3C;
public static final int _xbat_start_offset = 0x44;
public static final int _xbat_count_offset = 0x48;
public static final int _signature_offset = 0;
public static final int _bat_count_offset = 0x2C;
public static final int _property_start_offset = 0x30;
public static final int _sbat_start_offset = 0x3C;
public static final int _sbat_block_count_offset = 0x40;
public static final int _xbat_start_offset = 0x44;
public static final int _xbat_count_offset = 0x48;
} // end public interface HeaderBlockConstants

View File

@ -88,6 +88,9 @@ public class HeaderBlockWriter
// block allocation table's first big block)
private IntegerField _sbat_start;
// number of big blocks holding the small block allocation table
private IntegerField _sbat_block_count;
// big block index for extension to the big block allocation table
private IntegerField _xbat_start;
private IntegerField _xbat_count;
@ -121,7 +124,8 @@ public class HeaderBlockWriter
new IntegerField(0x38, 0x1000, _data);
_sbat_start = new IntegerField(_sbat_start_offset,
POIFSConstants.END_OF_CHAIN, _data);
new IntegerField(0x40, 1, _data);
_sbat_block_count = new IntegerField(_sbat_block_count_offset, 0,
_data);
_xbat_start = new IntegerField(_xbat_start_offset,
POIFSConstants.END_OF_CHAIN, _data);
_xbat_count = new IntegerField(_xbat_count_offset, 0, _data);
@ -200,6 +204,17 @@ public class HeaderBlockWriter
_sbat_start.set(startBlock, _data);
}
/**
* Set count of SBAT blocks
*
* @param count the number of SBAT blocks
*/
public void setSBATBlockCount(final int count)
{
_sbat_block_count.set(count, _data);
}
/**
* For a given number of BAT blocks, calculate how many XBAT
* blocks will be needed

View File

@ -112,6 +112,17 @@ public class SmallBlockTableWriter
_big_block_count = SmallDocumentBlock.fill(_small_blocks);
}
/**
* Get the number of SBAT blocks
*
* @return number of SBAT big blocks
*/
public int getSBATBlockCount()
{
return (_big_block_count + 15) / 16;
}
/**
* Get the SBAT
*

View File

@ -117,7 +117,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
@ -281,7 +281,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
@ -436,7 +436,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
@ -597,7 +597,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01,
@ -744,7 +744,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01,
@ -891,7 +891,7 @@ public class TestHeaderBlockWriter
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x01, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x67, ( byte ) 0x46, ( byte ) 0x23, ( byte ) 0x01,
( byte ) 0x02, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x67, ( byte ) 0x45, ( byte ) 0x23, ( byte ) 0x01,