diff options
author | Josh Micich <josh@apache.org> | 2008-10-27 21:30:02 +0000 |
---|---|---|
committer | Josh Micich <josh@apache.org> | 2008-10-27 21:30:02 +0000 |
commit | 8697fdb6d9a42d09034b9006105847e8f478c012 (patch) | |
tree | f23050bdd4922efbf1752e684b57e0f4239b5be1 /src/java/org | |
parent | 4ea70e1da597ae41f4e67e96e0e4da0538abd302 (diff) | |
download | poi-8697fdb6d9a42d09034b9006105847e8f478c012.tar.gz poi-8697fdb6d9a42d09034b9006105847e8f478c012.zip |
Merged revisions 707953,708242,708252,708260,708262,708286 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk
........
r707953 | josh | 2008-10-26 01:17:06 -0700 (Sun, 26 Oct 2008) | 1 line
Bugzilla 45966 - added implementation for FIND function (patch from Torstein Tauno Svendsen).
........
r708242 | nick | 2008-10-27 10:26:52 -0700 (Mon, 27 Oct 2008) | 1 line
Link typo fix
........
r708252 | nick | 2008-10-27 10:59:39 -0700 (Mon, 27 Oct 2008) | 1 line
Patch from bug #46092 - fix hssf dev utility
........
r708260 | josh | 2008-10-27 11:12:09 -0700 (Mon, 27 Oct 2008) | 1 line
Removed obsolete class
........
r708262 | josh | 2008-10-27 11:16:44 -0700 (Mon, 27 Oct 2008) | 1 line
Bugzilla 46065 - added implementation for VALUE function
........
r708286 | josh | 2008-10-27 12:24:42 -0700 (Mon, 27 Oct 2008) | 1 line
Preparation for fix for bug 46009. (Bug visible on ooxml branch, but this change will expose the problem)
........
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@708325 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org')
13 files changed, 297 insertions, 160 deletions
diff --git a/src/java/org/apache/poi/hssf/dev/HSSF.java b/src/java/org/apache/poi/hssf/dev/HSSF.java index 07baa3a2ba..c1af8a11e4 100644 --- a/src/java/org/apache/poi/hssf/dev/HSSF.java +++ b/src/java/org/apache/poi/hssf/dev/HSSF.java @@ -15,7 +15,6 @@ limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.dev; import java.io.FileInputStream; @@ -30,7 +29,7 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.util.Region; @@ -222,7 +221,7 @@ public class HSSF if (args.length < 2) { -/* try + try { HSSF hssf = new HSSF(args[ 0 ]); @@ -231,26 +230,30 @@ public class HSSF for (int k = 0; k < wb.getNumberOfSheets(); k++) { - System.out.println("Sheet " + k); HSSFSheet sheet = wb.getSheetAt(k); int rows = sheet.getPhysicalNumberOfRows(); - + System.out.println("Sheet " + k + " \"" + + wb.getSheetName(k) + "\" has " + + rows + " row(s)."); for (int r = 0; r < rows; r++) { - HSSFRow row = sheet.getPhysicalRowAt(r); - int cells = row.getPhysicalNumberOfCells(); - - System.out.println("ROW " + row.getRowNum()); + HSSFRow row = sheet.getRow(r); + int cells = (row != null) ? row.getPhysicalNumberOfCells() : 0; + if (row != null) { + System.out.println("\nROW " + row.getRowNum() + + " has " + cells + " cell(s)."); + } for (int c = 0; c < cells; c++) { - HSSFCell cell = row.getPhysicalCellAt(c); + HSSFCell cell = row.getCell(c); String value = null; switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_FORMULA : - value = "FORMULA "; + value = "FORMULA value=" + + cell.getCellFormula(); break; case HSSFCell.CELL_TYPE_NUMERIC : @@ -275,7 +278,7 @@ public class HSSF catch (Exception e) { e.printStackTrace(); - }*/ + } } else if (args.length == 2) { diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index c5e78af44d..901402eff0 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -68,7 +68,7 @@ import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; import org.apache.poi.hssf.record.aggregates.RecordAggregate.PositionTrackingVisitor; import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; import org.apache.poi.hssf.record.formula.FormulaShifter; -import org.apache.poi.hssf.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.hssf.util.PaneInformation; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java index 708b20d857..762af3be79 100644 --- a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java +++ b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java @@ -51,8 +51,8 @@ public final class CFHeaderRecord extends Record { { field_1_numcf = in.readShort(); field_2_need_recalculation = in.readShort(); - field_3_enclosing_cell_range = new org.apache.poi.hssf.util.CellRangeAddress(in); - field_4_cell_ranges = new org.apache.poi.hssf.util.CellRangeAddressList(in); + field_3_enclosing_cell_range = new CellRangeAddress(in); + field_4_cell_ranges = new CellRangeAddressList(in); } public int getNumberOfConditionalFormats() diff --git a/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java b/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java index 7683c6b863..1b917a7fce 100644 --- a/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java +++ b/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java @@ -50,7 +50,7 @@ public final class MergeCellsRecord extends Record { int nRegions = in.readUShort(); CellRangeAddress[] cras = new CellRangeAddress[nRegions]; for (int i = 0; i < nRegions; i++) { - cras[i] = new org.apache.poi.hssf.util.CellRangeAddress(in); + cras[i] = new CellRangeAddress(in); } _numberOfRegions = nRegions; _startIndex = 0; diff --git a/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java b/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java index bbf5c4d0a0..588276274f 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java @@ -22,8 +22,8 @@ import java.util.List; import org.apache.poi.hssf.model.RecordStream; import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.util.CellRangeAddress; -import org.apache.poi.hssf.util.CellRangeAddressList; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; /** * @@ -51,7 +51,8 @@ public final class MergedCellsTable extends RecordAggregate { MergeCellsRecord mcr = (MergeCellsRecord) rs.getNext(); int nRegions = mcr.getNumAreas(); for (int i = 0; i < nRegions; i++) { - temp.add(mcr.getAreaAt(i)); + CellRangeAddress cra = mcr.getAreaAt(i); + temp.add(cra); } } } @@ -102,7 +103,8 @@ public final class MergedCellsTable extends RecordAggregate { private void addMergeCellsRecord(MergeCellsRecord mcr) { int nRegions = mcr.getNumAreas(); for (int i = 0; i < nRegions; i++) { - _mergedRegions.add(mcr.getAreaAt(i)); + CellRangeAddress cra = mcr.getAreaAt(i); + _mergedRegions.add(cra); } } @@ -130,5 +132,4 @@ public final class MergedCellsTable extends RecordAggregate { public int getNumberOfMergedRegions() { return _mergedRegions.size(); } - } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java deleted file mode 100644 index e2a3c72a4c..0000000000 --- a/src/java/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java +++ /dev/null @@ -1,96 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 14, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class StringOperationEval implements OperationEval { - - - - /** - * Returns an instanceof StringValueEval or ErrorEval or BlankEval - * - * @param eval - * @param srcRow - * @param srcCol - */ - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { - ValueEval retval; - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if (ae.contains(srcRow, srcCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - retval = internalResolveEval(eval); - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - retval = internalResolveEval(eval); - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else { - retval = internalResolveEval(eval); - } - return retval; - } - - private ValueEval internalResolveEval(Eval eval) { - ValueEval retval; - if (eval instanceof StringValueEval) { - retval = (StringValueEval) eval; - } - else if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - ValueEval tve = re.getInnerValueEval(); - if (tve instanceof StringValueEval || tve instanceof BlankEval) { - retval = tve; - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else if (eval instanceof BlankEval) { - retval = (BlankEval) eval; - } - else { - retval = ErrorEval.NAME_INVALID; - } - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Find.java b/src/java/org/apache/poi/hssf/record/formula/functions/Find.java index 7bd11ecf34..5621eb5cea 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Find.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Find.java @@ -1,25 +1,65 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; + +/** + * Implementation of the FIND() function.<p/> + * + * <b>Syntax</b>:<br/> + * <b>FIND</b>(<b>find_text</b>, <b>within_text</b>, start_num)<p/> * + * FIND returns the character position of the first occurrence of <tt>find_text</tt> inside + * <tt>within_text</tt>. The third parameter, <tt>start_num</tt>, is optional (default=1) + * and specifies where to start searching from. Character positions are 1-based.<p/> + * + * @author Torstein Tauno Svendsen (torstei@officenet.no) */ -package org.apache.poi.hssf.record.formula.functions; +public class Find extends TextFunction { -public class Find extends NotImplementedFunction { + protected ValueEval evaluateFunc(Eval[] args, int srcCellRow, short srcCellCol) + throws EvaluationException { + int nArgs = args.length; + if (nArgs < 2 || nArgs > 3) { + return ErrorEval.VALUE_INVALID; + } + String needle = evaluateStringArg(args[0], srcCellRow, srcCellCol); + String haystack = evaluateStringArg(args[1], srcCellRow, srcCellCol); + int startpos; + if (nArgs == 3) { + startpos = evaluateIntArg(args[2], srcCellRow, srcCellCol); + if (startpos <= 0) { + return ErrorEval.VALUE_INVALID; + } + startpos--; // convert 1-based to zero based + } else { + startpos = 0; + } + int result = haystack.indexOf(needle, startpos); + if (result == -1) { + return ErrorEval.VALUE_INVALID; + } + return new NumberEval(result + 1); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Value.java b/src/java/org/apache/poi/hssf/record/formula/functions/Value.java index 6772dcf283..84f61db98e 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Value.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Value.java @@ -1,25 +1,188 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + package org.apache.poi.hssf.record.formula.functions; -public class Value extends NotImplementedFunction { +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.OperandResolver; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Implementation for Excel VALUE() function.<p/> + * + * <b>Syntax</b>:<br/> <b>VALUE</b>(<b>text</b>)<br/> + * + * Converts the text argument to a number. Leading and/or trailing whitespace is + * ignored. Currency symbols and thousands separators are stripped out. + * Scientific notation is also supported. If the supplied text does not convert + * properly the result is <b>#VALUE!</b> error. Blank string converts to zero. + * + * @author Josh Micich + */ +public final class Value implements Function { + + /** "1,0000" is valid, "1,00" is not */ + private static final int MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR = 4; + private static final Double ZERO = new Double(0.0); + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + if (args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + ValueEval veText; + try { + veText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + String strText = OperandResolver.coerceValueToString(veText); + Double result = convertTextToNumber(strText); + if (result == null) { + return ErrorEval.VALUE_INVALID; + } + return new NumberEval(result.doubleValue()); + } + + /** + * TODO see if the same functionality is needed in {@link OperandResolver#parseDouble(String)} + * + * @return <code>null</code> if there is any problem converting the text + */ + private static Double convertTextToNumber(String strText) { + boolean foundCurrency = false; + boolean foundUnaryPlus = false; + boolean foundUnaryMinus = false; + + int len = strText.length(); + int i; + for (i = 0; i < len; i++) { + char ch = strText.charAt(i); + if (Character.isDigit(ch) || ch == '.') { + break; + } + switch (ch) { + case ' ': + // intervening spaces between '$', '-', '+' are OK + continue; + case '$': + if (foundCurrency) { + // only one currency symbols is allowed + return null; + } + foundCurrency = true; + continue; + case '+': + if (foundUnaryMinus || foundUnaryPlus) { + return null; + } + foundUnaryPlus = true; + continue; + case '-': + if (foundUnaryMinus || foundUnaryPlus) { + return null; + } + foundUnaryMinus = true; + continue; + default: + // all other characters are illegal + return null; + } + } + if (i >= len) { + // didn't find digits or '.' + if (foundCurrency || foundUnaryMinus || foundUnaryPlus) { + return null; + } + return ZERO; + } + + // remove thousands separators + + boolean foundDecimalPoint = false; + int lastThousandsSeparatorIndex = Short.MIN_VALUE; + StringBuffer sb = new StringBuffer(len); + for (; i < len; i++) { + char ch = strText.charAt(i); + if (Character.isDigit(ch)) { + sb.append(ch); + continue; + } + switch (ch) { + case ' ': + String remainingText = strText.substring(i); + if (remainingText.trim().length() > 0) { + // intervening spaces not allowed once the digits start + return null; + } + break; + case '.': + if (foundDecimalPoint) { + return null; + } + if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { + return null; + } + foundDecimalPoint = true; + sb.append('.'); + continue; + case ',': + if (foundDecimalPoint) { + // thousands separators not allowed after '.' or 'E' + return null; + } + int distanceBetweenThousandsSeparators = i - lastThousandsSeparatorIndex; + // as long as there are 3 or more digits between + if (distanceBetweenThousandsSeparators < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { + return null; + } + lastThousandsSeparatorIndex = i; + // don't append ',' + continue; + + case 'E': + case 'e': + if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { + return null; + } + // append rest of strText and skip to end of loop + sb.append(strText.substring(i)); + i = len; + break; + default: + // all other characters are illegal + return null; + } + } + if (!foundDecimalPoint) { + if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) { + return null; + } + } + double d; + try { + d = Double.parseDouble(sb.toString()); + } catch (NumberFormatException e) { + // still a problem parsing the number - probably out of range + return null; + } + return new Double(foundUnaryMinus ? -d : d); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 75568f4dad..fd0e0a5359 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -670,7 +670,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet /** * @return the merged region at the specified index */ - public org.apache.poi.hssf.util.CellRangeAddress getMergedRegion(int index) { + public CellRangeAddress getMergedRegion(int index) { return sheet.getMergedRegionAt(index); } diff --git a/src/java/org/apache/poi/hssf/util/CellRangeAddress.java b/src/java/org/apache/poi/hssf/util/CellRangeAddress.java index cc67b8eb05..439db43dbe 100644 --- a/src/java/org/apache/poi/hssf/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/hssf/util/CellRangeAddress.java @@ -18,12 +18,12 @@ package org.apache.poi.hssf.util; import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.SelectionRecord;
-import org.apache.poi.util.LittleEndian;
/**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
*
* Note - {@link SelectionRecord} uses the BIFF5 version of this structure
+ * @deprecated use {@link org.apache.poi.ss.util.CellRangeAddress}
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
*/
public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress {
diff --git a/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java b/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java index 79ea50abb4..5f22fb7336 100644 --- a/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java +++ b/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java @@ -33,6 +33,8 @@ import org.apache.poi.util.LittleEndian; * range address (called an ADDR structure) contains 4 16-bit-values. * </p> * + * @deprecated use {@link org.apache.poi.ss.util.CellRangeAddressList} + * * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) */ public class CellRangeAddressList extends org.apache.poi.ss.util.CellRangeAddressList { diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddress.java b/src/java/org/apache/poi/ss/util/CellRangeAddress.java index 0d910c6824..3cc70cf483 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddress.java @@ -16,6 +16,7 @@ package org.apache.poi.ss.util; +import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.SelectionRecord; import org.apache.poi.util.LittleEndian; @@ -42,6 +43,17 @@ public class CellRangeAddress extends CellRangeAddressBase { LittleEndian.putUShort(data, offset + 6, getLastColumn()); return ENCODED_SIZE; } + public CellRangeAddress(RecordInputStream in) { + super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort()); + } + + private static int readUShortAndCheck(RecordInputStream in) { + if (in.remaining() < ENCODED_SIZE) { + // Ran out of data + throw new RuntimeException("Ran out of data reading CellRangeAddress"); + } + return in.readUShort(); + } public CellRangeAddress copy() { return new CellRangeAddress(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddressList.java b/src/java/org/apache/poi/ss/util/CellRangeAddressList.java index 72b5882488..65474ef980 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddressList.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddressList.java @@ -18,6 +18,8 @@ package org.apache.poi.ss.util; import java.util.ArrayList; import java.util.List; + +import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.util.LittleEndian; /** @@ -51,7 +53,17 @@ public class CellRangeAddressList { this(); addCellRangeAddress(firstRow, firstCol, lastRow, lastCol); } + /** + * @param in the RecordInputstream to read the record from + */ + public CellRangeAddressList(RecordInputStream in) { + this(); + int nItems = in.readUShort(); + for (int k = 0; k < nItems; k++) { + _list.add(new CellRangeAddress(in)); + } + } /** * Get the number of following ADDR structures. The number of this * structures is automatically set when reading an Excel file and/or |