If there is a formula like for example 'OFFSET(A1,0,0)' in an Excel sheet, HSSF stops parsing at row 32 while iterating the rows. The Problem seems to occur only with formulas that return strings.
Attach one. Include the minimum source necessary to reproduce the problem.
Created attachment 4050 [details] Excel sheet containing formula 'Offset' and size of 35 rows
Created attachment 4051 [details] Java program for parsing sheet "Test.xls"
Created attachment 4393 [details] Excel file, three sheets with text references in different rows
Hello, I use jakarta-poi-1.9.0-dev-20021107 and encountered a similar problem: Each reference (=A1) leads to a wrong result of row.getLastRowNum(), if the referenced cell contains String data. The returned length of the sheet depends on the row in which the =reference was placed. I send you some code and a Workbook, to demonstrate the mysteria: Sheet1 one has 99 rows an Text in B1, sheets2 & 3 are also 99 rows long but have a reference to sheet1!B1 in B31/B32 (row numbering 0-based). As you will see the barrier seems to be always n*32 ... If you need some more information, please contact me. Have a good time, Volker =============================== Here's the very basic sample code: (the referenced excel-sheet is Attachment #4393 [details]) (The sample output follows after) public static void poiFehler() { try { POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("C:\\tmp\\Mappe1.xls")); HSSFWorkbook wb = new HSSFWorkbook(fs); int x; int realLen=98; HSSFSheet sheet = wb.getSheet("Tabelle1"); x = sheet.getLastRowNum(); System.out.println("Tabelle1: Length="+realLen+", no String-reference"); System.out.println("POI-LastRowNum="+x); if(realLen==x) System.out.println("OK"); else System.out.println("BUG!!"); System.out.println(); System.out.println("Tabelle2: Length="+realLen+", String-reference in row 31 (or before)"); sheet = wb.getSheet("Tabelle2"); x = sheet.getLastRowNum(); System.out.println("POI-LastRowNum="+x); if(realLen==x) System.out.println("OK"); else System.out.println("BUG!!"); System.out.println(); System.out.println("Tabelle3: Length="+realLen+", String-reference in row 32 (or behind)"); sheet = wb.getSheet("Tabelle3"); x = sheet.getLastRowNum(); System.out.println("POI-LastRowNum="+x); if(realLen==x) System.out.println("OK"); else System.out.println("BUG!!"); System.out.println(); } catch (IOException e) { System.out.println("IO-Exc."); } } ------------------------------------------------ OUTPUT: Tabelle1: Length=98, no String-reference POI-LastRowNum=98 OK Tabelle2: Length=98, String-reference in row 31 (or before) POI-LastRowNum=31 BUG!! Tabelle3: Length=98, String-reference in row 32 (or behind) POI-LastRowNum=63 BUG!!
Created attachment 4502 [details] patch file to add string handling
The attachment should patch this problem. The problem was the loading loop was ending when it ran into Strings at row 32. There is similar code in the Cell loading loop which ignores strings, and this appears to work for all spreadsheets that I have tried.
so explain this patch to me. How will this work given a normal sheet with string records which just need to be converted to LabelSST
As far as I can tell the only function that this function performs is setting up the list of rowrecords -- with regards to the LabelSST - it was never done here. This function actually has three section, only two of which ever had an effect. The first section simply set and created a object that was never used. if (rec instanceof LabelSSTRecord) { LabelSSTRecord new_name = (LabelSSTRecord) rec; //System.out.println("Row for LabellSST: " + new_name.getRow()); } The second breaks the loop under certain circumstances: if (rec instanceof StringRecord == false && !rec.isInValueSection() && !(rec instanceof UnknownRecord)) { //System.out.println("Record is of type: " + rec.getClass()); // StringRecord r = (StringRecord)rec; // System.out.println("String:" + r.getString()); break; } The third ( the most important one), check to see if this is a RowRecord, and if so, adds new a new row. if (rec.getSid() == RowRecord.sid) { insertRow(( RowRecord ) rec); RowRecord row = (RowRecord)rec; // System.out.println("Row:" + row.getRowNumber()); }
Hi and thanks! The patch works fine with my cases. Thanks for the quick help. Do I get a message, if and when this patch is included in a upcomming release? Volker
Created attachment 5833 [details] Cleaner patch against current CVS
The above patch is just a cleaned up version of the one already attached to this bug. As you can see it is just a one line fix. The patch does fix the problem I was encountering (sheet says it only has 32 rows), but I can't make any claims as to if it is theoretically correct.
Im going to commit this tonight.
Fixed root of the problem that all the rows weren't being aggregated and committed fix. Please verify! And thanks for the bug report and debugging.