mirror of https://github.com/apache/poi.git
Fix for bug 45519 - keep data validation records together
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@681530 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fa669818ce
commit
b935799609
|
@ -37,6 +37,7 @@
|
|||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.1.1-alpha1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.1.1-alpha1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.apache.poi.hssf.record.Record;
|
|||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
final class RecordStream {
|
||||
public final class RecordStream {
|
||||
|
||||
private final List _list;
|
||||
private int _nextIndex;
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.*; // normally I don't do this, buy we literally mean ALL
|
||||
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
|
||||
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.util.PaneInformation;
|
||||
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
|
@ -31,7 +31,7 @@ import org.apache.poi.util.POILogger;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List; // normally I don't do this, buy we literally mean ALL
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Low level model implementation of a Sheet (one workbook contains many sheets)
|
||||
|
@ -90,6 +90,7 @@ public final class Sheet implements Model {
|
|||
protected ProtectRecord protect = null;
|
||||
protected PageBreakRecord rowBreaks = null;
|
||||
protected PageBreakRecord colBreaks = null;
|
||||
private DataValidityTable _dataValidityTable= null;
|
||||
protected ObjectProtectRecord objprotect = null;
|
||||
protected ScenarioProtectRecord scenprotect = null;
|
||||
protected PasswordRecord password = null;
|
||||
|
@ -299,7 +300,12 @@ public final class Sheet implements Model {
|
|||
// and POI always re-calculates its contents
|
||||
rec = null;
|
||||
}
|
||||
|
||||
else if ( rec.getSid() == DVALRecord.sid) {
|
||||
RecordStream rs = new RecordStream(recs, k);
|
||||
retval._dataValidityTable = new DataValidityTable(rs);
|
||||
k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
|
||||
rec = retval._dataValidityTable;
|
||||
}
|
||||
else if ( rec.getSid() == ProtectRecord.sid )
|
||||
{
|
||||
retval.protect = (ProtectRecord) rec;
|
||||
|
@ -425,56 +431,56 @@ public final class Sheet implements Model {
|
|||
Sheet retval = new Sheet();
|
||||
ArrayList records = new ArrayList(30);
|
||||
|
||||
records.add(retval.createBOF());
|
||||
records.add(createBOF());
|
||||
|
||||
// records.add(retval.createIndex());
|
||||
records.add(retval.createCalcMode());
|
||||
records.add(retval.createCalcCount() );
|
||||
records.add( retval.createRefMode() );
|
||||
records.add( retval.createIteration() );
|
||||
records.add( retval.createDelta() );
|
||||
records.add( retval.createSaveRecalc() );
|
||||
records.add( retval.createPrintHeaders() );
|
||||
retval.printGridlines = (PrintGridlinesRecord) retval.createPrintGridlines();
|
||||
records.add(createCalcMode());
|
||||
records.add(createCalcCount() );
|
||||
records.add(createRefMode() );
|
||||
records.add(createIteration() );
|
||||
records.add(createDelta() );
|
||||
records.add(createSaveRecalc() );
|
||||
records.add(createPrintHeaders() );
|
||||
retval.printGridlines = createPrintGridlines();
|
||||
records.add( retval.printGridlines );
|
||||
retval.gridset = (GridsetRecord) retval.createGridset();
|
||||
retval.gridset = createGridset();
|
||||
records.add( retval.gridset );
|
||||
records.add( retval.createGuts() );
|
||||
retval.defaultrowheight =
|
||||
(DefaultRowHeightRecord) retval.createDefaultRowHeight();
|
||||
retval.defaultrowheight = createDefaultRowHeight();
|
||||
records.add( retval.defaultrowheight );
|
||||
records.add( retval.createWSBool() );
|
||||
|
||||
// 'Page Settings Block'
|
||||
retval.rowBreaks = new PageBreakRecord(PageBreakRecord.HORIZONTAL_SID);
|
||||
records.add(retval.rowBreaks);
|
||||
retval.colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID);
|
||||
records.add(retval.colBreaks);
|
||||
|
||||
retval.header = (HeaderRecord) retval.createHeader();
|
||||
retval.header = createHeader();
|
||||
records.add( retval.header );
|
||||
retval.footer = (FooterRecord) retval.createFooter();
|
||||
retval.footer = createFooter();
|
||||
records.add( retval.footer );
|
||||
records.add( retval.createHCenter() );
|
||||
records.add( retval.createVCenter() );
|
||||
retval.printSetup = (PrintSetupRecord) retval.createPrintSetup();
|
||||
records.add(createHCenter() );
|
||||
records.add(createVCenter() );
|
||||
retval.printSetup = createPrintSetup();
|
||||
records.add( retval.printSetup );
|
||||
retval.defaultcolwidth =
|
||||
(DefaultColWidthRecord) retval.createDefaultColWidth();
|
||||
|
||||
// 'Worksheet Protection Block' (after 'Page Settings Block' and before DEFCOLWIDTH)
|
||||
// PROTECT record normally goes here, don't add yet since the flag is initially false
|
||||
|
||||
retval.defaultcolwidth = createDefaultColWidth();
|
||||
records.add( retval.defaultcolwidth);
|
||||
ColumnInfoRecordsAggregate columns = new ColumnInfoRecordsAggregate();
|
||||
records.add( columns );
|
||||
retval.columns = columns;
|
||||
retval.dims = ( DimensionsRecord ) retval.createDimensions();
|
||||
retval.dims = createDimensions();
|
||||
records.add(retval.dims);
|
||||
retval.dimsloc = records.size()-1;
|
||||
records.add(retval.windowTwo = retval.createWindowTwo());
|
||||
retval.setLoc(records.size() - 1);
|
||||
retval.selection =
|
||||
(SelectionRecord) retval.createSelection();
|
||||
retval.selection = createSelection();
|
||||
records.add(retval.selection);
|
||||
retval.protect = (ProtectRecord) retval.createProtect();
|
||||
records.add(retval.protect);
|
||||
records.add(retval.createEOF());
|
||||
records.add(new EOFRecord());
|
||||
|
||||
|
||||
retval.records = records;
|
||||
|
@ -522,7 +528,7 @@ public final class Sheet implements Model {
|
|||
|
||||
if (merged == null || merged.getNumAreas() == 1027)
|
||||
{
|
||||
merged = ( MergeCellsRecord ) createMergedCells();
|
||||
merged = createMergedCells();
|
||||
mergedRecords.add(merged);
|
||||
records.add(records.size() - 1, merged);
|
||||
}
|
||||
|
@ -911,124 +917,11 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* Create a row record. (does not add it to the records contained in this sheet)
|
||||
*
|
||||
* @param row number
|
||||
* @return RowRecord created for the passed in row number
|
||||
* @see org.apache.poi.hssf.record.RowRecord
|
||||
*/
|
||||
|
||||
public RowRecord createRow(int row)
|
||||
{
|
||||
private static RowRecord createRow(int row) {
|
||||
return RowRecordsAggregate.createRow( row );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a LABELSST Record (does not add it to the records contained in this sheet)
|
||||
*
|
||||
* @param row the row the LabelSST is a member of
|
||||
* @param col the column the LabelSST defines
|
||||
* @param index the index of the string within the SST (use workbook addSSTString method)
|
||||
* @return LabelSSTRecord newly created containing your SST Index, row,col.
|
||||
* @see org.apache.poi.hssf.record.SSTRecord
|
||||
*/
|
||||
public LabelSSTRecord createLabelSST(int row, short col, int index)
|
||||
{
|
||||
log.logFormatted(POILogger.DEBUG, "create labelsst row,col,index %,%,%",
|
||||
new int[]
|
||||
{
|
||||
row, col, index
|
||||
});
|
||||
LabelSSTRecord rec = new LabelSSTRecord();
|
||||
|
||||
rec.setRow(row);
|
||||
rec.setColumn(col);
|
||||
rec.setSSTIndex(index);
|
||||
rec.setXFIndex(( short ) 0x0f);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NUMBER Record (does not add it to the records contained in this sheet)
|
||||
*
|
||||
* @param row the row the NumberRecord is a member of
|
||||
* @param col the column the NumberRecord defines
|
||||
* @param value for the number record
|
||||
*
|
||||
* @return NumberRecord for that row, col containing that value as added to the sheet
|
||||
*/
|
||||
public NumberRecord createNumber(int row, short col, double value)
|
||||
{
|
||||
log.logFormatted(POILogger.DEBUG, "create number row,col,value %,%,%",
|
||||
new double[]
|
||||
{
|
||||
row, col, value
|
||||
});
|
||||
NumberRecord rec = new NumberRecord();
|
||||
|
||||
rec.setRow(row);
|
||||
rec.setColumn(col);
|
||||
rec.setValue(value);
|
||||
rec.setXFIndex(( short ) 0x0f);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a BLANK record (does not add it to the records contained in this sheet)
|
||||
*
|
||||
* @param row - the row the BlankRecord is a member of
|
||||
* @param col - the column the BlankRecord is a member of
|
||||
*/
|
||||
public BlankRecord createBlank(int row, short col)
|
||||
{
|
||||
log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new int[]
|
||||
{
|
||||
row, col
|
||||
});
|
||||
BlankRecord rec = new BlankRecord();
|
||||
|
||||
rec.setRow(row);
|
||||
rec.setColumn(col);
|
||||
rec.setXFIndex(( short ) 0x0f);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse the formula into PTGs and create a formula record
|
||||
* DOES NOT WORK YET
|
||||
*
|
||||
* @param row - the row for the formula record
|
||||
* @param col - the column of the formula record
|
||||
* @param formula - a String representing the formula. To be parsed to PTGs
|
||||
* @return bogus/useless formula record
|
||||
*/
|
||||
public FormulaRecord createFormula(int row, short col, String formula)
|
||||
{
|
||||
log.logFormatted(POILogger.DEBUG, "create formula row,col,formula %,%,%",
|
||||
new int[]
|
||||
{
|
||||
row, col
|
||||
}, formula);
|
||||
FormulaRecord rec = new FormulaRecord();
|
||||
|
||||
rec.setRow(row);
|
||||
rec.setColumn(col);
|
||||
rec.setOptions(( short ) 2);
|
||||
rec.setValue(0);
|
||||
rec.setXFIndex(( short ) 0x0f);
|
||||
FormulaParser fp = new FormulaParser(formula,null); //fix - do we need this method?
|
||||
fp.parse();
|
||||
Ptg[] ptg = fp.getRPNPtg();
|
||||
int size = 0;
|
||||
|
||||
for (int k = 0; k < ptg.length; k++)
|
||||
{
|
||||
size += ptg[ k ].getSize();
|
||||
rec.pushExpressionToken(ptg[ k ]);
|
||||
}
|
||||
rec.setExpressionLength(( short ) size);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value record to the sheet's contained binary records
|
||||
* (i.e. LabelSSTRecord or NumberRecord).
|
||||
|
@ -1247,13 +1140,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the BOF record
|
||||
* @see org.apache.poi.hssf.record.BOFRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a BOFRecord
|
||||
*/
|
||||
|
||||
protected Record createBOF()
|
||||
{
|
||||
private static BOFRecord createBOF() {
|
||||
BOFRecord retval = new BOFRecord();
|
||||
|
||||
retval.setVersion(( short ) 0x600);
|
||||
|
@ -1266,31 +1154,10 @@ public final class Sheet implements Model {
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the Index record - not currently used
|
||||
* @see org.apache.poi.hssf.record.IndexRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a IndexRecord
|
||||
*/
|
||||
|
||||
protected Record createIndex()
|
||||
{
|
||||
IndexRecord retval = new IndexRecord();
|
||||
|
||||
retval.setFirstRow(0); // must be set explicitly
|
||||
retval.setLastRowAdd1(0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the CalcMode record and sets it to 1 (automatic formula caculation)
|
||||
* @see org.apache.poi.hssf.record.CalcModeRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a CalcModeRecord
|
||||
*/
|
||||
|
||||
protected Record createCalcMode()
|
||||
{
|
||||
private static CalcModeRecord createCalcMode() {
|
||||
CalcModeRecord retval = new CalcModeRecord();
|
||||
|
||||
retval.setCalcMode(( short ) 1);
|
||||
|
@ -1298,29 +1165,19 @@ public final class Sheet implements Model {
|
|||
}
|
||||
|
||||
/**
|
||||
* creates the CalcCount record and sets it to 0x64 (default number of iterations)
|
||||
* @see org.apache.poi.hssf.record.CalcCountRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a CalcCountRecord
|
||||
* creates the CalcCount record and sets it to 100 (default number of iterations)
|
||||
*/
|
||||
|
||||
protected Record createCalcCount()
|
||||
{
|
||||
private static CalcCountRecord createCalcCount() {
|
||||
CalcCountRecord retval = new CalcCountRecord();
|
||||
|
||||
retval.setIterations(( short ) 0x64); // default 64 iterations
|
||||
retval.setIterations(( short ) 100); // default 100 iterations
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the RefMode record and sets it to A1 Mode (default reference mode)
|
||||
* @see org.apache.poi.hssf.record.RefModeRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a RefModeRecord
|
||||
*/
|
||||
|
||||
protected Record createRefMode()
|
||||
{
|
||||
private static RefModeRecord createRefMode() {
|
||||
RefModeRecord retval = new RefModeRecord();
|
||||
|
||||
retval.setMode(RefModeRecord.USE_A1_MODE);
|
||||
|
@ -1329,13 +1186,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Iteration record and sets it to false (don't iteratively calculate formulas)
|
||||
* @see org.apache.poi.hssf.record.IterationRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a IterationRecord
|
||||
*/
|
||||
|
||||
protected Record createIteration()
|
||||
{
|
||||
private static IterationRecord createIteration() {
|
||||
IterationRecord retval = new IterationRecord();
|
||||
|
||||
retval.setIteration(false);
|
||||
|
@ -1344,13 +1196,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Delta record and sets it to 0.0010 (default accuracy)
|
||||
* @see org.apache.poi.hssf.record.DeltaRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a DeltaRecord
|
||||
*/
|
||||
|
||||
protected Record createDelta()
|
||||
{
|
||||
private static DeltaRecord createDelta() {
|
||||
DeltaRecord retval = new DeltaRecord();
|
||||
|
||||
retval.setMaxChange(0.0010);
|
||||
|
@ -1359,13 +1206,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the SaveRecalc record and sets it to true (recalculate before saving)
|
||||
* @see org.apache.poi.hssf.record.SaveRecalcRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a SaveRecalcRecord
|
||||
*/
|
||||
|
||||
protected Record createSaveRecalc()
|
||||
{
|
||||
private static SaveRecalcRecord createSaveRecalc() {
|
||||
SaveRecalcRecord retval = new SaveRecalcRecord();
|
||||
|
||||
retval.setRecalc(true);
|
||||
|
@ -1374,13 +1216,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the PrintHeaders record and sets it to false (we don't create headers yet so why print them)
|
||||
* @see org.apache.poi.hssf.record.PrintHeadersRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a PrintHeadersRecord
|
||||
*/
|
||||
|
||||
protected Record createPrintHeaders()
|
||||
{
|
||||
private static PrintHeadersRecord createPrintHeaders() {
|
||||
PrintHeadersRecord retval = new PrintHeadersRecord();
|
||||
|
||||
retval.setPrintHeaders(false);
|
||||
|
@ -1390,14 +1227,8 @@ public final class Sheet implements Model {
|
|||
/**
|
||||
* creates the PrintGridlines record and sets it to false (that makes for ugly sheets). As far as I can
|
||||
* tell this does the same thing as the GridsetRecord
|
||||
*
|
||||
* @see org.apache.poi.hssf.record.PrintGridlinesRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a PrintGridlinesRecord
|
||||
*/
|
||||
|
||||
protected Record createPrintGridlines()
|
||||
{
|
||||
private static PrintGridlinesRecord createPrintGridlines() {
|
||||
PrintGridlinesRecord retval = new PrintGridlinesRecord();
|
||||
|
||||
retval.setPrintGridlines(false);
|
||||
|
@ -1406,13 +1237,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Gridset record and sets it to true (user has mucked with the gridlines)
|
||||
* @see org.apache.poi.hssf.record.GridsetRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a GridsetRecord
|
||||
*/
|
||||
|
||||
protected Record createGridset()
|
||||
{
|
||||
private static GridsetRecord createGridset() {
|
||||
GridsetRecord retval = new GridsetRecord();
|
||||
|
||||
retval.setGridset(true);
|
||||
|
@ -1421,13 +1247,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0
|
||||
* @see org.apache.poi.hssf.record.GutsRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a GutsRecordRecord
|
||||
*/
|
||||
|
||||
protected Record createGuts()
|
||||
{
|
||||
*/
|
||||
private static GutsRecord createGuts() {
|
||||
GutsRecord retval = new GutsRecord();
|
||||
|
||||
retval.setLeftRowGutter(( short ) 0);
|
||||
|
@ -1439,13 +1260,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the DefaultRowHeight Record and sets its options to 0 and rowheight to 0xff
|
||||
* @see org.apache.poi.hssf.record.DefaultRowHeightRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a DefaultRowHeightRecord
|
||||
*/
|
||||
|
||||
protected Record createDefaultRowHeight()
|
||||
{
|
||||
private static DefaultRowHeightRecord createDefaultRowHeight() {
|
||||
DefaultRowHeightRecord retval = new DefaultRowHeightRecord();
|
||||
|
||||
retval.setOptionFlags(( short ) 0);
|
||||
|
@ -1455,13 +1271,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the WSBoolRecord and sets its values to defaults
|
||||
* @see org.apache.poi.hssf.record.WSBoolRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a WSBoolRecord
|
||||
*/
|
||||
|
||||
protected Record createWSBool()
|
||||
{
|
||||
private static WSBoolRecord createWSBool() {
|
||||
WSBoolRecord retval = new WSBoolRecord();
|
||||
|
||||
retval.setWSBool1(( byte ) 0x4);
|
||||
|
@ -1471,13 +1282,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Header Record and sets it to nothing/0 length
|
||||
* @see org.apache.poi.hssf.record.HeaderRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a HeaderRecord
|
||||
*/
|
||||
|
||||
protected Record createHeader()
|
||||
{
|
||||
private static HeaderRecord createHeader() {
|
||||
HeaderRecord retval = new HeaderRecord();
|
||||
|
||||
retval.setHeaderLength(( byte ) 0);
|
||||
|
@ -1487,13 +1293,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the Footer Record and sets it to nothing/0 length
|
||||
* @see org.apache.poi.hssf.record.FooterRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a FooterRecord
|
||||
*/
|
||||
|
||||
protected Record createFooter()
|
||||
{
|
||||
private static FooterRecord createFooter() {
|
||||
FooterRecord retval = new FooterRecord();
|
||||
|
||||
retval.setFooterLength(( byte ) 0);
|
||||
|
@ -1503,13 +1304,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the HCenter Record and sets it to false (don't horizontally center)
|
||||
* @see org.apache.poi.hssf.record.HCenterRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a HCenterRecord
|
||||
*/
|
||||
|
||||
protected Record createHCenter()
|
||||
{
|
||||
private static HCenterRecord createHCenter() {
|
||||
HCenterRecord retval = new HCenterRecord();
|
||||
|
||||
retval.setHCenter(false);
|
||||
|
@ -1518,13 +1314,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the VCenter Record and sets it to false (don't horizontally center)
|
||||
* @see org.apache.poi.hssf.record.VCenterRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a VCenterRecord
|
||||
*/
|
||||
|
||||
protected Record createVCenter()
|
||||
{
|
||||
*/
|
||||
private static VCenterRecord createVCenter() {
|
||||
VCenterRecord retval = new VCenterRecord();
|
||||
|
||||
retval.setVCenter(false);
|
||||
|
@ -1537,9 +1328,7 @@ public final class Sheet implements Model {
|
|||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a PrintSetupRecord
|
||||
*/
|
||||
|
||||
protected Record createPrintSetup()
|
||||
{
|
||||
private static PrintSetupRecord createPrintSetup() {
|
||||
PrintSetupRecord retval = new PrintSetupRecord();
|
||||
|
||||
retval.setPaperSize(( short ) 1);
|
||||
|
@ -1558,30 +1347,13 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates the DefaultColWidth Record and sets it to 8
|
||||
* @see org.apache.poi.hssf.record.DefaultColWidthRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a DefaultColWidthRecord
|
||||
*/
|
||||
|
||||
protected Record createDefaultColWidth()
|
||||
{
|
||||
*/
|
||||
private static DefaultColWidthRecord createDefaultColWidth() {
|
||||
DefaultColWidthRecord retval = new DefaultColWidthRecord();
|
||||
|
||||
retval.setColWidth(( short ) 8);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the ColumnInfo Record and sets it to a default column/width
|
||||
* @see org.apache.poi.hssf.record.ColumnInfoRecord
|
||||
* @return record containing a ColumnInfoRecord
|
||||
*/
|
||||
// TODO change return type to ColumnInfoRecord
|
||||
protected Record createColInfo()
|
||||
{
|
||||
return ColumnInfoRecordsAggregate.createColInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the default column width for the sheet (if the columns do not define their own width)
|
||||
* @return default column width
|
||||
|
@ -1600,7 +1372,7 @@ public final class Sheet implements Model {
|
|||
public boolean isGridsPrinted()
|
||||
{
|
||||
if (gridset == null) {
|
||||
gridset = (GridsetRecord)createGridset();
|
||||
gridset = createGridset();
|
||||
//Insert the newlycreated Gridset record at the end of the record (just before the EOF)
|
||||
int loc = findFirstRecordLocBySid(EOFRecord.sid);
|
||||
records.add(loc, gridset);
|
||||
|
@ -1816,22 +1588,18 @@ public final class Sheet implements Model {
|
|||
|
||||
GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid );
|
||||
guts.setColLevelMax( (short) ( maxLevel+1 ) );
|
||||
if (maxLevel == 0)
|
||||
if (maxLevel == 0) {
|
||||
guts.setTopColGutter( (short)0 );
|
||||
else
|
||||
} else {
|
||||
guts.setTopColGutter( (short) ( 29 + (12 * (maxLevel-1)) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the Dimensions Record and sets it to bogus values (you should set this yourself
|
||||
* or let the high level API do it for you)
|
||||
* @see org.apache.poi.hssf.record.DimensionsRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a DimensionsRecord
|
||||
*/
|
||||
|
||||
protected Record createDimensions()
|
||||
{
|
||||
private static DimensionsRecord createDimensions() {
|
||||
DimensionsRecord retval = new DimensionsRecord();
|
||||
|
||||
retval.setFirstCol(( short ) 0);
|
||||
|
@ -1849,13 +1617,8 @@ public final class Sheet implements Model {
|
|||
* headercolor = 0x40 <P>
|
||||
* pagebreakzoom = 0x0 <P>
|
||||
* normalzoom = 0x0 <p>
|
||||
* @see org.apache.poi.hssf.record.WindowTwoRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a WindowTwoRecord
|
||||
*/
|
||||
|
||||
protected WindowTwoRecord createWindowTwo()
|
||||
{
|
||||
private static WindowTwoRecord createWindowTwo() {
|
||||
WindowTwoRecord retval = new WindowTwoRecord();
|
||||
|
||||
retval.setOptions(( short ) 0x6b6);
|
||||
|
@ -1869,14 +1632,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* Creates the Selection record and sets it to nothing selected
|
||||
*
|
||||
* @see org.apache.poi.hssf.record.SelectionRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a SelectionRecord
|
||||
*/
|
||||
|
||||
protected Record createSelection()
|
||||
{
|
||||
*/
|
||||
private static SelectionRecord createSelection() {
|
||||
SelectionRecord retval = new SelectionRecord();
|
||||
|
||||
retval.setPane(( byte ) 0x3);
|
||||
|
@ -1903,19 +1660,15 @@ public final class Sheet implements Model {
|
|||
* Sets the left column to show in desktop window pane.
|
||||
* @param leftCol the left column to show in desktop window pane
|
||||
*/
|
||||
public void setLeftCol(short leftCol){
|
||||
if (windowTwo!=null)
|
||||
{
|
||||
public void setLeftCol(short leftCol){
|
||||
if (windowTwo!=null) {
|
||||
windowTwo.setLeftCol(leftCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public short getLeftCol()
|
||||
{
|
||||
return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
|
||||
}
|
||||
|
||||
|
||||
public short getLeftCol() {
|
||||
return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active row
|
||||
|
@ -1977,25 +1730,12 @@ public final class Sheet implements Model {
|
|||
}
|
||||
}
|
||||
|
||||
protected Record createMergedCells()
|
||||
{
|
||||
private static MergeCellsRecord createMergedCells() {
|
||||
MergeCellsRecord retval = new MergeCellsRecord();
|
||||
retval.setNumAreas(( short ) 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the EOF record
|
||||
* @see org.apache.poi.hssf.record.EOFRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return record containing a EOFRecord
|
||||
*/
|
||||
|
||||
protected Record createEOF()
|
||||
{
|
||||
return new EOFRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the location of the DimensionsRecord (which is the last record before the value section)
|
||||
* @return location in the array of records of the DimensionsRecord
|
||||
|
@ -2383,28 +2123,20 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates a Protect record with protect set to false.
|
||||
* @see org.apache.poi.hssf.record.ProtectRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return a ProtectRecord
|
||||
*/
|
||||
protected Record createProtect()
|
||||
{
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
private static ProtectRecord createProtect() {
|
||||
if (log.check( POILogger.DEBUG )) {
|
||||
log.log(POILogger.DEBUG, "create protect record with protection disabled");
|
||||
}
|
||||
ProtectRecord retval = new ProtectRecord();
|
||||
|
||||
retval.setProtect(false);
|
||||
retval.setProtect(false); // TODO - supply param to constructor
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an ObjectProtect record with protect set to false.
|
||||
* @see org.apache.poi.hssf.record.ObjectProtectRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return an ObjectProtectRecord
|
||||
*/
|
||||
protected ObjectProtectRecord createObjectProtect()
|
||||
{
|
||||
private static ObjectProtectRecord createObjectProtect() {
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(POILogger.DEBUG, "create protect record with protection disabled");
|
||||
ObjectProtectRecord retval = new ObjectProtectRecord();
|
||||
|
@ -2415,12 +2147,8 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates a ScenarioProtect record with protect set to false.
|
||||
* @see org.apache.poi.hssf.record.ScenarioProtectRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return a ScenarioProtectRecord
|
||||
*/
|
||||
protected ScenarioProtectRecord createScenarioProtect()
|
||||
{
|
||||
private static ScenarioProtectRecord createScenarioProtect() {
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(POILogger.DEBUG, "create protect record with protection disabled");
|
||||
ScenarioProtectRecord retval = new ScenarioProtectRecord();
|
||||
|
@ -2435,9 +2163,9 @@ public final class Sheet implements Model {
|
|||
public ProtectRecord getProtect()
|
||||
{
|
||||
if (protect == null) {
|
||||
protect = (ProtectRecord)createProtect();
|
||||
//Insert the newlycreated protect record at the end of the record (just before the EOF)
|
||||
int loc = findFirstRecordLocBySid(EOFRecord.sid);
|
||||
protect = createProtect();
|
||||
// Insert the newly created protect record just before DefaultColWidthRecord
|
||||
int loc = findFirstRecordLocBySid(DefaultColWidthRecord.sid);
|
||||
records.add(loc, protect);
|
||||
}
|
||||
return protect;
|
||||
|
@ -2459,14 +2187,11 @@ public final class Sheet implements Model {
|
|||
|
||||
/**
|
||||
* creates a Password record with password set to 00.
|
||||
* @see org.apache.poi.hssf.record.PasswordRecord
|
||||
* @see org.apache.poi.hssf.record.Record
|
||||
* @return a PasswordRecord
|
||||
*/
|
||||
protected PasswordRecord createPassword()
|
||||
{
|
||||
if (log.check( POILogger.DEBUG ))
|
||||
log.log(POILogger.DEBUG, "create password record with 00 password");
|
||||
private static PasswordRecord createPassword() {
|
||||
if (log.check( POILogger.DEBUG )) {
|
||||
log.log(POILogger.DEBUG, "create password record with 00 password");
|
||||
}
|
||||
PasswordRecord retval = new PasswordRecord();
|
||||
|
||||
retval.setPassword((short)00);
|
||||
|
@ -2892,4 +2617,10 @@ public final class Sheet implements Model {
|
|||
rows.expandRow( row );
|
||||
}
|
||||
}
|
||||
public DataValidityTable getOrCreateDataValidityTable() {
|
||||
if (_dataValidityTable == null) {
|
||||
_dataValidityTable = DataValidityTable.createForSheet(records);
|
||||
}
|
||||
return _dataValidityTable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Stack;
|
|||
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
|
||||
import org.apache.poi.hssf.util.HSSFCellRangeAddress.AddrStructure;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
@ -114,7 +115,7 @@ public final class DVRecord extends Record
|
|||
private BitField opt_error_style = new BitField(0x00000070);
|
||||
private BitField opt_string_list_formula = new BitField(0x00000080);
|
||||
private BitField opt_empty_cell_allowed = new BitField(0x00000100);
|
||||
private BitField opt_surppres_dropdown_arrow = new BitField(0x00000200);
|
||||
private BitField opt_suppress_dropdown_arrow = new BitField(0x00000200);
|
||||
private BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000);
|
||||
private BitField opt_show_error_on_invalid_value = new BitField(0x00080000);
|
||||
private BitField opt_condition_operator = new BitField(0x00F00000);
|
||||
|
@ -283,25 +284,37 @@ public final class DVRecord extends Record
|
|||
{
|
||||
return (this.opt_empty_cell_allowed.isSet(this.field_option_flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* set if drop down arrow should be surppressed when list validation is used
|
||||
* @param type - true if drop down arrow should be surppressed when list validation is used, false otherwise
|
||||
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
|
||||
*/
|
||||
public void setSurppresDropdownArrow(boolean surppress)
|
||||
{
|
||||
this.field_option_flags = this.opt_surppres_dropdown_arrow.setBoolean(this.field_option_flags, surppress);
|
||||
* @deprecated - (Jul-2008) use setSuppressDropDownArrow
|
||||
*/
|
||||
public void setSurppresDropdownArrow(boolean suppress) {
|
||||
setSuppressDropdownArrow(suppress);
|
||||
}
|
||||
/**
|
||||
* @deprecated - (Jul-2008) use getSuppressDropDownArrow
|
||||
*/
|
||||
public boolean getSurppresDropdownArrow() {
|
||||
return getSuppressDropdownArrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if drop down arrow should be surppressed when list validation is used, false otherwise
|
||||
* @return if drop down arrow should be surppressed when list validation is used, false otherwise
|
||||
* set if drop down arrow should be suppressed when list validation is used
|
||||
* @param type - true if drop down arrow should be suppressed when list validation is used, false otherwise
|
||||
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
|
||||
*/
|
||||
public boolean getSurppresDropdownArrow()
|
||||
public void setSuppressDropdownArrow(boolean suppress)
|
||||
{
|
||||
return (this.opt_surppres_dropdown_arrow.isSet(this.field_option_flags));
|
||||
this.field_option_flags = this.opt_suppress_dropdown_arrow.setBoolean(this.field_option_flags, suppress);
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if drop down arrow should be suppressed when list validation is used, false otherwise
|
||||
* @return if drop down arrow should be suppressed when list validation is used, false otherwise
|
||||
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
|
||||
*/
|
||||
public boolean getSuppressDropdownArrow()
|
||||
{
|
||||
return (this.opt_suppress_dropdown_arrow.isSet(this.field_option_flags));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -433,9 +446,40 @@ public final class DVRecord extends Record
|
|||
public String toString()
|
||||
{
|
||||
/** @todo DVRecord string representation */
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("[DV]\n");
|
||||
sb.append(" options=").append(Integer.toHexString(field_option_flags));
|
||||
sb.append(" title-prompt=").append(field_title_prompt);
|
||||
sb.append(" title-error=").append(field_title_error);
|
||||
sb.append(" text-prompt=").append(field_text_prompt);
|
||||
sb.append(" text-error=").append(field_text_error);
|
||||
sb.append("\n");
|
||||
appendFormula(sb, "Formula 1:", field_rpn_token_1);
|
||||
appendFormula(sb, "Formula 2:", field_rpn_token_2);
|
||||
int nRegions = field_regions.getADDRStructureNumber();
|
||||
for(int i=0; i<nRegions; i++) {
|
||||
AddrStructure addr = field_regions.getADDRStructureAt(i);
|
||||
sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow());
|
||||
sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')');
|
||||
}
|
||||
sb.append("\n");
|
||||
sb.append("[/DV]");
|
||||
|
||||
return buffer.toString();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void appendFormula(StringBuffer sb, String label, Stack stack) {
|
||||
sb.append(label);
|
||||
if (stack.isEmpty()) {
|
||||
sb.append("<empty>\n");
|
||||
return;
|
||||
}
|
||||
sb.append("\n");
|
||||
Ptg[] ptgs = new Ptg[stack.size()];
|
||||
stack.toArray(ptgs);
|
||||
for (int i = 0; i < ptgs.length; i++) {
|
||||
sb.append('\t').append(ptgs[i].toString()).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte [] data)
|
||||
|
@ -506,7 +550,7 @@ public final class DVRecord extends Record
|
|||
* contents are somewhat complex
|
||||
*/
|
||||
public Object clone() {
|
||||
return cloneViaReserialise();
|
||||
return cloneViaReserialise();
|
||||
}
|
||||
|
||||
/**@todo DVRecord = Serializare */
|
||||
|
@ -535,7 +579,7 @@ public final class DVRecord extends Record
|
|||
this._string_unicode_flag = in.readByte();
|
||||
if (this._string_unicode_flag == 1)
|
||||
{
|
||||
this._string_data = in.readUnicodeLEString(this._string_length);
|
||||
this._string_data = in.readUnicodeLEString(this._string_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.aggregates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.model.FormulaParser;
|
||||
import org.apache.poi.hssf.model.RecordStream;
|
||||
import org.apache.poi.hssf.record.CFHeaderRecord;
|
||||
import org.apache.poi.hssf.record.CFRuleRecord;
|
||||
import org.apache.poi.hssf.record.DVALRecord;
|
||||
import org.apache.poi.hssf.record.DVRecord;
|
||||
import org.apache.poi.hssf.record.EOFRecord;
|
||||
import org.apache.poi.hssf.record.HyperlinkRecord;
|
||||
import org.apache.poi.hssf.record.MergeCellsRecord;
|
||||
import org.apache.poi.hssf.record.PaneRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.SelectionRecord;
|
||||
import org.apache.poi.hssf.record.WindowTwoRecord;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
|
||||
import org.apache.poi.hssf.util.HSSFDataValidation;
|
||||
|
||||
/**
|
||||
* Manages the DVALRecord and DVRecords for a single sheet<br/>
|
||||
* See OOO excelfileformat.pdf section 4.14
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class DataValidityTable extends RecordAggregate {
|
||||
|
||||
private static final short sid = -0x01B2; // not a real record
|
||||
private final DVALRecord _headerRec;
|
||||
/**
|
||||
* The list of data validations for the current sheet.
|
||||
* Note - this may be empty (contrary to OOO documentation)
|
||||
*/
|
||||
private final List _validationList;
|
||||
|
||||
public DataValidityTable(RecordStream rs) {
|
||||
_headerRec = (DVALRecord) rs.getNext();
|
||||
List temp = new ArrayList();
|
||||
while (rs.peekNextClass() == DVRecord.class) {
|
||||
temp.add(rs.getNext());
|
||||
}
|
||||
_validationList = temp;
|
||||
}
|
||||
|
||||
private DataValidityTable() {
|
||||
_headerRec = new DVALRecord();
|
||||
_validationList = new ArrayList();
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte[] data) {
|
||||
int result = _headerRec.serialize(offset, data);
|
||||
for (int i = 0; i < _validationList.size(); i++) {
|
||||
result += ((Record) _validationList.get(i)).serialize(offset + result, data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getRecordSize() {
|
||||
int result = _headerRec.getRecordSize();
|
||||
for (int i = _validationList.size() - 1; i >= 0; i--) {
|
||||
result += ((Record) _validationList.get(i)).getRecordSize();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <tt>DataValidityTable</tt> and inserts it in the right
|
||||
* place in the sheetRecords list.
|
||||
*/
|
||||
public static DataValidityTable createForSheet(List sheetRecords) {
|
||||
int index = findDVTableInsertPos(sheetRecords);
|
||||
|
||||
DataValidityTable result = new DataValidityTable();
|
||||
sheetRecords.add(index, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the index where the sheet validations header record should be inserted
|
||||
* @param records the records for this sheet
|
||||
*
|
||||
* + WINDOW2
|
||||
* o SCL
|
||||
* o PANE
|
||||
* oo SELECTION
|
||||
* o STANDARDWIDTH
|
||||
* oo MERGEDCELLS
|
||||
* o LABELRANGES
|
||||
* o PHONETICPR
|
||||
* o Conditional Formatting Table
|
||||
* o Hyperlink Table
|
||||
* o Data Validity Table
|
||||
* o SHEETLAYOUT
|
||||
* o SHEETPROTECTION
|
||||
* o RANGEPROTECTION
|
||||
* + EOF
|
||||
*/
|
||||
private static int findDVTableInsertPos(List records) {
|
||||
int i = records.size() - 1;
|
||||
if (!(records.get(i) instanceof EOFRecord)) {
|
||||
throw new IllegalStateException("Last sheet record should be EOFRecord");
|
||||
}
|
||||
while (i > 0) {
|
||||
i--;
|
||||
Record rec = (Record) records.get(i);
|
||||
if (isPriorRecord(rec.getSid())) {
|
||||
Record nextRec = (Record) records.get(i + 1);
|
||||
if (!isSubsequentRecord(nextRec.getSid())) {
|
||||
throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName()
|
||||
+ ") found after (" + rec.getClass().getName() + ")");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
if (!isSubsequentRecord(rec.getSid())) {
|
||||
throw new IllegalStateException("Unexpected (" + rec.getClass().getName()
|
||||
+ ") while looking for DV Table insert pos");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO - add UninterpretedRecord as base class for many of these
|
||||
// unimplemented sids
|
||||
|
||||
private static boolean isPriorRecord(short sid) {
|
||||
switch(sid) {
|
||||
case WindowTwoRecord.sid:
|
||||
case 0x00A0: // SCL
|
||||
case PaneRecord.sid:
|
||||
case SelectionRecord.sid:
|
||||
case 0x0099: // STANDARDWIDTH
|
||||
case MergeCellsRecord.sid:
|
||||
case 0x015F: // LABELRANGES
|
||||
case 0x00EF: // PHONETICPR
|
||||
case CFHeaderRecord.sid:
|
||||
case CFRuleRecord.sid:
|
||||
case HyperlinkRecord.sid:
|
||||
case 0x0800: // QUICKTIP
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isSubsequentRecord(short sid) {
|
||||
switch(sid) {
|
||||
case 0x0862: // SHEETLAYOUT
|
||||
case 0x0867: // SHEETPROTECTION
|
||||
case 0x0868: // RANGEPROTECTION
|
||||
case EOFRecord.sid:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addDataValidation(HSSFDataValidation dataValidation, HSSFWorkbook workbook) {
|
||||
|
||||
DVRecord dvRecord = new DVRecord();
|
||||
|
||||
// dv record's option flags
|
||||
dvRecord.setDataType(dataValidation.getDataValidationType());
|
||||
dvRecord.setErrorStyle(dataValidation.getErrorStyle());
|
||||
dvRecord.setEmptyCellAllowed(dataValidation.getEmptyCellAllowed());
|
||||
dvRecord.setSuppressDropdownArrow(dataValidation.getSuppressDropDownArrow());
|
||||
dvRecord.setShowPromptOnCellSelected(dataValidation.getShowPromptBox());
|
||||
dvRecord.setShowErrorOnInvalidValue(dataValidation.getShowErrorBox());
|
||||
dvRecord.setConditionOperator(dataValidation.getOperator());
|
||||
|
||||
// string fields
|
||||
dvRecord.setStringField(DVRecord.STRING_PROMPT_TITLE, dataValidation.getPromptBoxTitle());
|
||||
dvRecord.setStringField(DVRecord.STRING_PROMPT_TEXT, dataValidation.getPromptBoxText());
|
||||
dvRecord.setStringField(DVRecord.STRING_ERROR_TITLE, dataValidation.getErrorBoxTitle());
|
||||
dvRecord.setStringField(DVRecord.STRING_ERROR_TEXT, dataValidation.getErrorBoxText());
|
||||
|
||||
// formula fields ( size and data )
|
||||
Stack ptg_arr = new Stack();
|
||||
Ptg[] ptg = FormulaParser.parse(dataValidation.getFirstFormula(), workbook);
|
||||
int size = 0;
|
||||
for (int k = 0; k < ptg.length; k++) {
|
||||
if (ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg) {
|
||||
// we should set ptgClass to Ptg.CLASS_REF and explicit formula
|
||||
// string to false
|
||||
// ptg[k].setClass(Ptg.CLASS_REF);
|
||||
// obj_validation.setExplicitListFormula(false);
|
||||
}
|
||||
size += ptg[k].getSize();
|
||||
ptg_arr.push(ptg[k]);
|
||||
}
|
||||
dvRecord.setFirstFormulaRPN(ptg_arr);
|
||||
dvRecord.setFirstFormulaSize((short) size);
|
||||
|
||||
dvRecord.setListExplicitFormula(dataValidation.getExplicitListFormula());
|
||||
|
||||
if (dataValidation.getSecondFormula() != null) {
|
||||
|
||||
ptg_arr = new Stack();
|
||||
ptg = FormulaParser.parse(dataValidation.getSecondFormula(), workbook);
|
||||
size = 0;
|
||||
for (int k = 0; k < ptg.length; k++) {
|
||||
size += ptg[k].getSize();
|
||||
ptg_arr.push(ptg[k]);
|
||||
}
|
||||
dvRecord.setSecFormulaRPN(ptg_arr);
|
||||
dvRecord.setSecFormulaSize((short) size);
|
||||
}
|
||||
|
||||
// dv records cell range field
|
||||
HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
|
||||
cell_range.addADDRStructure(dataValidation.getFirstRow(), dataValidation.getFirstColumn(),
|
||||
dataValidation.getLastRow(), dataValidation.getLastColumn());
|
||||
dvRecord.setCellRangeAddress(cell_range);
|
||||
|
||||
_validationList.add(dvRecord);
|
||||
_headerRec.setDVRecNo(_validationList.size());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.aggregates;
|
||||
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
/**
|
||||
* <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored
|
||||
* together and/or updated together. Workbook / Sheet records are typically stored in a sequential
|
||||
* list, which does not provide much structure to coordinate updates.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public abstract class RecordAggregate extends Record {
|
||||
// TODO - convert existing aggregate classes to proper subclasses of this one
|
||||
protected final void validateSid(short id) {
|
||||
// TODO - break class hierarchy and make separate from Record
|
||||
throw new RuntimeException("Should not be called");
|
||||
}
|
||||
protected final void fillFields(RecordInputStream in) {
|
||||
throw new RuntimeException("Should not be called");
|
||||
}
|
||||
// force subclassses to provide better implementation than default
|
||||
public abstract int getRecordSize();
|
||||
}
|
|
@ -28,7 +28,6 @@ import java.text.NumberFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
|
@ -36,9 +35,9 @@ import org.apache.poi.hssf.model.FormulaParser;
|
|||
import org.apache.poi.hssf.model.Sheet;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
|
||||
import org.apache.poi.hssf.util.HSSFDataValidation;
|
||||
import org.apache.poi.hssf.util.PaneInformation;
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
|
@ -375,92 +374,18 @@ public final class HSSFSheet {
|
|||
|
||||
/**
|
||||
* Creates a data validation object
|
||||
* @param obj_validation The Data validation object settings
|
||||
* @param dataValidation The Data validation object settings
|
||||
*/
|
||||
public void addValidationData(HSSFDataValidation obj_validation)
|
||||
{
|
||||
if ( obj_validation == null )
|
||||
{
|
||||
return;
|
||||
public void addValidationData(HSSFDataValidation dataValidation) {
|
||||
if (dataValidation == null) {
|
||||
throw new IllegalArgumentException("objValidation must not be null");
|
||||
}
|
||||
DVALRecord dvalRec = (DVALRecord)sheet.findFirstRecordBySid( DVALRecord.sid );
|
||||
int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
|
||||
if ( dvalRec == null )
|
||||
{
|
||||
dvalRec = new DVALRecord();
|
||||
sheet.getRecords().add( eofLoc, dvalRec );
|
||||
}
|
||||
int curr_dvRecNo = dvalRec.getDVRecNo();
|
||||
dvalRec.setDVRecNo(curr_dvRecNo+1);
|
||||
DataValidityTable dvt = sheet.getOrCreateDataValidityTable();
|
||||
|
||||
//create dv record
|
||||
DVRecord dvRecord = new DVRecord();
|
||||
|
||||
//dv record's option flags
|
||||
dvRecord.setDataType( obj_validation.getDataValidationType() );
|
||||
dvRecord.setErrorStyle(obj_validation.getErrorStyle());
|
||||
dvRecord.setEmptyCellAllowed(obj_validation.getEmptyCellAllowed());
|
||||
dvRecord.setSurppresDropdownArrow(obj_validation.getSurppressDropDownArrow());
|
||||
dvRecord.setShowPromptOnCellSelected(obj_validation.getShowPromptBox());
|
||||
dvRecord.setShowErrorOnInvalidValue(obj_validation.getShowErrorBox());
|
||||
dvRecord.setConditionOperator(obj_validation.getOperator());
|
||||
|
||||
//string fields
|
||||
dvRecord.setStringField( DVRecord.STRING_PROMPT_TITLE,obj_validation.getPromptBoxTitle());
|
||||
dvRecord.setStringField( DVRecord.STRING_PROMPT_TEXT, obj_validation.getPromptBoxText());
|
||||
dvRecord.setStringField( DVRecord.STRING_ERROR_TITLE, obj_validation.getErrorBoxTitle());
|
||||
dvRecord.setStringField( DVRecord.STRING_ERROR_TEXT, obj_validation.getErrorBoxText());
|
||||
|
||||
//formula fields ( size and data )
|
||||
String str_formula = obj_validation.getFirstFormula();
|
||||
FormulaParser fp = new FormulaParser(str_formula, workbook);
|
||||
fp.parse();
|
||||
Stack ptg_arr = new Stack();
|
||||
Ptg[] ptg = fp.getRPNPtg();
|
||||
int size = 0;
|
||||
for (int k = 0; k < ptg.length; k++)
|
||||
{
|
||||
if ( ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg )
|
||||
{
|
||||
//we should set ptgClass to Ptg.CLASS_REF and explicit formula string to false
|
||||
ptg[k].setClass(Ptg.CLASS_REF);
|
||||
obj_validation.setExplicitListFormula(false);
|
||||
}
|
||||
size += ptg[k].getSize();
|
||||
ptg_arr.push(ptg[k]);
|
||||
}
|
||||
dvRecord.setFirstFormulaRPN(ptg_arr);
|
||||
dvRecord.setFirstFormulaSize((short)size);
|
||||
|
||||
dvRecord.setListExplicitFormula(obj_validation.getExplicitListFormula());
|
||||
|
||||
if ( obj_validation.getSecondFormula() != null )
|
||||
{
|
||||
str_formula = obj_validation.getSecondFormula();
|
||||
fp = new FormulaParser(str_formula, workbook);
|
||||
fp.parse();
|
||||
ptg_arr = new Stack();
|
||||
ptg = fp.getRPNPtg();
|
||||
size = 0;
|
||||
for (int k = 0; k < ptg.length; k++)
|
||||
{
|
||||
size += ptg[k].getSize();
|
||||
ptg_arr.push(ptg[k]);
|
||||
}
|
||||
dvRecord.setSecFormulaRPN(ptg_arr);
|
||||
dvRecord.setSecFormulaSize((short)size);
|
||||
}
|
||||
|
||||
//dv records cell range field
|
||||
HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
|
||||
cell_range.addADDRStructure(obj_validation.getFirstRow(), obj_validation.getFirstColumn(), obj_validation.getLastRow(), obj_validation.getLastColumn());
|
||||
dvRecord.setCellRangeAddress(cell_range);
|
||||
|
||||
//add dv record
|
||||
eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
|
||||
sheet.getRecords().add( eofLoc, dvRecord );
|
||||
dvt.addDataValidation(dataValidation, workbook);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the visibility state for a given column.
|
||||
* @param column - the column to get (0-based)
|
||||
|
|
|
@ -218,13 +218,25 @@ public class HSSFDataValidation
|
|||
{
|
||||
return this._empty_cell_allowed ;
|
||||
}
|
||||
/**
|
||||
* @deprecated - (Jul-2008) use setSuppressDropDownArrow
|
||||
*/
|
||||
public void setSurppressDropDownArrow( boolean suppress ) {
|
||||
setSuppressDropDownArrow(suppress);
|
||||
}
|
||||
/**
|
||||
* @deprecated - (Jul-2008) use getSuppressDropDownArrow
|
||||
*/
|
||||
public boolean getSurppressDropDownArrow( ) {
|
||||
return getSuppressDropDownArrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for list validation objects .
|
||||
* @param surppres True if a list should display the values into a drop down list , false otherwise .
|
||||
* In other words , if a list should display the arrow sign on its right side
|
||||
*/
|
||||
public void setSurppressDropDownArrow( boolean surppres )
|
||||
public void setSuppressDropDownArrow( boolean surppres )
|
||||
{
|
||||
this._surpress_dropdown_arrow = surppres;
|
||||
}
|
||||
|
@ -235,7 +247,7 @@ public class HSSFDataValidation
|
|||
* @return True if a list should display the values into a drop down list , false otherwise .
|
||||
* @see setDataValidationType( int data_type )
|
||||
*/
|
||||
public boolean getSurppressDropDownArrow( )
|
||||
public boolean getSuppressDropDownArrow( )
|
||||
{
|
||||
if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -297,7 +297,8 @@ public final class TestSheet extends TestCase {
|
|||
xfindex = sheet.getXFIndexForColAt((short) 1);
|
||||
assertEquals(DEFAULT_IDX, xfindex);
|
||||
|
||||
ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
|
||||
// TODO change return type to ColumnInfoRecord
|
||||
ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
|
||||
sheet.columns.insertColumn(nci);
|
||||
|
||||
// single column ColumnInfoRecord
|
||||
|
|
|
@ -17,13 +17,10 @@
|
|||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.record.ColumnInfoRecord;
|
||||
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
|
||||
|
||||
/**
|
||||
* @author Tony Poppleton
|
||||
|
@ -32,7 +29,8 @@ public final class TestSheetAdditional extends TestCase {
|
|||
|
||||
public void testGetCellWidth() {
|
||||
Sheet sheet = Sheet.createSheet();
|
||||
ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
|
||||
// TODO change return type to ColumnInfoRecord
|
||||
ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
|
||||
|
||||
// Prepare test model
|
||||
nci.setFirstColumn((short)5);
|
||||
|
|
|
@ -16,13 +16,25 @@
|
|||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.util.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.eventmodel.ERFListener;
|
||||
import org.apache.poi.hssf.eventmodel.EventRecordFactory;
|
||||
import org.apache.poi.hssf.record.DVRecord;
|
||||
import org.apache.poi.hssf.record.RecordFormatException;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.hssf.util.HSSFDataValidation;
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
|
||||
/**
|
||||
* <p>Title: TestDataValidation</p>
|
||||
|
@ -34,19 +46,6 @@ import java.text.SimpleDateFormat;
|
|||
*/
|
||||
public class TestDataValidation extends TestCase
|
||||
{
|
||||
public TestDataValidation(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp()
|
||||
{
|
||||
String filename = System.getProperty("HSSF.testdata.path");
|
||||
if (filename == null)
|
||||
{
|
||||
System.setProperty("HSSF.testdata.path", "src/testcases/org/apache/poi/hssf/data");
|
||||
}
|
||||
}
|
||||
|
||||
public void testDataValidation() throws Exception
|
||||
{
|
||||
|
@ -903,8 +902,88 @@ public class TestDataValidation extends TestCase
|
|||
cell.setCellValue(strStettings);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
junit.textui.TestRunner.run(TestDataValidation.class);
|
||||
}
|
||||
|
||||
public void testAddToExistingSheet() {
|
||||
|
||||
// dvEmpty.xls is a simple one sheet workbook. With a DataValidations header record but no
|
||||
// DataValidations. It's important that the example has one SHEETPROTECTION record.
|
||||
// Such a workbook can be created in Excel (2007) by adding datavalidation for one cell
|
||||
// and then deleting the row that contains the cell.
|
||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls");
|
||||
int dvRow = 0;
|
||||
HSSFSheet sheet = wb.getSheetAt(0);
|
||||
sheet.createRow(dvRow).createCell((short)0);
|
||||
HSSFDataValidation dv = new HSSFDataValidation((short)dvRow, (short)0, (short)dvRow, (short)0);
|
||||
|
||||
dv.setDataValidationType(HSSFDataValidation.DATA_TYPE_INTEGER);
|
||||
dv.setEmptyCellAllowed(false);
|
||||
dv.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
|
||||
dv.setFirstFormula("42");
|
||||
dv.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
|
||||
dv.setShowPromptBox(true);
|
||||
dv.createErrorBox("Error", "The value is wrong");
|
||||
dv.setSurppressDropDownArrow(true);
|
||||
|
||||
sheet.addValidationData(dv);
|
||||
wb.toString();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
wb.write(baos);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
byte[] wbData = baos.toByteArray();
|
||||
|
||||
if (false) { // TODO (Jul 2008) fix EventRecordFactory to process unknown records, (and DV records for that matter)
|
||||
EventRecordFactory erf = new EventRecordFactory();
|
||||
ERFListener erfListener = null; // new MyERFListener();
|
||||
erf.registerListener(erfListener, null);
|
||||
try {
|
||||
POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
|
||||
erf.processRecords(fs.createDocumentInputStream("Workbook"));
|
||||
} catch (RecordFormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
// else verify record ordering by navigating the raw bytes
|
||||
|
||||
byte[] dvHeaderRecStart= { (byte)0xB2, 0x01, 0x12, 0x00, };
|
||||
int dvHeaderOffset = findIndex(wbData, dvHeaderRecStart);
|
||||
assertTrue(dvHeaderOffset > 0);
|
||||
int nextRecIndex = dvHeaderOffset + 22;
|
||||
int nextSid
|
||||
= ((wbData[nextRecIndex + 0] << 0) & 0x00FF)
|
||||
+ ((wbData[nextRecIndex + 1] << 8) & 0xFF00)
|
||||
;
|
||||
// nextSid should be for a DVRecord. If anything comes between the DV header record
|
||||
// and the DV records, Excel will not be able to open the workbook without error.
|
||||
|
||||
if (nextSid == 0x0867) {
|
||||
throw new AssertionFailedError("Identified bug XXXX");
|
||||
}
|
||||
assertEquals(DVRecord.sid, nextSid);
|
||||
}
|
||||
private int findIndex(byte[] largeData, byte[] searchPattern) {
|
||||
byte firstByte = searchPattern[0];
|
||||
for (int i = 0; i < largeData.length; i++) {
|
||||
if(largeData[i] != firstByte) {
|
||||
continue;
|
||||
}
|
||||
boolean match = true;
|
||||
for (int j = 1; j < searchPattern.length; j++) {
|
||||
if(searchPattern[j] != largeData[i+j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue