From 937d2700ed463c3b5c636939050f81bea18fe93f Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 18 May 2008 16:25:00 +0000 Subject: [PATCH] Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657578 via svnmerge from https://svn.apache.org:443/repos/asf/poi/trunk ........ r657166 | josh | 2008-05-16 19:46:04 +0100 (Fri, 16 May 2008) | 1 line Simplification of BiffViewer. Made easier to send results to file. ........ r657167 | josh | 2008-05-16 19:55:02 +0100 (Fri, 16 May 2008) | 1 line Fix for bug 40414 - update selected/active sheet after removing sheet from workbook ........ r657180 | josh | 2008-05-16 20:24:47 +0100 (Fri, 16 May 2008) | 1 line fixed bug number in junit msg - from r656893 bug 44523 ........ r657355 | yegor | 2008-05-17 15:00:30 +0100 (Sat, 17 May 2008) | 1 line added HSSFName.isDeleted() to check if the name points to cell that no longer exists ........ r657358 | yegor | 2008-05-17 15:03:27 +0100 (Sat, 17 May 2008) | 1 line misc bug fixes ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@657579 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 2 + .../content/xdocs/spreadsheet/quick-guide.xml | 14 + src/documentation/content/xdocs/status.xml | 2 + .../org/apache/poi/hssf/dev/BiffViewer.java | 547 +++++++----------- .../apache/poi/hssf/usermodel/HSSFName.java | 9 + .../poi/hssf/usermodel/HSSFWorkbook.java | 48 +- .../org/apache/poi/hssf/data/24207.xls | Bin 0 -> 13824 bytes .../org/apache/poi/hssf/data/36947.xls | Bin 0 -> 142336 bytes .../org/apache/poi/hssf/data/39634.xls | Bin 0 -> 68608 bytes .../apache/poi/hssf/usermodel/TestBugs.java | 41 ++ .../poi/hssf/usermodel/TestHSSFWorkbook.java | 81 ++- .../poi/hssf/usermodel/TestNamedRange.java | 24 + 12 files changed, 413 insertions(+), 355 deletions(-) create mode 100755 src/testcases/org/apache/poi/hssf/data/24207.xls create mode 100755 src/testcases/org/apache/poi/hssf/data/36947.xls create mode 100755 src/testcases/org/apache/poi/hssf/data/39634.xls diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index b2dea5c40..380ecb923 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -44,6 +44,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx + 24207 - added HSSFName.isDeleted() to check if the name points to cell that no longer exists + 40414 - fixed selected/active sheet after removing sheet from workbook 44523 - fixed workbook sheet selection and focus 45000 - Fixed NPE in ListLevel when numberText is null 44985 - Properly update TextSpecInfoAtom when the parent text is changed diff --git a/src/documentation/content/xdocs/spreadsheet/quick-guide.xml b/src/documentation/content/xdocs/spreadsheet/quick-guide.xml index cdad1392b..7523f500d 100644 --- a/src/documentation/content/xdocs/spreadsheet/quick-guide.xml +++ b/src/documentation/content/xdocs/spreadsheet/quick-guide.xml @@ -1284,6 +1284,20 @@ Examples: Cell c = r.getCell(crefs[j].getCol()); // Do something with this corner cell } + } + +

+ Note, when a cell is deleted, Excel does not delete the + attached named range. As result, workbook can contain + named ranges that point to cells that no longer exist. + You should check the validity of a reference before + constructing AreaReference +

+ + if(hssfName.isDeleted()){ + //named range points to a deleted cell. + } else { + AreaReference ref = new AreaReference(hssfName.getReference()); } diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 75117754b..ebf869ce9 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -41,6 +41,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx
+ 24207 - added HSSFName.isDeleted() to check if the name points to cell that no longer exists + 40414 - fixed selected/active sheet after removing sheet from workbook 44523 - fixed workbook sheet selection and focus 45000 - Fixed NPE in ListLevel when numberText is null 44985 - Properly update TextSpecInfoAtom when the parent text is changed diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index 242a85f45..cd4365191 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -15,22 +15,20 @@ limitations under the License. ==================================================================== */ -/* - * BiffViewer.java - * - * Created on November 13, 2001, 9:23 AM - */ package org.apache.poi.hssf.dev; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + import org.apache.poi.hssf.record.*; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.HexDump; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - /** * Utillity for reading in BIFF8 records and displaying data from them. * @@ -38,38 +36,26 @@ import java.util.ArrayList; *@author Glen Stampoultzis (glens at apache.org) *@see #main */ - -public class BiffViewer { - String filename; +public final class BiffViewer { + private final File _inputFile; private boolean dump; + private final PrintStream _ps; - /** - * Creates new BiffViewer - * - *@param args - */ - - public BiffViewer(String[] args) { - if (args.length > 0) { - filename = args[0]; - } else { - System.out.println("BIFFVIEWER REQUIRES A FILENAME***"); - } + public BiffViewer(File inFile, PrintStream ps) { + _inputFile = inFile; + _ps = ps; } /** * Method run starts up BiffViewer... */ - public void run() { try { - POIFSFileSystem fs = - new POIFSFileSystem(new FileInputStream(filename)); - InputStream stream = - fs.createDocumentInputStream("Workbook"); - createRecords(stream, dump); + POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(_inputFile)); + InputStream stream = fs.createDocumentInputStream("Workbook"); + createRecords(stream, dump, _ps); } catch (Exception e) { e.printStackTrace(); } @@ -86,451 +72,306 @@ public class BiffViewer { * InputStream *@exception RecordFormatException on error processing the InputStream */ - - public static Record[] createRecords(InputStream in, boolean dump) + public static Record[] createRecords(InputStream in, boolean dump, PrintStream ps) throws RecordFormatException { ArrayList records = new ArrayList(); RecordDetails activeRecord = null; - try { - BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in); - while (recStream.hasNextRecord()) { + BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in); + while (recStream.hasNextRecord()) { recStream.nextRecord(); if (recStream.getSid() != 0) { - Record record = createRecord (recStream); + Record record = createRecord (recStream); if (record.getSid() != ContinueRecord.sid) { records.add(record); if (activeRecord != null) - activeRecord.dump(); - activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), (int)recStream.getPos(), record); + activeRecord.dump(ps); + activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), (int)recStream.getPos(), record); } if (dump) { - recStream.dumpBytes(); - } + recStream.dumpBytes(ps); } - } - activeRecord.dump(); - } catch (IOException e) { - throw new RecordFormatException("Error reading bytes", e); + } + } + if (activeRecord != null) { + activeRecord.dump(ps); } Record[] retval = new Record[records.size()]; - - retval = (Record[]) records.toArray(retval); + records.toArray(retval); return retval; } - private static void dumpNormal(Record record, int startloc, short rectype, short recsize) - { - System.out.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")"); - System.out.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize ); - System.out.println( record.toString() ); - - } /** - * Essentially a duplicate of RecordFactory. Kept seperate as not to screw + * Essentially a duplicate of RecordFactory. Kept separate as not to screw * up non-debug operations. * */ private static Record createRecord( RecordInputStream in ) { - Record retval = null; - switch ( in.getSid() ) { - case ChartRecord.sid: - retval = new ChartRecord( in ); - break; + return new ChartRecord( in ); case ChartFormatRecord.sid: - retval = new ChartFormatRecord( in ); - break; + return new ChartFormatRecord( in ); case SeriesRecord.sid: - retval = new SeriesRecord( in ); - break; + return new SeriesRecord( in ); case BeginRecord.sid: - retval = new BeginRecord( in ); - break; + return new BeginRecord( in ); case EndRecord.sid: - retval = new EndRecord( in ); - break; + return new EndRecord( in ); case BOFRecord.sid: - retval = new BOFRecord( in ); - break; + return new BOFRecord( in ); case InterfaceHdrRecord.sid: - retval = new InterfaceHdrRecord( in ); - break; + return new InterfaceHdrRecord( in ); case MMSRecord.sid: - retval = new MMSRecord( in ); - break; + return new MMSRecord( in ); case InterfaceEndRecord.sid: - retval = new InterfaceEndRecord( in ); - break; + return new InterfaceEndRecord( in ); case WriteAccessRecord.sid: - retval = new WriteAccessRecord( in ); - break; + return new WriteAccessRecord( in ); case CodepageRecord.sid: - retval = new CodepageRecord( in ); - break; + return new CodepageRecord( in ); case DSFRecord.sid: - retval = new DSFRecord( in ); - break; + return new DSFRecord( in ); case TabIdRecord.sid: - retval = new TabIdRecord( in ); - break; + return new TabIdRecord( in ); case FnGroupCountRecord.sid: - retval = new FnGroupCountRecord( in ); - break; + return new FnGroupCountRecord( in ); case WindowProtectRecord.sid: - retval = new WindowProtectRecord( in ); - break; + return new WindowProtectRecord( in ); case ProtectRecord.sid: - retval = new ProtectRecord( in ); - break; + return new ProtectRecord( in ); case PasswordRecord.sid: - retval = new PasswordRecord( in ); - break; + return new PasswordRecord( in ); case ProtectionRev4Record.sid: - retval = new ProtectionRev4Record( in ); - break; + return new ProtectionRev4Record( in ); case PasswordRev4Record.sid: - retval = new PasswordRev4Record( in ); - break; + return new PasswordRev4Record( in ); case WindowOneRecord.sid: - retval = new WindowOneRecord( in ); - break; + return new WindowOneRecord( in ); case BackupRecord.sid: - retval = new BackupRecord( in ); - break; + return new BackupRecord( in ); case HideObjRecord.sid: - retval = new HideObjRecord( in ); - break; + return new HideObjRecord( in ); case DateWindow1904Record.sid: - retval = new DateWindow1904Record( in ); - break; + return new DateWindow1904Record( in ); case PrecisionRecord.sid: - retval = new PrecisionRecord( in ); - break; + return new PrecisionRecord( in ); case RefreshAllRecord.sid: - retval = new RefreshAllRecord( in ); - break; + return new RefreshAllRecord( in ); case BookBoolRecord.sid: - retval = new BookBoolRecord( in ); - break; + return new BookBoolRecord( in ); case FontRecord.sid: - retval = new FontRecord( in ); - break; + return new FontRecord( in ); case FormatRecord.sid: - retval = new FormatRecord( in ); - break; + return new FormatRecord( in ); case ExtendedFormatRecord.sid: - retval = new ExtendedFormatRecord( in ); - break; + return new ExtendedFormatRecord( in ); case StyleRecord.sid: - retval = new StyleRecord( in ); - break; + return new StyleRecord( in ); case UseSelFSRecord.sid: - retval = new UseSelFSRecord( in ); - break; + return new UseSelFSRecord( in ); case BoundSheetRecord.sid: - retval = new BoundSheetRecord( in ); - break; + return new BoundSheetRecord( in ); case CountryRecord.sid: - retval = new CountryRecord( in ); - break; + return new CountryRecord( in ); case SSTRecord.sid: - retval = new SSTRecord( in ); - break; + return new SSTRecord( in ); case ExtSSTRecord.sid: - retval = new ExtSSTRecord( in ); - break; + return new ExtSSTRecord( in ); case EOFRecord.sid: - retval = new EOFRecord( in ); - break; + return new EOFRecord( in ); case IndexRecord.sid: - retval = new IndexRecord( in ); - break; + return new IndexRecord( in ); case CalcModeRecord.sid: - retval = new CalcModeRecord( in ); - break; + return new CalcModeRecord( in ); case CalcCountRecord.sid: - retval = new CalcCountRecord( in ); - break; + return new CalcCountRecord( in ); case RefModeRecord.sid: - retval = new RefModeRecord( in ); - break; + return new RefModeRecord( in ); case IterationRecord.sid: - retval = new IterationRecord( in ); - break; + return new IterationRecord( in ); case DeltaRecord.sid: - retval = new DeltaRecord( in ); - break; + return new DeltaRecord( in ); case SaveRecalcRecord.sid: - retval = new SaveRecalcRecord( in ); - break; + return new SaveRecalcRecord( in ); case PrintHeadersRecord.sid: - retval = new PrintHeadersRecord( in ); - break; + return new PrintHeadersRecord( in ); case PrintGridlinesRecord.sid: - retval = new PrintGridlinesRecord( in ); - break; + return new PrintGridlinesRecord( in ); case GridsetRecord.sid: - retval = new GridsetRecord( in ); - break; + return new GridsetRecord( in ); case DrawingGroupRecord.sid: - retval = new DrawingGroupRecord( in ); - break; + return new DrawingGroupRecord( in ); case DrawingRecordForBiffViewer.sid: - retval = new DrawingRecordForBiffViewer( in ); - break; + return new DrawingRecordForBiffViewer( in ); case DrawingSelectionRecord.sid: - retval = new DrawingSelectionRecord( in ); - break; + return new DrawingSelectionRecord( in ); case GutsRecord.sid: - retval = new GutsRecord( in ); - break; + return new GutsRecord( in ); case DefaultRowHeightRecord.sid: - retval = new DefaultRowHeightRecord( in ); - break; + return new DefaultRowHeightRecord( in ); case WSBoolRecord.sid: - retval = new WSBoolRecord( in ); - break; + return new WSBoolRecord( in ); case HeaderRecord.sid: - retval = new HeaderRecord( in ); - break; + return new HeaderRecord( in ); case FooterRecord.sid: - retval = new FooterRecord( in ); - break; + return new FooterRecord( in ); case HCenterRecord.sid: - retval = new HCenterRecord( in ); - break; + return new HCenterRecord( in ); case VCenterRecord.sid: - retval = new VCenterRecord( in ); - break; + return new VCenterRecord( in ); case PrintSetupRecord.sid: - retval = new PrintSetupRecord( in ); - break; + return new PrintSetupRecord( in ); case DefaultColWidthRecord.sid: - retval = new DefaultColWidthRecord( in ); - break; + return new DefaultColWidthRecord( in ); case DimensionsRecord.sid: - retval = new DimensionsRecord( in ); - break; + return new DimensionsRecord( in ); case RowRecord.sid: - retval = new RowRecord( in ); - break; + return new RowRecord( in ); case LabelSSTRecord.sid: - retval = new LabelSSTRecord( in ); - break; + return new LabelSSTRecord( in ); case RKRecord.sid: - retval = new RKRecord( in ); - break; + return new RKRecord( in ); case NumberRecord.sid: - retval = new NumberRecord( in ); - break; + return new NumberRecord( in ); case DBCellRecord.sid: - retval = new DBCellRecord( in ); - break; + return new DBCellRecord( in ); case WindowTwoRecord.sid: - retval = new WindowTwoRecord( in ); - break; + return new WindowTwoRecord( in ); case SelectionRecord.sid: - retval = new SelectionRecord( in ); - break; + return new SelectionRecord( in ); case ContinueRecord.sid: - retval = new ContinueRecord( in ); - break; + return new ContinueRecord( in ); case LabelRecord.sid: - retval = new LabelRecord( in ); - break; + return new LabelRecord( in ); case MulRKRecord.sid: - retval = new MulRKRecord( in ); - break; + return new MulRKRecord( in ); case MulBlankRecord.sid: - retval = new MulBlankRecord( in ); - break; + return new MulBlankRecord( in ); case BlankRecord.sid: - retval = new BlankRecord( in ); - break; + return new BlankRecord( in ); case BoolErrRecord.sid: - retval = new BoolErrRecord( in ); - break; + return new BoolErrRecord( in ); case ColumnInfoRecord.sid: - retval = new ColumnInfoRecord( in ); - break; + return new ColumnInfoRecord( in ); case MergeCellsRecord.sid: - retval = new MergeCellsRecord( in ); - break; + return new MergeCellsRecord( in ); case AreaRecord.sid: - retval = new AreaRecord( in ); - break; + return new AreaRecord( in ); case DataFormatRecord.sid: - retval = new DataFormatRecord( in ); - break; + return new DataFormatRecord( in ); case BarRecord.sid: - retval = new BarRecord( in ); - break; + return new BarRecord( in ); case DatRecord.sid: - retval = new DatRecord( in ); - break; + return new DatRecord( in ); case PlotGrowthRecord.sid: - retval = new PlotGrowthRecord( in ); - break; + return new PlotGrowthRecord( in ); case UnitsRecord.sid: - retval = new UnitsRecord( in ); - break; + return new UnitsRecord( in ); case FrameRecord.sid: - retval = new FrameRecord( in ); - break; + return new FrameRecord( in ); case ValueRangeRecord.sid: - retval = new ValueRangeRecord( in ); - break; + return new ValueRangeRecord( in ); case SeriesListRecord.sid: - retval = new SeriesListRecord( in ); - break; + return new SeriesListRecord( in ); case FontBasisRecord.sid: - retval = new FontBasisRecord( in ); - break; + return new FontBasisRecord( in ); case FontIndexRecord.sid: - retval = new FontIndexRecord( in ); - break; + return new FontIndexRecord( in ); case LineFormatRecord.sid: - retval = new LineFormatRecord( in ); - break; + return new LineFormatRecord( in ); case AreaFormatRecord.sid: - retval = new AreaFormatRecord( in ); - break; + return new AreaFormatRecord( in ); case LinkedDataRecord.sid: - retval = new LinkedDataRecord( in ); - break; + return new LinkedDataRecord( in ); case FormulaRecord.sid: - retval = new FormulaRecord( in ); - break; + return new FormulaRecord( in ); case SheetPropertiesRecord.sid: - retval = new SheetPropertiesRecord( in ); - break; + return new SheetPropertiesRecord( in ); case DefaultDataLabelTextPropertiesRecord.sid: - retval = new DefaultDataLabelTextPropertiesRecord( in ); - break; + return new DefaultDataLabelTextPropertiesRecord( in ); case TextRecord.sid: - retval = new TextRecord( in ); - break; + return new TextRecord( in ); case AxisParentRecord.sid: - retval = new AxisParentRecord( in ); - break; + return new AxisParentRecord( in ); case AxisLineFormatRecord.sid: - retval = new AxisLineFormatRecord( in ); - break; + return new AxisLineFormatRecord( in ); case SupBookRecord.sid: - retval = new SupBookRecord( in ); - break; + return new SupBookRecord( in ); case ExternSheetRecord.sid: - retval = new ExternSheetRecord( in ); - break; + return new ExternSheetRecord( in ); case SCLRecord.sid: - retval = new SCLRecord( in ); - break; + return new SCLRecord( in ); case SeriesToChartGroupRecord.sid: - retval = new SeriesToChartGroupRecord( in ); - break; + return new SeriesToChartGroupRecord( in ); case AxisUsedRecord.sid: - retval = new AxisUsedRecord( in ); - break; + return new AxisUsedRecord( in ); case AxisRecord.sid: - retval = new AxisRecord( in ); - break; + return new AxisRecord( in ); case CategorySeriesAxisRecord.sid: - retval = new CategorySeriesAxisRecord( in ); - break; + return new CategorySeriesAxisRecord( in ); case AxisOptionsRecord.sid: - retval = new AxisOptionsRecord( in ); - break; + return new AxisOptionsRecord( in ); case TickRecord.sid: - retval = new TickRecord( in ); - break; + return new TickRecord( in ); case SeriesTextRecord.sid: - retval = new SeriesTextRecord( in ); - break; + return new SeriesTextRecord( in ); case ObjectLinkRecord.sid: - retval = new ObjectLinkRecord( in ); - break; + return new ObjectLinkRecord( in ); case PlotAreaRecord.sid: - retval = new PlotAreaRecord( in ); - break; + return new PlotAreaRecord( in ); case SeriesIndexRecord.sid: - retval = new SeriesIndexRecord( in ); - break; + return new SeriesIndexRecord( in ); case LegendRecord.sid: - retval = new LegendRecord( in ); - break; + return new LegendRecord( in ); case LeftMarginRecord.sid: - retval = new LeftMarginRecord( in ); - break; + return new LeftMarginRecord( in ); case RightMarginRecord.sid: - retval = new RightMarginRecord( in ); - break; + return new RightMarginRecord( in ); case TopMarginRecord.sid: - retval = new TopMarginRecord( in ); - break; + return new TopMarginRecord( in ); case BottomMarginRecord.sid: - retval = new BottomMarginRecord( in ); - break; + return new BottomMarginRecord( in ); case PaletteRecord.sid: - retval = new PaletteRecord( in ); - break; + return new PaletteRecord( in ); case StringRecord.sid: - retval = new StringRecord( in ); - break; + return new StringRecord( in ); case NameRecord.sid: - retval = new NameRecord( in ); - break; + return new NameRecord( in ); case PaneRecord.sid: - retval = new PaneRecord( in ); - break; + return new PaneRecord( in ); case SharedFormulaRecord.sid: - retval = new SharedFormulaRecord( in); - break; + return new SharedFormulaRecord( in); case ObjRecord.sid: - retval = new ObjRecord( in); - break; + return new ObjRecord( in); case TextObjectRecord.sid: - retval = new TextObjectRecord( in); - break; + return new TextObjectRecord( in); case HorizontalPageBreakRecord.sid: - retval = new HorizontalPageBreakRecord( in); - break; + return new HorizontalPageBreakRecord( in); case VerticalPageBreakRecord.sid: - retval = new VerticalPageBreakRecord( in); - break; + return new VerticalPageBreakRecord( in); case WriteProtectRecord.sid: - retval = new WriteProtectRecord( in); - break; + return new WriteProtectRecord( in); case FilePassRecord.sid: - retval = new FilePassRecord(in); - break; + return new FilePassRecord(in); case NoteRecord.sid: - retval = new NoteRecord( in ); - break; + return new NoteRecord( in ); case FileSharingRecord.sid: - retval = new FileSharingRecord( in ); - break; + return new FileSharingRecord( in ); case HyperlinkRecord.sid: - retval = new HyperlinkRecord( in ); - break; - default: - retval = new UnknownRecord( in ); + return new HyperlinkRecord( in ); } - return retval; + return new UnknownRecord( in ); } /** * Method setDump - hex dump out data or not. - * - *@param dump */ - public void setDump(boolean dump) { this.dump = dump; } @@ -552,33 +393,44 @@ public class BiffViewer { * */ public static void main(String[] args) { + + System.setProperty("poi.deserialize.escher", "true"); + + if (args.length == 0) { + System.out.println( "Biff viewer needs a filename" ); + return; + } + try { - System.setProperty("poi.deserialize.escher", "true"); - - if (args.length == 0) - { - System.out.println( "Biff viewer needs a filename" ); + String inFileName = args[0]; + File inputFile = new File(inFileName); + if(!inputFile.exists()) { + throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist"); } - else - { - BiffViewer viewer = new BiffViewer(args); - if ((args.length > 1) && args[1].equals("on")) { - viewer.setDump(true); - } - if ((args.length > 1) && args[1].equals("bfd")) { - POIFSFileSystem fs = - new POIFSFileSystem(new FileInputStream(args[0])); - InputStream stream = - fs.createDocumentInputStream("Workbook"); - int size = stream.available(); - byte[] data = new byte[size]; - - stream.read(data); - HexDump.dump(data, 0, System.out, 0); - } else { - viewer.run(); - } + PrintStream ps; + if (false) { // set to true to output to file + OutputStream os = new FileOutputStream(inFileName + ".out"); + ps = new PrintStream(os); + } else { + ps = System.out; } + BiffViewer viewer = new BiffViewer(inputFile, ps); + + if (args.length > 1 && args[1].equals("on")) { + viewer.setDump(true); + } + if (args.length > 1 && args[1].equals("bfd")) { + POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile)); + InputStream stream = fs.createDocumentInputStream("Workbook"); + int size = stream.available(); + byte[] data = new byte[size]; + + stream.read(data); + HexDump.dump(data, 0, System.out, 0); + } else { + viewer.run(); + } + ps.close(); } catch (Exception e) { e.printStackTrace(); } @@ -587,7 +439,7 @@ public class BiffViewer { /** * This record supports dumping of completed continue records. */ - static class RecordDetails + private static final class RecordDetails { short rectype, recsize; int startloc; @@ -616,18 +468,19 @@ public class BiffViewer { return record; } - public void dump() throws IOException - { - dumpNormal(record, startloc, rectype, recsize); + public void dump(PrintStream ps) { + ps.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")"); + ps.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize ); + ps.println( record.toString() ); } } - static class BiffviewRecordInputStream extends RecordInputStream { + private static final class BiffviewRecordInputStream extends RecordInputStream { public BiffviewRecordInputStream(InputStream in) { super(in); } - public void dumpBytes() { - HexDump.dump(this.data, 0, this.currentLength); + public void dumpBytes(PrintStream ps) { + ps.println(HexDump.dump(this.data, 0, this.currentLength)); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java index bd955f825..31af2b773 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java @@ -140,4 +140,13 @@ public class HSSFName implements Name { } + /** + * Tests if this name points to a cell that no longer exists + * + * @return true if the name refers to a deleted cell, false otherwise + */ + public boolean isDeleted(){ + String ref = getReference(); + return "#REF!".endsWith(ref); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index b4c3cf3c7..08ddb9656 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -157,7 +157,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm protected HSSFWorkbook( Workbook book ) { - super(null, null); + super(null, null); workbook = book; sheets = new ArrayList( INITIAL_CAPACITY ); names = new ArrayList( INITIAL_CAPACITY ); @@ -775,14 +775,54 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm } /** - * removes sheet at the given index + * Removes sheet at the given index.

+ * + * Care must be taken if the removed sheet is the currently active or only selected sheet in + * the workbook. There are a few situations when Excel must have a selection and/or active + * sheet. (For example when printing - see Bug 40414).
+ * + * This method makes sure that if the removed sheet was active, another sheet will become + * active in its place. Furthermore, if the removed sheet was the only selected sheet, another + * sheet will become selected. The newly active/selected sheet will have the same index, or + * one less if the removed sheet was the last in the workbook. + * * @param index of the sheet (0-based) */ + public void removeSheetAt(int index) { + validateSheetIndex(index); + boolean wasActive = getSheetAt(index).isActive(); + boolean wasSelected = getSheetAt(index).isSelected(); - public void removeSheetAt(int index) - { sheets.remove(index); workbook.removeSheet(index); + + // set the remaining active/selected sheet + int nSheets = sheets.size(); + if (nSheets < 1) { + // nothing more to do if there are no sheets left + return; + } + // the index of the closest remaining sheet to the one just deleted + int newSheetIndex = index; + if (newSheetIndex >= nSheets) { + newSheetIndex = nSheets-1; + } + if (wasActive) { + setActiveSheet(newSheetIndex); + } + + if (wasSelected) { + boolean someOtherSheetIsStillSelected = false; + for (int i =0; i < nSheets; i++) { + if (getSheetAt(i).isSelected()) { + someOtherSheetIsStillSelected = true; + break; + } + } + if (!someOtherSheetIsStillSelected) { + setSelectedTab(newSheetIndex); + } + } } /** diff --git a/src/testcases/org/apache/poi/hssf/data/24207.xls b/src/testcases/org/apache/poi/hssf/data/24207.xls new file mode 100755 index 0000000000000000000000000000000000000000..eca56425efdc749421a5d25214eaba23d68ce9c5 GIT binary patch literal 13824 zcmeHOU2IfE6#nk^Zo9Pwwk_pPsMjrq?Y1_h7-_7~)dlGnQ#vw zP#@xhtPSGV*2{I@O)^;nTt@((+f(GgPoxA6qY>DX-j~Tb&u88o%e?L^ba+~ANLgaT zBnRFms}>ezHJBh@%yB3=&B|Mpf2L)>R=$ZjM|eHdzjJLL%Yk)w2jW`pedQ75i^(l~ zsdcWYWIa~l63Z9fJ|V*$I2p8_LKX**!Wb4Vx6NLSAeIA>wUPF&_V%7+M}H#f-6T5N z?1woQSC{3#JeVGNrMyrCby!m>)ZJ6w4)3L@bqFCcx73{0ibXdfhF%~kro69*Dy!;J&1o#v$Ng8q(b#2^j>u&osQgba>-KUPne&yeB$rm_D}O)BEjZG> zV({?nbaA*bSKd)U-c>;!t01rcm;6+~MmS$nkhm#dt8sJQ*0?2Kr!n%-cxgUZc$I5~ zg=1WSW`bg6Eq3frr*rE?!ns$H^opb|I5QamoBu@sk7L!*VV8UJa!(|J9Lx4X9 zzHpAe{)=>pY$PAS5=}Re17Rwd{p9y6+lICeBvl?$d8hJsRg(9a^augwvWj<@GiA$U z6La3v(npn_mNkhb1R{%2mBRFZo0j+`mSvv;gu5(k4m9Hn-L1rZ@-?)%#>Loe7Whr~ zG#go{S{N?yq1-hXya7UctA;@Vh%0xQ!r&&o_U;^pZwdQdgTdFC1%$z;#Uu>^1_6VB zLBJqzA0u#+Cpba%f6F^5+l1+3AN?`&;{NcbCqw95cmBs7%Fd8vk1F|bl5EqSCCN5( zC#jh{>(~kjHRvwNz2C5f570EZ#yuY&5URE=A11@hSOuJ z7a!bM8U5;_6_DNdLcU=B)Vtv!r^G`2X8UOGvv(^7d+k)IbvdU;OzTN&Nn|NXtmx zdBAa|<$T~GX}ofI+|@U=T0}7z7Lg1_6VBLBJqj z5HJYbdkBbQD?Ye*z~W2GN3HS|rTEnHzYg*BFgM%$N#5jvL_~fb&%lP$(*E1PMPDnT~sT^C~$mJhj zdn_m4X~=l+X`okxusw1sJfyYP%#9t1FzvAuax%vIij#vZ4yb2 v|NF>LQaMDaU*?d^pKA5Xw=#M_#wdtqs9{)bNb3{0Gkf~}L;tnw#s2>T8j~~f literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/data/36947.xls b/src/testcases/org/apache/poi/hssf/data/36947.xls new file mode 100755 index 0000000000000000000000000000000000000000..4c7bde6c2a0863465d009cf12c1b676156581ed0 GIT binary patch literal 142336 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,MATCH(V4:V220,V4:V220,0),""),IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),""))>0,1))} + */ + public void test21334() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sh = wb.createSheet(); + HSSFCell cell = sh.createRow(0).createCell((short)0); + String formula = "SUM(IF(FREQUENCY(IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),\"\"),IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),\"\"))>0,1))"; + cell.setCellFormula(formula); + + HSSFWorkbook wb_sv = writeOutAndReadBack(wb); + HSSFCell cell_sv = wb_sv.getSheetAt(0).getRow(0).getCell((short)0); + assertEquals(formula, cell_sv.getCellFormula()); + } + + public void test36947() throws Exception { + HSSFWorkbook wb = openSample("36947.xls"); + assertTrue("no errors reading sample xls", true); + writeOutAndReadBack(wb); + assertTrue("no errors writing sample xls", true); + } + + /** + * Bug 42448: Can't parse SUMPRODUCT(A!C7:A!C67, B8:B68) / B69 + */ + public void test42448(){ + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFCell cell = wb.createSheet().createRow(0).createCell((short)0); + cell.setCellFormula("SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"); + assertTrue("no errors parsing formula", true); + } + + public void test39634() throws Exception { + HSSFWorkbook wb = openSample("39634.xls"); + assertTrue("no errors reading sample xls", true); + writeOutAndReadBack(wb); + assertTrue("no errors writing sample xls", true); + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index e1afb453b..cb5b3d355 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -232,11 +232,11 @@ public final class TestHSSFWorkbook extends TestCase { // Demonstrate bug 44525: // Well... not quite, since isActive + isSelected were also added in the same bug fix if (sheet1.isSelected()) { - throw new AssertionFailedError("Identified bug 44525 a"); + throw new AssertionFailedError("Identified bug 44523 a"); } wb.setActiveSheet(1); if (sheet1.isActive()) { - throw new AssertionFailedError("Identified bug 44525 b"); + throw new AssertionFailedError("Identified bug 44523 b"); } confirmActiveSelected(sheet1, false); @@ -299,8 +299,81 @@ public final class TestHSSFWorkbook extends TestCase { } } + + public void testActiveSheetAfterDelete_bug40414() { + HSSFWorkbook wb=new HSSFWorkbook(); + HSSFSheet sheet0 = wb.createSheet("Sheet0"); + HSSFSheet sheet1 = wb.createSheet("Sheet1"); + HSSFSheet sheet2 = wb.createSheet("Sheet2"); + HSSFSheet sheet3 = wb.createSheet("Sheet3"); + HSSFSheet sheet4 = wb.createSheet("Sheet4"); + + // confirm default activation/selection + confirmActiveSelected(sheet0, true); + confirmActiveSelected(sheet1, false); + confirmActiveSelected(sheet2, false); + confirmActiveSelected(sheet3, false); + confirmActiveSelected(sheet4, false); + + wb.setActiveSheet(3); + wb.setSelectedTab(3); + + confirmActiveSelected(sheet0, false); + confirmActiveSelected(sheet1, false); + confirmActiveSelected(sheet2, false); + confirmActiveSelected(sheet3, true); + confirmActiveSelected(sheet4, false); + + wb.removeSheetAt(3); + // after removing the only active/selected sheet, another should be active/selected in its place + if (!sheet4.isSelected()) { + throw new AssertionFailedError("identified bug 40414 a"); + } + if (!sheet4.isActive()) { + throw new AssertionFailedError("identified bug 40414 b"); + } + + confirmActiveSelected(sheet0, false); + confirmActiveSelected(sheet1, false); + confirmActiveSelected(sheet2, false); + confirmActiveSelected(sheet4, true); + + sheet3 = sheet4; // re-align local vars in this test case + + // Some more cases of removing sheets + + // Starting with a multiple selection, and different active sheet + wb.setSelectedTabs(new int[] { 1, 3, }); + wb.setActiveSheet(2); + confirmActiveSelected(sheet0, false, false); + confirmActiveSelected(sheet1, false, true); + confirmActiveSelected(sheet2, true, false); + confirmActiveSelected(sheet3, false, true); + + // removing a sheet that is not active, and not the only selected sheet + wb.removeSheetAt(3); + confirmActiveSelected(sheet0, false, false); + confirmActiveSelected(sheet1, false, true); + confirmActiveSelected(sheet2, true, false); + + // removing the only selected sheet + wb.removeSheetAt(1); + confirmActiveSelected(sheet0, false, false); + confirmActiveSelected(sheet2, true, true); + + // The last remaining sheet should always be active+selected + wb.removeSheetAt(1); + confirmActiveSelected(sheet0, true, true); + } + private static void confirmActiveSelected(HSSFSheet sheet, boolean expected) { - assertEquals(expected, sheet.isActive()); - assertEquals(expected, sheet.isSelected()); + confirmActiveSelected(sheet, expected, expected); + } + + + private static void confirmActiveSelected(HSSFSheet sheet, + boolean expectedActive, boolean expectedSelected) { + assertEquals("active", expectedActive, sheet.isActive()); + assertEquals("selected", expectedSelected, sheet.isSelected()); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java index 98500960d..b3d08bf72 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java @@ -533,4 +533,28 @@ public final class TestNamedRange extends TestCase { String contents = c.getStringCellValue(); assertEquals("Contents of cell retrieved by its named reference", contents, cvalue); } + + public void testDeletedReference() throws Exception { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("24207.xls"); + assertEquals(2, wb.getNumberOfNames()); + + HSSFName name1 = wb.getNameAt(0); + assertEquals("a", name1.getNameName()); + assertEquals("Sheet1!$A$1", name1.getReference()); + AreaReference ref1 = new AreaReference(name1.getReference()); + assertTrue("Successfully constructed first reference", true); + + HSSFName name2 = wb.getNameAt(1); + assertEquals("b", name2.getNameName()); + assertEquals("#REF!", name2.getReference()); + assertTrue(name2.isDeleted()); + try { + AreaReference ref2 = new AreaReference(name2.getReference()); + fail("attempt to supply an invalid reference to AreaReference constructor results in exception"); + } catch (Exception e){ + ; + } + + } + }