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-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659524,659526-659571,659574,659576-660255,660257-660262,660264-660279,660281-660343,660345-660473,660475-660827,660829-660833,660835-660888,660890-663321,663323-663435,663437-663764,663766-663854,663856-664219,664221-664489,664494-664514,664516-668013,668015-668142,668144-668152,668154,668156-668256,668258,668260-669139,669141-669455,669457-669657,669659-669808,669810-670189,670191-671321,671323-672229,672231-672549,672551-672552,672554-672561,672563-672566,672568,672571-673049,673051-673852,673854-673862,673864-673986,673988-673996,673998-674347,674349-674890,674892-674910,674912-674936,674938-674952,674954-675078,675080-675085,675087-675217,675219-675660,675662-675670,675672-675716,675718-675726,675728-675733,675735-675775,675777-675782,675784,675786-675791,675794-675852,675854-676200,676202,676204,676206-676220,676222-676309,676311-676456,676458-676994,676996-677027,677030-677040,677042-677056,677058-677375,677377-677968,677970-677971,677973,677975-677994,677996-678286,678288-678538,678540-680393,680395-680469,680471-680529,680531-680852,680854-681529,681531-681571,681573-682224,682226,682228,682231-682281,682283-682335,682337-682507,682509,682512-682517,682519-682532,682534-682619,682622-682777,682779-682998,683000-683019,683021-683022,683024-683080,683082-683092,683094-683095,683097-683127,683129-683131,683133-683166,683168-683698,683700-683705,683707-683757,683759-683787,683789-683870,683872-683879,683881-683900,683902-684066,684068-684074,684076-684222,684224-684254,684257-684370 via svnmerge from

https://svn.apache.org/repos/asf/poi/trunk

........
  r684282 | nick | 2008-08-09 16:58:24 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Prepare to change how we do ranges, to handle different kinds of text in the cp area
........
  r684287 | nick | 2008-08-09 17:24:20 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Start to document the whole FIB stuff better
........
  r684293 | nick | 2008-08-09 17:46:39 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Add lots more getters/setters for useful things to the FIB
........
  r684299 | nick | 2008-08-09 18:23:42 +0100 (Sat, 09 Aug 2008) | 1 line
  
  More tests to show that the range based stuff is working properly
........
  r684302 | nick | 2008-08-09 18:33:29 +0100 (Sat, 09 Aug 2008) | 1 line
  
  More header and footer files, this time with unicode in it too
........
  r684309 | nick | 2008-08-09 18:58:35 +0100 (Sat, 09 Aug 2008) | 1 line
  
  More range tests, which show that we do have a bug in the hwpf unicode support
........
  r684318 | josh | 2008-08-09 20:29:23 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Converted rows map within HSSFSheet to use Integer keys
........
  r684319 | nick | 2008-08-09 20:34:38 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Big big unicode rationalisation in text piece code
........
  r684321 | josh | 2008-08-09 20:47:39 +0100 (Sat, 09 Aug 2008) | 1 line
  
  added getRowIndex() to HSSFCell, deprecated HSSFFormulaEvaluator.setCurrentRow()
........
  r684322 | nick | 2008-08-09 20:56:37 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Get most of the hwpf tests passing again
........
  r684336 | nick | 2008-08-09 21:31:48 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Improve FIB updating on range changes, and add passing tests for non unicode paragraph properties
........
  r684349 | nick | 2008-08-09 22:31:28 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Start on headers/footers support
........
  r684355 | nick | 2008-08-09 22:46:14 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Tests to show that header stuff all works right
........
  r684362 | nick | 2008-08-09 23:08:34 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Add header/footer support to HWPF WordExtractor
........
  r684370 | nick | 2008-08-09 23:24:47 +0100 (Sat, 09 Aug 2008) | 1 line
  
  Disable a few HWPF tests that aren't working while the unicode/paragraph bug is outstanding
........


git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@684374 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-08-09 22:55:33 +00:00
parent d36f6623f1
commit 9315f880d8
55 changed files with 2131 additions and 767 deletions

View File

@ -58,6 +58,9 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action> <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release> </release>
<release version="3.1.1-alpha1" date="2008-??-??"> <release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="add">Include headers and footers int he extracted text from HWPF's WordExtractor</action>
<action dev="POI-DEVELOPERS" type="add">Added support to HWPF for headers and footers</action>
<action dev="POI-DEVELOPERS" type="fix">Improve how HWPF deals with unicode internally. Should avoid some odd behaviour when manipulating unicode text</action>
<action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action> <action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action>
<action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action> <action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
<action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action> <action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action>

View File

@ -55,6 +55,9 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action> <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release> </release>
<release version="3.1.1-alpha1" date="2008-??-??"> <release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="add">Include headers and footers int he extracted text from HWPF's WordExtractor</action>
<action dev="POI-DEVELOPERS" type="add">Added support to HWPF for headers and footers</action>
<action dev="POI-DEVELOPERS" type="fix">Improve how HWPF deals with unicode internally. Should avoid some odd behaviour when manipulating unicode text</action>
<action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action> <action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action>
<action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action> <action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
<action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action> <action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action>

View File

@ -26,6 +26,7 @@ import org.apache.poi.hssf.record.formula.*;
import org.apache.poi.hssf.record.formula.function.FunctionMetadata; import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry; import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.AreaReference; import org.apache.poi.hssf.util.AreaReference;
import org.apache.poi.hssf.util.CellReference; import org.apache.poi.hssf.util.CellReference;
@ -113,7 +114,7 @@ public final class FormulaParser {
} }
public static Ptg[] parse(String formula, Workbook workbook, int formulaType) { public static Ptg[] parse(String formula, Workbook workbook, int formulaType) {
FormulaParser fp = new FormulaParser(formula, workbook); FormulaParser fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, formula);
fp.parse(); fp.parse();
return fp.getRPNPtg(formulaType); return fp.getRPNPtg(formulaType);
} }
@ -817,7 +818,7 @@ end;
/** /**
* API call to execute the parsing of the formula * API call to execute the parsing of the formula
* @deprecated use Ptg[] FormulaParser.parse(String, Workbook) directly * @deprecated use {@link #parse(String, Workbook)} directly
*/ */
public void parse() { public void parse() {
pointer=0; pointer=0;

View File

@ -48,6 +48,7 @@ import org.apache.poi.hssf.record.TextObjectRecord;
import org.apache.poi.hssf.record.UnicodeString; import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Comment;
@ -73,59 +74,24 @@ import org.apache.poi.ss.usermodel.RichTextString;
* @version 1.0-pre * @version 1.0-pre
*/ */
public class HSSFCell implements Cell { public class HSSFCell implements Cell {
/** /** Numeric Cell type (0) @see #setCellType(int) @see #getCellType() */
* Numeric Cell type (0) public final static int CELL_TYPE_NUMERIC = 0;
* @see #setCellType(int) /** String Cell type (1) @see #setCellType(int) @see #getCellType() */
* @see #getCellType() public final static int CELL_TYPE_STRING = 1;
*/ /** Formula Cell type (2) @see #setCellType(int) @see #getCellType() */
public final static int CELL_TYPE_FORMULA = 2;
/** Blank Cell type (3) @see #setCellType(int) @see #getCellType() */
public final static int CELL_TYPE_BLANK = 3;
/** Boolean Cell type (4) @see #setCellType(int) @see #getCellType() */
public final static int CELL_TYPE_BOOLEAN = 4;
/** Error Cell type (5) @see #setCellType(int) @see #getCellType() */
public final static int CELL_TYPE_ERROR = 5;
public final static int CELL_TYPE_NUMERIC = 0;
/**
* String Cell type (1)
* @see #setCellType(int)
* @see #getCellType()
*/
public final static int CELL_TYPE_STRING = 1;
/**
* Formula Cell type (2)
* @see #setCellType(int)
* @see #getCellType()
*/
public final static int CELL_TYPE_FORMULA = 2;
/**
* Blank Cell type (3)
* @see #setCellType(int)
* @see #getCellType()
*/
public final static int CELL_TYPE_BLANK = 3;
/**
* Boolean Cell type (4)
* @see #setCellType(int)
* @see #getCellType()
*/
public final static int CELL_TYPE_BOOLEAN = 4;
/**
* Error Cell type (5)
* @see #setCellType(int)
* @see #getCellType()
*/
public final static int CELL_TYPE_ERROR = 5;
public final static short ENCODING_UNCHANGED = -1; public final static short ENCODING_UNCHANGED = -1;
public final static short ENCODING_COMPRESSED_UNICODE = 0; public final static short ENCODING_COMPRESSED_UNICODE = 0;
public final static short ENCODING_UTF_16 = 1; public final static short ENCODING_UTF_16 = 1;
private int cellType; private int cellType;
private HSSFRichTextString stringValue; private HSSFRichTextString stringValue;
private short encoding = ENCODING_UNCHANGED;
private HSSFWorkbook book; private HSSFWorkbook book;
private Sheet sheet; private Sheet sheet;
private CellValueRecordInterface record; private CellValueRecordInterface record;
@ -195,9 +161,7 @@ public class HSSFCell implements Cell {
* @param sheet - Sheet record of the sheet containing this cell * @param sheet - Sheet record of the sheet containing this cell
* @param cval - the Cell Value Record we wish to represent * @param cval - the Cell Value Record we wish to represent
*/ */
protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, protected HSSFCell(HSSFWorkbook book, Sheet sheet, CellValueRecordInterface cval) {
CellValueRecordInterface cval)
{
record = cval; record = cval;
cellType = determineType(cval); cellType = determineType(cval);
stringValue = null; stringValue = null;
@ -269,6 +233,12 @@ public class HSSFCell implements Cell {
return book.getWorkbook(); return book.getWorkbook();
} }
/**
* @return the (zero based) index of the row containing this cell
*/
public int getRowIndex() {
return record.getRow();
}
/** /**
* Set the cell's number within the row (0 based). * Set the cell's number within the row (0 based).
* @param num short the cell number * @param num short the cell number
@ -984,13 +954,13 @@ public class HSSFCell implements Cell {
* Errors are displayed as #ERR&lt;errIdx&gt; * Errors are displayed as #ERR&lt;errIdx&gt;
*/ */
public String toString() { public String toString() {
switch (getCellType()) { switch (getCellType()) {
case CELL_TYPE_BLANK: case CELL_TYPE_BLANK:
return ""; return "";
case CELL_TYPE_BOOLEAN: case CELL_TYPE_BOOLEAN:
return getBooleanCellValue()?"TRUE":"FALSE"; return getBooleanCellValue()?"TRUE":"FALSE";
case CELL_TYPE_ERROR: case CELL_TYPE_ERROR:
return "#ERR"+getErrorCellValue(); return ErrorEval.getText((( BoolErrRecord ) record).getErrorValue());
case CELL_TYPE_FORMULA: case CELL_TYPE_FORMULA:
return getCellFormula(); return getCellFormula();
case CELL_TYPE_NUMERIC: case CELL_TYPE_NUMERIC:
@ -998,7 +968,7 @@ public class HSSFCell implements Cell {
if (HSSFDateUtil.isCellDateFormatted(this)) { if (HSSFDateUtil.isCellDateFormatted(this)) {
DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy"); DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
return sdf.format(getDateCellValue()); return sdf.format(getDateCellValue());
}else { } else {
return getNumericCellValue() + ""; return getNumericCellValue() + "";
} }
case CELL_TYPE_STRING: case CELL_TYPE_STRING:

View File

@ -39,7 +39,7 @@ public class HSSFFormulaEvaluator extends FormulaEvaluator {
* your needs are more complex than just having the * your needs are more complex than just having the
* formula evaluated. * formula evaluated.
*/ */
public static FormulaParser getUnderlyingParser(HSSFWorkbook workbook, String formula) { public static FormulaParser getUnderlyingParser(Workbook workbook, String formula) {
return new FormulaParser(formula, workbook); return new FormulaParser(formula, workbook);
} }
@ -52,7 +52,7 @@ public class HSSFFormulaEvaluator extends FormulaEvaluator {
* @param workbook * @param workbook
*/ */
void inspectPtgs(String formula) { void inspectPtgs(String formula) {
HSSFWorkbook hssfWb = (HSSFWorkbook)workbook; HSSFWorkbook hssfWb = (HSSFWorkbook)_workbook;
FormulaParser fp = new FormulaParser(formula, hssfWb); FormulaParser fp = new FormulaParser(formula, hssfWb);
fp.parse(); fp.parse();
Ptg[] ptgs = fp.getRPNPtg(); Ptg[] ptgs = fp.getRPNPtg();

View File

@ -45,26 +45,18 @@ public final class HSSFRow implements Comparable, Row {
/** /**
* reference to low level representation * reference to low level representation
*/ */
private RowRecord row; private RowRecord row;
/** /**
* reference to containing low level Workbook * reference to containing low level Workbook
*/ */
private HSSFWorkbook book; private HSSFWorkbook book;
/** /**
* reference to containing Sheet * reference to containing Sheet
*/ */
private Sheet sheet; private Sheet sheet;
// TODO - ditch this constructor
HSSFRow()
{
}
/** /**
* Creates new HSSFRow from scratch. Only HSSFSheet should do this. * Creates new HSSFRow from scratch. Only HSSFSheet should do this.
* *
@ -204,14 +196,10 @@ public final class HSSFRow implements Comparable, Row {
* @param cell low level cell to create the high level representation from * @param cell low level cell to create the high level representation from
* @return HSSFCell representing the low level record passed in * @return HSSFCell representing the low level record passed in
*/ */
protected HSSFCell createCellFromRecord(CellValueRecordInterface cell) {
protected HSSFCell createCellFromRecord(CellValueRecordInterface cell) HSSFCell hcell = new HSSFCell(book, sheet, cell);
{
HSSFCell hcell = new HSSFCell(book, sheet, getRowNum(), cell);
addCell(hcell); addCell(hcell);
// sheet.addValueRecord(getRowNum(),cell.getCellValueRecord());
return hcell; return hcell;
} }
@ -318,15 +306,7 @@ public final class HSSFRow implements Comparable, Row {
} }
/** /**
* Get the hssfcell representing a given column (logical cell) * @deprecated (Aug 2008) use {@link #getCell(int)}
* 0-based. If you ask for a cell that is not defined then
* you get a null, unless you have set a different
* {@link MissingCellPolicy} on the base workbook.
* Short method signature provided to retain binary
* compatibility.
*
* @param cellnum 0 based column number
* @return HSSFCell representing that column or null if undefined.
*/ */
public HSSFCell getCell(short cellnum) { public HSSFCell getCell(short cellnum) {
int ushortCellNum = cellnum & 0x0000FFFF; // avoid sign extension int ushortCellNum = cellnum & 0x0000FFFF; // avoid sign extension

View File

@ -98,7 +98,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
*/ */
private Sheet sheet; private Sheet sheet;
private TreeMap rows; // TODO - use simple key into this map /** stores <tt>HSSFRow</tt>s by <tt>Integer</tt> (zero-based row number) key */
private TreeMap rows;
protected Workbook book; protected Workbook book;
protected HSSFWorkbook workbook; protected HSSFWorkbook workbook;
private int firstrow; private int firstrow;
@ -116,7 +117,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
protected HSSFSheet(HSSFWorkbook workbook) protected HSSFSheet(HSSFWorkbook workbook)
{ {
sheet = Sheet.createSheet(); sheet = Sheet.createSheet();
rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY); rows = new TreeMap();
this.workbook = workbook; this.workbook = workbook;
this.book = workbook.getWorkbook(); this.book = workbook.getWorkbook();
} }
@ -243,7 +244,14 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
HSSFRow hrow = (HSSFRow) row; HSSFRow hrow = (HSSFRow) row;
if (rows.size() > 0) if (rows.size() > 0)
{ {
rows.remove(row); Integer key = new Integer(row.getRowNum());
HSSFRow removedRow = (HSSFRow) rows.remove(key);
if (removedRow != row) {
if (removedRow != null) {
rows.put(key, removedRow);
}
throw new RuntimeException("Specified row does not belong to this sheet");
}
if (hrow.getRowNum() == getLastRowNum()) if (hrow.getRowNum() == getLastRowNum())
{ {
lastrow = findLastRow(lastrow); lastrow = findLastRow(lastrow);
@ -303,7 +311,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
private void addRow(HSSFRow row, boolean addLow) private void addRow(HSSFRow row, boolean addLow)
{ {
rows.put(row, row); rows.put(new Integer(row.getRowNum()), row);
if (addLow) if (addLow)
{ {
sheet.addRow(row.getRowRecord()); sheet.addRow(row.getRowRecord());
@ -321,17 +329,11 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
/** /**
* Returns the logical row (not physical) 0-based. If you ask for a row that is not * Returns the logical row (not physical) 0-based. If you ask for a row that is not
* defined you get a null. This is to say row 4 represents the fifth row on a sheet. * defined you get a null. This is to say row 4 represents the fifth row on a sheet.
* @param rownum row to get * @param rowIndex row to get
* @return HSSFRow representing the rownumber or null if its not defined on the sheet * @return HSSFRow representing the rownumber or null if its not defined on the sheet
*/ */
public HSSFRow getRow(int rowIndex) {
public HSSFRow getRow(int rownum) return (HSSFRow) rows.get(new Integer(rowIndex));
{
HSSFRow row = new HSSFRow();
//row.setRowNum((short) rownum);
row.setRowNum( rownum);
return (HSSFRow) rows.get(row);
} }
/** /**
@ -592,7 +594,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
public void setHorizontallyCenter(boolean value) public void setHorizontallyCenter(boolean value)
{ {
sheet.getPageSettings().getHCenter().setHCenter(value); sheet.getPageSettings().getHCenter().setHCenter(value);
} }
/** /**

View File

@ -26,7 +26,6 @@ import java.util.Stack;
import org.apache.poi.hssf.model.FormulaParser; import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.AreaPtg; import org.apache.poi.hssf.record.formula.AreaPtg;
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.BoolPtg; import org.apache.poi.hssf.record.formula.BoolPtg;
import org.apache.poi.hssf.record.formula.ControlPtg; import org.apache.poi.hssf.record.formula.ControlPtg;
import org.apache.poi.hssf.record.formula.IntPtg; import org.apache.poi.hssf.record.formula.IntPtg;
@ -36,7 +35,6 @@ import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg; import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.NumberPtg; import org.apache.poi.hssf.record.formula.NumberPtg;
import org.apache.poi.hssf.record.formula.OperationPtg; import org.apache.poi.hssf.record.formula.OperationPtg;
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg; import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.RefPtg; import org.apache.poi.hssf.record.formula.RefPtg;
@ -93,18 +91,19 @@ public class FormulaEvaluator {
} }
protected Row row; protected Sheet _sheet;
protected Sheet sheet; protected Workbook _workbook;
protected Workbook workbook;
public FormulaEvaluator(Sheet sheet, Workbook workbook) { public FormulaEvaluator(Sheet sheet, Workbook workbook) {
this.sheet = sheet; this._sheet = sheet;
this.workbook = workbook; this._workbook = workbook;
} }
public void setCurrentRow(Row row) { /**
this.row = row; * Does nothing
} * @deprecated - not needed, since the current row can be derived from the cell
*/
public void setCurrentRow(Row row) {}
/** /**
* If cell contains a formula, the formula is evaluated and returned, * If cell contains a formula, the formula is evaluated and returned,
@ -119,25 +118,25 @@ public class FormulaEvaluator {
if (cell != null) { if (cell != null) {
switch (cell.getCellType()) { switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK: case Cell.CELL_TYPE_BLANK:
retval = new CellValue(Cell.CELL_TYPE_BLANK, workbook.getCreationHelper()); retval = new CellValue(Cell.CELL_TYPE_BLANK, _workbook.getCreationHelper());
break; break;
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
retval = new CellValue(Cell.CELL_TYPE_BOOLEAN, workbook.getCreationHelper()); retval = new CellValue(Cell.CELL_TYPE_BOOLEAN, _workbook.getCreationHelper());
retval.setBooleanValue(cell.getBooleanCellValue()); retval.setBooleanValue(cell.getBooleanCellValue());
break; break;
case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_ERROR:
retval = new CellValue(Cell.CELL_TYPE_ERROR, workbook.getCreationHelper()); retval = new CellValue(Cell.CELL_TYPE_ERROR, _workbook.getCreationHelper());
retval.setErrorValue(cell.getErrorCellValue()); retval.setErrorValue(cell.getErrorCellValue());
break; break;
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
retval = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook), workbook.getCreationHelper()); retval = getCellValueForEval(internalEvaluate(cell, _sheet, _workbook), _workbook.getCreationHelper());
break; break;
case Cell.CELL_TYPE_NUMERIC: case Cell.CELL_TYPE_NUMERIC:
retval = new CellValue(Cell.CELL_TYPE_NUMERIC, workbook.getCreationHelper()); retval = new CellValue(Cell.CELL_TYPE_NUMERIC, _workbook.getCreationHelper());
retval.setNumberValue(cell.getNumericCellValue()); retval.setNumberValue(cell.getNumericCellValue());
break; break;
case Cell.CELL_TYPE_STRING: case Cell.CELL_TYPE_STRING:
retval = new CellValue(Cell.CELL_TYPE_STRING, workbook.getCreationHelper()); retval = new CellValue(Cell.CELL_TYPE_STRING, _workbook.getCreationHelper());
retval.setRichTextStringValue(cell.getRichStringCellValue()); retval.setRichTextStringValue(cell.getRichStringCellValue());
break; break;
} }
@ -168,7 +167,7 @@ public class FormulaEvaluator {
if (cell != null) { if (cell != null) {
switch (cell.getCellType()) { switch (cell.getCellType()) {
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook), workbook.getCreationHelper()); CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet, _workbook), _workbook.getCreationHelper());
switch (cv.getCellType()) { switch (cv.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
cell.setCellValue(cv.getBooleanValue()); cell.setCellValue(cv.getBooleanValue());
@ -213,7 +212,7 @@ public class FormulaEvaluator {
if (cell != null) { if (cell != null) {
switch (cell.getCellType()) { switch (cell.getCellType()) {
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook), workbook.getCreationHelper()); CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet, _workbook), _workbook.getCreationHelper());
switch (cv.getCellType()) { switch (cv.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
cell.setCellType(Cell.CELL_TYPE_BOOLEAN); cell.setCellType(Cell.CELL_TYPE_BOOLEAN);
@ -258,7 +257,6 @@ public class FormulaEvaluator {
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) { for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
Row r = (Row)rit.next(); Row r = (Row)rit.next();
evaluator.setCurrentRow(r);
for (Iterator cit = r.cellIterator(); cit.hasNext();) { for (Iterator cit = r.cellIterator(); cit.hasNext();) {
Cell c = (Cell)cit.next(); Cell c = (Cell)cit.next();
@ -312,8 +310,8 @@ public class FormulaEvaluator {
* else a runtime exception will be thrown somewhere inside the method. * else a runtime exception will be thrown somewhere inside the method.
* (Hence this is a private method.) * (Hence this is a private method.)
*/ */
private static ValueEval internalEvaluate(Cell srcCell, Row srcRow, Sheet sheet, Workbook workbook) { private static ValueEval internalEvaluate(Cell srcCell, Sheet sheet, Workbook workbook) {
int srcRowNum = srcRow.getRowNum(); int srcRowNum = srcCell.getRowIndex();
short srcColNum = srcCell.getCellNum(); short srcColNum = srcCell.getCellNum();
@ -379,7 +377,7 @@ public class FormulaEvaluator {
int rowIx = refPtg.getRow(); int rowIx = refPtg.getRow();
Row row = sheet.getRow(rowIx); Row row = sheet.getRow(rowIx);
Cell cell = (row != null) ? row.getCell(colIx) : null; Cell cell = (row != null) ? row.getCell(colIx) : null;
stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook)); stack.push(createRef2DEval(refPtg, cell, sheet, workbook));
} }
else if (ptg instanceof Ref3DPtg) { else if (ptg instanceof Ref3DPtg) {
Ref3DPtg refPtg = (Ref3DPtg) ptg; Ref3DPtg refPtg = (Ref3DPtg) ptg;
@ -390,7 +388,7 @@ public class FormulaEvaluator {
); );
Row row = xsheet.getRow(rowIx); Row row = xsheet.getRow(rowIx);
Cell cell = (row != null) ? row.getCell(colIx) : null; Cell cell = (row != null) ? row.getCell(colIx) : null;
stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook)); stack.push(createRef3DEval(refPtg, cell, xsheet, workbook));
} }
else if (ptg instanceof AreaPtg) { else if (ptg instanceof AreaPtg) {
AreaPtg ap = (AreaPtg) ptg; AreaPtg ap = (AreaPtg) ptg;
@ -581,7 +579,7 @@ public class FormulaEvaluator {
case Cell.CELL_TYPE_STRING: case Cell.CELL_TYPE_STRING:
return new StringEval(cell.getRichStringCellValue().getString()); return new StringEval(cell.getRichStringCellValue().getString());
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
return internalEvaluate(cell, row, sheet, workbook); return internalEvaluate(cell, sheet, workbook);
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue()); return BoolEval.valueOf(cell.getBooleanCellValue());
case Cell.CELL_TYPE_BLANK: case Cell.CELL_TYPE_BLANK:
@ -597,7 +595,7 @@ public class FormulaEvaluator {
* Non existent cells are treated as RefEvals containing BlankEval. * Non existent cells are treated as RefEvals containing BlankEval.
*/ */
private static Ref2DEval createRef2DEval(RefPtg ptg, Cell cell, private static Ref2DEval createRef2DEval(RefPtg ptg, Cell cell,
Row row, Sheet sheet, Workbook workbook) { Sheet sheet, Workbook workbook) {
if (cell == null) { if (cell == null) {
return new Ref2DEval(ptg, BlankEval.INSTANCE); return new Ref2DEval(ptg, BlankEval.INSTANCE);
} }
@ -608,7 +606,7 @@ public class FormulaEvaluator {
case Cell.CELL_TYPE_STRING: case Cell.CELL_TYPE_STRING:
return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
return new Ref2DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); return new Ref2DEval(ptg, internalEvaluate(cell, sheet, workbook));
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
case Cell.CELL_TYPE_BLANK: case Cell.CELL_TYPE_BLANK:
@ -623,7 +621,7 @@ public class FormulaEvaluator {
* create a Ref3DEval for Ref3DPtg. * create a Ref3DEval for Ref3DPtg.
*/ */
private static Ref3DEval createRef3DEval(Ref3DPtg ptg, Cell cell, private static Ref3DEval createRef3DEval(Ref3DPtg ptg, Cell cell,
Row row, Sheet sheet, Workbook workbook) { Sheet sheet, Workbook workbook) {
if (cell == null) { if (cell == null) {
return new Ref3DEval(ptg, BlankEval.INSTANCE); return new Ref3DEval(ptg, BlankEval.INSTANCE);
} }
@ -633,7 +631,7 @@ public class FormulaEvaluator {
case Cell.CELL_TYPE_STRING: case Cell.CELL_TYPE_STRING:
return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString()));
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
return new Ref3DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); return new Ref3DEval(ptg, internalEvaluate(cell, sheet, workbook));
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue()));
case Cell.CELL_TYPE_BLANK: case Cell.CELL_TYPE_BLANK:

View File

@ -77,6 +77,7 @@ public interface Cell {
int getCellType(); int getCellType();
short getCellNum(); short getCellNum();
int getRowIndex();
String getCellFormula(); String getCellFormula();

View File

@ -104,6 +104,8 @@ public interface Cell {
short getCellNum(); short getCellNum();
int getRowIndex();
/** /**
* set the cells type (numeric, formula or string) * set the cells type (numeric, formula or string)
* @see #CELL_TYPE_NUMERIC * @see #CELL_TYPE_NUMERIC

View File

@ -100,6 +100,9 @@ public final class XSSFCell implements Cell {
public short getCellNum() { public short getCellNum() {
return (short)this.cellNum; return (short)this.cellNum;
} }
public int getRowIndex() {
return row.getRowNum();
}
public CellStyle getCellStyle() { public CellStyle getCellStyle() {
// Zero is the empty default // Zero is the empty default

View File

@ -50,8 +50,10 @@ import org.apache.poi.hwpf.usermodel.*;
public class HWPFDocument extends POIDocument public class HWPFDocument extends POIDocument
// implements Cloneable // implements Cloneable
{ {
/** The FIB*/ /** The FIB */
protected FileInformationBlock _fib; protected FileInformationBlock _fib;
/** And for making sense of CP lengths in the FIB */
protected CPSplitCalculator _cpSplit;
/** main document stream buffer*/ /** main document stream buffer*/
protected byte[] _mainStream; protected byte[] _mainStream;
@ -177,6 +179,7 @@ public class HWPFDocument extends POIDocument
// Create our FIB, and check for the doc being encrypted // Create our FIB, and check for the doc being encrypted
_fib = new FileInformationBlock(_mainStream); _fib = new FileInformationBlock(_mainStream);
_cpSplit = new CPSplitCalculator(_fib);
if(_fib.isFEncrypted()) { if(_fib.isFEncrypted()) {
throw new EncryptedDocumentException("Cannot process encrypted word files!"); throw new EncryptedDocumentException("Cannot process encrypted word files!");
} }
@ -285,19 +288,63 @@ public class HWPFDocument extends POIDocument
{ {
return _fib; return _fib;
} }
public CPSplitCalculator getCPSplitCalculator()
{
return _cpSplit;
}
public DocumentProperties getDocProperties() public DocumentProperties getDocProperties()
{ {
return _dop; return _dop;
} }
public Range getRange() /**
{ * Returns the range that covers all text in the
// hack to get the ending cp of the document, Have to revisit this. * file, including main text, footnotes, headers
java.util.List text = _tpt.getTextPieces(); * and comments
PropertyNode p = (PropertyNode)text.get(text.size() - 1); */
public Range getOverallRange() {
// hack to get the ending cp of the document, Have to revisit this.
java.util.List text = _tpt.getTextPieces();
PropertyNode p = (PropertyNode)text.get(text.size() - 1);
return new Range(0, p.getEnd(), this); return new Range(0, p.getEnd(), this);
}
/**
* Returns the range which covers the whole of the
* document, but excludes any headers and footers.
*/
public Range getRange() {
return new Range(
_cpSplit.getMainDocumentStart(),
_cpSplit.getMainDocumentEnd(),
this
);
}
/**
* Returns the range which covers all the Footnotes.
*/
public Range getFootnoteRange() {
return new Range(
_cpSplit.getFootnoteStart(),
_cpSplit.getFootnoteEnd(),
this
);
}
/**
* Returns the range which covers all "Header Stories".
* A header story contains a header, footer, end note
* separators and footnote separators.
*/
public Range getHeaderStoryRange() {
return new Range(
_cpSplit.getHeaderStoryStart(),
_cpSplit.getHeaderStoryEnd(),
this
);
} }
/** /**
@ -515,6 +562,10 @@ public class HWPFDocument extends POIDocument
{ {
return _dataStream; return _dataStream;
} }
public byte[] getTableStream()
{
return _tableStream;
}
public int registerList(HWPFList list) public int registerList(HWPFList list)
{ {

View File

@ -0,0 +1,52 @@
/* ====================================================================
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.hwpf.dev;
import java.io.FileInputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.FileInformationBlock;
/**
* Used by developers to list out key information on a
* HWPF file. End users will probably never need to
* use this program.
*/
public class HWPFLister {
private HWPFDocument doc;
public HWPFLister(HWPFDocument doc) {
this.doc = doc;
}
public static void main(String[] args) throws Exception {
if(args.length == 0) {
System.err.println("Use:");
System.err.println(" HWPFLister <filename>");
System.exit(1);
}
HWPFLister l = new HWPFLister(
new HWPFDocument(new FileInputStream(args[0]))
);
l.dumpFIB();
}
public void dumpFIB() throws Exception {
FileInformationBlock fib = doc.getFileInformationBlock();
System.out.println(fib.toString());
}
}

View File

@ -25,6 +25,7 @@ import java.util.Iterator;
import org.apache.poi.POIOLE2TextExtractor; import org.apache.poi.POIOLE2TextExtractor;
import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.TextPiece; import org.apache.poi.hwpf.model.TextPiece;
import org.apache.poi.hwpf.usermodel.HeaderStories;
import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@ -115,6 +116,65 @@ public class WordExtractor extends POIOLE2TextExtractor {
return ret; return ret;
} }
/**
* Add the header/footer text, if it's not empty
*/
private void appendHeaderFooter(String text, StringBuffer out) {
if(text == null || text.length() == 0)
return;
text = text.replace('\r', '\n');
if(! text.endsWith("\n")) {
out.append(text);
out.append('\n');
return;
}
if(text.endsWith("\n\n")) {
out.append(text.substring(0, text.length()-1));
return;
}
out.append(text);
return;
}
/**
* Grab the text from the headers
*/
public String getHeaderText() {
HeaderStories hs = new HeaderStories(doc);
StringBuffer ret = new StringBuffer();
if(hs.getFirstHeader() != null) {
appendHeaderFooter(hs.getFirstHeader(), ret);
}
if(hs.getEvenHeader() != null) {
appendHeaderFooter(hs.getEvenHeader(), ret);
}
if(hs.getOddHeader() != null) {
appendHeaderFooter(hs.getOddHeader(), ret);
}
return ret.toString();
}
/**
* Grab the text from the footers
*/
public String getFooterText() {
HeaderStories hs = new HeaderStories(doc);
StringBuffer ret = new StringBuffer();
if(hs.getFirstFooter() != null) {
appendHeaderFooter(hs.getFirstFooter(), ret);
}
if(hs.getEvenFooter() != null) {
appendHeaderFooter(hs.getEvenFooter(), ret);
}
if(hs.getOddFooter() != null) {
appendHeaderFooter(hs.getOddFooter(), ret);
}
return ret.toString();
}
/** /**
* Grab the text out of the text pieces. Might also include various * Grab the text out of the text pieces. Might also include various
* bits of crud, but will work in cases where the text piece -> paragraph * bits of crud, but will work in cases where the text piece -> paragraph
@ -128,7 +188,7 @@ public class WordExtractor extends POIOLE2TextExtractor {
TextPiece piece = (TextPiece) textPieces.next(); TextPiece piece = (TextPiece) textPieces.next();
String encoding = "Cp1252"; String encoding = "Cp1252";
if (piece.usesUnicode()) { if (piece.isUnicode()) {
encoding = "UTF-16LE"; encoding = "UTF-16LE";
} }
try { try {
@ -158,10 +218,16 @@ public class WordExtractor extends POIOLE2TextExtractor {
*/ */
public String getText() { public String getText() {
StringBuffer ret = new StringBuffer(); StringBuffer ret = new StringBuffer();
ret.append(getHeaderText());
String[] text = getParagraphText(); String[] text = getParagraphText();
for(int i=0; i<text.length; i++) { for(int i=0; i<text.length; i++) {
ret.append(text[i]); ret.append(text[i]);
} }
ret.append(getFooterText());
return ret.toString(); return ret.toString();
} }
} }

View File

@ -0,0 +1,141 @@
/* ====================================================================
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.hwpf.model;
import org.apache.poi.hwpf.HWPFDocument;
/**
* Helper class for {@link HWPFDocument}, which figures out
* where different kinds of text can be found within the
* overall CP splurge.
*/
public class CPSplitCalculator {
private FileInformationBlock fib;
public CPSplitCalculator(FileInformationBlock fib) {
this.fib = fib;
}
/**
* Where the main document text starts. Always 0.
*/
public int getMainDocumentStart() {
return 0;
}
/**
* Where the main document text ends.
* Given by FibRgLw97.ccpText
*/
public int getMainDocumentEnd() {
return fib.getCcpText();
}
/**
* Where the Footnotes text starts.
* Follows straight on from the main text.
*/
public int getFootnoteStart() {
return getMainDocumentEnd();
}
/**
* Where the Footnotes text ends.
* Length comes from FibRgLw97.ccpFtn
*/
public int getFootnoteEnd() {
return getFootnoteStart() +
fib.getCcpFtn();
}
/**
* Where the "Header Story" text starts.
* Follows straight on from the footnotes.
*/
public int getHeaderStoryStart() {
return getFootnoteEnd();
}
/**
* Where the "Header Story" text ends.
* Length comes from FibRgLw97.ccpHdd
*/
public int getHeaderStoryEnd() {
return getHeaderStoryStart() +
fib.getCcpHdd();
}
/**
* Where the Comment (Atn) text starts.
* Follows straight on from the header stories.
*/
public int getCommentsStart() {
return getHeaderStoryEnd();
}
/**
* Where the Comment (Atn) text ends.
* Length comes from FibRgLw97.ccpAtn
*/
public int getCommentsEnd() {
return getCommentsStart() +
fib.getCcpCommentAtn();
}
/**
* Where the End Note text starts.
* Follows straight on from the comments.
*/
public int getEndNoteStart() {
return getCommentsEnd();
}
/**
* Where the End Note text ends.
* Length comes from FibRgLw97.ccpEdn
*/
public int getEndNoteEnd() {
return getEndNoteStart() +
fib.getCcpEdn();
}
/**
* Where the Main Textbox text starts.
* Follows straight on from the end note.
*/
public int getMainTextboxStart() {
return getEndNoteEnd();
}
/**
* Where the Main textbox text ends.
* Length comes from FibRgLw97.ccpTxBx
*/
public int getMainTextboxEnd() {
return getMainTextboxStart() +
fib.getCcpTxtBx();
}
/**
* Where the Header Textbox text starts.
* Follows straight on from the main textbox.
*/
public int getHeaderTextboxStart() {
return getMainTextboxEnd();
}
/**
* Where the Header textbox text ends.
* Length comes from FibRgLw97.ccpHdrTxBx
*/
public int getHeaderTextboxEnd() {
return getHeaderTextboxStart() +
fib.getCcpHdrTxtBx();
}
}

View File

@ -22,8 +22,11 @@ import java.io.IOException;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
public class FIBLongHandler /**
{ * Handles the fibRgLw / The FibRgLw97 part of
* the FIB (File Information Block)
*/
public class FIBLongHandler {
public static final int CBMAC = 0; public static final int CBMAC = 0;
public static final int PRODUCTCREATED = 1; public static final int PRODUCTCREATED = 1;
public static final int PRODUCTREVISED = 2; public static final int PRODUCTREVISED = 2;

View File

@ -22,10 +22,11 @@ import java.io.IOException;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.hwpf.model.io.HWPFOutputStream; /**
* Handles the fibRgW / FibRgW97 part of
class FIBShortHandler * the FIB (File Information Block)
{ */
public class FIBShortHandler {
public final static int MAGICCREATED = 0; public final static int MAGICCREATED = 0;
public final static int MAGICREVISED = 1; public final static int MAGICREVISED = 1;
public final static int MAGICCREATEDPRIVATE = 2; public final static int MAGICCREATEDPRIVATE = 2;

View File

@ -28,6 +28,18 @@ import org.apache.poi.hwpf.model.io.*;
import org.apache.poi.hwpf.model.types.FIBAbstractType; import org.apache.poi.hwpf.model.types.FIBAbstractType;
/** /**
* The File Information Block (FIB). Holds pointers
* to various bits of the file, and lots of flags which
* specify properties of the document.
*
* The parent class, {@link FIBAbstractType}, holds the
* first 32 bytes, which make up the FibBase.
* The next part, the fibRgW / FibRgW97, is handled
* by {@link FIBShortHandler}.
* The next part, the fibRgLw / The FibRgLw97, is
* handled by the {@link FIBLongHandler}.
* Finally, the rest of the fields are handled by
* the {@link FIBFieldHandler}.
* *
* @author andy * @author andy
*/ */
@ -63,9 +75,9 @@ public class FileInformationBlock extends FIBAbstractType
_shortHandler = new FIBShortHandler(mainDocument); _shortHandler = new FIBShortHandler(mainDocument);
_longHandler = new FIBLongHandler(mainDocument, _shortHandler.START + _shortHandler.sizeInBytes()); _longHandler = new FIBLongHandler(mainDocument, FIBShortHandler.START + _shortHandler.sizeInBytes());
_fieldHandler = new FIBFieldHandler(mainDocument, _fieldHandler = new FIBFieldHandler(mainDocument,
_shortHandler.START + _shortHandler.sizeInBytes() + _longHandler.sizeInBytes(), FIBShortHandler.START + _shortHandler.sizeInBytes() + _longHandler.sizeInBytes(),
tableStream, fieldSet, true); tableStream, fieldSet, true);
} }
@ -249,6 +261,27 @@ public class FileInformationBlock extends FIBAbstractType
_fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn); _fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn);
} }
/**
* Return the offset to the PlcfHdd, in the table stream,
* i.e. fcPlcfHdd
*/
public int getPlcfHddOffset() {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFHDD);
}
/**
* Return the size of the PlcfHdd, in the table stream,
* i.e. lcbPlcfHdd
*/
public int getPlcfHddSize() {
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFHDD);
}
public void setPlcfHddOffset(int fcPlcfHdd) {
_fieldHandler.setFieldOffset(FIBFieldHandler.PLCFHDD, fcPlcfHdd);
}
public void setPlcfHddSize(int lcbPlcfHdd) {
_fieldHandler.setFieldSize(FIBFieldHandler.PLCFHDD, lcbPlcfHdd);
}
public int getFcSttbSavedBy() public int getFcSttbSavedBy()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY); return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY);
@ -289,20 +322,115 @@ public class FileInformationBlock extends FIBAbstractType
_fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh); _fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh);
} }
public void setCbMac(int cbMac)
{ /**
_longHandler.setLong(FIBLongHandler.CBMAC, cbMac); * How many bytes of the main stream contain real data.
*/
public int getCbMac() {
return _longHandler.getLong(FIBLongHandler.CBMAC);
}
/**
* Updates the count of the number of bytes in the
* main stream which contain real data
*/
public void setCbMac(int cbMac) {
_longHandler.setLong(FIBLongHandler.CBMAC, cbMac);
} }
public int getCcpText() /**
{ * The count of CPs in the main document
return _longHandler.getLong(FIBLongHandler.CCPTEXT); */
} public int getCcpText() {
return _longHandler.getLong(FIBLongHandler.CCPTEXT);
}
/**
* Updates the count of CPs in the main document
*/
public void setCcpText(int ccpText) {
_longHandler.setLong(FIBLongHandler.CCPTEXT, ccpText);
}
/**
* The count of CPs in the footnote subdocument
*/
public int getCcpFtn() {
return _longHandler.getLong(FIBLongHandler.CCPFTN);
}
/**
* Updates the count of CPs in the footnote subdocument
*/
public void setCcpFtn(int ccpFtn) {
_longHandler.setLong(FIBLongHandler.CCPFTN, ccpFtn);
}
/**
* The count of CPs in the header story subdocument
*/
public int getCcpHdd() {
return _longHandler.getLong(FIBLongHandler.CCPHDD);
}
/**
* Updates the count of CPs in the header story subdocument
*/
public void setCcpHdd(int ccpHdd) {
_longHandler.setLong(FIBLongHandler.CCPHDD, ccpHdd);
}
/**
* The count of CPs in the comments (atn) subdocument
*/
public int getCcpAtn() {
return _longHandler.getLong(FIBLongHandler.CCPATN);
}
public int getCcpCommentAtn() {
return getCcpAtn();
}
/**
* Updates the count of CPs in the comments (atn) story subdocument
*/
public void setCcpAtn(int ccpAtn) {
_longHandler.setLong(FIBLongHandler.CCPATN, ccpAtn);
}
/**
* The count of CPs in the end note subdocument
*/
public int getCcpEdn() {
return _longHandler.getLong(FIBLongHandler.CCPEDN);
}
/**
* Updates the count of CPs in the end note subdocument
*/
public void setCcpEdn(int ccpEdn) {
_longHandler.setLong(FIBLongHandler.CCPEDN, ccpEdn);
}
/**
* The count of CPs in the main document textboxes
*/
public int getCcpTxtBx() {
return _longHandler.getLong(FIBLongHandler.CCPTXBX);
}
/**
* Updates the count of CPs in the main document textboxes
*/
public void setCcpTxtBx(int ccpTxtBx) {
_longHandler.setLong(FIBLongHandler.CCPTXBX, ccpTxtBx);
}
/**
* The count of CPs in the header textboxes
*/
public int getCcpHdrTxtBx() {
return _longHandler.getLong(FIBLongHandler.CCPHDRTXBX);
}
/**
* Updates the count of CPs in the header textboxes
*/
public void setCcpHdrTxtBx(int ccpTxtBx) {
_longHandler.setLong(FIBLongHandler.CCPHDRTXBX, ccpTxtBx);
}
public void setCcpText(int ccpText)
{
_longHandler.setLong(FIBLongHandler.CCPTEXT, ccpText);
}
public void clearOffsetsSizes() public void clearOffsetsSizes()
{ {

View File

@ -54,7 +54,9 @@ public class PlexOfCps
*/ */
public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct) public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
{ {
// Figure out the number we hold
_count = (size - 4)/(4 + sizeOfStruct); _count = (size - 4)/(4 + sizeOfStruct);
_sizeOfStruct = sizeOfStruct; _sizeOfStruct = sizeOfStruct;
_props = new ArrayList(_count); _props = new ArrayList(_count);

View File

@ -22,20 +22,22 @@ import java.util.Arrays;
/** /**
* Represents a lightweight node in the Trees used to store content * Represents a lightweight node in the Trees used to store content
* properties. * properties. Works only in characters.
* *
* @author Ryan Ackley * @author Ryan Ackley
*/ */
public abstract class PropertyNode implements Comparable, Cloneable public abstract class PropertyNode implements Comparable, Cloneable
{ {
protected Object _buf; protected Object _buf;
/** The start, in characters */
private int _cpStart; private int _cpStart;
/** The end, in characters */
private int _cpEnd; private int _cpEnd;
/** /**
* @param fcStart The start of the text for this property. * @param fcStart The start of the text for this property, in characters.
* @param fcEnd The end of the text for this property. * @param fcEnd The end of the text for this property, in characters.
* @param buf FIXME: Old documentation is: "grpprl The property description in compressed form." * @param buf FIXME: Old documentation is: "grpprl The property description in compressed form."
*/ */
protected PropertyNode(int fcStart, int fcEnd, Object buf) protected PropertyNode(int fcStart, int fcEnd, Object buf)
@ -43,11 +45,10 @@ public abstract class PropertyNode implements Comparable, Cloneable
_cpStart = fcStart; _cpStart = fcStart;
_cpEnd = fcEnd; _cpEnd = fcEnd;
_buf = buf; _buf = buf;
} }
/** /**
* @return The offset of this property's text. * @return The start offset of this property's text.
*/ */
public int getStart() public int getStart()
{ {
@ -142,9 +143,4 @@ public abstract class PropertyNode implements Comparable, Cloneable
return 1; return 1;
} }
} }
} }

View File

@ -104,7 +104,6 @@ public class SectionTable
} }
int FC = TP.getPieceDescriptor().getFilePosition(); int FC = TP.getPieceDescriptor().getFilePosition();
int offset = CP - TP.getCP(); int offset = CP - TP.getCP();
if(TP.usesUnicode()) offset*=2;
FC = FC+offset-((TextPiece)_text.get(0)).getPieceDescriptor().getFilePosition(); FC = FC+offset-((TextPiece)_text.get(0)).getPieceDescriptor().getFilePosition();
return FC; return FC;
} }
@ -120,12 +119,12 @@ public class SectionTable
if (fc <= piece.getEnd()) if (fc <= piece.getEnd())
{ {
cp += ((fc - piece.getStart())/ (piece.usesUnicode() ? 2 : 1)); cp += (fc - piece.getStart());
break; break;
} }
else else
{ {
cp += ((piece.getEnd() - piece.getStart())/ (piece.usesUnicode() ? 2 : 1)); cp += (piece.getEnd() - piece.getStart());
} }
} }
return cp; return cp;

View File

@ -22,6 +22,9 @@ package org.apache.poi.hwpf.model;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
/** /**
* Lightweight representation of a text piece. * Lightweight representation of a text piece.
* Works in the character domain, not the byte domain, so you
* need to have turned byte references into character
* references before getting here.
* *
* @author Ryan Ackley * @author Ryan Ackley
*/ */
@ -32,25 +35,47 @@ public class TextPiece extends PropertyNode implements Comparable
private PieceDescriptor _pd; private PieceDescriptor _pd;
private int _cpStart; /**
* @param start Beginning offset in main document stream, in characters.
* @param end Ending offset in main document stream, in characters.
* @param text The raw bytes of our text
*/
public TextPiece(int start, int end, byte[] text, PieceDescriptor pd, int cpStart) {
super(start, end, buildInitSB(text, pd));
_usesUnicode = pd.isUnicode();
_pd = pd;
// Validate
int textLength = ((StringBuffer)_buf).length();
if(end-start != textLength) {
throw new IllegalStateException("Told we're for characters " + start + " -> " + end + ", but actually covers " + textLength + " characters!");
}
if(end < start) {
throw new IllegalStateException("Told we're of negative size! start="+start + " end="+end);
}
}
/** /**
* @param start Offset in main document stream. * Create the StringBuffer from the text and unicode flag
*/ */
public TextPiece(int start, int end, byte[] text, PieceDescriptor pd, int cpStart) private static StringBuffer buildInitSB(byte[] text, PieceDescriptor pd) {
throws UnsupportedEncodingException String str;
{ try {
/** start - end is length on file. This is double the expected when its if(pd.isUnicode()) {
* unicode.*/ str = new String(text, "UTF-16LE");
super(start, end, new StringBuffer(new String(text, pd.isUnicode() ? "UTF-16LE" : "Cp1252"))); } else {
_usesUnicode = pd.isUnicode(); str = new String(text, "Cp1252");
_pd = pd; }
_cpStart = cpStart; } catch(UnsupportedEncodingException e) {
throw new RuntimeException("Your Java is broken! It doesn't know about basic, required character encodings!");
}
return new StringBuffer(str);
} }
/** /**
* @return If this text piece uses unicode * @return If this text piece is unicode
*/ */
public boolean usesUnicode() public boolean isUnicode()
{ {
return _usesUnicode; return _usesUnicode;
} }
@ -67,38 +92,43 @@ public class TextPiece extends PropertyNode implements Comparable
public byte[] getRawBytes() public byte[] getRawBytes()
{ {
try try {
{
return ((StringBuffer)_buf).toString().getBytes(_usesUnicode ? return ((StringBuffer)_buf).toString().getBytes(_usesUnicode ?
"UTF-16LE" : "Cp1252"); "UTF-16LE" : "Cp1252");
} catch (UnsupportedEncodingException ignore) {
throw new RuntimeException("Your Java is broken! It doesn't know about basic, required character encodings!");
} }
catch (UnsupportedEncodingException ignore)
{
// shouldn't ever happen considering we wouldn't have been able to
// create the StringBuffer w/o getting this exception
return ((StringBuffer)_buf).toString().getBytes();
}
} }
/**
* Returns part of the string.
* Works only in characters, not in bytes!
* @param start Local start position, in characters
* @param end Local end position, in characters
* @return
*/
public String substring(int start, int end) public String substring(int start, int end)
{ {
int denominator = _usesUnicode ? 2 : 1; StringBuffer buf = (StringBuffer)_buf;
return ((StringBuffer)_buf).substring(start/denominator, end/denominator); // Validate
if(start < 0) {
throw new StringIndexOutOfBoundsException("Can't request a substring before 0 - asked for " + start);
}
if(end > buf.length()) {
throw new StringIndexOutOfBoundsException("Index " + end + " out of range 0 -> " + buf.length());
}
return buf.substring(start, end);
} }
public void adjustForDelete(int start, int length) /**
{ * Adjusts the internal string for deletinging
* some characters within this.
// length is expected to be the number of code-points, * @param start The start position for the delete, in characters
// not the number of characters * @param length The number of characters to delete
*/
public void adjustForDelete(int start, int length) {
int numChars = length; int numChars = length;
if (usesUnicode()) {
start /= 2;
numChars = (length / 2);
}
int myStart = getStart(); int myStart = getStart();
int myEnd = getEnd(); int myEnd = getEnd();
@ -121,9 +151,18 @@ public class TextPiece extends PropertyNode implements Comparable
super.adjustForDelete(start, length); super.adjustForDelete(start, length);
} }
/**
* Returns the length, in characters
*/
public int characterLength() public int characterLength()
{ {
return (getEnd() - getStart()) / (_usesUnicode ? 2 : 1); return (getEnd() - getStart());
}
/**
* Returns the length, in bytes
*/
public int bytesLength() {
return (getEnd() - getStart()) * (_usesUnicode ? 2 : 1);
} }
public boolean equals(Object o) public boolean equals(Object o)
@ -138,9 +177,11 @@ public class TextPiece extends PropertyNode implements Comparable
} }
/**
* Returns the character position we start at.
*/
public int getCP() public int getCP()
{ {
return _cpStart; return getStart();
} }
} }

View File

@ -28,6 +28,11 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* The piece table for matching up character positions
* to bits of text.
* This mostly works in bytes, but the TextPieces
* themselves work in characters. This does the icky
* convertion.
* @author Ryan Ackley * @author Ryan Ackley
*/ */
public class TextPieceTable public class TextPieceTable
@ -36,8 +41,7 @@ public class TextPieceTable
//int _multiple; //int _multiple;
int _cpMin; int _cpMin;
public TextPieceTable() public TextPieceTable() {
{
} }
public TextPieceTable(byte[] documentStream, byte[] tableStream, int offset, public TextPieceTable(byte[] documentStream, byte[] tableStream, int offset,
@ -47,7 +51,6 @@ public class TextPieceTable
// get our plex of PieceDescriptors // get our plex of PieceDescriptors
PlexOfCps pieceTable = new PlexOfCps(tableStream, offset, size, PieceDescriptor.getSizeInBytes()); PlexOfCps pieceTable = new PlexOfCps(tableStream, offset, size, PieceDescriptor.getSizeInBytes());
//_multiple = 2;
int length = pieceTable.length(); int length = pieceTable.length();
PieceDescriptor[] pieces = new PieceDescriptor[length]; PieceDescriptor[] pieces = new PieceDescriptor[length];
@ -57,11 +60,6 @@ public class TextPieceTable
{ {
GenericPropertyNode node = pieceTable.getProperty(x); GenericPropertyNode node = pieceTable.getProperty(x);
pieces[x] = new PieceDescriptor(node.getBytes(), 0); pieces[x] = new PieceDescriptor(node.getBytes(), 0);
// if (!pieces[x].isUnicode())
// {
// _multiple = 1;
// }
} }
int firstPieceFilePosition = pieces[0].getFilePosition(); int firstPieceFilePosition = pieces[0].getFilePosition();
@ -72,26 +70,28 @@ public class TextPieceTable
{ {
int start = pieces[x].getFilePosition(); int start = pieces[x].getFilePosition();
PropertyNode node = pieceTable.getProperty(x); PropertyNode node = pieceTable.getProperty(x);
int nodeStart = node.getStart();
// multiple will be 2 if there is only one piece and its unicode. Some // Grab the start and end, which are in characters
// type of optimization. int nodeStartChars = node.getStart();
int nodeEndChars = node.getEnd();
// What's the relationship between bytes and characters?
boolean unicode = pieces[x].isUnicode(); boolean unicode = pieces[x].isUnicode();
int multiple = 1; int multiple = 1;
if (unicode) if (unicode) {
{
multiple = 2; multiple = 2;
} }
int nodeEnd = ((node.getEnd() - nodeStart) * multiple) + nodeStart;
int textSize = nodeEnd - nodeStart;
// Figure out the length, in bytes and chars
int textSizeChars = (nodeEndChars - nodeStartChars);
int textSizeBytes = textSizeChars * multiple;
byte[] buf = new byte[textSize]; // Grab the data that makes up the piece
System.arraycopy(documentStream, start, buf, 0, textSize); byte[] buf = new byte[textSizeBytes];
System.arraycopy(documentStream, start, buf, 0, textSizeBytes);
int startFilePosition = start - firstPieceFilePosition; // And now build the piece
_textPieces.add(new TextPiece(startFilePosition, startFilePosition+textSize, buf, pieces[x], node.getStart())); _textPieces.add(new TextPiece(nodeStartChars, nodeEndChars, buf, pieces[x], node.getStart()));
} }
} }
@ -113,7 +113,6 @@ public class TextPieceTable
//int fcMin = docStream.getOffset(); //int fcMin = docStream.getOffset();
int size = _textPieces.size(); int size = _textPieces.size();
int bumpDown = 0;
for (int x = 0; x < size; x++) for (int x = 0; x < size; x++)
{ {
TextPiece next = (TextPiece)_textPieces.get(x); TextPiece next = (TextPiece)_textPieces.get(x);
@ -134,47 +133,43 @@ public class TextPieceTable
// write the text to the docstream and save the piece descriptor to the // write the text to the docstream and save the piece descriptor to the
// plex which will be written later to the tableStream. // plex which will be written later to the tableStream.
//if (_multiple == 1 && pd.isUnicode() &&
docStream.write(next.getRawBytes()); docStream.write(next.getRawBytes());
// The TextPiece is already in characters, which
// makes our life much easier
int nodeStart = next.getStart(); int nodeStart = next.getStart();
int multiple = 1; int nodeEnd = next.getEnd();
if (pd.isUnicode()) textPlex.addProperty(new GenericPropertyNode(nodeStart, nodeEnd,
{
multiple = 2;
}
textPlex.addProperty(new GenericPropertyNode(nodeStart - bumpDown,
((next.getEnd() - nodeStart)/multiple + nodeStart) - bumpDown,
pd.toByteArray())); pd.toByteArray()));
if (pd.isUnicode())
{
bumpDown += ((next.getEnd() - nodeStart)/multiple);
}
} }
return textPlex.toByteArray(); return textPlex.toByteArray();
} }
/**
public int adjustForInsert(int listIndex, int length) * Adjust all the text piece after inserting
{ * some text into one of them
* @param listIndex The TextPiece that had characters inserted into
* @param length The number of characters inserted
*/
public int adjustForInsert(int listIndex, int length) {
int size = _textPieces.size(); int size = _textPieces.size();
TextPiece tp = (TextPiece)_textPieces.get(listIndex); TextPiece tp = (TextPiece)_textPieces.get(listIndex);
//The text piece stores the length on file. // Update with the new end
length = length * (tp.usesUnicode() ? 2 : 1);
tp.setEnd(tp.getEnd() + length); tp.setEnd(tp.getEnd() + length);
// Now change all subsequent ones
for (int x = listIndex + 1; x < size; x++) for (int x = listIndex + 1; x < size; x++)
{ {
tp = (TextPiece)_textPieces.get(x); tp = (TextPiece)_textPieces.get(x);
tp.setStart(tp.getStart() + length); tp.setStart(tp.getStart() + length);
tp.setEnd(tp.getEnd() + length); tp.setEnd(tp.getEnd() + length);
} }
// All done
return length; return length;
} }

View File

@ -31,7 +31,7 @@ import org.apache.poi.hdf.model.hdftypes.HDFType;
import org.apache.poi.hwpf.usermodel.*; import org.apache.poi.hwpf.usermodel.*;
/** /**
* File information Block. * Base part of the File information Block (FibBase). Holds the core part of the FIB, from the first 32 bytes.
* NOTE: This source is automatically generated please do not modify this file. Either subclass or * NOTE: This source is automatically generated please do not modify this file. Either subclass or
* remove the record in src/records/definitions. * remove the record in src/records/definitions.

View File

@ -0,0 +1,170 @@
/* ====================================================================
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.hwpf.usermodel;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.FileInformationBlock;
import org.apache.poi.hwpf.model.GenericPropertyNode;
import org.apache.poi.hwpf.model.PlexOfCps;
/**
* A HeaderStory is a Header, a Footer, or footnote/endnote
* separator.
* All the Header Stories get stored in the same Range in the
* document, and this handles getting out all the individual
* parts.
*
* WARNING - you shouldn't change the headers or footers,
* as offsets are not yet updated!
*/
public class HeaderStories {
private Range headerStories;
private PlexOfCps plcfHdd;
public HeaderStories(HWPFDocument doc) {
this.headerStories = doc.getHeaderStoryRange();
FileInformationBlock fib = doc.getFileInformationBlock();
// If there's no PlcfHdd, nothing to do
if(fib.getCcpHdd() == 0) {
return;
}
if(fib.getPlcfHddSize() == 0) {
return;
}
// Handle the PlcfHdd
plcfHdd = new PlexOfCps(
doc.getTableStream(), fib.getPlcfHddOffset(),
fib.getPlcfHddSize(), 0
);
}
public String getFootnoteSeparator() {
return getAt(0);
}
public String getFootnoteContSeparator() {
return getAt(1);
}
public String getFootnoteContNote() {
return getAt(2);
}
public String getEndnoteSeparator() {
return getAt(3);
}
public String getEndnoteContSeparator() {
return getAt(4);
}
public String getEndnoteContNote() {
return getAt(5);
}
public String getEvenHeader() {
return getAt(6+0);
}
public String getOddHeader() {
return getAt(6+1);
}
public String getFirstHeader() {
return getAt(6+4);
}
/**
* Returns the correct, defined header for the given
* one based page
* @param pageNumber The one based page number
* @return
*/
public String getHeader(int pageNumber) {
// First page header is optional, only return
// if it's set
if(pageNumber == 1) {
if(getFirstHeader().length() > 0) {
return getFirstHeader();
}
}
// Even page header is optional, only return
// if it's set
if(pageNumber % 2 == 0) {
if(getEvenHeader().length() > 0) {
return getEvenHeader();
}
}
// Odd is the default
return getOddHeader();
}
public String getEvenFooter() {
return getAt(6+2);
}
public String getOddFooter() {
return getAt(6+3);
}
public String getFirstFooter() {
return getAt(6+5);
}
/**
* Returns the correct, defined footer for the given
* one based page
* @param pageNumber The one based page number
* @return
*/
public String getFooter(int pageNumber) {
// First page footer is optional, only return
// if it's set
if(pageNumber == 1) {
if(getFirstFooter().length() > 0) {
return getFirstFooter();
}
}
// Even page footer is optional, only return
// if it's set
if(pageNumber % 2 == 0) {
if(getEvenFooter().length() > 0) {
return getEvenFooter();
}
}
// Odd is the default
return getOddFooter();
}
/**
* Get the string that's pointed to by the
* given plcfHdd index
*/
private String getAt(int plcfHddIndex) {
if(plcfHdd == null) return null;
GenericPropertyNode prop = plcfHdd.getProperty(plcfHddIndex);
if(prop.getStart() == prop.getEnd()) {
// Empty story
return "";
}
// Return the contents
return headerStories.text().substring(prop.getStart(), prop.getEnd());
}
public Range getRange() {
return headerStories;
}
protected PlexOfCps getPlcfHdd() {
return plcfHdd;
}
}

View File

@ -29,6 +29,8 @@ import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.ParagraphProperties; import org.apache.poi.hwpf.usermodel.ParagraphProperties;
import org.apache.poi.hwpf.usermodel.Section; import org.apache.poi.hwpf.usermodel.Section;
import org.apache.poi.hwpf.model.CPSplitCalculator;
import org.apache.poi.hwpf.model.FileInformationBlock;
import org.apache.poi.hwpf.model.PropertyNode; import org.apache.poi.hwpf.model.PropertyNode;
import org.apache.poi.hwpf.model.StyleSheet; import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.model.CHPX; import org.apache.poi.hwpf.model.CHPX;
@ -41,6 +43,8 @@ import org.apache.poi.hwpf.sprm.CharacterSprmCompressor;
import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor; import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor;
import org.apache.poi.hwpf.sprm.SprmBuffer; import org.apache.poi.hwpf.sprm.SprmBuffer;
import sun.security.krb5.internal.aj;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -137,7 +141,8 @@ public class Range
/** /**
* Used to construct a Range from a document. This is generally used to * Used to construct a Range from a document. This is generally used to
* create a Range that spans the whole document. * create a Range that spans the whole document, or at least one
* whole part of the document (eg main text, header, comment)
* *
* @param start Starting character offset of the range. * @param start Starting character offset of the range.
* @param end Ending character offset of the range. * @param end Ending character offset of the range.
@ -238,7 +243,7 @@ public class Range
for (int i = _textStart; i < _textEnd; i++) for (int i = _textStart; i < _textEnd; i++)
{ {
TextPiece piece = (TextPiece)_text.get(i); TextPiece piece = (TextPiece)_text.get(i);
if (piece.usesUnicode()) if (piece.isUnicode())
return true; return true;
} }
@ -259,15 +264,21 @@ public class Range
for (int x = _textStart; x < _textEnd; x++) for (int x = _textStart; x < _textEnd; x++)
{ {
TextPiece piece = (TextPiece)_text.get(x); TextPiece piece = (TextPiece)_text.get(x);
int start = _start > piece.getStart() ? _start - piece.getStart() : 0;
int end = _end <= piece.getEnd() ? _end - piece.getStart() : piece.getEnd() - piece.getStart();
if(piece.usesUnicode()) // convert the byte pointers to char pointers // Figure out where in this piece the text
{ // we're after lives
start/=2; int rStart = 0;
end/=2; int rEnd = piece.characterLength();
if(_start > piece.getStart()) {
rStart = _start - piece.getStart();
} }
sb.append(piece.getStringBuffer().substring(start, end)); if(_end < piece.getEnd()) {
rEnd -= (piece.getEnd() - _end);
}
// Luckily TextPieces work in characters, so we don't
// need to worry about unicode here
sb.append(piece.substring(rStart, rEnd));
} }
return sb.toString(); return sb.toString();
} }
@ -325,8 +336,6 @@ public class Range
// Since this is the first item in our list, it is safe to assume that // Since this is the first item in our list, it is safe to assume that
// _start >= tp.getStart() // _start >= tp.getStart()
int insertIndex = _start - tp.getStart(); int insertIndex = _start - tp.getStart();
if (tp.usesUnicode())
insertIndex /= 2;
sb.insert(insertIndex, text); sb.insert(insertIndex, text);
int adjustedLength = _doc.getTextTable().adjustForInsert(_textStart, text.length()); int adjustedLength = _doc.getTextTable().adjustForInsert(_textStart, text.length());
@ -335,7 +344,7 @@ public class Range
_doc.getSectionTable().adjustForInsert(_sectionStart, adjustedLength); _doc.getSectionTable().adjustForInsert(_sectionStart, adjustedLength);
adjustForInsert(adjustedLength); adjustForInsert(adjustedLength);
// update the FIB.CCPText field // update the FIB.CCPText + friends fields
adjustFIB(text.length()); adjustFIB(text.length());
return getCharacterRun(0); return getCharacterRun(0);
@ -546,11 +555,8 @@ public class Range
piece.adjustForDelete(_start, _end - _start); piece.adjustForDelete(_start, _end - _start);
} }
// update the FIB.CCPText field // update the FIB.CCPText + friends field
if (usesUnicode()) adjustFIB(-(_end - _start));
adjustFIB(-((_end - _start) / 2));
else
adjustFIB(-(_end - _start));
} }
/** /**
@ -929,16 +935,44 @@ public class Range
} }
/** /**
* Adjust the value of <code>FIB.CCPText</code> after an insert or a delete... * Adjust the value of the various FIB character count fields,
* eg <code>FIB.CCPText</code> after an insert or a delete...
* *
* @param adjustment The (signed) value that should be added to <code>FIB.CCPText</code> * Works on all CCP fields from this range onwards
*
* @param adjustment The (signed) value that should be added to the FIB CCP fields
*/ */
protected void adjustFIB(int adjustment) { protected void adjustFIB(int adjustment) {
// update the FIB.CCPText field (this should happen once per adjustment, so we don't want it in // update the FIB.CCPText field (this should happen once per adjustment, so we don't want it in
// adjustForInsert() or it would get updated multiple times if the range has a parent) // adjustForInsert() or it would get updated multiple times if the range has a parent)
// without this, OpenOffice.org (v. 2.2.x) does not see all the text in the document // without this, OpenOffice.org (v. 2.2.x) does not see all the text in the document
_doc.getFileInformationBlock().setCcpText(_doc.getFileInformationBlock().getCcpText() + adjustment);
CPSplitCalculator cpS = _doc.getCPSplitCalculator();
FileInformationBlock fib = _doc.getFileInformationBlock();
// Do for each affected part
if(_start < cpS.getMainDocumentEnd()) {
fib.setCcpText(fib.getCcpText() + adjustment);
}
if(_start < cpS.getCommentsEnd()) {
fib.setCcpAtn(fib.getCcpAtn() + adjustment);
}
if(_start < cpS.getEndNoteEnd()) {
fib.setCcpEdn(fib.getCcpEdn() + adjustment);
}
if(_start < cpS.getFootnoteEnd()) {
fib.setCcpFtn(fib.getCcpFtn() + adjustment);
}
if(_start < cpS.getHeaderStoryEnd()) {
fib.setCcpHdd(fib.getCcpHdd() + adjustment);
}
if(_start < cpS.getHeaderTextboxEnd()) {
fib.setCcpHdrTxtBx(fib.getCcpHdrTxtBx() + adjustment);
}
if(_start < cpS.getMainTextboxEnd()) {
fib.setCcpTxtBx(fib.getCcpTxtBx() + adjustment);
}
} }
/** /**

View File

@ -0,0 +1,253 @@
/* ====================================================================
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.hwpf;
import java.io.FileInputStream;
import org.apache.poi.hwpf.usermodel.Range;
import junit.framework.TestCase;
/**
* Test that we pull out the right bits of a file into
* the different ranges
*/
public class TestHWPFRangeParts extends TestCase {
private static final char page_break = (char)12;
private static final String headerDef =
"\u0003\r\r" +
"\u0004\r\r" +
"\u0003\r\r" +
"\u0004\r\r"
;
private static final String footerDef = "\r";
private static final String endHeaderFooter = "\r\r";
private static final String a_page_1 =
"This is a sample word document. It has two pages. It has a three column heading, and a three column footer\r" +
"\r" +
"HEADING TEXT\r" +
"\r" +
"More on page one\r" +
"\r\r" +
"End of page 1\r"
;
private static final String a_page_2 =
"This is page two. It also has a three column heading, and a three column footer.\r"
;
private static final String a_header =
"First header column!\tMid header Right header!\r"
;
private static final String a_footer =
"Footer Left\tFooter Middle Footer Right\r"
;
private static final String u_page_1 =
"This is a fairly simple word document, over two pages, with headers and footers.\r" +
"The trick with this one is that it contains some Unicode based strings in it.\r" +
"Firstly, some currency symbols:\r" +
"\tGBP - \u00a3\r" +
"\tEUR - \u20ac\r" +
"Now, we\u2019ll have some French text, in bold and big:\r" +
"\tMoli\u00e8re\r" +
"And some normal French text:\r" +
"\tL'Avare ou l'\u00c9cole du mensonge\r" +
"That\u2019s it for page one\r"
;
private static final String u_page_2 =
"This is page two. Les Pr\u00e9cieuses ridicules. The end.\r"
;
private static final String u_header =
"\r\r" +
"This is a simple header, with a \u20ac euro symbol in it.\r"
;
private static final String u_footer =
"\r\r\r" +
"The footer, with Moli\u00e8re, has Unicode in it.\r" +
"\r\r\r\r"
;
/**
* A document made up only of basic ASCII text
*/
private HWPFDocument docAscii;
/**
* A document with some unicode in it too
*/
private HWPFDocument docUnicode;
public void setUp() throws Exception {
String dirname = System.getProperty("HWPF.testdata.path");
String filename = dirname + "/HeaderFooterUnicode.doc";
docUnicode = new HWPFDocument(
new FileInputStream(filename)
);
filename = dirname + "/ThreeColHeadFoot.doc";
docAscii = new HWPFDocument(
new FileInputStream(filename)
);
}
public void testBasics() throws Exception {
// First check the start and end bits
assertEquals(
0,
docAscii._cpSplit.getMainDocumentStart()
);
assertEquals(
a_page_1.length() +
2 + // page break
a_page_2.length(),
docAscii._cpSplit.getMainDocumentEnd()
);
assertEquals(
238,
docAscii._cpSplit.getFootnoteStart()
);
assertEquals(
238,
docAscii._cpSplit.getFootnoteEnd()
);
assertEquals(
238,
docAscii._cpSplit.getHeaderStoryStart()
);
assertEquals(
238 + headerDef.length() + a_header.length() +
footerDef.length() + a_footer.length() + endHeaderFooter.length(),
docAscii._cpSplit.getHeaderStoryEnd()
);
}
public void testContents() throws Exception {
Range r;
// Now check the real ranges
r = docAscii.getRange();
assertEquals(
a_page_1 +
page_break + "\r" +
a_page_2,
r.text()
);
r = docAscii.getHeaderStoryRange();
assertEquals(
headerDef +
a_header +
footerDef +
a_footer +
endHeaderFooter,
r.text()
);
r = docAscii.getOverallRange();
assertEquals(
a_page_1 +
page_break + "\r" +
a_page_2 +
headerDef +
a_header +
footerDef +
a_footer +
endHeaderFooter +
"\r",
r.text()
);
}
public void testBasicsUnicode() throws Exception {
// First check the start and end bits
assertEquals(
0,
docUnicode._cpSplit.getMainDocumentStart()
);
assertEquals(
u_page_1.length() +
2 + // page break
u_page_2.length(),
docUnicode._cpSplit.getMainDocumentEnd()
);
assertEquals(
408,
docUnicode._cpSplit.getFootnoteStart()
);
assertEquals(
408,
docUnicode._cpSplit.getFootnoteEnd()
);
assertEquals(
408,
docUnicode._cpSplit.getHeaderStoryStart()
);
// TODO - fix this one
assertEquals(
408 + headerDef.length() + u_header.length() +
footerDef.length() + u_footer.length() + endHeaderFooter.length(),
docUnicode._cpSplit.getHeaderStoryEnd()
);
}
public void testContentsUnicode() throws Exception {
Range r;
// Now check the real ranges
r = docUnicode.getRange();
assertEquals(
u_page_1 +
page_break + "\r" +
u_page_2,
r.text()
);
r = docUnicode.getHeaderStoryRange();
assertEquals(
headerDef +
u_header +
footerDef +
u_footer +
endHeaderFooter,
r.text()
);
r = docUnicode.getOverallRange();
assertEquals(
u_page_1 +
page_break + "\r" +
u_page_2 +
headerDef +
u_header +
footerDef +
u_footer +
endHeaderFooter +
"\r",
r.text()
);
}
}

View File

@ -87,7 +87,7 @@ public class TestDifferentRoutes extends TestCase {
TextPiece piece = (TextPiece) textPieces.next(); TextPiece piece = (TextPiece) textPieces.next();
String encoding = "Cp1252"; String encoding = "Cp1252";
if (piece.usesUnicode()) { if (piece.isUnicode()) {
encoding = "UTF-16LE"; encoding = "UTF-16LE";
} }
String text = new String(piece.getRawBytes(), encoding); String text = new String(piece.getRawBytes(), encoding);

View File

@ -55,6 +55,11 @@ public class TestWordExtractor extends TestCase {
// A word doc embeded in an excel file // A word doc embeded in an excel file
private String filename3; private String filename3;
// With header and footer
private String filename4;
// With unicode header and footer
private String filename5;
protected void setUp() throws Exception { protected void setUp() throws Exception {
String dirname = System.getProperty("HWPF.testdata.path"); String dirname = System.getProperty("HWPF.testdata.path");
String pdirname = System.getProperty("POIFS.testdata.path"); String pdirname = System.getProperty("POIFS.testdata.path");
@ -62,6 +67,9 @@ public class TestWordExtractor extends TestCase {
String filename = dirname + "/test2.doc"; String filename = dirname + "/test2.doc";
String filename2 = dirname + "/test.doc"; String filename2 = dirname + "/test.doc";
filename3 = pdirname + "/excel_with_embeded.xls"; filename3 = pdirname + "/excel_with_embeded.xls";
filename4 = dirname + "/ThreeColHeadFoot.doc";
filename5 = dirname + "/HeaderFooterUnicode.doc";
extractor = new WordExtractor(new FileInputStream(filename)); extractor = new WordExtractor(new FileInputStream(filename));
extractor2 = new WordExtractor(new FileInputStream(filename2)); extractor2 = new WordExtractor(new FileInputStream(filename2));
@ -149,4 +157,72 @@ public class TestWordExtractor extends TestCase {
assertEquals("Sample Doc 2", extractor3.getSummaryInformation().getTitle()); assertEquals("Sample Doc 2", extractor3.getSummaryInformation().getTitle());
assertEquals("Another Sample Test", extractor3.getSummaryInformation().getSubject()); assertEquals("Another Sample Test", extractor3.getSummaryInformation().getSubject());
} }
public void testWithHeader() throws Exception {
// Non-unicode
HWPFDocument doc = new HWPFDocument(
new FileInputStream(filename4)
);
extractor = new WordExtractor(doc);
assertEquals(
"First header column!\tMid header Right header!\n",
extractor.getHeaderText()
);
String text = extractor.getText();
assertTrue(
text.indexOf("First header column!") > -1
);
// Unicode
doc = new HWPFDocument(
new FileInputStream(filename5)
);
extractor = new WordExtractor(doc);
assertEquals(
"\n\nThis is a simple header, with a \u20ac euro symbol in it.\n\n",
extractor.getHeaderText()
);
text = extractor.getText();
assertTrue(
text.indexOf("This is a simple header") > -1
);
}
public void testWithFooter() throws Exception {
// Non-unicode
HWPFDocument doc = new HWPFDocument(
new FileInputStream(filename4)
);
extractor = new WordExtractor(doc);
assertEquals(
"Footer Left\tFooter Middle Footer Right\n",
extractor.getFooterText()
);
String text = extractor.getText();
assertTrue(
text.indexOf("Footer Left") > -1
);
// Unicode
doc = new HWPFDocument(
new FileInputStream(filename5)
);
extractor = new WordExtractor(doc);
assertEquals(
"\n\nThe footer, with Moli\u00e8re, has Unicode in it.\n",
extractor.getFooterText()
);
text = extractor.getText();
assertTrue(
text.indexOf("The footer, with") > -1
);
}
} }

View File

@ -18,19 +18,21 @@
package org.apache.poi.hwpf.model; package org.apache.poi.hwpf.model;
import junit.framework.*; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.ArrayList; import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.hwpf.*; import junit.framework.TestCase;
import org.apache.poi.hwpf.model.io.*;
import org.apache.poi.hwpf.HWPFDocFixture;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.io.HWPFFileSystem;
public class TestTextPieceTable public class TestTextPieceTable extends TestCase {
extends TestCase
{
private HWPFDocFixture _hWPFDocFixture; private HWPFDocFixture _hWPFDocFixture;
private String dirname;
public TestTextPieceTable(String name) public TestTextPieceTable(String name)
{ {
@ -63,9 +65,117 @@ public class TestTextPieceTable
TextPieceTable newTextPieceTable = newCft.getTextPieceTable(); TextPieceTable newTextPieceTable = newCft.getTextPieceTable();
assertEquals(oldTextPieceTable, newTextPieceTable); assertEquals(oldTextPieceTable, newTextPieceTable);
} }
/**
* Check that we do the positions correctly when
* working with pure-ascii
*/
public void testAsciiParts() throws Exception {
HWPFDocument doc = new HWPFDocument(
new FileInputStream(new File(dirname, "ThreeColHeadFoot.doc"))
);
TextPieceTable tbl = doc.getTextTable();
// All ascii, so stored in one big lump
assertEquals(1, tbl.getTextPieces().size());
TextPiece tp = (TextPiece)tbl.getTextPieces().get(0);
assertEquals(0, tp.getStart());
assertEquals(339, tp.getEnd());
assertEquals(339, tp.characterLength());
assertEquals(339, tp.bytesLength());
assertTrue(tp.getStringBuffer().toString().startsWith("This is a sample word document"));
// Save and re-load
HWPFDocument docB = saveAndReload(doc);
tbl = docB.getTextTable();
assertEquals(1, tbl.getTextPieces().size());
tp = (TextPiece)tbl.getTextPieces().get(0);
assertEquals(0, tp.getStart());
assertEquals(339, tp.getEnd());
assertEquals(339, tp.characterLength());
assertEquals(339, tp.bytesLength());
assertTrue(tp.getStringBuffer().toString().startsWith("This is a sample word document"));
}
/**
* Check that we do the positions correctly when
* working with a mix ascii, unicode file
*/
public void testUnicodeParts() throws Exception {
HWPFDocument doc = new HWPFDocument(
new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc"))
);
TextPieceTable tbl = doc.getTextTable();
// In three bits, split every 512 bytes
assertEquals(3, tbl.getTextPieces().size());
TextPiece tpA = (TextPiece)tbl.getTextPieces().get(0);
TextPiece tpB = (TextPiece)tbl.getTextPieces().get(1);
TextPiece tpC = (TextPiece)tbl.getTextPieces().get(2);
assertTrue(tpA.isUnicode());
assertTrue(tpB.isUnicode());
assertTrue(tpC.isUnicode());
assertEquals(256, tpA.characterLength());
assertEquals(256, tpB.characterLength());
assertEquals(19, tpC.characterLength());
assertEquals(512, tpA.bytesLength());
assertEquals(512, tpB.bytesLength());
assertEquals(38, tpC.bytesLength());
assertEquals(0, tpA.getStart());
assertEquals(256, tpA.getEnd());
assertEquals(256, tpB.getStart());
assertEquals(512, tpB.getEnd());
assertEquals(512, tpC.getStart());
assertEquals(531, tpC.getEnd());
// Save and re-load
HWPFDocument docB = saveAndReload(doc);
tbl = docB.getTextTable();
assertEquals(3, tbl.getTextPieces().size());
tpA = (TextPiece)tbl.getTextPieces().get(0);
tpB = (TextPiece)tbl.getTextPieces().get(1);
tpC = (TextPiece)tbl.getTextPieces().get(2);
assertTrue(tpA.isUnicode());
assertTrue(tpB.isUnicode());
assertTrue(tpC.isUnicode());
assertEquals(256, tpA.characterLength());
assertEquals(256, tpB.characterLength());
assertEquals(19, tpC.characterLength());
assertEquals(512, tpA.bytesLength());
assertEquals(512, tpB.bytesLength());
assertEquals(38, tpC.bytesLength());
assertEquals(0, tpA.getStart());
assertEquals(256, tpA.getEnd());
assertEquals(256, tpB.getStart());
assertEquals(512, tpB.getEnd());
assertEquals(512, tpC.getStart());
assertEquals(531, tpC.getEnd());
}
protected HWPFDocument saveAndReload(HWPFDocument doc) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.write(baos);
return new HWPFDocument(
new ByteArrayInputStream(baos.toByteArray())
);
}
protected void setUp() protected void setUp()
throws Exception throws Exception
{ {
@ -73,6 +183,8 @@ public class TestTextPieceTable
_hWPFDocFixture = new HWPFDocFixture(this); _hWPFDocFixture = new HWPFDocFixture(this);
_hWPFDocFixture.setUp(); _hWPFDocFixture.setUp();
dirname = System.getProperty("HWPF.testdata.path");
} }
protected void tearDown() protected void tearDown()

View File

@ -0,0 +1,189 @@
/* ====================================================================
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.hwpf.usermodel;
import java.io.File;
import java.io.FileInputStream;
import junit.framework.TestCase;
import org.apache.poi.hwpf.HWPFDocument;
/**
* Tests for the handling of header stories into
* headers, footers etc
*/
public class TestHeaderStories extends TestCase {
private HWPFDocument none;
private HWPFDocument header;
private HWPFDocument footer;
private HWPFDocument headerFooter;
private HWPFDocument oddEven;
private HWPFDocument diffFirst;
private HWPFDocument unicode;
protected void setUp() throws Exception {
String dirname = System.getProperty("HWPF.testdata.path");
none = new HWPFDocument(
new FileInputStream(new File(dirname, "NoHeadFoot.doc"))
);
header = new HWPFDocument(
new FileInputStream(new File(dirname, "ThreeColHead.doc"))
);
footer = new HWPFDocument(
new FileInputStream(new File(dirname, "ThreeColFoot.doc"))
);
headerFooter = new HWPFDocument(
new FileInputStream(new File(dirname, "SimpleHeadThreeColFoot.doc"))
);
oddEven = new HWPFDocument(
new FileInputStream(new File(dirname, "PageSpecificHeadFoot.doc"))
);
diffFirst = new HWPFDocument(
new FileInputStream(new File(dirname, "DiffFirstPageHeadFoot.doc"))
);
unicode = new HWPFDocument(
new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc"))
);
}
public void testNone() throws Exception {
HeaderStories hs = new HeaderStories(none);
assertNull(hs.getPlcfHdd());
assertEquals(0, hs.getRange().text().length());
}
public void testHeader() throws Exception {
HeaderStories hs = new HeaderStories(header);
assertEquals(60, hs.getRange().text().length());
// Should have the usual 6 separaters
// Then all 6 of the different header/footer kinds
// Finally a terminater
assertEquals(13, hs.getPlcfHdd().length());
assertEquals(215, hs.getRange().getStartOffset());
assertEquals(0, hs.getPlcfHdd().getProperty(0).getStart());
assertEquals(3, hs.getPlcfHdd().getProperty(1).getStart());
assertEquals(6, hs.getPlcfHdd().getProperty(2).getStart());
assertEquals(6, hs.getPlcfHdd().getProperty(3).getStart());
assertEquals(9, hs.getPlcfHdd().getProperty(4).getStart());
assertEquals(12, hs.getPlcfHdd().getProperty(5).getStart());
assertEquals(12, hs.getPlcfHdd().getProperty(6).getStart());
assertEquals(12, hs.getPlcfHdd().getProperty(7).getStart());
assertEquals(59, hs.getPlcfHdd().getProperty(8).getStart());
assertEquals(59, hs.getPlcfHdd().getProperty(9).getStart());
assertEquals(59, hs.getPlcfHdd().getProperty(10).getStart());
assertEquals(59, hs.getPlcfHdd().getProperty(11).getStart());
assertEquals(59, hs.getPlcfHdd().getProperty(12).getStart());
assertEquals("\u0003\r\r", hs.getFootnoteSeparator());
assertEquals("\u0004\r\r", hs.getFootnoteContSeparator());
assertEquals("", hs.getFootnoteContNote());
assertEquals("\u0003\r\r", hs.getEndnoteSeparator());
assertEquals("\u0004\r\r", hs.getEndnoteContSeparator());
assertEquals("", hs.getEndnoteContNote());
assertEquals("", hs.getFirstHeader());
assertEquals("", hs.getEvenHeader());
assertEquals("First header column!\tMid header Right header!\r\r", hs.getOddHeader());
assertEquals("", hs.getFirstFooter());
assertEquals("", hs.getEvenFooter());
assertEquals("", hs.getOddFooter());
}
public void testFooter() throws Exception {
HeaderStories hs = new HeaderStories(footer);
assertEquals("", hs.getFirstHeader());
assertEquals("", hs.getEvenHeader());
assertEquals("\r\r", hs.getOddHeader());
assertEquals("", hs.getFirstFooter());
assertEquals("", hs.getEvenFooter());
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getOddFooter());
}
public void testHeaderFooter() throws Exception {
HeaderStories hs = new HeaderStories(headerFooter);
assertEquals("", hs.getFirstHeader());
assertEquals("", hs.getEvenHeader());
assertEquals("I am some simple header text here\r\r\r", hs.getOddHeader());
assertEquals("", hs.getFirstFooter());
assertEquals("", hs.getEvenFooter());
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getOddFooter());
}
public void testOddEven() throws Exception {
HeaderStories hs = new HeaderStories(oddEven);
assertEquals("", hs.getFirstHeader());
assertEquals("[This is an Even Page, with a Header]\u0007August 20, 2008\u0007\u0007\r\r", hs.getEvenHeader());
assertEquals("August 20, 2008\u0007[ODD Page Header text]\u0007\u0007\r\r", hs.getOddHeader());
assertEquals("", hs.getFirstFooter());
assertEquals("\u0007Page \u0013 PAGE \\* MERGEFORMAT \u00142\u0015\u0007\u0007\u0007\u0007\u0007\u0007\u0007This is a simple footer on the second page\r\r", hs.getEvenFooter());
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getOddFooter());
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getFooter(1));
assertEquals("\u0007Page \u0013 PAGE \\* MERGEFORMAT \u00142\u0015\u0007\u0007\u0007\u0007\u0007\u0007\u0007This is a simple footer on the second page\r\r", hs.getFooter(2));
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getFooter(3));
}
public void testFirst() throws Exception {
HeaderStories hs = new HeaderStories(diffFirst);
assertEquals("I am the header on the first page, and I\u2019m nice and simple\r\r", hs.getFirstHeader());
assertEquals("", hs.getEvenHeader());
assertEquals("First header column!\tMid header Right header!\r\r", hs.getOddHeader());
assertEquals("The footer of the first page\r\r", hs.getFirstFooter());
assertEquals("", hs.getEvenFooter());
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getOddFooter());
assertEquals("The footer of the first page\r\r", hs.getFooter(1));
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getFooter(2));
assertEquals("Footer Left\tFooter Middle Footer Right\r\r", hs.getFooter(3));
}
public void testUnicode() throws Exception {
HeaderStories hs = new HeaderStories(unicode);
assertEquals("\r\r", hs.getFirstHeader());
assertEquals("\r\r", hs.getEvenHeader());
assertEquals("This is a simple header, with a \u20ac euro symbol in it.\r\r\r", hs.getOddHeader());
assertEquals("\r\r", hs.getFirstFooter());
assertEquals("\r\r", hs.getEvenFooter());
assertEquals("The footer, with Moli\u00e8re, has Unicode in it.\r\r", hs.getOddFooter());
}
}

View File

@ -31,8 +31,10 @@ import junit.framework.TestCase;
/** /**
* Test to see if Range.delete() works even if the Range contains a * Test to see if Range.delete() works even if the Range contains a
* CharacterRun that uses Unicode characters. * CharacterRun that uses Unicode characters.
*
* TODO - re-enable me when unicode paragraph stuff is fixed!
*/ */
public class TestRangeDelete extends TestCase { public abstract class TestRangeDelete extends TestCase {
// u201c and u201d are "smart-quotes" // u201c and u201d are "smart-quotes"
private String originalText = private String originalText =
@ -67,7 +69,7 @@ public class TestRangeDelete extends TestCase {
HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile)); HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile));
Range range = daDoc.getRange(); Range range = daDoc.getOverallRange();
assertEquals(1, range.numSections()); assertEquals(1, range.numSections());
Section section = range.getSection(0); Section section = range.getSection(0);
@ -78,6 +80,20 @@ public class TestRangeDelete extends TestCase {
assertEquals(5, para.numCharacterRuns()); assertEquals(5, para.numCharacterRuns());
assertEquals(originalText, para.text()); assertEquals(originalText, para.text());
// Now check on just the main text
range = daDoc.getRange();
assertEquals(1, range.numSections());
section = range.getSection(0);
assertEquals(5, section.numParagraphs());
para = section.getParagraph(2);
assertEquals(5, para.numCharacterRuns());
assertEquals(originalText, para.text());
} }
/** /**
@ -87,7 +103,7 @@ public class TestRangeDelete extends TestCase {
HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile)); HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile));
Range range = daDoc.getRange(); Range range = daDoc.getOverallRange();
assertEquals(1, range.numSections()); assertEquals(1, range.numSections());
Section section = range.getSection(0); Section section = range.getSection(0);

View File

@ -31,8 +31,10 @@ import junit.framework.TestCase;
/** /**
* Test to see if Range.insertBefore() works even if the Range contains a * Test to see if Range.insertBefore() works even if the Range contains a
* CharacterRun that uses Unicode characters. * CharacterRun that uses Unicode characters.
*
* TODO - re-enable me when unicode paragraph stuff is fixed!
*/ */
public class TestRangeInsertion extends TestCase { public abstract class TestRangeInsertion extends TestCase {
// u201c and u201d are "smart-quotes" // u201c and u201d are "smart-quotes"
private String originalText = private String originalText =

View File

@ -0,0 +1,169 @@
/* ====================================================================
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.hwpf.usermodel;
import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.hwpf.HWPFDocument;
import junit.framework.TestCase;
/**
* Tests to ensure that our ranges end up with
* the right text in them, and the right font/styling
* properties applied to them.
*
* TODO - re-enable me when unicode paragraph stuff is fixed!
*/
public abstract class TestRangeProperties extends TestCase {
private static final char page_break = (char)12;
private static final String u_page_1 =
"This is a fairly simple word document, over two pages, with headers and footers.\r" +
"The trick with this one is that it contains some Unicode based strings in it.\r" +
"Firstly, some currency symbols:\r" +
"\tGBP - \u00a3\r" +
"\tEUR - \u20ac\r" +
"Now, we\u2019ll have some French text, in bold and big:\r" +
"\tMoli\u00e8re\r" +
"And some normal French text:\r" +
"\tL'Avare ou l'\u00c9cole du mensonge\r" +
"That\u2019s it for page one\r"
;
private static final String u_page_2 =
"This is page two. Les Pr\u00e9cieuses ridicules. The end.\r"
;
private static final String a_page_1 =
"I am a test document\r" +
"This is page 1\r" +
"I am Calibri (Body) in font size 11\r"
;
private static final String a_page_2 =
"This is page two\r" +
"It\u2019s Arial Black in 16 point\r" +
"It\u2019s also in blue\r"
;
private HWPFDocument u;
private HWPFDocument a;
private String dirname;
protected void setUp() throws Exception {
dirname = System.getProperty("HWPF.testdata.path");
u = new HWPFDocument(
new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc"))
);
a = new HWPFDocument(
new FileInputStream(new File(dirname, "SampleDoc.doc"))
);
}
public void testAsciiTextParagraphs() throws Exception {
Range r = a.getRange();
assertEquals(
a_page_1 +
page_break + "\r" +
a_page_2,
r.text()
);
assertEquals(
7,
r.numParagraphs()
);
String[] p1_parts = a_page_1.split("\r");
String[] p2_parts = a_page_2.split("\r");
// Check paragraph contents
assertEquals(
p1_parts[0] + "\r",
r.getParagraph(0).text()
);
assertEquals(
p1_parts[1] + "\r",
r.getParagraph(1).text()
);
assertEquals(
p1_parts[2] + "\r",
r.getParagraph(2).text()
);
assertEquals(
page_break + "\r",
r.getParagraph(3).text()
);
assertEquals(
p2_parts[0] + "\r",
r.getParagraph(4).text()
);
assertEquals(
p2_parts[1] + "\r",
r.getParagraph(5).text()
);
assertEquals(
p2_parts[2] + "\r",
r.getParagraph(6).text()
);
}
public void testAsciiStyling() throws Exception {
Range r = a.getRange();
Paragraph p1 = r.getParagraph(0);
Paragraph p7 = r.getParagraph(6);
assertEquals(1, p1.numCharacterRuns());
assertEquals(1, p7.numCharacterRuns());
CharacterRun c1 = p1.getCharacterRun(0);
CharacterRun c7 = p7.getCharacterRun(0);
assertEquals("Times New Roman", c1.getFontName()); // No Calibri
assertEquals("Arial Black", c7.getFontName());
assertEquals(22, c1.getFontSize());
assertEquals(32, c7.getFontSize());
}
public void testUnicodeTextParagraphs() throws Exception {
Range r = u.getRange();
assertEquals(
u_page_1 +
page_break + "\r" +
u_page_2,
r.text()
);
assertEquals(
5,
r.numParagraphs()
);
String[] p1_parts = u_page_1.split("\r");
String[] p2_parts = u_page_2.split("\r");
System.out.println(r.getParagraph(2).text());
// TODO
}
public void testUnicodeStyling() throws Exception {
// TODO
}
}

View File

@ -31,8 +31,10 @@ import junit.framework.TestCase;
/** /**
* Test to see if Range.replaceText() works even if the Range contains a * Test to see if Range.replaceText() works even if the Range contains a
* CharacterRun that uses Unicode characters. * CharacterRun that uses Unicode characters.
*
* TODO - re-enable me when unicode paragraph stuff is fixed!
*/ */
public class TestRangeReplacement extends TestCase { public abstract class TestRangeReplacement extends TestCase {
// u201c and u201d are "smart-quotes" // u201c and u201d are "smart-quotes"
private String originalText = private String originalText =

View File

@ -38,42 +38,34 @@ import org.apache.poi.ss.usermodel.FormulaEvaluator.CellValue;
*/ */
public final class TestFormulaParserEval extends TestCase { public final class TestFormulaParserEval extends TestCase {
public void testWithNamedRange() throws Exception { public void testWithNamedRange() {
HSSFWorkbook workbook = new HSSFWorkbook(); HSSFWorkbook workbook = new HSSFWorkbook();
FormulaParser fp;
Ptg[] ptgs; Ptg[] ptgs;
HSSFSheet s = workbook.createSheet("Foo"); HSSFSheet s = workbook.createSheet("Foo");
s.createRow(0).createCell((short)0).setCellValue(1.1); s.createRow(0).createCell(0).setCellValue(1.1);
s.createRow(1).createCell((short)0).setCellValue(2.3); s.createRow(1).createCell(0).setCellValue(2.3);
s.createRow(2).createCell((short)2).setCellValue(3.1); s.createRow(2).createCell(2).setCellValue(3.1);
HSSFName name = workbook.createName(); HSSFName name = workbook.createName();
name.setNameName("testName"); name.setNameName("testName");
name.setReference("A1:A2"); name.setReference("A1:A2");
fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); ptgs = FormulaParser.parse("SUM(testName)", workbook);
fp.parse();
ptgs = fp.getRPNPtg();
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass()); assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass()); assertEquals(FuncVarPtg.class, ptgs[1].getClass());
// Now make it a single cell // Now make it a single cell
name.setReference("C3"); name.setReference("C3");
ptgs = FormulaParser.parse("SUM(testName)", workbook);
fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)");
fp.parse();
ptgs = fp.getRPNPtg();
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass()); assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass()); assertEquals(FuncVarPtg.class, ptgs[1].getClass());
// And make it non-contiguous // And make it non-contiguous
name.setReference("A1:A2,C3"); name.setReference("A1:A2,C3");
fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); ptgs = FormulaParser.parse("SUM(testName)", workbook);
fp.parse();
ptgs = fp.getRPNPtg();
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass()); assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass()); assertEquals(FuncVarPtg.class, ptgs[1].getClass());
@ -86,15 +78,14 @@ public final class TestFormulaParserEval extends TestCase {
wb.setSheetName(0, "Sheet1"); wb.setSheetName(0, "Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
cell.setCellFormula("SUM(A32769:A32770)"); cell.setCellFormula("SUM(A32769:A32770)");
// put some values in the cells to make the evaluation more interesting // put some values in the cells to make the evaluation more interesting
sheet.createRow(32768).createCell((short)0).setCellValue(31); sheet.createRow(32768).createCell(0).setCellValue(31);
sheet.createRow(32769).createCell((short)0).setCellValue(11); sheet.createRow(32769).createCell(0).setCellValue(11);
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
CellValue result; CellValue result;
try { try {
result = fe.evaluate(cell); result = fe.evaluate(cell);

View File

@ -35,10 +35,9 @@ public final class TestCircularReferences extends TestCase {
/** /**
* Translates StackOverflowError into AssertionFailedError * Translates StackOverflowError into AssertionFailedError
*/ */
private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFRow row, HSSFCell testCell) private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFCell testCell)
throws AssertionFailedError { throws AssertionFailedError {
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
evaluator.setCurrentRow(row);
try { try {
return evaluator.evaluate(testCell); return evaluator.evaluate(testCell);
} catch (StackOverflowError e) { } catch (StackOverflowError e) {
@ -63,12 +62,12 @@ public final class TestCircularReferences extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFSheet sheet = wb.createSheet("Sheet1");
short colB = 1; int colB = 1;
sheet.createRow(0).createCell(colB).setCellValue(1); sheet.createRow(0).createCell(colB).setCellValue(1);
sheet.createRow(1).createCell(colB).setCellValue(2); sheet.createRow(1).createCell(colB).setCellValue(2);
sheet.createRow(2).createCell(colB).setCellValue(3); sheet.createRow(2).createCell(colB).setCellValue(3);
HSSFRow row4 = sheet.createRow(3); HSSFRow row4 = sheet.createRow(3);
HSSFCell testCell = row4.createCell((short)0); HSSFCell testCell = row4.createCell(0);
// This formula should evaluate to the contents of B2, // This formula should evaluate to the contents of B2,
testCell.setCellFormula("INDEX(A1:B4,2,2)"); testCell.setCellFormula("INDEX(A1:B4,2,2)");
// However the range A1:B4 also includes the current cell A4. If the other parameters // However the range A1:B4 also includes the current cell A4. If the other parameters
@ -76,7 +75,7 @@ public final class TestCircularReferences extends TestCase {
// arguments before invoking operators, POI must handle such potential cycles gracefully. // arguments before invoking operators, POI must handle such potential cycles gracefully.
CellValue cellValue = evaluateWithCycles(wb, sheet, row4, testCell); CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC); assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC);
assertEquals(2, cellValue.getNumberValue(), 0); assertEquals(2, cellValue.getNumberValue(), 0);
@ -91,12 +90,11 @@ public final class TestCircularReferences extends TestCase {
HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell testCell = row.createCell((short)0); HSSFCell testCell = row.createCell(0);
testCell.setCellFormula("A1"); testCell.setCellFormula("A1");
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
evaluator.setCurrentRow(row); CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell);
confirmCycleErrorCode(cellValue); confirmCycleErrorCode(cellValue);
} }
@ -110,15 +108,14 @@ public final class TestCircularReferences extends TestCase {
HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
row.createCell((short)0).setCellFormula("B1"); row.createCell(0).setCellFormula("B1");
row.createCell((short)1).setCellFormula("C1"); row.createCell(1).setCellFormula("C1");
row.createCell((short)2).setCellFormula("D1"); row.createCell(2).setCellFormula("D1");
HSSFCell testCell = row.createCell((short)3); HSSFCell testCell = row.createCell(3);
testCell.setCellFormula("A1"); testCell.setCellFormula("A1");
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
evaluator.setCurrentRow(row); CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell);
confirmCycleErrorCode(cellValue); confirmCycleErrorCode(cellValue);
} }

View File

@ -40,7 +40,7 @@ public final class TestExternalFunction extends TestCase {
HSSFSheet sheet = wb.createSheet(); HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0, "Sheet1"); wb.setSheetName(0, "Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
HSSFName hssfName = wb.createName(); HSSFName hssfName = wb.createName();
hssfName.setNameName("myFunc"); hssfName.setNameName("myFunc");
@ -50,7 +50,6 @@ public final class TestExternalFunction extends TestCase {
assertEquals("myFunc()", actualFormula); assertEquals("myFunc()", actualFormula);
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
CellValue evalResult = fe.evaluate(cell); CellValue evalResult = fe.evaluate(cell);
// Check the return value from ExternalFunction.evaluate() // Check the return value from ExternalFunction.evaluate()

View File

@ -67,7 +67,6 @@ public final class TestFormulaBugs extends TestCase {
// We might as well evaluate the formula // We might as well evaluate the formula
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
CellValue cv = fe.evaluate(cell); CellValue cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
@ -84,20 +83,20 @@ public final class TestFormulaBugs extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("input"); HSSFSheet sheet = wb.createSheet("input");
// input row 0 // input row 0
HSSFRow row = sheet.createRow((short) 0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell = row.createCell((short) 1); cell = row.createCell(1);
cell.setCellValue(1); // B1 cell.setCellValue(1); // B1
// input row 1 // input row 1
row = sheet.createRow((short) 1); row = sheet.createRow(1);
cell = row.createCell((short) 1); cell = row.createCell(1);
cell.setCellValue(999); // B2 cell.setCellValue(999); // B2
int rno = 4; int rno = 4;
row = sheet.createRow(rno); row = sheet.createRow(rno);
cell = row.createCell((short) 1); // B5 cell = row.createCell(1); // B5
cell.setCellFormula("isnumber(b1)"); cell.setCellFormula("isnumber(b1)");
cell = row.createCell((short) 3); // D5 cell = row.createCell(3); // D5
cell.setCellFormula("IF(ISNUMBER(b1),b1,b2)"); cell.setCellFormula("IF(ISNUMBER(b1),b1,b2)");
if (false) { // set true to check excel file manually if (false) { // set true to check excel file manually
@ -113,7 +112,6 @@ public final class TestFormulaBugs extends TestCase {
// use POI's evaluator as an extra sanity check // use POI's evaluator as an extra sanity check
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
CellValue cv; CellValue cv;
cv = fe.evaluate(cell); cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
@ -132,7 +130,7 @@ public final class TestFormulaBugs extends TestCase {
HSSFSheet sheet1 = wb.createSheet("Sheet1"); HSSFSheet sheet1 = wb.createSheet("Sheet1");
HSSFRow row = sheet1.createRow(0); HSSFRow row = sheet1.createRow(0);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
// it's important to create the referenced sheet first // it's important to create the referenced sheet first
HSSFSheet sheet2 = wb.createSheet("A"); // note name 'A' HSSFSheet sheet2 = wb.createSheet("A"); // note name 'A'
@ -165,7 +163,6 @@ public final class TestFormulaBugs extends TestCase {
double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0; double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0;
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb);
fe.setCurrentRow(row);
CellValue cv = fe.evaluate(cell); CellValue cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
@ -174,6 +171,6 @@ public final class TestFormulaBugs extends TestCase {
private static void addCell(HSSFSheet sheet, int rowIx, int colIx, private static void addCell(HSSFSheet sheet, int rowIx, int colIx,
double value) { double value) {
sheet.createRow(rowIx).createCell((short) colIx).setCellValue(value); sheet.createRow(rowIx).createCell(colIx).setCellValue(value);
} }
} }

View File

@ -1,19 +1,19 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
@ -70,7 +70,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
/** /**
* Index of the column that contains the function names * Index of the column that contains the function names
*/ */
public static final short COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' public static final int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B'
/** /**
* Used to indicate when there are no more functions left * Used to indicate when there are no more functions left
@ -97,7 +97,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
private int _evaluationFailureCount; private int _evaluationFailureCount;
private int _evaluationSuccessCount; private int _evaluationSuccessCount;
private static final Cell getExpectedValueCell(Row row, short columnIndex) { private static final Cell getExpectedValueCell(Row row, int columnIndex) {
if (row == null) { if (row == null) {
return null; return null;
} }
@ -239,10 +239,9 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
int result = Result.NO_EVALUATIONS_FOUND; // so far int result = Result.NO_EVALUATIONS_FOUND; // so far
short endcolnum = formulasRow.getLastCellNum(); short endcolnum = formulasRow.getLastCellNum();
evaluator.setCurrentRow(formulasRow);
// iterate across the row for all the evaluation cases // iterate across the row for all the evaluation cases
for (short colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { for (int colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) {
Cell c = formulasRow.getCell(colnum); Cell c = formulasRow.getCell(colnum);
if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) { if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) {
continue; continue;
@ -298,7 +297,6 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
for(int i=startIx; i<endIx; i++) { for(int i=startIx; i<endIx; i++) {
ps.println("\tat " + stes[i].toString()); ps.println("\tat " + stes[i].toString());
} }
} }
/** /**

View File

@ -59,12 +59,11 @@ public final class TestPercentEval extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
cell.setCellFormula("B1%"); cell.setCellFormula("B1%");
row.createCell((short)1).setCellValue(50.0); row.createCell(1).setCellValue(50.0);
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
CellValue cv; CellValue cv;
try { try {
cv = fe.evaluate(cell); cv = fe.evaluate(cell);

View File

@ -290,7 +290,6 @@ public final class TestCountFuncs extends TestCase {
continue; continue;
} }
HSSFCell cell = row.getCell(COL_IX_ACTUAL); HSSFCell cell = row.getCell(COL_IX_ACTUAL);
fe.setCurrentRow(row);
CellValue cv = fe.evaluate(cell); CellValue cv = fe.evaluate(cell);
double actualValue = cv.getNumberValue(); double actualValue = cv.getNumberValue();
double expectedValue = row.getCell(COL_IX_EXPECTED).getNumericCellValue(); double expectedValue = row.getCell(COL_IX_EXPECTED).getNumericCellValue();

View File

@ -1,100 +1,83 @@
/* /* ====================================================================
* Created on Sep 11, 2007 Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* The Copyright statements and Licenses for the commons application may be this work for additional information regarding copyright ownership.
* found in the file LICENSE.txt 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; package org.apache.poi.hssf.record.formula.functions;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
/** /**
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/ */
public class TestDate extends TestCase { public final class TestDate extends TestCase {
public void setUp() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row1 = sheet.createRow((short) 0);
this.cell11 = row1.createCell((short) 0);
this.evaluator = new HSSFFormulaEvaluator(sheet, wb);
this.evaluator.setCurrentRow(row1);
}
/**
* Test disabled pending a fix in the formula parser
*/
public void DISABLEDtestSomeArgumentsMissing() throws Exception {
this.cell11.setCellFormula("DATE(, 1, 0)");
assertEquals(0.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(, 1, 1)");
assertEquals(1.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
}
public void testValid() throws Exception {
this.cell11.setCellType(HSSFCell.CELL_TYPE_FORMULA);
this.cell11.setCellFormula("DATE(1900, 1, 1)");
assertEquals(1, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 1, 32)");
assertEquals(32, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 222, 1)");
assertEquals(6727, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 2, 0)");
assertEquals(31, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(2000, 1, 222)");
assertEquals(36747.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(2007, 1, 1)");
assertEquals(39083, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
}
public void testBugDate() {
this.cell11.setCellFormula("DATE(1900, 2, 29)");
assertEquals(60, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 2, 30)");
assertEquals(61, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 1, 222)");
assertEquals(222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 1, 2222)");
assertEquals(2222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1900, 1, 22222)");
assertEquals(22222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
}
public void testPartYears() {
this.cell11.setCellFormula("DATE(4, 1, 1)");
assertEquals(1462.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(14, 1, 1)");
assertEquals(5115.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(104, 1, 1)");
assertEquals(37987.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
this.cell11.setCellFormula("DATE(1004, 1, 1)");
assertEquals(366705.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0);
}
private HSSFCell cell11; private HSSFCell cell11;
private HSSFFormulaEvaluator evaluator; private HSSFFormulaEvaluator evaluator;
public void setUp() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
cell11 = sheet.createRow(0).createCell(0);
cell11.setCellType(HSSFCell.CELL_TYPE_FORMULA);
evaluator = new HSSFFormulaEvaluator(sheet, wb);
}
/**
* Test disabled pending a fix in the formula evaluator
* TODO - create MissingArgEval and modify the formula evaluator to handle this
*/
public void DISABLEDtestSomeArgumentsMissing() {
confirm("DATE(, 1, 0)", 0.0);
confirm("DATE(, 1, 1)", 1.0);
}
public void testValid() {
confirm("DATE(1900, 1, 1)", 1);
confirm("DATE(1900, 1, 32)", 32);
confirm("DATE(1900, 222, 1)", 6727);
confirm("DATE(1900, 2, 0)", 31);
confirm("DATE(2000, 1, 222)", 36747.00);
confirm("DATE(2007, 1, 1)", 39083);
}
public void testBugDate() {
confirm("DATE(1900, 2, 29)", 60);
confirm("DATE(1900, 2, 30)", 61);
confirm("DATE(1900, 1, 222)", 222);
confirm("DATE(1900, 1, 2222)", 2222);
confirm("DATE(1900, 1, 22222)", 22222);
}
public void testPartYears() {
confirm("DATE(4, 1, 1)", 1462.00);
confirm("DATE(14, 1, 1)", 5115.00);
confirm("DATE(104, 1, 1)", 37987.00);
confirm("DATE(1004, 1, 1)", 366705.00);
}
private void confirm(String formulaText, double expectedResult) {
cell11.setCellFormula(formulaText);
double actualValue = evaluator.evaluate(cell11).getNumberValue();
assertEquals(expectedResult, actualValue, 0);
}
} }

View File

@ -32,8 +32,6 @@ import org.apache.poi.ss.usermodel.FormulaEvaluator.CellValue;
*/ */
public final class TestIsBlank extends TestCase { public final class TestIsBlank extends TestCase {
public void test3DArea() { public void test3DArea() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet(); HSSFSheet sheet1 = wb.createSheet();
@ -41,13 +39,12 @@ public final class TestIsBlank extends TestCase {
wb.createSheet(); wb.createSheet();
wb.setSheetName(1, "Sheet2"); wb.setSheetName(1, "Sheet2");
HSSFRow row = sheet1.createRow(0); HSSFRow row = sheet1.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
cell.setCellFormula("isblank(Sheet2!A1:A1)"); cell.setCellFormula("isblank(Sheet2!A1:A1)");
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb);
fe.setCurrentRow(row);
CellValue result = fe.evaluate(cell); CellValue result = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType());
assertEquals(true, result.getBooleanValue()); assertEquals(true, result.getBooleanValue());
@ -57,6 +54,5 @@ public final class TestIsBlank extends TestCase {
result = fe.evaluate(cell); result = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType());
assertEquals(true, result.getBooleanValue()); assertEquals(true, result.getBooleanValue());
} }
} }

View File

@ -1,25 +1,22 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at 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.
*/
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; package org.apache.poi.hssf.record.formula.functions;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import junit.framework.Assert; import junit.framework.Assert;
@ -70,10 +67,10 @@ public final class TestLookupFunctionsFromSpreadsheet extends TestCase {
/** Row (zero-based) in each sheet where the evaluation cases start. */ /** Row (zero-based) in each sheet where the evaluation cases start. */
public static final int START_TEST_CASES_ROW_INDEX = 4; // Row '5' public static final int START_TEST_CASES_ROW_INDEX = 4; // Row '5'
/** Index of the column that contains the function names */ /** Index of the column that contains the function names */
public static final short COLUMN_INDEX_MARKER = 0; // Column 'A' public static final int COLUMN_INDEX_MARKER = 0; // Column 'A'
public static final short COLUMN_INDEX_EVALUATION = 1; // Column 'B' public static final int COLUMN_INDEX_EVALUATION = 1; // Column 'B'
public static final short COLUMN_INDEX_EXPECTED_RESULT = 2; // Column 'C' public static final int COLUMN_INDEX_EXPECTED_RESULT = 2; // Column 'C'
public static final short COLUMN_ROW_COMMENT = 3; // Column 'D' public static final int COLUMN_ROW_COMMENT = 3; // Column 'D'
/** Used to indicate when there are no more test cases on the current sheet */ /** Used to indicate when there are no more test cases on the current sheet */
public static final String TEST_CASES_END_MARKER = "<end>"; public static final String TEST_CASES_END_MARKER = "<end>";
@ -240,7 +237,6 @@ public final class TestLookupFunctionsFromSpreadsheet extends TestCase {
if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
continue; continue;
} }
evaluator.setCurrentRow(r);
CellValue actualValue = evaluator.evaluate(c); CellValue actualValue = evaluator.evaluate(c);
HSSFCell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_RESULT); HSSFCell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_RESULT);
String rowComment = getRowCommentColumnValue(r); String rowComment = getRowCommentColumnValue(r);
@ -307,9 +303,8 @@ public final class TestLookupFunctionsFromSpreadsheet extends TestCase {
throw new RuntimeException("First sheet's name was '" + firstSheetName + "' but expected '" + SS.README_SHEET_NAME + "'"); throw new RuntimeException("First sheet's name was '" + firstSheetName + "' but expected '" + SS.README_SHEET_NAME + "'");
} }
HSSFSheet sheet = workbook.getSheetAt(0); HSSFSheet sheet = workbook.getSheetAt(0);
String specifiedClassName = sheet.getRow(2).getCell((short)0).getRichStringCellValue().getString(); String specifiedClassName = sheet.getRow(2).getCell(0).getRichStringCellValue().getString();
assertEquals("Test class name in spreadsheet comment", getClass().getName(), specifiedClassName); assertEquals("Test class name in spreadsheet comment", getClass().getName(), specifiedClassName);
} }
@ -362,7 +357,7 @@ public final class TestLookupFunctionsFromSpreadsheet extends TestCase {
if(r == null) { if(r == null) {
return null; return null;
} }
HSSFCell cell = r.getCell((short) colIndex); HSSFCell cell = r.getCell(colIndex);
if(cell == null) { if(cell == null) {
return null; return null;
} }

View File

@ -51,7 +51,6 @@ public final class TestBug42464 extends TestCase {
Iterator it = s.rowIterator(); Iterator it = s.rowIterator();
while(it.hasNext()) { while(it.hasNext()) {
HSSFRow r = (HSSFRow)it.next(); HSSFRow r = (HSSFRow)it.next();
eval.setCurrentRow(r);
process(r, eval); process(r, eval);
} }
} }

View File

@ -19,41 +19,43 @@ package org.apache.poi.hssf.usermodel;
import junit.framework.TestCase; import junit.framework.TestCase;
public class TestBug43093 extends TestCase { /**
*
*/
public final class TestBug43093 extends TestCase {
private static void addNewSheetWithCellsA1toD4(HSSFWorkbook book, int sheet) { private static void addNewSheetWithCellsA1toD4(HSSFWorkbook book, int sheet) {
HSSFSheet sht = book .createSheet("s" + sheet); HSSFSheet sht = book .createSheet("s" + sheet);
for (short r=0; r < 4; r++) { for (int r=0; r < 4; r++) {
HSSFRow row = sht.createRow (r); HSSFRow row = sht.createRow (r);
for (short c=0; c < 4; c++) { for (int c=0; c < 4; c++) {
HSSFCell cel = row.createCell(c); HSSFCell cel = row.createCell(c);
/**/ cel.setCellValue(sheet*100 + r*10 + c); cel.setCellValue(sheet*100 + r*10 + c);
} }
} }
} }
public void testBug43093() throws Exception { public void testBug43093() {
HSSFWorkbook xlw = new HSSFWorkbook(); HSSFWorkbook xlw = new HSSFWorkbook();
addNewSheetWithCellsA1toD4(xlw, 1); addNewSheetWithCellsA1toD4(xlw, 1);
addNewSheetWithCellsA1toD4(xlw, 2); addNewSheetWithCellsA1toD4(xlw, 2);
addNewSheetWithCellsA1toD4(xlw, 3); addNewSheetWithCellsA1toD4(xlw, 3);
addNewSheetWithCellsA1toD4(xlw, 4); addNewSheetWithCellsA1toD4(xlw, 4);
HSSFSheet s2 = xlw.getSheet("s2"); HSSFSheet s2 = xlw.getSheet("s2");
HSSFRow s2r3 = s2.getRow(3); HSSFRow s2r3 = s2.getRow(3);
HSSFCell s2E4 = s2r3.createCell((short)4); HSSFCell s2E4 = s2r3.createCell(4);
/**/ s2E4.setCellFormula("SUM(s3!B2:C3)"); s2E4.setCellFormula("SUM(s3!B2:C3)");
HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(s2, xlw); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(s2, xlw);
eva.setCurrentRow(s2r3); double d = eva.evaluate(s2E4).getNumberValue();
double d = eva.evaluate(s2E4).getNumberValue();
// internalEvaluate(...) Area3DEval.: 311+312+321+322 expected // internalEvaluate(...) Area3DEval.: 311+312+321+322 expected
assertEquals(d, (double)(311+312+321+322), 0.0000001); assertEquals(d, (311+312+321+322), 0.0000001);
// System.out.println("Area3DEval ok.: 311+312+321+322=" + d); // System.out.println("Area3DEval ok.: 311+312+321+322=" + d);
} }
} }

View File

@ -80,7 +80,7 @@ public final class TestBugs extends TestCase {
HSSFWorkbook wb = openSample("15228.xls"); HSSFWorkbook wb = openSample("15228.xls");
HSSFSheet s = wb.getSheetAt(0); HSSFSheet s = wb.getSheetAt(0);
HSSFRow r = s.createRow(0); HSSFRow r = s.createRow(0);
HSSFCell c = r.createCell((short)0); HSSFCell c = r.createCell(0);
c.setCellValue(10); c.setCellValue(10);
writeTestOutputFileForViewing(wb, "test15228"); writeTestOutputFileForViewing(wb, "test15228");
} }
@ -89,7 +89,7 @@ public final class TestBugs extends TestCase {
HSSFWorkbook wb = openSample("13796.xls"); HSSFWorkbook wb = openSample("13796.xls");
HSSFSheet s = wb.getSheetAt(0); HSSFSheet s = wb.getSheetAt(0);
HSSFRow r = s.createRow(0); HSSFRow r = s.createRow(0);
HSSFCell c = r.createCell((short)0); HSSFCell c = r.createCell(0);
c.setCellValue(10); c.setCellValue(10);
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
} }
@ -99,7 +99,7 @@ public final class TestBugs extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet(); HSSFSheet s = wb.createSheet();
HSSFRow r = s.createRow(0); HSSFRow r = s.createRow(0);
r.createCell((short)0).setCellFormula("HYPERLINK( \"http://jakarta.apache.org\", \"Jakarta\" )"); r.createCell(0).setCellFormula("HYPERLINK( \"http://jakarta.apache.org\", \"Jakarta\" )");
writeTestOutputFileForViewing(wb, "test23094"); writeTestOutputFileForViewing(wb, "test23094");
} }
@ -111,8 +111,8 @@ public final class TestBugs extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("My sheet"); HSSFSheet sheet = wb.createSheet("My sheet");
HSSFRow row = sheet.createRow( (short) 0 ); HSSFRow row = sheet.createRow( 0 );
HSSFCell cell = row.createCell( (short) 0 ); HSSFCell cell = row.createCell( 0 );
cell.setCellFormula("HYPERLINK(\"http://google.com\",\"Google\")"); cell.setCellFormula("HYPERLINK(\"http://google.com\",\"Google\")");
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -144,9 +144,9 @@ public final class TestBugs extends TestCase {
HSSFSheet sheet = wb.getSheetAt(0); HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = sheet.getRow(5); HSSFRow row = sheet.getRow(5);
HSSFCell cell = row.getCell((short)3); HSSFCell cell = row.getCell(3);
if (cell == null) if (cell == null)
cell = row.createCell((short)3); cell = row.createCell(3);
// Write test // Write test
cell.setCellType(HSSFCell.CELL_TYPE_STRING); cell.setCellType(HSSFCell.CELL_TYPE_STRING);
@ -155,9 +155,9 @@ public final class TestBugs extends TestCase {
// change existing numeric cell value // change existing numeric cell value
HSSFRow oRow = sheet.getRow(14); HSSFRow oRow = sheet.getRow(14);
HSSFCell oCell = oRow.getCell((short)4); HSSFCell oCell = oRow.getCell(4);
oCell.setCellValue(75); oCell.setCellValue(75);
oCell = oRow.getCell((short)5); oCell = oRow.getCell(5);
setCellText(oCell, "0.3"); setCellText(oCell, "0.3");
writeTestOutputFileForViewing(wb, "test15375"); writeTestOutputFileForViewing(wb, "test15375");
@ -179,13 +179,13 @@ public final class TestBugs extends TestCase {
tmp2 = "Test2" + i; tmp2 = "Test2" + i;
tmp3 = "Test3" + i; tmp3 = "Test3" + i;
HSSFRow row = sheet.createRow((short)i); HSSFRow row = sheet.createRow(i);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
setCellText(cell, tmp1); setCellText(cell, tmp1);
cell = row.createCell((short)1); cell = row.createCell(1);
setCellText(cell, tmp2); setCellText(cell, tmp2);
cell = row.createCell((short)2); cell = row.createCell(2);
setCellText(cell, tmp3); setCellText(cell, tmp3);
} }
writeTestOutputFileForViewing(wb, "test15375-2"); writeTestOutputFileForViewing(wb, "test15375-2");
@ -205,16 +205,16 @@ public final class TestBugs extends TestCase {
HSSFRow rw = null ; HSSFRow rw = null ;
HSSFCell cell =null; HSSFCell cell =null;
rw = sheet.createRow((short)0) ; rw = sheet.createRow(0) ;
//Header row //Header row
for(short j=0; j<col_cnt; j++){ for(int j=0; j<col_cnt; j++){
cell = rw.createCell(j) ; cell = rw.createCell(j) ;
setCellText(cell, "Col " + (j+1)) ; setCellText(cell, "Col " + (j+1)) ;
} }
for(int i=1; i<rw_cnt; i++){ for(int i=1; i<rw_cnt; i++){
rw = sheet.createRow((short)i) ; rw = sheet.createRow(i) ;
for(short j=0; j<col_cnt; j++){ for(int j=0; j<col_cnt; j++){
cell = rw.createCell(j) ; cell = rw.createCell(j) ;
setCellText(cell, "Row:" + (i+1) + ",Column:" + (j+1)) ; setCellText(cell, "Row:" + (i+1) + ",Column:" + (j+1)) ;
} }
@ -279,7 +279,7 @@ public final class TestBugs extends TestCase {
HSSFRow row = sheet.getRow(rowIndex); HSSFRow row = sheet.getRow(rowIndex);
int cells = row.getLastCellNum(); int cells = row.getLastCellNum();
for (short cellIndex = 0; cellIndex < cells; cellIndex++) { for (int cellIndex = 0; cellIndex < cells; cellIndex++) {
row.getCell(cellIndex); row.getCell(cellIndex);
} }
} }
@ -291,12 +291,12 @@ public final class TestBugs extends TestCase {
book.createSheet("TEST"); book.createSheet("TEST");
HSSFSheet sheet = book.cloneSheet(0); HSSFSheet sheet = book.cloneSheet(0);
book.setSheetName(1,"CLONE"); book.setSheetName(1,"CLONE");
sheet.createRow(0).createCell((short)0).setCellValue(new HSSFRichTextString("Test")); sheet.createRow(0).createCell(0).setCellValue(new HSSFRichTextString("Test"));
book = writeOutAndReadBack(book); book = writeOutAndReadBack(book);
sheet = book.getSheet("CLONE"); sheet = book.getSheet("CLONE");
HSSFRow row = sheet.getRow(0); HSSFRow row = sheet.getRow(0);
HSSFCell cell = row.getCell((short)0); HSSFCell cell = row.getCell(0);
assertEquals("Test", cell.getRichStringCellValue().getString()); assertEquals("Test", cell.getRichStringCellValue().getString());
} }
@ -338,14 +338,14 @@ public final class TestBugs extends TestCase {
HSSFWorkbook w = openSample("25695.xls"); HSSFWorkbook w = openSample("25695.xls");
HSSFCell a1 = w.getSheetAt(0).getRow(0).getCell((short) 0); HSSFCell a1 = w.getSheetAt(0).getRow(0).getCell(0);
HSSFCell a2 = w.getSheetAt(0).getRow(0).getCell((short) 1); HSSFCell a2 = w.getSheetAt(0).getRow(0).getCell(1);
HSSFCell b1 = w.getSheetAt(0).getRow(1).getCell((short) 0); HSSFCell b1 = w.getSheetAt(0).getRow(1).getCell(0);
HSSFCell b2 = w.getSheetAt(0).getRow(1).getCell((short) 1); HSSFCell b2 = w.getSheetAt(0).getRow(1).getCell(1);
HSSFCell c1 = w.getSheetAt(0).getRow(2).getCell((short) 0); HSSFCell c1 = w.getSheetAt(0).getRow(2).getCell(0);
HSSFCell c2 = w.getSheetAt(0).getRow(2).getCell((short) 1); HSSFCell c2 = w.getSheetAt(0).getRow(2).getCell(1);
HSSFCell d1 = w.getSheetAt(0).getRow(3).getCell((short) 0); HSSFCell d1 = w.getSheetAt(0).getRow(3).getCell(0);
HSSFCell d2 = w.getSheetAt(0).getRow(3).getCell((short) 1); HSSFCell d2 = w.getSheetAt(0).getRow(3).getCell(1);
if (false) { if (false) {
// THAI code page // THAI code page
@ -368,14 +368,14 @@ public final class TestBugs extends TestCase {
HSSFWorkbook rw = writeOutAndReadBack(w); HSSFWorkbook rw = writeOutAndReadBack(w);
HSSFCell ra1 = rw.getSheetAt(0).getRow(0).getCell((short) 0); HSSFCell ra1 = rw.getSheetAt(0).getRow(0).getCell(0);
HSSFCell ra2 = rw.getSheetAt(0).getRow(0).getCell((short) 1); HSSFCell ra2 = rw.getSheetAt(0).getRow(0).getCell(1);
HSSFCell rb1 = rw.getSheetAt(0).getRow(1).getCell((short) 0); HSSFCell rb1 = rw.getSheetAt(0).getRow(1).getCell(0);
HSSFCell rb2 = rw.getSheetAt(0).getRow(1).getCell((short) 1); HSSFCell rb2 = rw.getSheetAt(0).getRow(1).getCell(1);
HSSFCell rc1 = rw.getSheetAt(0).getRow(2).getCell((short) 0); HSSFCell rc1 = rw.getSheetAt(0).getRow(2).getCell(0);
HSSFCell rc2 = rw.getSheetAt(0).getRow(2).getCell((short) 1); HSSFCell rc2 = rw.getSheetAt(0).getRow(2).getCell(1);
HSSFCell rd1 = rw.getSheetAt(0).getRow(3).getCell((short) 0); HSSFCell rd1 = rw.getSheetAt(0).getRow(3).getCell(0);
HSSFCell rd2 = rw.getSheetAt(0).getRow(3).getCell((short) 1); HSSFCell rd2 = rw.getSheetAt(0).getRow(3).getCell(1);
confirmSameCellText(a1, ra1); confirmSameCellText(a1, ra1);
confirmSameCellText(b1, rb1); confirmSameCellText(b1, rb1);
@ -427,7 +427,7 @@ public final class TestBugs extends TestCase {
wb.setSheetName(0, "Sheet1"); wb.setSheetName(0, "Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
String formulaText = String formulaText =
"IF(ROUND(A2*B2*C2,2)>ROUND(B2*D2,2),ROUND(A2*B2*C2,2),ROUND(B2*D2,2))"; "IF(ROUND(A2*B2*C2,2)>ROUND(B2*D2,2),ROUND(A2*B2*C2,2),ROUND(B2*D2,2))";
cell.setCellFormula(formulaText); cell.setCellFormula(formulaText);
@ -489,7 +489,7 @@ public final class TestBugs extends TestCase {
for(int i = 1; i < 400; i++) { for(int i = 1; i < 400; i++) {
HSSFRow row = sheet.getRow(i); HSSFRow row = sheet.getRow(i);
if(row != null) { if(row != null) {
row.getCell((short)0); row.getCell(0);
} }
} }
@ -499,7 +499,7 @@ public final class TestBugs extends TestCase {
for(int i = 1; i < 400; i++) { for(int i = 1; i < 400; i++) {
HSSFRow row = sheet.getRow(i); HSSFRow row = sheet.getRow(i);
if(row != null) { if(row != null) {
row.getCell((short)0); row.getCell(0);
} }
} }
} }
@ -523,7 +523,7 @@ public final class TestBugs extends TestCase {
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) { for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
HSSFRow row = sheet.getRow(i); HSSFRow row = sheet.getRow(i);
if (row != null) { if (row != null) {
HSSFCell cell = row .getCell((short)0); HSSFCell cell = row .getCell(0);
assertEquals(HSSFCell.CELL_TYPE_STRING, cell.getCellType()); assertEquals(HSSFCell.CELL_TYPE_STRING, cell.getCellType());
count++; count++;
} }
@ -632,11 +632,11 @@ public final class TestBugs extends TestCase {
HSSFSheet workSheet = workBook.createSheet("Sheet1"); HSSFSheet workSheet = workBook.createSheet("Sheet1");
HSSFCell cell; HSSFCell cell;
HSSFRow row = workSheet.createRow(0); HSSFRow row = workSheet.createRow(0);
cell = row.createCell((short)0, HSSFCell.CELL_TYPE_NUMERIC); cell = row.createCell(0, HSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(1.0); cell.setCellValue(1.0);
cell = row.createCell((short)1, HSSFCell.CELL_TYPE_NUMERIC); cell = row.createCell(1, HSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(2.0); cell.setCellValue(2.0);
cell = row.createCell((short)2, HSSFCell.CELL_TYPE_FORMULA); cell = row.createCell(2, HSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula("SUM(A1:B1)"); cell.setCellFormula("SUM(A1:B1)");
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -753,12 +753,12 @@ public final class TestBugs extends TestCase {
// Textual value // Textual value
HSSFRow r1 = s.getRow(0); HSSFRow r1 = s.getRow(0);
HSSFCell c1 = r1.getCell((short)1); HSSFCell c1 = r1.getCell(1);
assertEquals("=CHOOSE(2,A2,A3,A4)", c1.getRichStringCellValue().toString()); assertEquals("=CHOOSE(2,A2,A3,A4)", c1.getRichStringCellValue().toString());
// Formula Value // Formula Value
HSSFRow r2 = s.getRow(1); HSSFRow r2 = s.getRow(1);
HSSFCell c2 = r2.getCell((short)1); HSSFCell c2 = r2.getCell(1);
assertEquals(25, (int)c2.getNumericCellValue()); assertEquals(25, (int)c2.getNumericCellValue());
try { try {
@ -900,7 +900,7 @@ public final class TestBugs extends TestCase {
* Had a problem apparently, not sure what as it * Had a problem apparently, not sure what as it
* works just fine... * works just fine...
*/ */
public void test44891() throws Exception { public void test44891() {
HSSFWorkbook wb = openSample("44891.xls"); HSSFWorkbook wb = openSample("44891.xls");
assertTrue("no errors reading sample xls", true); assertTrue("no errors reading sample xls", true);
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -912,7 +912,7 @@ public final class TestBugs extends TestCase {
* *
* Works fine with poi-3.1-beta1. * Works fine with poi-3.1-beta1.
*/ */
public void test44235() throws Exception { public void test44235() {
HSSFWorkbook wb = openSample("44235.xls"); HSSFWorkbook wb = openSample("44235.xls");
assertTrue("no errors reading sample xls", true); assertTrue("no errors reading sample xls", true);
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -927,16 +927,16 @@ public final class TestBugs extends TestCase {
public void test21334() { public void test21334() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sh = wb.createSheet(); HSSFSheet sh = wb.createSheet();
HSSFCell cell = sh.createRow(0).createCell((short)0); HSSFCell cell = sh.createRow(0).createCell(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))"; 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); cell.setCellFormula(formula);
HSSFWorkbook wb_sv = writeOutAndReadBack(wb); HSSFWorkbook wb_sv = writeOutAndReadBack(wb);
HSSFCell cell_sv = wb_sv.getSheetAt(0).getRow(0).getCell((short)0); HSSFCell cell_sv = wb_sv.getSheetAt(0).getRow(0).getCell(0);
assertEquals(formula, cell_sv.getCellFormula()); assertEquals(formula, cell_sv.getCellFormula());
} }
public void test36947() throws Exception { public void test36947() {
HSSFWorkbook wb = openSample("36947.xls"); HSSFWorkbook wb = openSample("36947.xls");
assertTrue("no errors reading sample xls", true); assertTrue("no errors reading sample xls", true);
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -948,12 +948,12 @@ public final class TestBugs extends TestCase {
*/ */
public void test42448(){ public void test42448(){
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFCell cell = wb.createSheet().createRow(0).createCell((short)0); HSSFCell cell = wb.createSheet().createRow(0).createCell(0);
cell.setCellFormula("SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"); cell.setCellFormula("SUMPRODUCT(A!C7:A!C67, B8:B68) / B69");
assertTrue("no errors parsing formula", true); assertTrue("no errors parsing formula", true);
} }
public void test39634() throws Exception { public void test39634() {
HSSFWorkbook wb = openSample("39634.xls"); HSSFWorkbook wb = openSample("39634.xls");
assertTrue("no errors reading sample xls", true); assertTrue("no errors reading sample xls", true);
writeOutAndReadBack(wb); writeOutAndReadBack(wb);
@ -965,7 +965,7 @@ public final class TestBugs extends TestCase {
* HSSFObjectData * HSSFObjectData
* @throws Exception * @throws Exception
*/ */
public void test44840() throws Exception { public void test44840() {
HSSFWorkbook wb = openSample("WithCheckBoxes.xls"); HSSFWorkbook wb = openSample("WithCheckBoxes.xls");
// Take a look at the embeded objects // Take a look at the embeded objects
@ -993,7 +993,11 @@ public final class TestBugs extends TestCase {
try { try {
obj.getDirectory(); obj.getDirectory();
fail(); fail();
} catch(FileNotFoundException e) {} } catch(FileNotFoundException e) {
// expectd during successful test
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
/** /**
@ -1002,7 +1006,7 @@ public final class TestBugs extends TestCase {
* used for printing stuff. * used for printing stuff.
* Currently broken, as we change the Ptg * Currently broken, as we change the Ptg
*/ */
public void test30978() throws Exception { public void test30978() {
HSSFWorkbook wb = openSample("30978-alt.xls"); HSSFWorkbook wb = openSample("30978-alt.xls");
assertEquals(1, wb.getNumberOfNames()); assertEquals(1, wb.getNumberOfNames());
assertEquals(3, wb.getNumberOfSheets()); assertEquals(3, wb.getNumberOfSheets());
@ -1058,15 +1062,15 @@ public final class TestBugs extends TestCase {
/** /**
* Test that fonts get added properly * Test that fonts get added properly
*/ */
public void test45338() throws Exception { public void test45338() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
assertEquals(4, wb.getNumberOfFonts()); assertEquals(4, wb.getNumberOfFonts());
HSSFSheet s = wb.createSheet(); HSSFSheet s = wb.createSheet();
s.createRow(0); s.createRow(0);
s.createRow(1); s.createRow(1);
HSSFCell c1 = s.getRow(0).createCell((short)0); HSSFCell c1 = s.getRow(0).createCell(0);
HSSFCell c2 = s.getRow(1).createCell((short)0); HSSFCell c2 = s.getRow(1).createCell(0);
assertEquals(4, wb.getNumberOfFonts()); assertEquals(4, wb.getNumberOfFonts());
@ -1142,15 +1146,14 @@ public final class TestBugs extends TestCase {
/** /**
* From the mailing list - ensure we can handle a formula * From the mailing list - ensure we can handle a formula
* containing a zip code, eg ="70164" * containing a zip code, eg ="70164"
* @throws Exception
*/ */
public void testZipCodeFormulas() throws Exception { public void testZipCodeFormulas() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet(); HSSFSheet s = wb.createSheet();
s.createRow(0); s.createRow(0);
HSSFCell c1 = s.getRow(0).createCell((short)0); HSSFCell c1 = s.getRow(0).createCell(0);
HSSFCell c2 = s.getRow(0).createCell((short)1); HSSFCell c2 = s.getRow(0).createCell(1);
HSSFCell c3 = s.getRow(0).createCell((short)2); HSSFCell c3 = s.getRow(0).createCell(2);
// As number and string // As number and string
c1.setCellFormula("70164"); c1.setCellFormula("70164");
@ -1178,7 +1181,6 @@ public final class TestBugs extends TestCase {
// Now evaluate, they should all be changed // Now evaluate, they should all be changed
HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb); HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
eval.setCurrentRow(s.getRow(0));
eval.evaluateFormulaCell(c1); eval.evaluateFormulaCell(c1);
eval.evaluateFormulaCell(c2); eval.evaluateFormulaCell(c2);
eval.evaluateFormulaCell(c3); eval.evaluateFormulaCell(c3);
@ -1196,9 +1198,9 @@ public final class TestBugs extends TestCase {
// Write and read // Write and read
HSSFWorkbook nwb = writeOutAndReadBack(wb); HSSFWorkbook nwb = writeOutAndReadBack(wb);
HSSFSheet ns = nwb.getSheetAt(0); HSSFSheet ns = nwb.getSheetAt(0);
HSSFCell nc1 = ns.getRow(0).getCell((short)0); HSSFCell nc1 = ns.getRow(0).getCell(0);
HSSFCell nc2 = ns.getRow(0).getCell((short)1); HSSFCell nc2 = ns.getRow(0).getCell(1);
HSSFCell nc3 = ns.getRow(0).getCell((short)2); HSSFCell nc3 = ns.getRow(0).getCell(2);
// Re-check // Re-check
assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001); assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001);
@ -1243,7 +1245,7 @@ public final class TestBugs extends TestCase {
* For now, blows up with an exception from ExtPtg * For now, blows up with an exception from ExtPtg
* Expected ExpPtg to be converted from Shared to Non-Shared... * Expected ExpPtg to be converted from Shared to Non-Shared...
*/ */
public void DISABLEDtest43623() throws Exception { public void DISABLEDtest43623() {
HSSFWorkbook wb = openSample("43623.xls"); HSSFWorkbook wb = openSample("43623.xls");
assertEquals(1, wb.getNumberOfSheets()); assertEquals(1, wb.getNumberOfSheets());
@ -1274,7 +1276,7 @@ public final class TestBugs extends TestCase {
* People are all getting confused about the last * People are all getting confused about the last
* row and cell number * row and cell number
*/ */
public void test30635() throws Exception { public void test30635() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet(); HSSFSheet s = wb.createSheet();
@ -1303,17 +1305,17 @@ public final class TestBugs extends TestCase {
assertEquals(0, r.getPhysicalNumberOfCells()); assertEquals(0, r.getPhysicalNumberOfCells());
// Add a cell, things move off -1 // Add a cell, things move off -1
r.createCell((short)0); r.createCell(0);
assertEquals(0, r.getFirstCellNum()); assertEquals(0, r.getFirstCellNum());
assertEquals(1, r.getLastCellNum()); // last cell # + 1 assertEquals(1, r.getLastCellNum()); // last cell # + 1
assertEquals(1, r.getPhysicalNumberOfCells()); assertEquals(1, r.getPhysicalNumberOfCells());
r.createCell((short)1); r.createCell(1);
assertEquals(0, r.getFirstCellNum()); assertEquals(0, r.getFirstCellNum());
assertEquals(2, r.getLastCellNum()); // last cell # + 1 assertEquals(2, r.getLastCellNum()); // last cell # + 1
assertEquals(2, r.getPhysicalNumberOfCells()); assertEquals(2, r.getPhysicalNumberOfCells());
r.createCell((short)4); r.createCell(4);
assertEquals(0, r.getFirstCellNum()); assertEquals(0, r.getFirstCellNum());
assertEquals(5, r.getLastCellNum()); // last cell # + 1 assertEquals(5, r.getLastCellNum()); // last cell # + 1
assertEquals(3, r.getPhysicalNumberOfCells()); assertEquals(3, r.getPhysicalNumberOfCells());
@ -1322,7 +1324,7 @@ public final class TestBugs extends TestCase {
/** /**
* Data Tables - ptg 0x2 * Data Tables - ptg 0x2
*/ */
public void test44958() throws Exception { public void test44958() {
HSSFWorkbook wb = openSample("44958.xls"); HSSFWorkbook wb = openSample("44958.xls");
HSSFSheet s; HSSFSheet s;
HSSFRow r; HSSFRow r;
@ -1353,7 +1355,7 @@ public final class TestBugs extends TestCase {
/** /**
* 45322: HSSFSheet.autoSizeColumn fails when style.getDataFormat() returns -1 * 45322: HSSFSheet.autoSizeColumn fails when style.getDataFormat() returns -1
*/ */
public void test45322() throws Exception { public void test45322() {
HSSFWorkbook wb = openSample("44958.xls"); HSSFWorkbook wb = openSample("44958.xls");
HSSFSheet sh = wb.getSheetAt(0); HSSFSheet sh = wb.getSheetAt(0);
for(short i=0; i < 30; i++) sh.autoSizeColumn(i); for(short i=0; i < 30; i++) sh.autoSizeColumn(i);
@ -1363,7 +1365,7 @@ public final class TestBugs extends TestCase {
* We used to add too many UncalcRecords to sheets * We used to add too many UncalcRecords to sheets
* with diagrams on. Don't any more * with diagrams on. Don't any more
*/ */
public void test45414() throws Exception { public void test45414() {
HSSFWorkbook wb = openSample("WithThreeCharts.xls"); HSSFWorkbook wb = openSample("WithThreeCharts.xls");
wb.getSheetAt(0).setForceFormulaRecalculation(true); wb.getSheetAt(0).setForceFormulaRecalculation(true);
wb.getSheetAt(1).setForceFormulaRecalculation(false); wb.getSheetAt(1).setForceFormulaRecalculation(false);

View File

@ -59,11 +59,11 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFSheet sheet = wb.getSheetAt(0); HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = sheet.getRow(0); HSSFRow row = sheet.getRow(0);
row.getCell((short) 0).setCellValue(4.2); row.getCell(0).setCellValue(4.2);
row.getCell((short) 2).setCellValue(25); row.getCell(2).setCellValue(25);
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
assertEquals(4.2 * 25, row.getCell((short) 3).getNumericCellValue(), 0.0001); assertEquals(4.2 * 25, row.getCell(3).getNumericCellValue(), 0.0001);
// Save // Save
File existing = new File(tmpDirName, "44636-existing.xls"); File existing = new File(tmpDirName, "44636-existing.xls");
@ -77,14 +77,14 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
sheet = wb.createSheet(); sheet = wb.createSheet();
row = sheet.createRow(0); row = sheet.createRow(0);
row.createCell((short) 0).setCellValue(1.2); row.createCell(0).setCellValue(1.2);
row.createCell((short) 1).setCellValue(4.2); row.createCell(1).setCellValue(4.2);
row = sheet.createRow(1); row = sheet.createRow(1);
row.createCell((short) 0).setCellFormula("SUM(A1:B1)"); row.createCell(0).setCellFormula("SUM(A1:B1)");
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
assertEquals(5.4, row.getCell((short) 0).getNumericCellValue(), 0.0001); assertEquals(5.4, row.getCell(0).getNumericCellValue(), 0.0001);
// Save // Save
File scratch = new File(tmpDirName, "44636-scratch.xls"); File scratch = new File(tmpDirName, "44636-scratch.xls");
@ -113,57 +113,48 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
row = sheet.getRow(0); row = sheet.getRow(0);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("31+46", cell.getCellFormula()); assertEquals("31+46", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(77, eva.evaluate(cell).getNumberValue(), 0); assertEquals(77, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(1); row = sheet.getRow(1);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("30+53", cell.getCellFormula()); assertEquals("30+53", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(83, eva.evaluate(cell).getNumberValue(), 0); assertEquals(83, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(2); row = sheet.getRow(2);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("SUM(A1:A2)", cell.getCellFormula()); assertEquals("SUM(A1:A2)", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(160, eva.evaluate(cell).getNumberValue(), 0); assertEquals(160, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(4); row = sheet.getRow(4);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("32767+32768", cell.getCellFormula()); assertEquals("32767+32768", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0); assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(7); row = sheet.getRow(7);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("32744+42333", cell.getCellFormula()); assertEquals("32744+42333", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0); assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(8); row = sheet.getRow(8);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("327680.0/32768", cell.getCellFormula()); assertEquals("327680.0/32768", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(10, eva.evaluate(cell).getNumberValue(), 0); assertEquals(10, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(9); row = sheet.getRow(9);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("32767+32769", cell.getCellFormula()); assertEquals("32767+32769", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0); assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(10); row = sheet.getRow(10);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("35000+36000", cell.getCellFormula()); assertEquals("35000+36000", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0); assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0);
row = sheet.getRow(11); row = sheet.getRow(11);
cell = row.getCell((short) 0); cell = row.getCell(0);
assertEquals("-1000000.0-3000000.0", cell.getCellFormula()); assertEquals("-1000000.0-3000000.0", cell.getCellFormula());
eva.setCurrentRow(row);
assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0);
} }
@ -189,7 +180,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFRow rowSUM2D = sheet.getRow(5); HSSFRow rowSUM2D = sheet.getRow(5);
// Test the sum // Test the sum
HSSFCell cellSUM = rowSUM.getCell((short) 0); HSSFCell cellSUM = rowSUM.getCell(0);
FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord(); FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord();
List ops = frec.getFormulaRecord().getParsedExpression(); List ops = frec.getFormulaRecord().getParsedExpression();
@ -210,7 +201,6 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
// rows it covers as we don't have the sheet // rows it covers as we don't have the sheet
// to hand when turning the Ptgs into a string // to hand when turning the Ptgs into a string
assertEquals("SUM(C:C)", cellSUM.getCellFormula()); assertEquals("SUM(C:C)", cellSUM.getCellFormula());
eva.setCurrentRow(rowSUM);
// But the evaluator knows the sheet, so it // But the evaluator knows the sheet, so it
// can do it properly // can do it properly
@ -219,15 +209,13 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
// Test the index // Test the index
// Again, the formula string will be right but // Again, the formula string will be right but
// lacking row count, evaluated will be right // lacking row count, evaluated will be right
HSSFCell cellIDX = rowIDX.getCell((short) 0); HSSFCell cellIDX = rowIDX.getCell(0);
assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula()); assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula());
eva.setCurrentRow(rowIDX);
assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0); assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0);
// Across two colums // Across two colums
HSSFCell cellSUM2D = rowSUM2D.getCell((short) 0); HSSFCell cellSUM2D = rowSUM2D.getCell(0);
assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); assertEquals("SUM(C:D)", cellSUM2D.getCellFormula());
eva.setCurrentRow(rowSUM2D);
assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0);
} }
@ -239,12 +227,11 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFSheet sheet = wb.createSheet(); HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0, "Sheet1"); wb.setSheetName(0, "Sheet1");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellFormula("1=1"); cell.setCellFormula("1=1");
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
try { try {
fe.evaluateInCell(cell); fe.evaluateInCell(cell);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@ -267,7 +254,6 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
for (Iterator rows = s.rowIterator(); rows.hasNext();) { for (Iterator rows = s.rowIterator(); rows.hasNext();) {
HSSFRow r = (HSSFRow) rows.next(); HSSFRow r = (HSSFRow) rows.next();
eval.setCurrentRow(r);
for (Iterator cells = r.cellIterator(); cells.hasNext();) { for (Iterator cells = r.cellIterator(); cells.hasNext();) {
HSSFCell c = (HSSFCell) cells.next(); HSSFCell c = (HSSFCell) cells.next();
@ -281,10 +267,9 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1"); HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(1); HSSFRow row = sheet.createRow(1);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellFormula("na()"); // this formula evaluates to an Excel error code '#N/A' cell.setCellFormula("na()"); // this formula evaluates to an Excel error code '#N/A'
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
fe.setCurrentRow(row);
try { try {
fe.evaluateInCell(cell); fe.evaluateInCell(cell);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@ -320,8 +305,6 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
final HSSFFormulaEvaluator evaluator = new final HSSFFormulaEvaluator evaluator = new
HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator(sheet, wb);
evaluator.setCurrentRow(excelRow);
now = System.currentTimeMillis(); now = System.currentTimeMillis();
evaluator.evaluate(excelCell); evaluator.evaluate(excelCell);
then = System.currentTimeMillis(); then = System.currentTimeMillis();
@ -333,8 +316,6 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
final HSSFFormulaEvaluator evaluator = new final HSSFFormulaEvaluator evaluator = new
HSSFFormulaEvaluator(sheet, wb); HSSFFormulaEvaluator(sheet, wb);
evaluator.setCurrentRow(excelRow);
now = System.currentTimeMillis(); now = System.currentTimeMillis();
evaluator.evaluate(excelCell); evaluator.evaluate(excelCell);
then = System.currentTimeMillis(); then = System.currentTimeMillis();

View File

@ -1,3 +1,20 @@
/* ====================================================================
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.usermodel; package org.apache.poi.hssf.usermodel;
import java.util.Iterator; import java.util.Iterator;
@ -9,15 +26,12 @@ import junit.framework.TestCase;
* http://poi.apache.org/hssf/eval.html * http://poi.apache.org/hssf/eval.html
* all actually works as we'd expect them to * all actually works as we'd expect them to
*/ */
public class TestFormulaEvaluatorDocs extends TestCase { public final class TestFormulaEvaluatorDocs extends TestCase {
protected void setUp() throws Exception {
super.setUp();
}
/** /**
* http://poi.apache.org/hssf/eval.html#EvaluateAll * http://poi.apache.org/hssf/eval.html#EvaluateAll
*/ */
public void testEvaluateAll() throws Exception { public void testEvaluateAll() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s1 = wb.createSheet(); HSSFSheet s1 = wb.createSheet();
HSSFSheet s2 = wb.createSheet(); HSSFSheet s2 = wb.createSheet();
@ -28,21 +42,21 @@ public class TestFormulaEvaluatorDocs extends TestCase {
HSSFRow s1r2 = s1.createRow(1); HSSFRow s1r2 = s1.createRow(1);
HSSFRow s2r1 = s2.createRow(0); HSSFRow s2r1 = s2.createRow(0);
HSSFCell s1r1c1 = s1r1.createCell((short)0); HSSFCell s1r1c1 = s1r1.createCell(0);
HSSFCell s1r1c2 = s1r1.createCell((short)1); HSSFCell s1r1c2 = s1r1.createCell(1);
HSSFCell s1r1c3 = s1r1.createCell((short)2); HSSFCell s1r1c3 = s1r1.createCell(2);
s1r1c1.setCellValue(22.3); s1r1c1.setCellValue(22.3);
s1r1c2.setCellValue(33.4); s1r1c2.setCellValue(33.4);
s1r1c3.setCellFormula("SUM(A1:B1)"); s1r1c3.setCellFormula("SUM(A1:B1)");
HSSFCell s1r2c1 = s1r2.createCell((short)0); HSSFCell s1r2c1 = s1r2.createCell(0);
HSSFCell s1r2c2 = s1r2.createCell((short)1); HSSFCell s1r2c2 = s1r2.createCell(1);
HSSFCell s1r2c3 = s1r2.createCell((short)2); HSSFCell s1r2c3 = s1r2.createCell(2);
s1r2c1.setCellValue(-1.2); s1r2c1.setCellValue(-1.2);
s1r2c2.setCellValue(-3.4); s1r2c2.setCellValue(-3.4);
s1r2c3.setCellFormula("SUM(A2:B2)"); s1r2c3.setCellFormula("SUM(A2:B2)");
HSSFCell s2r1c1 = s2r1.createCell((short)0); HSSFCell s2r1c1 = s2r1.createCell(0);
s2r1c1.setCellFormula("S1!A1"); s2r1c1.setCellFormula("S1!A1");
// Not evaluated yet // Not evaluated yet
@ -58,7 +72,6 @@ public class TestFormulaEvaluatorDocs extends TestCase {
for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next(); HSSFRow r = (HSSFRow)rit.next();
evaluator.setCurrentRow(r);
for(Iterator cit = r.cellIterator(); cit.hasNext();) { for(Iterator cit = r.cellIterator(); cit.hasNext();) {
HSSFCell c = (HSSFCell)cit.next(); HSSFCell c = (HSSFCell)cit.next();
@ -73,17 +86,17 @@ public class TestFormulaEvaluatorDocs extends TestCase {
} }
// Check now as expected // Check now as expected
assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell(2).getNumericCellValue(), 0);
assertEquals("SUM(A1:B1)", wb.getSheetAt(0).getRow(0).getCell((short)2).getCellFormula()); assertEquals("SUM(A1:B1)", wb.getSheetAt(0).getRow(0).getCell(2).getCellFormula());
assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(0).getCell(2).getCellType());
assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell(2).getNumericCellValue(), 0);
assertEquals("SUM(A2:B2)", wb.getSheetAt(0).getRow(1).getCell((short)2).getCellFormula()); assertEquals("SUM(A2:B2)", wb.getSheetAt(0).getRow(1).getCell(2).getCellFormula());
assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(1).getCell(2).getCellType());
assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell(0).getNumericCellValue(), 0);
assertEquals("'S1'!A1", wb.getSheetAt(1).getRow(0).getCell((short)0).getCellFormula()); assertEquals("'S1'!A1", wb.getSheetAt(1).getRow(0).getCell(0).getCellFormula());
assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(1).getRow(0).getCell(0).getCellType());
// Now do the alternate call, which zaps the formulas // Now do the alternate call, which zaps the formulas
@ -94,7 +107,6 @@ public class TestFormulaEvaluatorDocs extends TestCase {
for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next(); HSSFRow r = (HSSFRow)rit.next();
evaluator.setCurrentRow(r);
for(Iterator cit = r.cellIterator(); cit.hasNext();) { for(Iterator cit = r.cellIterator(); cit.hasNext();) {
HSSFCell c = (HSSFCell)cit.next(); HSSFCell c = (HSSFCell)cit.next();
@ -105,13 +117,13 @@ public class TestFormulaEvaluatorDocs extends TestCase {
} }
} }
assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell(2).getNumericCellValue(), 0);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(0).getCell(2).getCellType());
assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell(2).getNumericCellValue(), 0);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(1).getCell(2).getCellType());
assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell(0).getNumericCellValue(), 0);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(1).getRow(0).getCell(0).getCellType());
} }
} }

View File

@ -17,12 +17,6 @@
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -32,7 +26,6 @@ import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.util.TempFile;
/** /**
* Tests various functionity having to do with HSSFCell. For instance support for * Tests various functionity having to do with HSSFCell. For instance support for
@ -47,23 +40,15 @@ public final class TestHSSFCell extends TestCase {
return HSSFTestDataSamples.openSampleWorkbook(sampleFileName); return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
} }
private static HSSFWorkbook writeOutAndReadBack(HSSFWorkbook original) { private static HSSFWorkbook writeOutAndReadBack(HSSFWorkbook original) {
return HSSFTestDataSamples.writeOutAndReadBack(original);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
original.write(baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return new HSSFWorkbook(bais);
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
public void testSetValues() throws Exception { public void testSetValues() {
HSSFWorkbook book = new HSSFWorkbook(); HSSFWorkbook book = new HSSFWorkbook();
HSSFSheet sheet = book.createSheet("test"); HSSFSheet sheet = book.createSheet("test");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0); HSSFCell cell = row.createCell(0);
cell.setCellValue(1.2); cell.setCellValue(1.2);
assertEquals(1.2, cell.getNumericCellValue(), 0.0001); assertEquals(1.2, cell.getNumericCellValue(), 0.0001);
@ -85,54 +70,42 @@ public final class TestHSSFCell extends TestCase {
/** /**
* test that Boolean and Error types (BoolErrRecord) are supported properly. * test that Boolean and Error types (BoolErrRecord) are supported properly.
*/ */
public void testBoolErr() public void testBoolErr() {
throws java.io.IOException {
File file = TempFile.createTempFile("testBoolErr",".xls"); HSSFWorkbook wb = new HSSFWorkbook();
FileOutputStream out = new FileOutputStream(file); HSSFSheet s = wb.createSheet("testSheet1");
HSSFWorkbook wb = new HSSFWorkbook(); HSSFRow r = null;
HSSFSheet s = wb.createSheet("testSheet1"); HSSFCell c = null;
HSSFRow r = null; r = s.createRow((short)0);
HSSFCell c = null; c=r.createCell(1);
r = s.createRow((short)0); //c.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
c=r.createCell((short)1); c.setCellValue(true);
//c.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
c.setCellValue(true);
c=r.createCell((short)2); c=r.createCell(2);
//c.setCellType(HSSFCell.CELL_TYPE_BOOLEAN); //c.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
c.setCellValue(false); c.setCellValue(false);
r = s.createRow((short)1); r = s.createRow((short)1);
c=r.createCell((short)1); c=r.createCell(1);
//c.setCellType(HSSFCell.CELL_TYPE_ERROR); //c.setCellType(HSSFCell.CELL_TYPE_ERROR);
c.setCellErrorValue((byte)0); c.setCellErrorValue((byte)0);
c=r.createCell((short)2); c=r.createCell(2);
//c.setCellType(HSSFCell.CELL_TYPE_ERROR); //c.setCellType(HSSFCell.CELL_TYPE_ERROR);
c.setCellErrorValue((byte)7); c.setCellErrorValue((byte)7);
wb = writeOutAndReadBack(wb);
wb.write(out); s = wb.getSheetAt(0);
out.close(); r = s.getRow(0);
c = r.getCell(1);
assertTrue("file exists",file.exists()); assertTrue("boolean value 0,1 = true",c.getBooleanCellValue());
c = r.getCell(2);
FileInputStream in = new FileInputStream(file); assertTrue("boolean value 0,2 = false",c.getBooleanCellValue()==false);
wb = new HSSFWorkbook(in); r = s.getRow(1);
s = wb.getSheetAt(0); c = r.getCell(1);
r = s.getRow(0); assertTrue("boolean value 0,1 = 0",c.getErrorCellValue() == 0);
c = r.getCell((short)1); c = r.getCell(2);
assertTrue("boolean value 0,1 = true",c.getBooleanCellValue()); assertTrue("boolean value 0,2 = 7",c.getErrorCellValue() == 7);
c = r.getCell((short)2);
assertTrue("boolean value 0,2 = false",c.getBooleanCellValue()==false);
r = s.getRow(1);
c = r.getCell((short)1);
assertTrue("boolean value 0,1 = 0",c.getErrorCellValue() == 0);
c = r.getCell((short)2);
assertTrue("boolean value 0,2 = 7",c.getErrorCellValue() == 7);
in.close();
} }
/** /**
@ -140,7 +113,7 @@ public final class TestHSSFCell extends TestCase {
* is working properly. Conversion of the date is also an issue, * is working properly. Conversion of the date is also an issue,
* but there's a separate unit test for that. * but there's a separate unit test for that.
*/ */
public void testDateWindowingRead() throws Exception { public void testDateWindowingRead() {
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
Date date = cal.getTime(); Date date = cal.getTime();
@ -150,7 +123,7 @@ public final class TestHSSFCell extends TestCase {
assertEquals("Date from file using 1900 Date Windowing", assertEquals("Date from file using 1900 Date Windowing",
date.getTime(), date.getTime(),
sheet.getRow(0).getCell((short)0) sheet.getRow(0).getCell(0)
.getDateCellValue().getTime()); .getDateCellValue().getTime());
// now check a file with 1904 Date Windowing // now check a file with 1904 Date Windowing
@ -159,7 +132,7 @@ public final class TestHSSFCell extends TestCase {
assertEquals("Date from file using 1904 Date Windowing", assertEquals("Date from file using 1904 Date Windowing",
date.getTime(), date.getTime(),
sheet.getRow(0).getCell((short)0) sheet.getRow(0).getCell(0)
.getDateCellValue().getTime()); .getDateCellValue().getTime());
} }
@ -169,7 +142,7 @@ public final class TestHSSFCell extends TestCase {
* previous test ({@link #testDateWindowingRead}) fails, the * previous test ({@link #testDateWindowingRead}) fails, the
* results of this test are meaningless. * results of this test are meaningless.
*/ */
public void testDateWindowingWrite() throws Exception { public void testDateWindowingWrite() {
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
Date date = cal.getTime(); Date date = cal.getTime();
@ -199,7 +172,7 @@ public final class TestHSSFCell extends TestCase {
HSSFCell cell = row.getCell(colIdx); HSSFCell cell = row.getCell(colIdx);
if (cell == null) { if (cell == null) {
cell = row.createCell((short)colIdx); cell = row.createCell(colIdx);
} }
cell.setCellValue(date); cell.setCellValue(date);
} }
@ -214,8 +187,7 @@ public final class TestHSSFCell extends TestCase {
/** /**
* Tests that the active cell can be correctly read and set * Tests that the active cell can be correctly read and set
*/ */
public void testActiveCell() throws Exception public void testActiveCell() {
{
//read in sample //read in sample
HSSFWorkbook book = openSample("Simple.xls"); HSSFWorkbook book = openSample("Simple.xls");
@ -228,7 +200,7 @@ public final class TestHSSFCell extends TestCase {
1, s.getActiveCellRow()); 1, s.getActiveCellRow());
//modify position through HSSFCell //modify position through HSSFCell
HSSFCell cell = umSheet.createRow(3).createCell((short) 2); HSSFCell cell = umSheet.createRow(3).createCell(2);
cell.setAsActiveCell(); cell.setAsActiveCell();
assertEquals("After modify, active cell should be in col 2", assertEquals("After modify, active cell should be in col 2",
(short) 2, s.getActiveCellCol()); (short) 2, s.getActiveCellCol());
@ -270,14 +242,14 @@ public final class TestHSSFCell extends TestCase {
cs.setBorderBottom((short)1); cs.setBorderBottom((short)1);
r = s.createRow((short)0); r = s.createRow((short)0);
c=r.createCell((short)0); c=r.createCell(0);
c.setCellStyle(cs); c.setCellStyle(cs);
c.setCellFormula("2*3"); c.setCellFormula("2*3");
wb = writeOutAndReadBack(wb); wb = writeOutAndReadBack(wb);
s = wb.getSheetAt(0); s = wb.getSheetAt(0);
r = s.getRow(0); r = s.getRow(0);
c = r.getCell((short)0); c = r.getCell(0);
assertTrue("Formula Cell at 0,0", (c.getCellType()==c.CELL_TYPE_FORMULA)); assertTrue("Formula Cell at 0,0", (c.getCellType()==c.CELL_TYPE_FORMULA));
cs = c.getCellStyle(); cs = c.getCellStyle();
@ -298,7 +270,7 @@ public final class TestHSSFCell extends TestCase {
HSSFWorkbook wb = openSample("WithHyperlink.xls"); HSSFWorkbook wb = openSample("WithHyperlink.xls");
HSSFSheet sheet = wb.getSheetAt(0); HSSFSheet sheet = wb.getSheetAt(0);
HSSFCell cell = sheet.getRow(4).getCell((short)0); HSSFCell cell = sheet.getRow(4).getCell(0);
HSSFHyperlink link = cell.getHyperlink(); HSSFHyperlink link = cell.getHyperlink();
assertNotNull(link); assertNotNull(link);
@ -311,13 +283,13 @@ public final class TestHSSFCell extends TestCase {
/** /**
* Test reading hyperlinks * Test reading hyperlinks
*/ */
public void testWithTwoHyperlinks() throws Exception { public void testWithTwoHyperlinks() {
HSSFWorkbook wb = openSample("WithTwoHyperLinks.xls"); HSSFWorkbook wb = openSample("WithTwoHyperLinks.xls");
HSSFSheet sheet = wb.getSheetAt(0); HSSFSheet sheet = wb.getSheetAt(0);
HSSFCell cell1 = sheet.getRow(4).getCell((short)0); HSSFCell cell1 = sheet.getRow(4).getCell(0);
HSSFHyperlink link1 = cell1.getHyperlink(); HSSFHyperlink link1 = cell1.getHyperlink();
assertNotNull(link1); assertNotNull(link1);
assertEquals("Foo", link1.getLabel()); assertEquals("Foo", link1.getLabel());
@ -325,55 +297,46 @@ public final class TestHSSFCell extends TestCase {
assertEquals(4, link1.getFirstRow()); assertEquals(4, link1.getFirstRow());
assertEquals(0, link1.getFirstColumn()); assertEquals(0, link1.getFirstColumn());
HSSFCell cell2 = sheet.getRow(8).getCell((short)1); HSSFCell cell2 = sheet.getRow(8).getCell(1);
HSSFHyperlink link2 = cell2.getHyperlink(); HSSFHyperlink link2 = cell2.getHyperlink();
assertNotNull(link2); assertNotNull(link2);
assertEquals("Bar", link2.getLabel()); assertEquals("Bar", link2.getLabel());
assertEquals("http://poi.apache.org/hssf/", link2.getAddress()); assertEquals("http://poi.apache.org/hssf/", link2.getAddress());
assertEquals(8, link2.getFirstRow()); assertEquals(8, link2.getFirstRow());
assertEquals(1, link2.getFirstColumn()); assertEquals(1, link2.getFirstColumn());
} }
/*tests the toString() method of HSSFCell*/ /*tests the toString() method of HSSFCell*/
public void testToString() throws Exception { public void testToString() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet("Sheet1"); HSSFRow r = wb.createSheet("Sheet1").createRow(0);
HSSFRow r = s.createRow(0);
HSSFCell c; r.createCell(0).setCellValue(true);
c=r.createCell((short) 0); c.setCellValue(true); r.createCell(1).setCellValue(1.5);
assertEquals("Boolean", "TRUE", c.toString()); r.createCell(2).setCellValue(new HSSFRichTextString("Astring"));
c=r.createCell((short) 1); c.setCellValue(1.5); r.createCell(3).setCellErrorValue((byte)HSSFErrorConstants.ERROR_DIV_0);
assertEquals("Numeric", "1.5", c.toString()); r.createCell(4).setCellFormula("A1+B1");
c=r.createCell((short)(2)); c.setCellValue(new HSSFRichTextString("Astring"));
assertEquals("String", "Astring", c.toString()); assertEquals("Boolean", "TRUE", r.getCell(0).toString());
c=r.createCell((short) 3); c.setCellErrorValue((byte) 7); assertEquals("Numeric", "1.5", r.getCell(1).toString());
assertEquals("Error", "#ERR7", c.toString()); assertEquals("String", "Astring", r.getCell(2).toString());
c=r.createCell((short)4); c.setCellFormula("A1+B1"); assertEquals("Error", "#DIV/0!", r.getCell(3).toString());
assertEquals("Formula", "A1+B1", c.toString()); assertEquals("Formula", "A1+B1", r.getCell(4).toString());
//Write out the file, read it in, and then check cell values //Write out the file, read it in, and then check cell values
File f = File.createTempFile("testCellToString",".xls"); wb = writeOutAndReadBack(wb);
wb.write(new FileOutputStream(f));
wb = new HSSFWorkbook(new FileInputStream(f));
assertTrue("File exists and can be read", f.canRead());
s = wb.getSheetAt(0);r=s.getRow(0); r = wb.getSheetAt(0).getRow(0);
c=r.getCell((short) 0); assertEquals("Boolean", "TRUE", r.getCell(0).toString());
assertEquals("Boolean", "TRUE", c.toString()); assertEquals("Numeric", "1.5", r.getCell(1).toString());
c=r.getCell((short) 1); assertEquals("String", "Astring", r.getCell(2).toString());
assertEquals("Numeric", "1.5", c.toString()); assertEquals("Error", "#DIV/0!", r.getCell(3).toString());
c=r.getCell((short)(2)); assertEquals("Formula", "A1+B1", r.getCell(4).toString());
assertEquals("String", "Astring", c.toString());
c=r.getCell((short) 3);
assertEquals("Error", "#ERR7", c.toString());
c=r.getCell((short)4);
assertEquals("Formula", "A1+B1", c.toString());
} }
public void testSetStringInFormulaCell_bug44606() { public void testSetStringInFormulaCell_bug44606() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();
HSSFCell cell = wb.createSheet("Sheet1").createRow(0).createCell((short)0); HSSFCell cell = wb.createSheet("Sheet1").createRow(0).createCell(0);
cell.setCellFormula("B1&C1"); cell.setCellFormula("B1&C1");
try { try {
cell.setCellValue(new HSSFRichTextString("hello")); cell.setCellValue(new HSSFRichTextString("hello"));
@ -404,8 +367,8 @@ public final class TestHSSFCell extends TestCase {
fail(); fail();
} catch(IllegalArgumentException e) {} } catch(IllegalArgumentException e) {}
HSSFCell cellA = wbA.createSheet().createRow(0).createCell((short)0); HSSFCell cellA = wbA.createSheet().createRow(0).createCell(0);
HSSFCell cellB = wbB.createSheet().createRow(0).createCell((short)0); HSSFCell cellB = wbB.createSheet().createRow(0).createCell(0);
cellA.setCellStyle(styA); cellA.setCellStyle(styA);
cellB.setCellStyle(styB); cellB.setCellStyle(styB);
@ -418,9 +381,5 @@ public final class TestHSSFCell extends TestCase {
fail(); fail();
} catch(IllegalArgumentException e) {} } catch(IllegalArgumentException e) {}
} }
public static void main(String [] args) {
junit.textui.TestRunner.run(TestHSSFCell.class);
}
} }

View File

@ -19,7 +19,6 @@ package org.apache.poi.hssf.usermodel;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.Format; import java.text.Format;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -96,7 +95,7 @@ public final class TestHSSFDataFormatter extends TestCase {
// create cells with good date patterns // create cells with good date patterns
for (int i = 0; i < goodDatePatterns.length; i++) { for (int i = 0; i < goodDatePatterns.length; i++) {
HSSFCell cell = row.createCell((short) i); HSSFCell cell = row.createCell(i);
cell.setCellValue(dateNum); cell.setCellValue(dateNum);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat(goodDatePatterns[i])); cellStyle.setDataFormat(format.getFormat(goodDatePatterns[i]));
@ -106,7 +105,7 @@ public final class TestHSSFDataFormatter extends TestCase {
// create cells with num patterns // create cells with num patterns
for (int i = 0; i < goodNumPatterns.length; i++) { for (int i = 0; i < goodNumPatterns.length; i++) {
HSSFCell cell = row.createCell((short) i); HSSFCell cell = row.createCell(i);
cell.setCellValue(-1234567890.12345); cell.setCellValue(-1234567890.12345);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat(goodNumPatterns[i])); cellStyle.setDataFormat(format.getFormat(goodNumPatterns[i]));
@ -116,7 +115,7 @@ public final class TestHSSFDataFormatter extends TestCase {
// create cells with bad num patterns // create cells with bad num patterns
for (int i = 0; i < badNumPatterns.length; i++) { for (int i = 0; i < badNumPatterns.length; i++) {
HSSFCell cell = row.createCell((short) i); HSSFCell cell = row.createCell(i);
cell.setCellValue(1234567890.12345); cell.setCellValue(1234567890.12345);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat(badNumPatterns[i])); cellStyle.setDataFormat(format.getFormat(badNumPatterns[i]));
@ -127,7 +126,7 @@ public final class TestHSSFDataFormatter extends TestCase {
{ // Zip + 4 format { // Zip + 4 format
row = sheet.createRow(3); row = sheet.createRow(3);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellValue(123456789); cell.setCellValue(123456789);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat("00000-0000")); cellStyle.setDataFormat(format.getFormat("00000-0000"));
@ -136,7 +135,7 @@ public final class TestHSSFDataFormatter extends TestCase {
{ // Phone number format { // Phone number format
row = sheet.createRow(4); row = sheet.createRow(4);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellValue(5551234567D); cell.setCellValue(5551234567D);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat("[<=9999999]###-####;(###) ###-####")); cellStyle.setDataFormat(format.getFormat("[<=9999999]###-####;(###) ###-####"));
@ -145,7 +144,7 @@ public final class TestHSSFDataFormatter extends TestCase {
{ // SSN format { // SSN format
row = sheet.createRow(5); row = sheet.createRow(5);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellValue(444551234); cell.setCellValue(444551234);
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(format.getFormat("000-00-0000")); cellStyle.setDataFormat(format.getFormat("000-00-0000"));
@ -154,7 +153,7 @@ public final class TestHSSFDataFormatter extends TestCase {
{ // formula cell { // formula cell
row = sheet.createRow(6); row = sheet.createRow(6);
HSSFCell cell = row.createCell((short) 0); HSSFCell cell = row.createCell(0);
cell.setCellType(HSSFCell.CELL_TYPE_FORMULA); cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula("SUM(12.25,12.25)/100"); cell.setCellFormula("SUM(12.25,12.25)/100");
HSSFCellStyle cellStyle = wb.createCellStyle(); HSSFCellStyle cellStyle = wb.createCellStyle();
@ -231,7 +230,6 @@ public final class TestHSSFDataFormatter extends TestCase {
// null test-- null cell should result in empty String // null test-- null cell should result in empty String
assertEquals(formatter.formatCellValue(null), ""); assertEquals(formatter.formatCellValue(null), "");
} }
public void testGetFormattedCellValueHSSFCellHSSFFormulaEvaluator() { public void testGetFormattedCellValueHSSFCellHSSFFormulaEvaluator() {
@ -246,14 +244,10 @@ public final class TestHSSFDataFormatter extends TestCase {
// now with a formula evaluator // now with a formula evaluator
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb); HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
//! must set current row !
evaluator.setCurrentRow(row);
log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)"); log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
assertEquals("24.50%", formatter.formatCellValue(cell,evaluator)); assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
} }
/** /**
* Test using a default number format. The format should be used when a * Test using a default number format. The format should be used when a
* format pattern cannot be parsed by DecimalFormat. * format pattern cannot be parsed by DecimalFormat.

View File

@ -20,7 +20,7 @@
<record fromfile="true" name="FIB" package="org.apache.poi.hwpf.model.types"> <record fromfile="true" name="FIB" package="org.apache.poi.hwpf.model.types">
<suffix>AbstractType</suffix> <suffix>AbstractType</suffix>
<extends>HDFType</extends> <extends>HDFType</extends>
<description>File information Block.</description> <description>Base part of the File information Block (FibBase). Holds the core part of the FIB, from the first 32 bytes.</description>
<author>Andrew C. Oliver</author> <author>Andrew C. Oliver</author>
<fields> <fields>
<!-- <field type="int" size="2" name="format flags"> <!-- <field type="int" size="2" name="format flags">