Summary: | File Error Data May Have been Lost error while opening commented workbook(excel file) | ||
---|---|---|---|
Product: | POI | Reporter: | Reddy <cbenjaram> |
Component: | HSSF | Assignee: | POI Developers List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | major | CC: | cbenjaram, manuela.munaretto |
Priority: | P1 | ||
Version: | 3.2-FINAL | ||
Target Milestone: | --- | ||
Hardware: | Macintosh | ||
OS: | other | ||
Bug Depends on: | |||
Bug Blocks: | 48846, 53010 | ||
Attachments: | Error throwing file attachment |
Description
Reddy
2009-08-02 12:40:19 UTC
I've experienced this problem too. After some tracing with the 3.6 stable release source, the problem seems to be rely in... Sheet.java: public int aggregateDrawingRecords(DrawingManager2 drawingManager, boolean createIfMissing). 1491:1499 EscherAggregate r = EscherAggregate.createAggregate( records, loc, drawingManager ); int startloc = loc; while ( loc + 1 < records.size() && records.get( loc ) instanceof DrawingRecord && records.get( loc + 1 ) instanceof ObjRecord ) { loc += 2; } where a practical DrawingRecord and ObjRecord pair loop looks like the following inside EscherAggregate: while ( loc + 1 < records.size() && sid( records, loc ) == DrawingRecord.sid && isObjectRecord( records, loc + 1 ) ) . Thus the Sheet's loop for calculating loc will be too early terminated since there could be non-ObjRecord but TextObjRecord that should be taken into consideration too. I'll try to patch it locally and observe how it goes. The latest development branch seems to refactored alot and renamed Sheet.java to InternalSheet.java, though the code snippet around this issue is still similar. *** Bug 48327 has been marked as a duplicate of this bug. *** A simple workaround as a PoC is as below. Where Invoker is a reflection util to read the private property by force. ----------------------- if ( null == drawing ) { drawing = sh.createDrawingPatriarch(); // Remove redundant records to avoid error. Sheet _sh = (Sheet)Invoker.getProperty(sh, "_sheet"); List list = _sh.getRecords(); for ( Iterator it = list.iterator(); it.hasNext(); ) { RecordBase e = (RecordBase)it.next(); if ( e instanceof TextObjectRecord || e instanceof DrawingRecord || e instanceof ObjRecord ) { it.remove(); } } } ----------------------- The idea is that the Sheet.aggregateDrawingRecords(..) called by HSSFSheet.createDrawingPatriarch() fails to remove and also destroyed the pairing of DrawingRecord and *ObjRecord that causing the Excel open file error prompt. The patch to Sheet.java will follow. Further testing reveals that NoteRecord is also a factor of the error prompt. If any of the new comments are on in the same location as the old comments, the redundant NoteRecord will cause Excel to report an error upon opening. Removing the NoteRecord manually seems to solve this problem. The issues related are out of my knowledge. I opt to not do the patch but just derive a workaround for my own case. For those who want to solve the problem, try removing NoteRecord after Sheet.createDrawingPatriarch(..). NoteRecord reading and re-writing is not supported in 3.6 either. It is a limitation of HSSF - comments are graphic objects and HSSF can create drawings from scratch, but cannot modify existing ones. This means that if you add an comment to a sheet that already has graphic objects (comments, shapes, pictures, etc.) then the existing graphic objects are invalidated. As a workaround, try to output in .xlsx format, it should handle comments across re-saves without problems. Yegor *** This bug has been marked as a duplicate of bug 50696 *** This problem should be fixed in trunk. Please try with a nightly build - see download links on http://poi.apache.org/ or build yourself from SVN trunk, see http://poi.apache.org/subversion.html |