44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@653117 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8fb40de628
commit
bbe3ee9b4d
@ -37,6 +37,7 @@
|
||||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.1-beta2" date="2008-05-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44921 - allow Ptg.writeBytes() to be called on relative ref Ptgs (RefN* and AreaN*)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44914 - Fix/suppress warning message "WARN. Unread n bytes of record 0xNN"</action>
|
||||
|
@ -34,6 +34,7 @@
|
||||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.1-beta2" date="2008-05-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44921 - allow Ptg.writeBytes() to be called on relative ref Ptgs (RefN* and AreaN*)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44914 - Fix/suppress warning message "WARN. Unread n bytes of record 0xNN"</action>
|
||||
|
@ -165,7 +165,43 @@ public class HSSFWorkbook extends POIDocument
|
||||
public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
|
||||
throws IOException
|
||||
{
|
||||
this(fs.getRoot(), fs, preserveNodes);
|
||||
this(fs.getRoot(), fs, preserveNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally, the Workbook will be in a POIFS Stream
|
||||
* called "Workbook". However, some weird XLS generators use "WORKBOOK"
|
||||
*/
|
||||
private static final String[] WORKBOOK_DIR_ENTRY_NAMES = {
|
||||
"Workbook", // as per BIFF8 spec
|
||||
"WORKBOOK",
|
||||
};
|
||||
|
||||
|
||||
private static String getWorkbookDirEntryName(DirectoryNode directory) {
|
||||
|
||||
String[] potentialNames = WORKBOOK_DIR_ENTRY_NAMES;
|
||||
for (int i = 0; i < potentialNames.length; i++) {
|
||||
String wbName = potentialNames[i];
|
||||
try {
|
||||
directory.getEntry(wbName);
|
||||
return wbName;
|
||||
} catch (FileNotFoundException e) {
|
||||
// continue - to try other options
|
||||
}
|
||||
}
|
||||
|
||||
// check for previous version of file format
|
||||
try {
|
||||
directory.getEntry("Book");
|
||||
throw new IllegalArgumentException("The supplied spreadsheet seems to be Excel 5.0/7.0 (BIFF5) format. "
|
||||
+ "POI only supports BIFF8 format (from Excel versions 97/2000/XP/2003)");
|
||||
} catch (FileNotFoundException e) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. "
|
||||
+ "Is it really an excel file?");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,7 +221,9 @@ public class HSSFWorkbook extends POIDocument
|
||||
public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes)
|
||||
throws IOException
|
||||
{
|
||||
super(directory, fs);
|
||||
super(directory, fs);
|
||||
String workbookName = getWorkbookDirEntryName(directory);
|
||||
|
||||
this.preserveNodes = preserveNodes;
|
||||
|
||||
// If we're not preserving nodes, don't track the
|
||||
@ -198,27 +236,8 @@ public class HSSFWorkbook extends POIDocument
|
||||
sheets = new ArrayList(INITIAL_CAPACITY);
|
||||
names = new ArrayList(INITIAL_CAPACITY);
|
||||
|
||||
// Normally, the Workbook will be in a POIFS Stream
|
||||
// called "Workbook". However, some wierd XLS generators
|
||||
// put theirs in one called "WORKBOOK"
|
||||
String workbookName = "Workbook";
|
||||
try {
|
||||
directory.getEntry(workbookName);
|
||||
// Is the default name
|
||||
} catch(FileNotFoundException fe) {
|
||||
// Try the upper case form
|
||||
try {
|
||||
workbookName = "WORKBOOK";
|
||||
directory.getEntry(workbookName);
|
||||
} catch(FileNotFoundException wfe) {
|
||||
// Doesn't contain it in either form
|
||||
throw new IllegalArgumentException("The supplied POIFSFileSystem contained neither a 'Workbook' entry, nor a 'WORKBOOK' entry. Is it really an excel file?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Grab the data from the workbook stream, however
|
||||
// it happens to be spelt.
|
||||
// it happens to be spelled.
|
||||
InputStream stream = directory.createDocumentInputStream(workbookName);
|
||||
|
||||
EventRecordFactory factory = new EventRecordFactory();
|
||||
@ -516,12 +535,12 @@ public class HSSFWorkbook extends POIDocument
|
||||
*/
|
||||
public int getSheetIndex(HSSFSheet sheet)
|
||||
{
|
||||
for(int i=0; i<sheets.size(); i++) {
|
||||
if(sheets.get(i) == sheet) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
for(int i=0; i<sheets.size(); i++) {
|
||||
if(sheets.get(i) == sheet) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -532,7 +551,7 @@ public class HSSFWorkbook extends POIDocument
|
||||
* named range things.
|
||||
*/
|
||||
public short getExternalSheetIndex(int internalSheetIndex) {
|
||||
return workbook.checkExternSheet(internalSheetIndex);
|
||||
return workbook.checkExternSheet(internalSheetIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -576,18 +595,18 @@ public class HSSFWorkbook extends POIDocument
|
||||
sheets.add(clonedSheet);
|
||||
int i=1;
|
||||
while (true) {
|
||||
//Try and find the next sheet name that is unique
|
||||
String name = srcName;
|
||||
String index = Integer.toString(i++);
|
||||
if (name.length()+index.length()+2<31)
|
||||
name = name + "("+index+")";
|
||||
else name = name.substring(0, 31-index.length()-2)+"("+index+")";
|
||||
//Try and find the next sheet name that is unique
|
||||
String name = srcName;
|
||||
String index = Integer.toString(i++);
|
||||
if (name.length()+index.length()+2<31)
|
||||
name = name + "("+index+")";
|
||||
else name = name.substring(0, 31-index.length()-2)+"("+index+")";
|
||||
|
||||
//If the sheet name is unique, then set it otherwise move on to the next number.
|
||||
if (workbook.getSheetIndex(name) == -1) {
|
||||
//If the sheet name is unique, then set it otherwise move on to the next number.
|
||||
if (workbook.getSheetIndex(name) == -1) {
|
||||
workbook.setSheetName(sheets.size()-1, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return clonedSheet;
|
||||
}
|
||||
@ -663,7 +682,7 @@ public class HSSFWorkbook extends POIDocument
|
||||
}
|
||||
|
||||
public SheetReferences getSheetReferences() {
|
||||
return workbook.getSheetReferences();
|
||||
return workbook.getSheetReferences();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -999,13 +1018,13 @@ public class HSSFWorkbook extends POIDocument
|
||||
writeProperties(fs, excepts);
|
||||
|
||||
if (preserveNodes) {
|
||||
// Don't write out the old Workbook, we'll be doing our new one
|
||||
// Don't write out the old Workbook, we'll be doing our new one
|
||||
excepts.add("Workbook");
|
||||
// If the file had WORKBOOK instead of Workbook, we'll write it
|
||||
// out correctly shortly, so don't include the old one
|
||||
// If the file had WORKBOOK instead of Workbook, we'll write it
|
||||
// out correctly shortly, so don't include the old one
|
||||
excepts.add("WORKBOOK");
|
||||
|
||||
// Copy over all the other nodes to our new poifs
|
||||
// Copy over all the other nodes to our new poifs
|
||||
copyNodes(this.filesystem,fs,excepts);
|
||||
}
|
||||
fs.writeFilesystem(stream);
|
||||
@ -1127,76 +1146,76 @@ public class HSSFWorkbook extends POIDocument
|
||||
* @return the string representation of the defined or external name
|
||||
*/
|
||||
public String resolveNameXText(int refIndex, int definedNameIndex) {
|
||||
return workbook.resolveNameXText(refIndex, definedNameIndex);
|
||||
return workbook.resolveNameXText(refIndex, definedNameIndex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the printarea for the sheet provided
|
||||
* <p>
|
||||
* i.e. Reference = $A$1:$B$2
|
||||
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
||||
* @param reference Valid name Reference for the Print Area
|
||||
*/
|
||||
public void setPrintArea(int sheetIndex, String reference)
|
||||
{
|
||||
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
/**
|
||||
* Sets the printarea for the sheet provided
|
||||
* <p>
|
||||
* i.e. Reference = $A$1:$B$2
|
||||
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
||||
* @param reference Valid name Reference for the Print Area
|
||||
*/
|
||||
public void setPrintArea(int sheetIndex, String reference)
|
||||
{
|
||||
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
|
||||
|
||||
if (name == null)
|
||||
name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
if (name == null)
|
||||
name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
|
||||
|
||||
short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
|
||||
name.setExternSheetNumber(externSheetIndex);
|
||||
name.setAreaReference(reference);
|
||||
short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
|
||||
name.setExternSheetNumber(externSheetIndex);
|
||||
name.setAreaReference(reference);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For the Convenience of Java Programmers maintaining pointers.
|
||||
* @see #setPrintArea(int, String)
|
||||
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
|
||||
* @param startColumn Column to begin printarea
|
||||
* @param endColumn Column to end the printarea
|
||||
* @param startRow Row to begin the printarea
|
||||
* @param endRow Row to end the printarea
|
||||
*/
|
||||
public void setPrintArea(int sheetIndex, int startColumn, int endColumn,
|
||||
int startRow, int endRow) {
|
||||
/**
|
||||
* For the Convenience of Java Programmers maintaining pointers.
|
||||
* @see #setPrintArea(int, String)
|
||||
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
|
||||
* @param startColumn Column to begin printarea
|
||||
* @param endColumn Column to end the printarea
|
||||
* @param startRow Row to begin the printarea
|
||||
* @param endRow Row to end the printarea
|
||||
*/
|
||||
public void setPrintArea(int sheetIndex, int startColumn, int endColumn,
|
||||
int startRow, int endRow) {
|
||||
|
||||
//using absolute references because they don't get copied and pasted anyway
|
||||
CellReference cell = new CellReference(startRow, startColumn, true, true);
|
||||
String reference = cell.formatAsString();
|
||||
//using absolute references because they don't get copied and pasted anyway
|
||||
CellReference cell = new CellReference(startRow, startColumn, true, true);
|
||||
String reference = cell.formatAsString();
|
||||
|
||||
cell = new CellReference(endRow, endColumn, true, true);
|
||||
reference = reference+":"+cell.formatAsString();
|
||||
cell = new CellReference(endRow, endColumn, true, true);
|
||||
reference = reference+":"+cell.formatAsString();
|
||||
|
||||
setPrintArea(sheetIndex, reference);
|
||||
}
|
||||
setPrintArea(sheetIndex, reference);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified.
|
||||
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
||||
* @return String Null if no print area has been defined
|
||||
*/
|
||||
public String getPrintArea(int sheetIndex)
|
||||
{
|
||||
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
if (name == null) return null;
|
||||
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
|
||||
/**
|
||||
* Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified.
|
||||
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
|
||||
* @return String Null if no print area has been defined
|
||||
*/
|
||||
public String getPrintArea(int sheetIndex)
|
||||
{
|
||||
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
if (name == null) return null;
|
||||
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
|
||||
|
||||
return name.getAreaReference(this);
|
||||
}
|
||||
return name.getAreaReference(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the printarea for the sheet specified
|
||||
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
|
||||
*/
|
||||
public void removePrintArea(int sheetIndex) {
|
||||
getWorkbook().removeBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
getWorkbook().removeBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
|
||||
}
|
||||
|
||||
/** creates a new named range and add it to the model
|
||||
@ -1252,9 +1271,9 @@ public class HSSFWorkbook extends POIDocument
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
*/
|
||||
public HSSFDataFormat createDataFormat() {
|
||||
if (formatter == null)
|
||||
formatter = new HSSFDataFormat(workbook);
|
||||
return formatter;
|
||||
if (formatter == null)
|
||||
formatter = new HSSFDataFormat(workbook);
|
||||
return formatter;
|
||||
}
|
||||
|
||||
/** remove the named range by his name
|
||||
@ -1433,7 +1452,7 @@ public class HSSFWorkbook extends POIDocument
|
||||
* Is the workbook protected with a password (not encrypted)?
|
||||
*/
|
||||
public boolean isWriteProtected() {
|
||||
return this.workbook.isWriteProtected();
|
||||
return this.workbook.isWriteProtected();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user