注意此问题在poi的changlog中并没有体现。
针对2.5.1版本中代码如下:
类:org.apache.poi.hssf.usermodel.HSSFWorkbook
方法:
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);
InputStream stream = fs.createDocumentInputStream("Workbook");
EventRecordFactory factory = new EventRecordFactory();
//excel默认为3个sheet记录数为390条记录,偏移量始终从291开始,每增加一行,则记录总数增加2,每增加一列加1
List records = RecordFactory.createRecords(stream);
workbook = Workbook.createWorkbook(records);
setPropertiesFromWorkbook(workbook);
int recOffset = workbook.getNumRecords();
int sheetNum = 0;
//如果只有一个sheet则记录数为322,偏移量为289
while (recOffset < records.size())
{
Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
//正确的数据应该每一格SHEET记录处理完成后他的偏移了为322+他的记录行数与列数,
//这里需要获得结束标签的所处的位置数,为什么要加1,因为是从0推的
recOffset = sheet.getEofLoc()+1;
//针对2.5.1如果excel文件的结束标签有问题,则会导致计算不出来结束标签的位置,这样就会造成返回的地recOffset偏移量为1;所以后来在2007年的3.0正式版本中弥补了此处的问题,加入了一个判断
if(recOffset == 1){
break;
}
sheet.convertLabelRecords(
workbook); // convert all LabelRecord records to LabelSSTRecord
HSSFSheet hsheet = new HSSFSheet(workbook, sheet);
sheets.add(hsheet);
// workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
}
for (int i = 0 ; i < workbook.getNumNames() ; ++i){
HSSFName name = new HSSFName(workbook, workbook.getNameRecord(i));
names.add(name);
}
}
如果是2.5版本的poi还需要修改为以下红色部分
nameRecord = findExistingRowColHeaderNameRecord(sheetIndex);
if (removingRange )
{
if (nameRecord != null)
workbook.removeName(findExistingRowColHeaderNameRecordIdx(sheetIndex+1));
return;
}
if ( nameRecord == null )
{
nameRecord = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_TITLE, sheetIndex+1);
//does a lot of the house keeping for builtin records, like setting lengths to zero etc
isNewRecord = true;
}