move cleaned up jxl into this project, get rid of log4j dependency
This commit is contained in:
parent
754f1d5873
commit
2202d328be
451 changed files with 80883 additions and 7 deletions
15
datastructures-xslx/NOTICE.txt
Normal file
15
datastructures-xslx/NOTICE.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
datastructures-xslx is composed of the following works
|
||||
|
||||
jxl
|
||||
https://sourceforge.net/projects/jexcelapi/
|
||||
GNU Library or Lesser General Public License version 2.0 (LGPLv2)
|
||||
|
||||
with the log4j dependency removed
|
||||
|
||||
and
|
||||
|
||||
com.incesoft.tools.excel
|
||||
https://code.google.com/archive/p/sjxslx/ -> https://github.com/davidpelfree/sjxlsx
|
||||
License: Apache License 2.0
|
||||
|
||||
The code will be refactored to the org.xbib package group.
|
|
@ -1,3 +0,0 @@
|
|||
dependencies {
|
||||
implementation libs.jxl
|
||||
}
|
45
datastructures-xslx/src/main/java/jxl/BooleanCell.java
Executable file
45
datastructures-xslx/src/main/java/jxl/BooleanCell.java
Executable file
|
@ -0,0 +1,45 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* This type represents the Microsoft concept of a Boolean. Accordingly, this
|
||||
* cell represents either TRUE, FALSE or an error condition. This third
|
||||
* state naturally makes handling BooleanCells quite tricky, and use of
|
||||
* the specific access methods should be handled with care
|
||||
*/
|
||||
public interface BooleanCell extends Cell {
|
||||
/**
|
||||
* Gets the boolean value stored in this cell. If this cell contains an
|
||||
* error, then returns FALSE. Always query this cell type using the
|
||||
* accessor method isError() prior to calling this method
|
||||
*
|
||||
* @return TRUE if this cell contains TRUE, FALSE if it contains FALSE or
|
||||
* an error code
|
||||
*/
|
||||
boolean getValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
27
datastructures-xslx/src/main/java/jxl/BooleanFormulaCell.java
Executable file
27
datastructures-xslx/src/main/java/jxl/BooleanFormulaCell.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A mixin interface for numerical formulas, which combines the interfaces
|
||||
* for formulas and for numbers
|
||||
*/
|
||||
public interface BooleanFormulaCell extends BooleanCell, FormulaCell {
|
||||
}
|
86
datastructures-xslx/src/main/java/jxl/Cell.java
Executable file
86
datastructures-xslx/src/main/java/jxl/Cell.java
Executable file
|
@ -0,0 +1,86 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import jxl.format.CellFormat;
|
||||
|
||||
/**
|
||||
* Represents an individual Cell within a Sheet. May be queried for its
|
||||
* type and its content
|
||||
*/
|
||||
public interface Cell {
|
||||
/**
|
||||
* Returns the row number of this cell
|
||||
*
|
||||
* @return the row number of this cell
|
||||
*/
|
||||
int getRow();
|
||||
|
||||
/**
|
||||
* Returns the column number of this cell
|
||||
*
|
||||
* @return the column number of this cell
|
||||
*/
|
||||
int getColumn();
|
||||
|
||||
/**
|
||||
* Returns the content type of this cell
|
||||
*
|
||||
* @return the content type for this cell
|
||||
*/
|
||||
CellType getType();
|
||||
|
||||
/**
|
||||
* Indicates whether or not this cell is hidden, by virtue of either
|
||||
* the entire row or column being collapsed
|
||||
*
|
||||
* @return TRUE if this cell is hidden, FALSE otherwise
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
/**
|
||||
* Quick and dirty function to return the contents of this cell as a string.
|
||||
* For more complex manipulation of the contents, it is necessary to cast
|
||||
* this interface to correct subinterface
|
||||
*
|
||||
* @return the contents of this cell as a string
|
||||
*/
|
||||
String getContents();
|
||||
|
||||
/**
|
||||
* Gets the cell format which applies to this cell
|
||||
* Note that for cell with a cell type of EMPTY, which has no formatting
|
||||
* information, this method will return null. Some empty cells (eg. on
|
||||
* template spreadsheets) may have a cell type of EMPTY, but will
|
||||
* actually contain formatting information
|
||||
*
|
||||
* @return the cell format applied to this cell, or NULL if this is an
|
||||
* empty cell
|
||||
*/
|
||||
CellFormat getCellFormat();
|
||||
|
||||
/**
|
||||
* Gets any special cell features, such as comments (notes) or cell
|
||||
* validation present for this cell
|
||||
*
|
||||
* @return the cell features, or NULL if this cell has no special features
|
||||
*/
|
||||
CellFeatures getCellFeatures();
|
||||
}
|
74
datastructures-xslx/src/main/java/jxl/CellFeatures.java
Executable file
74
datastructures-xslx/src/main/java/jxl/CellFeatures.java
Executable file
|
@ -0,0 +1,74 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import jxl.biff.BaseCellFeatures;
|
||||
|
||||
/**
|
||||
* Container for any additional cell features
|
||||
*/
|
||||
public class CellFeatures extends BaseCellFeatures {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public CellFeatures() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param cf cell to copy
|
||||
*/
|
||||
protected CellFeatures(CellFeatures cf) {
|
||||
super(cf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell comment
|
||||
*
|
||||
* @return the cell comment, or NULL if this cell doesn't have
|
||||
* a comment associated with it
|
||||
*/
|
||||
public String getComment() {
|
||||
return super.getComment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data validation list
|
||||
*
|
||||
* @return the data validation list
|
||||
*/
|
||||
public String getDataValidationList() {
|
||||
return super.getDataValidationList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the range of cells to which the data validation applies. If the
|
||||
* validation applies to just this cell, this will be reflected in the
|
||||
* returned range
|
||||
*
|
||||
* @return the range to which the same validation extends, or NULL if this
|
||||
* cell doesn't have a validation
|
||||
*/
|
||||
public Range getSharedDataValidationRange() {
|
||||
return super.getSharedDataValidationRange();
|
||||
}
|
||||
}
|
28
datastructures-xslx/src/main/java/jxl/CellFormat.java
Executable file
28
datastructures-xslx/src/main/java/jxl/CellFormat.java
Executable file
|
@ -0,0 +1,28 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* Interface for cell formats - used for typing information
|
||||
*
|
||||
* @deprecated Repackaged as jxl.format.CellFormat
|
||||
*/
|
||||
public interface CellFormat extends jxl.format.CellFormat {
|
||||
}
|
254
datastructures-xslx/src/main/java/jxl/CellReferenceHelper.java
Executable file
254
datastructures-xslx/src/main/java/jxl/CellReferenceHelper.java
Executable file
|
@ -0,0 +1,254 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import jxl.write.WritableWorkbook;
|
||||
|
||||
/**
|
||||
* Exposes some cell reference helper methods to the public interface.
|
||||
* This class merely delegates to the internally used reference helper
|
||||
*/
|
||||
public final class CellReferenceHelper {
|
||||
/**
|
||||
* Hide the default constructor
|
||||
*/
|
||||
private CellReferenceHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the cell reference for the column and row passed in to the string
|
||||
* buffer
|
||||
*
|
||||
* @param column the column
|
||||
* @param row the row
|
||||
* @param buf the string buffer to append
|
||||
*/
|
||||
public static void getCellReference(int column, int row, StringBuffer buf) {
|
||||
jxl.biff.CellReferenceHelper.getCellReference(column, row, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded method which prepends $ for absolute reference
|
||||
*
|
||||
* @param column the column number
|
||||
* @param colabs TRUE if the column reference is absolute
|
||||
* @param row the row number
|
||||
* @param rowabs TRUE if the row reference is absolute
|
||||
* @param buf the string buffer
|
||||
*/
|
||||
public static void getCellReference(int column,
|
||||
boolean colabs,
|
||||
int row,
|
||||
boolean rowabs,
|
||||
StringBuffer buf) {
|
||||
jxl.biff.CellReferenceHelper.getCellReference(column, colabs,
|
||||
row, rowabs,
|
||||
buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the cell reference for the specified column and row
|
||||
*
|
||||
* @param column the column
|
||||
* @param row the row
|
||||
* @return the cell reference
|
||||
*/
|
||||
public static String getCellReference(int column, int row) {
|
||||
return jxl.biff.CellReferenceHelper.getCellReference(column, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the columnn number of the string cell reference
|
||||
*
|
||||
* @param s the string to parse
|
||||
* @return the column portion of the cell reference
|
||||
*/
|
||||
public static int getColumn(String s) {
|
||||
return jxl.biff.CellReferenceHelper.getColumn(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column letter corresponding to the 0-based column number
|
||||
*
|
||||
* @param c the column number
|
||||
* @return the letter for that column number
|
||||
*/
|
||||
public static String getColumnReference(int c) {
|
||||
return jxl.biff.CellReferenceHelper.getColumnReference(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the row number of the cell reference
|
||||
*
|
||||
* @param s the cell reference
|
||||
* @return the row number
|
||||
*/
|
||||
public static int getRow(String s) {
|
||||
return jxl.biff.CellReferenceHelper.getRow(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if the column component is relative or not
|
||||
*
|
||||
* @param s the cell
|
||||
* @return TRUE if the column is relative, FALSE otherwise
|
||||
*/
|
||||
public static boolean isColumnRelative(String s) {
|
||||
return jxl.biff.CellReferenceHelper.isColumnRelative(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if the row component is relative or not
|
||||
*
|
||||
* @param s the cell
|
||||
* @return TRUE if the row is relative, FALSE otherwise
|
||||
*/
|
||||
public static boolean isRowRelative(String s) {
|
||||
return jxl.biff.CellReferenceHelper.isRowRelative(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet the sheet index
|
||||
* @param column the column index
|
||||
* @param row the row index
|
||||
* @param workbook the workbook
|
||||
* @param buf a string buffer
|
||||
*/
|
||||
public static void getCellReference
|
||||
(int sheet, int column, int row,
|
||||
Workbook workbook, StringBuffer buf) {
|
||||
jxl.biff.CellReferenceHelper.getCellReference
|
||||
(sheet, column, row, (jxl.biff.formula.ExternalSheet) workbook, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param column the column
|
||||
* @param row the row
|
||||
* @param workbook the workbook
|
||||
* @param buf the buffer
|
||||
*/
|
||||
public static void getCellReference(int sheet,
|
||||
int column,
|
||||
int row,
|
||||
WritableWorkbook workbook,
|
||||
StringBuffer buf) {
|
||||
jxl.biff.CellReferenceHelper.getCellReference
|
||||
(sheet, column, row, (jxl.biff.formula.ExternalSheet) workbook, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param column the column
|
||||
* @param colabs TRUE if the column is an absolute reference
|
||||
* @param row the row
|
||||
* @param rowabs TRUE if the row is an absolute reference
|
||||
* @param workbook the workbook
|
||||
* @param buf the string buffer
|
||||
*/
|
||||
public static void getCellReference(int sheet,
|
||||
int column,
|
||||
boolean colabs,
|
||||
int row,
|
||||
boolean rowabs,
|
||||
Workbook workbook,
|
||||
StringBuffer buf) {
|
||||
jxl.biff.CellReferenceHelper.getCellReference
|
||||
(sheet, column, colabs, row, rowabs,
|
||||
(jxl.biff.formula.ExternalSheet) workbook, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param column the column
|
||||
* @param row the row
|
||||
* @param workbook the workbook
|
||||
* @return the cell reference in the form 'Sheet 1'!A1
|
||||
*/
|
||||
public static String getCellReference(int sheet,
|
||||
int column,
|
||||
int row,
|
||||
Workbook workbook) {
|
||||
return jxl.biff.CellReferenceHelper.getCellReference
|
||||
(sheet, column, row, (jxl.biff.formula.ExternalSheet) workbook);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param column the column
|
||||
* @param row the row
|
||||
* @param workbook the workbook
|
||||
* @return the cell reference in the form 'Sheet 1'!A1
|
||||
*/
|
||||
public static String getCellReference(int sheet,
|
||||
int column,
|
||||
int row,
|
||||
WritableWorkbook workbook) {
|
||||
return jxl.biff.CellReferenceHelper.getCellReference
|
||||
(sheet, column, row, (jxl.biff.formula.ExternalSheet) workbook);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the sheet name from the cell reference string
|
||||
*
|
||||
* @param ref the cell reference
|
||||
* @return the sheet name
|
||||
*/
|
||||
public static String getSheet(String ref) {
|
||||
return jxl.biff.CellReferenceHelper.getSheet(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell reference for the cell
|
||||
*
|
||||
* @param the cell
|
||||
*/
|
||||
public static String getCellReference(Cell c) {
|
||||
return getCellReference(c.getColumn(), c.getRow());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell reference for the cell
|
||||
*
|
||||
* @param c the cell
|
||||
* @param sb string buffer
|
||||
*/
|
||||
public static void getCellReference(Cell c, StringBuffer sb) {
|
||||
getCellReference(c.getColumn(), c.getRow(), sb);
|
||||
}
|
||||
|
||||
}
|
97
datastructures-xslx/src/main/java/jxl/CellType.java
Executable file
97
datastructures-xslx/src/main/java/jxl/CellType.java
Executable file
|
@ -0,0 +1,97 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* An enumeration type listing the available content types for a cell
|
||||
*/
|
||||
public final class CellType {
|
||||
|
||||
/**
|
||||
* An empty cell can still contain formatting information and comments
|
||||
*/
|
||||
public static final CellType EMPTY = new CellType("Empty");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType LABEL = new CellType("Label");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType NUMBER = new CellType("Number");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType BOOLEAN = new CellType("Boolean");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType ERROR = new CellType("Error");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType NUMBER_FORMULA =
|
||||
new CellType("Numerical Formula");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType DATE_FORMULA = new CellType("Date Formula");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType STRING_FORMULA = new CellType("String Formula");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType BOOLEAN_FORMULA =
|
||||
new CellType("Boolean Formula");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType FORMULA_ERROR = new CellType("Formula Error");
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final CellType DATE = new CellType("Date");
|
||||
/**
|
||||
* The text description of this cell type
|
||||
*/
|
||||
private final String description;
|
||||
/**
|
||||
* Private constructor
|
||||
*
|
||||
* @param desc the description of this type
|
||||
*/
|
||||
private CellType(String desc) {
|
||||
description = desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string description of this cell
|
||||
*
|
||||
* @return the string description for this type
|
||||
*/
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
196
datastructures-xslx/src/main/java/jxl/CellView.java
Executable file
196
datastructures-xslx/src/main/java/jxl/CellView.java
Executable file
|
@ -0,0 +1,196 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import jxl.format.CellFormat;
|
||||
|
||||
/**
|
||||
* This is a bean which client applications may use to get/set various
|
||||
* properties for a row or column on a spreadsheet
|
||||
*/
|
||||
public final class CellView {
|
||||
/**
|
||||
* The dimension for the associated group of cells. For columns this
|
||||
* will be width in characters, for rows this will be the
|
||||
* height in points
|
||||
* This attribute is deprecated in favour of the size attribute
|
||||
*/
|
||||
private int dimension;
|
||||
|
||||
/**
|
||||
* The size for the associated group of cells. For columns this
|
||||
* will be width in characters multiplied by 256, for rows this will be the
|
||||
* height in points
|
||||
*/
|
||||
private int size;
|
||||
|
||||
/**
|
||||
* Indicates whether the deprecated function was used to set the dimension
|
||||
*/
|
||||
private boolean depUsed;
|
||||
|
||||
/**
|
||||
* Indicates whether or not this sheet is hidden
|
||||
*/
|
||||
private boolean hidden;
|
||||
|
||||
/**
|
||||
* The cell format for the row/column
|
||||
*/
|
||||
private CellFormat format;
|
||||
|
||||
/**
|
||||
* Indicates that this column/row should be autosized
|
||||
*/
|
||||
private boolean autosize;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public CellView() {
|
||||
hidden = false;
|
||||
depUsed = false;
|
||||
dimension = 1;
|
||||
size = 1;
|
||||
autosize = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
public CellView(CellView cv) {
|
||||
hidden = cv.hidden;
|
||||
depUsed = cv.depUsed;
|
||||
dimension = cv.dimension;
|
||||
size = cv.size;
|
||||
autosize = cv.autosize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the hidden nature of this row/column
|
||||
*
|
||||
* @return TRUE if this row/column is hidden, FALSE otherwise
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hidden status of this row/column
|
||||
*
|
||||
* @param h the hidden flag
|
||||
*/
|
||||
public void setHidden(boolean h) {
|
||||
hidden = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the column in characters or the height of the
|
||||
* row in 1/20ths
|
||||
*
|
||||
* @return the dimension
|
||||
* @deprecated use getSize() instead
|
||||
*/
|
||||
public int getDimension() {
|
||||
return dimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dimension for this view
|
||||
*
|
||||
* @param d the width of the column in characters, or the height of the
|
||||
* row in 1/20ths of a point
|
||||
* @deprecated use the setSize method instead
|
||||
*/
|
||||
public void setDimension(int d) {
|
||||
dimension = d;
|
||||
depUsed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the column in characters multiplied by 256, or the
|
||||
* height of the row in 1/20ths of a point
|
||||
*
|
||||
* @return the dimension
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dimension for this view
|
||||
*
|
||||
* @param d the width of the column in characters multiplied by 256,
|
||||
* or the height of the row in 1/20ths of a point
|
||||
*/
|
||||
public void setSize(int d) {
|
||||
size = d;
|
||||
depUsed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell format for this group.
|
||||
*
|
||||
* @return the format for the column/row, or NULL if no format was
|
||||
* specified
|
||||
*/
|
||||
public CellFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell format for this group of cells
|
||||
*
|
||||
* @param cf the format for every cell in the column/row
|
||||
*/
|
||||
public void setFormat(CellFormat cf) {
|
||||
format = cf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the depUsed attribute
|
||||
*
|
||||
* @return TRUE if the deprecated methods were used to set the size,
|
||||
* FALSE otherwise
|
||||
*/
|
||||
public boolean depUsed() {
|
||||
return depUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the autosize flag
|
||||
* NOTE: use of the autosize function is very processor intensive, so
|
||||
* use with care
|
||||
*
|
||||
* @return TRUE if this row/column is to be autosized
|
||||
*/
|
||||
public boolean isAutosize() {
|
||||
return autosize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autosize flag. Currently, this only works for column views
|
||||
*
|
||||
* @param a autosize
|
||||
*/
|
||||
public void setAutosize(boolean a) {
|
||||
autosize = a;
|
||||
}
|
||||
}
|
53
datastructures-xslx/src/main/java/jxl/DateCell.java
Executable file
53
datastructures-xslx/src/main/java/jxl/DateCell.java
Executable file
|
@ -0,0 +1,53 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A date cell
|
||||
*/
|
||||
public interface DateCell extends Cell {
|
||||
/**
|
||||
* Gets the date contained in this cell
|
||||
*
|
||||
* @return the cell contents
|
||||
*/
|
||||
Date getDate();
|
||||
|
||||
/**
|
||||
* Indicates whether the date value contained in this cell refers to a date,
|
||||
* or merely a time
|
||||
*
|
||||
* @return TRUE if the value refers to a time
|
||||
*/
|
||||
boolean isTime();
|
||||
|
||||
/**
|
||||
* Gets the DateFormat used to format the cell. This will normally be
|
||||
* the format specified in the excel spreadsheet, but in the event of any
|
||||
* difficulty parsing this, it will revert to the default date/time format.
|
||||
*
|
||||
* @return the DateFormat object used to format the date in the original
|
||||
* excel cell
|
||||
*/
|
||||
DateFormat getDateFormat();
|
||||
}
|
27
datastructures-xslx/src/main/java/jxl/DateFormulaCell.java
Executable file
27
datastructures-xslx/src/main/java/jxl/DateFormulaCell.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A mixin interface for date formulas, which combines the interfaces
|
||||
* for formulas and for dates
|
||||
*/
|
||||
public interface DateFormulaCell extends DateCell, FormulaCell {
|
||||
}
|
36
datastructures-xslx/src/main/java/jxl/ErrorCell.java
Executable file
36
datastructures-xslx/src/main/java/jxl/ErrorCell.java
Executable file
|
@ -0,0 +1,36 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* This type represents a cell which contains an error. This error will
|
||||
* usually, but not always be the result of some error resulting from
|
||||
* a formula
|
||||
*/
|
||||
public interface ErrorCell extends Cell {
|
||||
/**
|
||||
* Gets the error code for this cell. If this cell does not represent
|
||||
* an error, then it returns 0. Always use the method isError() to
|
||||
* determine this prior to calling this method
|
||||
*
|
||||
* @return the error code if this cell contains an error, 0 otherwise
|
||||
*/
|
||||
int getErrorCode();
|
||||
}
|
27
datastructures-xslx/src/main/java/jxl/ErrorFormulaCell.java
Executable file
27
datastructures-xslx/src/main/java/jxl/ErrorFormulaCell.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A mixin interface for numerical formulas, which combines the interfaces
|
||||
* for formulas and for numbers
|
||||
*/
|
||||
public interface ErrorFormulaCell extends ErrorCell, FormulaCell {
|
||||
}
|
35
datastructures-xslx/src/main/java/jxl/FormulaCell.java
Executable file
35
datastructures-xslx/src/main/java/jxl/FormulaCell.java
Executable file
|
@ -0,0 +1,35 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import jxl.biff.formula.FormulaException;
|
||||
|
||||
/**
|
||||
* Interface for formulas which allow clients to read the Excel formula
|
||||
*/
|
||||
public interface FormulaCell extends Cell {
|
||||
/**
|
||||
* Gets the formula as a string
|
||||
*
|
||||
* @return the formula as a string
|
||||
* @throws FormulaException if an error occurred whilst parsing
|
||||
*/
|
||||
String getFormula() throws FormulaException;
|
||||
}
|
344
datastructures-xslx/src/main/java/jxl/HeaderFooter.java
Executable file
344
datastructures-xslx/src/main/java/jxl/HeaderFooter.java
Executable file
|
@ -0,0 +1,344 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan, Eric Jung
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* Class which represents an Excel header or footer.
|
||||
*/
|
||||
public final class HeaderFooter extends jxl.biff.HeaderFooter {
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public HeaderFooter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param hf the item to copy
|
||||
*/
|
||||
public HeaderFooter(HeaderFooter hf) {
|
||||
super(hf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when reading workbooks to separate the left, right
|
||||
* a central part of the strings into their constituent parts
|
||||
*
|
||||
* @param s the header string
|
||||
*/
|
||||
public HeaderFooter(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>String</code>ified
|
||||
* version of this object
|
||||
*
|
||||
* @return the header string
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which appear on the right hand side of the page
|
||||
*
|
||||
* @return the right aligned contents
|
||||
*/
|
||||
public Contents getRight() {
|
||||
return (Contents) super.getRightText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which in the centre of the page
|
||||
*
|
||||
* @return the centrally aligned contents
|
||||
*/
|
||||
public Contents getCentre() {
|
||||
return (Contents) super.getCentreText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which appear on the left hand side of the page
|
||||
*
|
||||
* @return the left aligned contents
|
||||
*/
|
||||
public Contents getLeft() {
|
||||
return (Contents) super.getLeftText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of the header/footer
|
||||
*/
|
||||
public void clear() {
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*
|
||||
* @return the created contents
|
||||
*/
|
||||
protected jxl.biff.HeaderFooter.Contents createContents() {
|
||||
return new Contents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*
|
||||
* @param s the string to create the contents
|
||||
* @return the created contents
|
||||
*/
|
||||
protected jxl.biff.HeaderFooter.Contents createContents(String s) {
|
||||
return new Contents(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*
|
||||
* @param c the contents to copy
|
||||
* @return the new contents
|
||||
*/
|
||||
protected jxl.biff.HeaderFooter.Contents
|
||||
createContents(jxl.biff.HeaderFooter.Contents c) {
|
||||
return new Contents((Contents) c);
|
||||
}
|
||||
|
||||
/**
|
||||
* The contents - a simple wrapper around a string buffer
|
||||
*/
|
||||
public static class Contents extends jxl.biff.HeaderFooter.Contents {
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
Contents() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when reading worksheets. The string contains all
|
||||
* the formatting (but not alignment characters
|
||||
*
|
||||
* @param s the format string
|
||||
*/
|
||||
Contents(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param copy the contents to copy
|
||||
*/
|
||||
Contents(Contents copy) {
|
||||
super(copy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the text to the string buffer
|
||||
*
|
||||
* @param txt the text to append
|
||||
*/
|
||||
public void append(String txt) {
|
||||
super.append(txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns bold printing on or off. Bold printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be bolded until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleBold() {
|
||||
super.toggleBold();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns underline printing on or off. Underline printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be underlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleUnderline() {
|
||||
super.toggleUnderline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns italics printing on or off. Italics printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be italicized until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleItalics() {
|
||||
super.toggleItalics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns strikethrough printing on or off. Strikethrough printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be striked out until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleStrikethrough() {
|
||||
super.toggleStrikethrough();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns double-underline printing on or off. Double-underline printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be double-underlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleDoubleUnderline() {
|
||||
super.toggleDoubleUnderline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns superscript printing on or off. Superscript printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be superscripted until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleSuperScript() {
|
||||
super.toggleSuperScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns subscript printing on or off. Subscript printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be subscripted until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleSubScript() {
|
||||
super.toggleSubScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns outline printing on or off (Macintosh only).
|
||||
* Outline printing is initially off. Text subsequently appended
|
||||
* to this object will be outlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleOutline() {
|
||||
super.toggleOutline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns shadow printing on or off (Macintosh only).
|
||||
* Shadow printing is initially off. Text subsequently appended
|
||||
* to this object will be shadowed until this method is
|
||||
* called again.
|
||||
*/
|
||||
public void toggleShadow() {
|
||||
super.toggleShadow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font of text subsequently appended to this
|
||||
* object.. Previously appended text is not affected.
|
||||
* <p/>
|
||||
* <strong>Note:</strong> no checking is performed to
|
||||
* determine if fontName is a valid font.
|
||||
*
|
||||
* @param fontName name of the font to use
|
||||
*/
|
||||
public void setFontName(String fontName) {
|
||||
super.setFontName(fontName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font size of text subsequently appended to this
|
||||
* object. Previously appended text is not affected.
|
||||
* <p/>
|
||||
* Valid point sizes are between 1 and 99 (inclusive). If
|
||||
* size is outside this range, this method returns false
|
||||
* and does not change font size. If size is within this
|
||||
* range, the font size is changed and true is returned.
|
||||
*
|
||||
* @param size The size in points. Valid point sizes are
|
||||
* between 1 and 99 (inclusive).
|
||||
* @return true if the font size was changed, false if font
|
||||
* size was not changed because 1 > size > 99.
|
||||
*/
|
||||
public boolean setFontSize(int size) {
|
||||
return super.setFontSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the page number
|
||||
*/
|
||||
public void appendPageNumber() {
|
||||
super.appendPageNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the total number of pages
|
||||
*/
|
||||
public void appendTotalPages() {
|
||||
super.appendTotalPages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the current date
|
||||
*/
|
||||
public void appendDate() {
|
||||
super.appendDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the current time
|
||||
*/
|
||||
public void appendTime() {
|
||||
super.appendTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the workbook name
|
||||
*/
|
||||
public void appendWorkbookName() {
|
||||
super.appendWorkbookName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the worksheet name
|
||||
*/
|
||||
public void appendWorkSheetName() {
|
||||
super.appendWorkSheetName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of this portion
|
||||
*/
|
||||
public void clear() {
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries if the contents are empty
|
||||
*
|
||||
* @return TRUE if the contents are empty, FALSE otherwise
|
||||
*/
|
||||
public boolean empty() {
|
||||
return super.empty();
|
||||
}
|
||||
}
|
||||
}
|
106
datastructures-xslx/src/main/java/jxl/Hyperlink.java
Executable file
106
datastructures-xslx/src/main/java/jxl/Hyperlink.java
Executable file
|
@ -0,0 +1,106 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Hyperlink information. Only URLs or file links are supported
|
||||
* <p>
|
||||
* Hyperlinks may apply to a range of cells; in such cases the methods
|
||||
* getRow and getColumn return the cell at the top left of the range
|
||||
* the hyperlink refers to. Hyperlinks have no specific cell format
|
||||
* information applied to them, so the getCellFormat method will return null
|
||||
*/
|
||||
public interface Hyperlink {
|
||||
/**
|
||||
* Returns the row number of this cell
|
||||
*
|
||||
* @return the row number of this cell
|
||||
*/
|
||||
int getRow();
|
||||
|
||||
/**
|
||||
* Returns the column number of this cell
|
||||
*
|
||||
* @return the column number of this cell
|
||||
*/
|
||||
int getColumn();
|
||||
|
||||
/**
|
||||
* Gets the range of cells which activate this hyperlink
|
||||
* The get sheet index methods will all return -1, because the
|
||||
* cells will all be present on the same sheet
|
||||
*
|
||||
* @return the range of cells which activate the hyperlink
|
||||
*/
|
||||
Range getRange();
|
||||
|
||||
/**
|
||||
* Determines whether this is a hyperlink to a file
|
||||
*
|
||||
* @return TRUE if this is a hyperlink to a file, FALSE otherwise
|
||||
*/
|
||||
boolean isFile();
|
||||
|
||||
/**
|
||||
* Determines whether this is a hyperlink to a web resource
|
||||
*
|
||||
* @return TRUE if this is a URL
|
||||
*/
|
||||
boolean isURL();
|
||||
|
||||
/**
|
||||
* Determines whether this is a hyperlink to a location in this workbook
|
||||
*
|
||||
* @return TRUE if this is a link to an internal location
|
||||
*/
|
||||
boolean isLocation();
|
||||
|
||||
/**
|
||||
* Returns the row number of the bottom right cell
|
||||
*
|
||||
* @return the row number of this cell
|
||||
*/
|
||||
int getLastRow();
|
||||
|
||||
/**
|
||||
* Returns the column number of the bottom right cell
|
||||
*
|
||||
* @return the column number of this cell
|
||||
*/
|
||||
int getLastColumn();
|
||||
|
||||
/**
|
||||
* Gets the URL referenced by this Hyperlink
|
||||
*
|
||||
* @return the URL, or NULL if this hyperlink is not a URL
|
||||
*/
|
||||
URL getURL();
|
||||
|
||||
/**
|
||||
* Returns the local file eferenced by this Hyperlink
|
||||
*
|
||||
* @return the file, or NULL if this hyperlink is not a file
|
||||
*/
|
||||
File getFile();
|
||||
}
|
||||
|
120
datastructures-xslx/src/main/java/jxl/Image.java
Executable file
120
datastructures-xslx/src/main/java/jxl/Image.java
Executable file
|
@ -0,0 +1,120 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.io.File;
|
||||
import jxl.common.LengthUnit;
|
||||
|
||||
/**
|
||||
* Accessor functions for an image
|
||||
*/
|
||||
public interface Image {
|
||||
/**
|
||||
* Accessor for the image position
|
||||
*
|
||||
* @return the column number at which the image is positioned
|
||||
*/
|
||||
double getColumn();
|
||||
|
||||
/**
|
||||
* Accessor for the image position
|
||||
*
|
||||
* @return the row number at which the image is positioned
|
||||
*/
|
||||
double getRow();
|
||||
|
||||
/**
|
||||
* Accessor for the image dimensions
|
||||
*
|
||||
* @return the number of columns this image spans
|
||||
*/
|
||||
double getWidth();
|
||||
|
||||
/**
|
||||
* Accessor for the image dimensions
|
||||
*
|
||||
* @return the number of rows which this image spans
|
||||
*/
|
||||
double getHeight();
|
||||
|
||||
/**
|
||||
* Accessor for the image file
|
||||
*
|
||||
* @return the file which the image references
|
||||
*/
|
||||
File getImageFile();
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
byte[] getImageData();
|
||||
|
||||
/**
|
||||
* Get the width of this image as rendered within Excel
|
||||
*
|
||||
* @param unit the unit of measurement
|
||||
* @return the width of the image within Excel
|
||||
*/
|
||||
double getWidth(LengthUnit unit);
|
||||
|
||||
/**
|
||||
* Get the height of this image as rendered within Excel
|
||||
*
|
||||
* @param unit the unit of measurement
|
||||
* @return the height of the image within Excel
|
||||
*/
|
||||
double getHeight(LengthUnit unit);
|
||||
|
||||
/**
|
||||
* Gets the width of the image. Note that this is the width of the
|
||||
* underlying image, and does not take into account any size manipulations
|
||||
* that may have occurred when the image was added into Excel
|
||||
*
|
||||
* @return the image width in pixels
|
||||
*/
|
||||
int getImageWidth();
|
||||
|
||||
/**
|
||||
* Gets the height of the image. Note that this is the height of the
|
||||
* underlying image, and does not take into account any size manipulations
|
||||
* that may have occurred when the image was added into Excel
|
||||
*
|
||||
* @return the image height in pixels
|
||||
*/
|
||||
int getImageHeight();
|
||||
|
||||
/**
|
||||
* Gets the horizontal resolution of the image, if that information
|
||||
* is available.
|
||||
*
|
||||
* @return the number of dots per unit specified, if available, 0 otherwise
|
||||
*/
|
||||
double getHorizontalResolution(LengthUnit unit);
|
||||
|
||||
/**
|
||||
* Gets the vertical resolution of the image, if that information
|
||||
* is available.
|
||||
*
|
||||
* @return the number of dots per unit specified, if available, 0 otherwise
|
||||
*/
|
||||
double getVerticalResolution(LengthUnit unit);
|
||||
}
|
34
datastructures-xslx/src/main/java/jxl/JXLException.java
Executable file
34
datastructures-xslx/src/main/java/jxl/JXLException.java
Executable file
|
@ -0,0 +1,34 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* Base exception class for JExcelAPI exceptions
|
||||
*/
|
||||
public class JXLException extends Exception {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param message the exception message
|
||||
*/
|
||||
protected JXLException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
33
datastructures-xslx/src/main/java/jxl/LabelCell.java
Executable file
33
datastructures-xslx/src/main/java/jxl/LabelCell.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A label cell
|
||||
*/
|
||||
public interface LabelCell extends Cell {
|
||||
/**
|
||||
* Gets the label for this cell. The value returned will be the same
|
||||
* as for the getContents method in the base class
|
||||
*
|
||||
* @return the cell contents
|
||||
*/
|
||||
String getString();
|
||||
}
|
43
datastructures-xslx/src/main/java/jxl/NumberCell.java
Executable file
43
datastructures-xslx/src/main/java/jxl/NumberCell.java
Executable file
|
@ -0,0 +1,43 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
/**
|
||||
* A cell which contains a numerical value
|
||||
*/
|
||||
public interface NumberCell extends Cell {
|
||||
/**
|
||||
* Gets the double contents for this cell.
|
||||
*
|
||||
* @return the cell contents
|
||||
*/
|
||||
double getValue();
|
||||
|
||||
/**
|
||||
* Gets the NumberFormat used to format this cell. This is the java
|
||||
* equivalent of the Excel format
|
||||
*
|
||||
* @return the NumberFormat used to format the cell
|
||||
*/
|
||||
NumberFormat getNumberFormat();
|
||||
}
|
||||
|
27
datastructures-xslx/src/main/java/jxl/NumberFormulaCell.java
Executable file
27
datastructures-xslx/src/main/java/jxl/NumberFormulaCell.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A mixin interface for numerical formulas, which combines the interfaces
|
||||
* for formulas and for numbers
|
||||
*/
|
||||
public interface NumberFormulaCell extends NumberCell, FormulaCell {
|
||||
}
|
57
datastructures-xslx/src/main/java/jxl/Range.java
Executable file
57
datastructures-xslx/src/main/java/jxl/Range.java
Executable file
|
@ -0,0 +1,57 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* Represents a 3-D range of cells in a workbook. This object is
|
||||
* returned by the method findByName in a workbook
|
||||
*/
|
||||
public interface Range {
|
||||
/**
|
||||
* Gets the cell at the top left of this range
|
||||
*
|
||||
* @return the cell at the top left
|
||||
*/
|
||||
Cell getTopLeft();
|
||||
|
||||
/**
|
||||
* Gets the cell at the bottom right of this range
|
||||
*
|
||||
* @return the cell at the bottom right
|
||||
*/
|
||||
Cell getBottomRight();
|
||||
|
||||
/**
|
||||
* Gets the index of the first sheet in the range
|
||||
*
|
||||
* @return the index of the first sheet in the range
|
||||
*/
|
||||
int getFirstSheetIndex();
|
||||
|
||||
/**
|
||||
* Gets the index of the last sheet in the range
|
||||
*
|
||||
* @return the index of the last sheet in the range
|
||||
*/
|
||||
int getLastSheetIndex();
|
||||
}
|
||||
|
||||
|
||||
|
278
datastructures-xslx/src/main/java/jxl/Sheet.java
Executable file
278
datastructures-xslx/src/main/java/jxl/Sheet.java
Executable file
|
@ -0,0 +1,278 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import jxl.format.CellFormat;
|
||||
|
||||
/**
|
||||
* Represents a sheet within a workbook. Provides a handle to the individual
|
||||
* cells, or lines of cells (grouped by Row or Column)
|
||||
*/
|
||||
public interface Sheet {
|
||||
/**
|
||||
* Returns the cell specified at this row and at this column.
|
||||
* If a column/row combination forms part of a merged group of cells
|
||||
* then (unless it is the first cell of the group) a blank cell
|
||||
* will be returned
|
||||
*
|
||||
* @param column the column number
|
||||
* @param row the row number
|
||||
* @return the cell at the specified co-ordinates
|
||||
*/
|
||||
Cell getCell(int column, int row);
|
||||
|
||||
/**
|
||||
* Returns the cell for the specified location eg. "A4". Note that this
|
||||
* method is identical to calling getCell(CellReferenceHelper.getColumn(loc),
|
||||
* CellReferenceHelper.getRow(loc)) and its implicit performance
|
||||
* overhead for string parsing. As such,this method should therefore
|
||||
* be used sparingly
|
||||
*
|
||||
* @param loc the cell reference
|
||||
* @return the cell at the specified co-ordinates
|
||||
*/
|
||||
Cell getCell(String loc);
|
||||
|
||||
/**
|
||||
* Returns the number of rows in this sheet
|
||||
*
|
||||
* @return the number of rows in this sheet
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Returns the number of columns in this sheet
|
||||
*
|
||||
* @return the number of columns in this sheet
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Gets all the cells on the specified row
|
||||
*
|
||||
* @param row the rows whose cells are to be returned
|
||||
* @return the cells on the given row
|
||||
*/
|
||||
Cell[] getRow(int row);
|
||||
|
||||
/**
|
||||
* Gets all the cells on the specified column
|
||||
*
|
||||
* @param col the column whose cells are to be returned
|
||||
* @return the cells on the specified column
|
||||
*/
|
||||
Cell[] getColumn(int col);
|
||||
|
||||
/**
|
||||
* Gets the name of this sheet
|
||||
*
|
||||
* @return the name of the sheet
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Determines whether the sheet is hidden
|
||||
*
|
||||
* @return whether or not the sheet is hidden
|
||||
* @deprecated in favour of the getSettings() method
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
/**
|
||||
* Determines whether the sheet is protected
|
||||
*
|
||||
* @return whether or not the sheet is protected
|
||||
* @deprecated in favour of the getSettings() method
|
||||
*/
|
||||
boolean isProtected();
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the string passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @return the Cell whose contents match the paramter, null if not found
|
||||
*/
|
||||
Cell findCell(String contents);
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the string passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @param firstCol the first column within the range
|
||||
* @param firstRow the first row of the range
|
||||
* @param lastCol the last column within the range
|
||||
* @param lastRow the last row within the range
|
||||
* @param reverse indicates whether to perform a reverse search or not
|
||||
* @return the Cell whose contents match the parameter, null if not found
|
||||
*/
|
||||
Cell findCell(String contents,
|
||||
int firstCol,
|
||||
int firstRow,
|
||||
int lastCol,
|
||||
int lastRow,
|
||||
boolean reverse);
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the regular expressionstring passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform
|
||||
*
|
||||
* @param pattern the regular expression string to match
|
||||
* @param firstCol the first column within the range
|
||||
* @param firstRow the first row of the rang
|
||||
* @param lastCol the last column within the range
|
||||
* @param lastRow the last row within the range
|
||||
* @param reverse indicates whether to perform a reverse search or not
|
||||
* @return the Cell whose contents match the parameter, null if not found
|
||||
*/
|
||||
Cell findCell(Pattern pattern,
|
||||
int firstCol,
|
||||
int firstRow,
|
||||
int lastCol,
|
||||
int lastRow,
|
||||
boolean reverse);
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the string passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform. This method differs
|
||||
* from the findCell method in that only cells with labels are
|
||||
* queried - all numerical cells are ignored. This should therefore
|
||||
* improve performance.
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @return the Cell whose contents match the paramter, null if not found
|
||||
*/
|
||||
LabelCell findLabelCell(String contents);
|
||||
|
||||
/**
|
||||
* Gets the hyperlinks on this sheet
|
||||
*
|
||||
* @return an array of hyperlinks
|
||||
*/
|
||||
Hyperlink[] getHyperlinks();
|
||||
|
||||
/**
|
||||
* Gets the cells which have been merged on this sheet
|
||||
*
|
||||
* @return an array of range objects
|
||||
*/
|
||||
Range[] getMergedCells();
|
||||
|
||||
/**
|
||||
* Gets the settings used on a particular sheet
|
||||
*
|
||||
* @return the sheet settings
|
||||
*/
|
||||
SheetSettings getSettings();
|
||||
|
||||
/**
|
||||
* Gets the column format for the specified column
|
||||
*
|
||||
* @param col the column number
|
||||
* @return the column format, or NULL if the column has no specific format
|
||||
* @deprecated Use getColumnView and the CellView bean instead
|
||||
*/
|
||||
CellFormat getColumnFormat(int col);
|
||||
|
||||
/**
|
||||
* Gets the column width for the specified column
|
||||
*
|
||||
* @param col the column number
|
||||
* @return the column width, or the default width if the column has no
|
||||
* specified format
|
||||
* @deprecated Use getColumnView instead
|
||||
*/
|
||||
int getColumnWidth(int col);
|
||||
|
||||
/**
|
||||
* Gets the column width for the specified column
|
||||
*
|
||||
* @param col the column number
|
||||
* @return the column format, or the default format if no override is
|
||||
* specified
|
||||
*/
|
||||
CellView getColumnView(int col);
|
||||
|
||||
/**
|
||||
* Gets the row height for the specified column
|
||||
*
|
||||
* @param row the row number
|
||||
* @return the row height, or the default height if the column has no
|
||||
* specified format
|
||||
* @deprecated use getRowView instead
|
||||
*/
|
||||
int getRowHeight(int row);
|
||||
|
||||
/**
|
||||
* Gets the row height for the specified column
|
||||
*
|
||||
* @param row the row number
|
||||
* @return the row format, which may be the default format if no format
|
||||
* is specified
|
||||
*/
|
||||
CellView getRowView(int row);
|
||||
|
||||
/**
|
||||
* Accessor for the number of images on the sheet
|
||||
*
|
||||
* @return the number of images on this sheet
|
||||
*/
|
||||
int getNumberOfImages();
|
||||
|
||||
/**
|
||||
* Accessor for the image
|
||||
*
|
||||
* @param i the 0 based image number
|
||||
* @return the image at the specified position
|
||||
*/
|
||||
Image getDrawing(int i);
|
||||
|
||||
/**
|
||||
* Accessor for the page breaks on this sheet
|
||||
*
|
||||
* @return the page breaks on this sheet
|
||||
*/
|
||||
int[] getRowPageBreaks();
|
||||
|
||||
/**
|
||||
* Accessor for the page breaks on this sheet
|
||||
*
|
||||
* @return the page breaks on this sheet
|
||||
*/
|
||||
int[] getColumnPageBreaks();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1204
datastructures-xslx/src/main/java/jxl/SheetSettings.java
Executable file
1204
datastructures-xslx/src/main/java/jxl/SheetSettings.java
Executable file
File diff suppressed because it is too large
Load diff
29
datastructures-xslx/src/main/java/jxl/StringFormulaCell.java
Executable file
29
datastructures-xslx/src/main/java/jxl/StringFormulaCell.java
Executable file
|
@ -0,0 +1,29 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
/**
|
||||
* A mixin interface for numerical formulas, which combines the interfaces
|
||||
* for formulas and for strings
|
||||
*/
|
||||
public interface StringFormulaCell extends LabelCell, FormulaCell {
|
||||
}
|
||||
|
||||
|
397
datastructures-xslx/src/main/java/jxl/Workbook.java
Executable file
397
datastructures-xslx/src/main/java/jxl/Workbook.java
Executable file
|
@ -0,0 +1,397 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import jxl.read.biff.BiffException;
|
||||
import jxl.read.biff.File;
|
||||
import jxl.read.biff.PasswordException;
|
||||
import jxl.read.biff.WorkbookParser;
|
||||
import jxl.write.WritableWorkbook;
|
||||
import jxl.write.biff.WritableWorkbookImpl;
|
||||
|
||||
/**
|
||||
* Represents a Workbook. Contains the various factory methods and provides
|
||||
* a variety of accessors which provide access to the work sheets.
|
||||
*/
|
||||
public abstract class Workbook {
|
||||
/**
|
||||
* The current version of the software
|
||||
*/
|
||||
private static final String VERSION = "2.6.12";
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
protected Workbook() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the software version
|
||||
*
|
||||
* @return the version
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method which takes in an excel file and reads in the contents.
|
||||
*
|
||||
* @param file the excel 97 spreadsheet to parse
|
||||
* @return a workbook instance
|
||||
* @throws IOException
|
||||
* @throws BiffException
|
||||
*/
|
||||
public static Workbook getWorkbook(java.io.File file)
|
||||
throws IOException, BiffException {
|
||||
return getWorkbook(file, new WorkbookSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method which takes in an excel file and reads in the contents.
|
||||
*
|
||||
* @param file the excel 97 spreadsheet to parse
|
||||
* @param ws the settings for the workbook
|
||||
* @return a workbook instance
|
||||
* @throws IOException
|
||||
* @throws BiffException
|
||||
*/
|
||||
public static Workbook getWorkbook(java.io.File file, WorkbookSettings ws)
|
||||
throws IOException, BiffException {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
|
||||
// Always close down the input stream, regardless of whether or not the
|
||||
// file can be parsed. Thanks to Steve Hahn for this
|
||||
File dataFile = null;
|
||||
|
||||
try {
|
||||
dataFile = new File(fis, ws);
|
||||
} catch (IOException e) {
|
||||
fis.close();
|
||||
throw e;
|
||||
} catch (BiffException e) {
|
||||
fis.close();
|
||||
throw e;
|
||||
}
|
||||
|
||||
fis.close();
|
||||
|
||||
Workbook workbook = new WorkbookParser(dataFile, ws);
|
||||
workbook.parse();
|
||||
|
||||
return workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method which takes in an excel file and reads in the contents.
|
||||
*
|
||||
* @param is an open stream which is the the excel 97 spreadsheet to parse
|
||||
* @return a workbook instance
|
||||
* @throws IOException
|
||||
* @throws BiffException
|
||||
*/
|
||||
public static Workbook getWorkbook(InputStream is)
|
||||
throws IOException, BiffException {
|
||||
return getWorkbook(is, new WorkbookSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method which takes in an excel file and reads in the contents.
|
||||
*
|
||||
* @param is an open stream which is the the excel 97 spreadsheet to parse
|
||||
* @param ws the settings for the workbook
|
||||
* @return a workbook instance
|
||||
* @throws IOException
|
||||
* @throws BiffException
|
||||
*/
|
||||
public static Workbook getWorkbook(InputStream is, WorkbookSettings ws)
|
||||
throws IOException, BiffException {
|
||||
File dataFile = new File(is, ws);
|
||||
|
||||
Workbook workbook = new WorkbookParser(dataFile, ws);
|
||||
workbook.parse();
|
||||
|
||||
return workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook with the given file name
|
||||
*
|
||||
* @param file the workbook to copy
|
||||
* @return a writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(java.io.File file)
|
||||
throws IOException {
|
||||
return createWorkbook(file, new WorkbookSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook with the given file name
|
||||
*
|
||||
* @param file the file to copy from
|
||||
* @param ws the global workbook settings
|
||||
* @return a writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(java.io.File file,
|
||||
WorkbookSettings ws)
|
||||
throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
WritableWorkbook w = new WritableWorkbookImpl(fos, true, ws);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook with the given filename as a copy of
|
||||
* the workbook passed in. Once created, the contents of the writable
|
||||
* workbook may be modified
|
||||
*
|
||||
* @param file the output file for the copy
|
||||
* @param in the workbook to copy
|
||||
* @return a writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(java.io.File file,
|
||||
Workbook in)
|
||||
throws IOException {
|
||||
return createWorkbook(file, in, new WorkbookSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook with the given filename as a copy of
|
||||
* the workbook passed in. Once created, the contents of the writable
|
||||
* workbook may be modified
|
||||
*
|
||||
* @param file the output file for the copy
|
||||
* @param in the workbook to copy
|
||||
* @param ws the configuration for this workbook
|
||||
* @return a writable workbook
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(java.io.File file,
|
||||
Workbook in,
|
||||
WorkbookSettings ws)
|
||||
throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
WritableWorkbook w = new WritableWorkbookImpl(fos, in, true, ws);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook as a copy of
|
||||
* the workbook passed in. Once created, the contents of the writable
|
||||
* workbook may be modified
|
||||
*
|
||||
* @param os the stream to write to
|
||||
* @param in the workbook to copy
|
||||
* @return a writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(OutputStream os,
|
||||
Workbook in)
|
||||
throws IOException {
|
||||
return createWorkbook(os, in, ((WorkbookParser) in).getSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook as a copy of
|
||||
* the workbook passed in. Once created, the contents of the writable
|
||||
* workbook may be modified
|
||||
*
|
||||
* @param os the output stream to write to
|
||||
* @param in the workbook to copy
|
||||
* @param ws the configuration for this workbook
|
||||
* @return a writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(OutputStream os,
|
||||
Workbook in,
|
||||
WorkbookSettings ws)
|
||||
throws IOException {
|
||||
WritableWorkbook w = new WritableWorkbookImpl(os, in, false, ws);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook. When the workbook is closed,
|
||||
* it will be streamed directly to the output stream. In this
|
||||
* manner, a generated excel spreadsheet can be passed from
|
||||
* a servlet to the browser over HTTP
|
||||
*
|
||||
* @param os the output stream
|
||||
* @return the writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(OutputStream os)
|
||||
throws IOException {
|
||||
return createWorkbook(os, new WorkbookSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writable workbook. When the workbook is closed,
|
||||
* it will be streamed directly to the output stream. In this
|
||||
* manner, a generated excel spreadsheet can be passed from
|
||||
* a servlet to the browser over HTTP
|
||||
*
|
||||
* @param os the output stream
|
||||
* @param ws the configuration for this workbook
|
||||
* @return the writable workbook
|
||||
* @throws IOException
|
||||
*/
|
||||
public static WritableWorkbook createWorkbook(OutputStream os,
|
||||
WorkbookSettings ws)
|
||||
throws IOException {
|
||||
WritableWorkbook w = new WritableWorkbookImpl(os, false, ws);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sheets within this workbook. Use of this method for
|
||||
* large worksheets can cause performance problems.
|
||||
*
|
||||
* @return an array of the individual sheets
|
||||
*/
|
||||
public abstract Sheet[] getSheets();
|
||||
|
||||
/**
|
||||
* Gets the sheet names
|
||||
*
|
||||
* @return an array of strings containing the sheet names
|
||||
*/
|
||||
public abstract String[] getSheetNames();
|
||||
|
||||
/**
|
||||
* Gets the specified sheet within this workbook
|
||||
* As described in the accompanying technical notes, each call
|
||||
* to getSheet forces a reread of the sheet (for memory reasons).
|
||||
* Therefore, do not make unnecessary calls to this method. Furthermore,
|
||||
* do not hold unnecessary references to Sheets in client code, as
|
||||
* this will prevent the garbage collector from freeing the memory
|
||||
*
|
||||
* @param index the zero based index of the reQuired sheet
|
||||
* @return The sheet specified by the index
|
||||
* @throws IndexOutOfBoundException when index refers to a non-existent
|
||||
* sheet
|
||||
*/
|
||||
public abstract Sheet getSheet(int index)
|
||||
throws IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Gets the sheet with the specified name from within this workbook.
|
||||
* As described in the accompanying technical notes, each call
|
||||
* to getSheet forces a reread of the sheet (for memory reasons).
|
||||
* Therefore, do not make unnecessary calls to this method. Furthermore,
|
||||
* do not hold unnecessary references to Sheets in client code, as
|
||||
* this will prevent the garbage collector from freeing the memory
|
||||
*
|
||||
* @param name the sheet name
|
||||
* @return The sheet with the specified name, or null if it is not found
|
||||
*/
|
||||
public abstract Sheet getSheet(String name);
|
||||
|
||||
/**
|
||||
* Returns the number of sheets in this workbook
|
||||
*
|
||||
* @return the number of sheets in this workbook
|
||||
*/
|
||||
public abstract int getNumberOfSheets();
|
||||
|
||||
/**
|
||||
* Gets the named cell from this workbook. If the name refers to a
|
||||
* range of cells, then the cell on the top left is returned. If
|
||||
* the name cannot be found, null is returned.
|
||||
* This is a convenience function to quickly access the contents
|
||||
* of a single cell. If you need further information (such as the
|
||||
* sheet or adjacent cells in the range) use the functionally
|
||||
* richer method, findByName which returns a list of ranges
|
||||
*
|
||||
* @param name the name of the cell/range to search for
|
||||
* @return the cell in the top left of the range if found, NULL
|
||||
* otherwise
|
||||
*/
|
||||
public abstract Cell findCellByName(String name);
|
||||
|
||||
/**
|
||||
* Returns the cell for the specified location eg. "Sheet1!A4".
|
||||
* This is identical to using the CellReferenceHelper with its
|
||||
* associated performance overheads, consequently it should
|
||||
* be use sparingly
|
||||
*
|
||||
* @param loc the cell to retrieve
|
||||
* @return the cell at the specified location
|
||||
*/
|
||||
public abstract Cell getCell(String loc);
|
||||
|
||||
/**
|
||||
* Gets the named range from this workbook. The Range object returns
|
||||
* contains all the cells from the top left to the bottom right
|
||||
* of the range.
|
||||
* If the named range comprises an adjacent range,
|
||||
* the Range[] will contain one object; for non-adjacent
|
||||
* ranges, it is necessary to return an array of length greater than
|
||||
* one.
|
||||
* If the named range contains a single cell, the top left and
|
||||
* bottom right cell will be the same cell
|
||||
*
|
||||
* @param name the name of the cell/range to search for
|
||||
* @return the range of cells, or NULL if the range does not exist
|
||||
*/
|
||||
public abstract Range[] findByName(String name);
|
||||
|
||||
/**
|
||||
* Gets the named ranges
|
||||
*
|
||||
* @return the list of named cells within the workbook
|
||||
*/
|
||||
public abstract String[] getRangeNames();
|
||||
|
||||
/**
|
||||
* Determines whether the sheet is protected
|
||||
*
|
||||
* @return TRUE if the workbook is protected, FALSE otherwise
|
||||
*/
|
||||
public abstract boolean isProtected();
|
||||
|
||||
/**
|
||||
* Parses the excel file.
|
||||
* If the workbook is password protected a PasswordException is thrown
|
||||
* in case consumers of the API wish to handle this in a particular way
|
||||
*
|
||||
* @throws BiffException
|
||||
* @throws PasswordException
|
||||
*/
|
||||
protected abstract void parse() throws BiffException, PasswordException;
|
||||
|
||||
/**
|
||||
* Closes this workbook, and frees makes any memory allocated available
|
||||
* for garbage collection
|
||||
*/
|
||||
public abstract void close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
798
datastructures-xslx/src/main/java/jxl/WorkbookSettings.java
Executable file
798
datastructures-xslx/src/main/java/jxl/WorkbookSettings.java
Executable file
|
@ -0,0 +1,798 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import jxl.biff.CountryCode;
|
||||
import jxl.biff.formula.FunctionNames;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* This is a bean which client applications may use to set various advanced
|
||||
* workbook properties. Use of this bean is not mandatory, and its absence
|
||||
* will merely result in workbooks being read/written using the default
|
||||
* settings
|
||||
*/
|
||||
public final class WorkbookSettings {
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab.
|
||||
*/
|
||||
public final static int HIDEOBJ_HIDE_ALL = 2;
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab.
|
||||
*/
|
||||
public final static int HIDEOBJ_SHOW_PLACEHOLDERS = 1;
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab.
|
||||
*/
|
||||
public final static int HIDEOBJ_SHOW_ALL = 0;
|
||||
// **
|
||||
// The default values
|
||||
// **
|
||||
private static final int DEFAULT_INITIAL_FILE_SIZE = 5 * 1024 * 1024;
|
||||
// 5 megabytes
|
||||
private static final int DEFAULT_ARRAY_GROW_SIZE = 1024 * 1024; // 1 megabyte
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(WorkbookSettings.class);
|
||||
/**
|
||||
* The amount of memory allocated to store the workbook data when
|
||||
* reading a worksheet. For processeses reading many small workbooks inside
|
||||
* a WAS it might be necessary to reduce the default size
|
||||
*/
|
||||
private int initialFileSize;
|
||||
/**
|
||||
* The amount of memory allocated to the array containing the workbook
|
||||
* data when its current amount is exhausted.
|
||||
*/
|
||||
private int arrayGrowSize;
|
||||
/**
|
||||
* Flag to indicate whether the drawing feature is enabled or not
|
||||
* Drawings deactivated using -Djxl.nodrawings=true on the JVM command line
|
||||
* Activated by default or by using -Djxl.nodrawings=false on the JVM command
|
||||
* line
|
||||
*/
|
||||
private boolean drawingsDisabled;
|
||||
/**
|
||||
* Flag to indicate whether the name feature is enabled or not
|
||||
* Names deactivated using -Djxl.nonames=true on the JVM command line
|
||||
* Activated by default or by using -Djxl.nonames=false on the JVM command
|
||||
* line
|
||||
*/
|
||||
private boolean namesDisabled;
|
||||
/**
|
||||
* Flag to indicate whether formula cell references should be adjusted
|
||||
* following row/column insertion/deletion
|
||||
*/
|
||||
private boolean formulaReferenceAdjustDisabled;
|
||||
/**
|
||||
* Flag to indicate whether the system hint garbage collection
|
||||
* is enabled or not.
|
||||
* As a rule of thumb, it is desirable to enable garbage collection
|
||||
* when reading large spreadsheets from a batch process or from the
|
||||
* command line, but better to deactivate the feature when reading
|
||||
* large spreadsheets within a WAS, as the calls to System.gc() not
|
||||
* only garbage collect the junk in JExcelApi, but also in the
|
||||
* webservers JVM and can cause significant slowdown
|
||||
* GC deactivated using -Djxl.nogc=true on the JVM command line
|
||||
* Activated by default or by using -Djxl.nogc=false on the JVM command line
|
||||
*/
|
||||
private boolean gcDisabled;
|
||||
/**
|
||||
* Flag to indicate whether the rationalization of cell formats is
|
||||
* disabled or not.
|
||||
* Rationalization is enabled by default, but may be disabled for
|
||||
* performance reasons. It can be deactivated using -Djxl.norat=true on
|
||||
* the JVM command line
|
||||
*/
|
||||
private boolean rationalizationDisabled;
|
||||
/**
|
||||
* Flag to indicate whether or not the merged cell checking has been
|
||||
* disabled
|
||||
*/
|
||||
private boolean mergedCellCheckingDisabled;
|
||||
/**
|
||||
* Flag to indicate whether the copying of additional property sets
|
||||
* are disabled
|
||||
*/
|
||||
private boolean propertySetsDisabled;
|
||||
/**
|
||||
* Flag to indicate that cell validation criteria are ignored
|
||||
*/
|
||||
private boolean cellValidationDisabled;
|
||||
/**
|
||||
* Flag to indicate whether or not to ignore blank cells when processing
|
||||
* sheets. Cells which are identified as blank can still have associated
|
||||
* cell formats which the processing program may still need to read
|
||||
*/
|
||||
private boolean ignoreBlankCells;
|
||||
/**
|
||||
* Flag to indicate whether auto filtering should be read/copied
|
||||
*/
|
||||
private boolean autoFilterDisabled;
|
||||
/**
|
||||
* Flag to indicate whether a temporary file should be used when
|
||||
* writing out the workbook
|
||||
*/
|
||||
private boolean useTemporaryFileDuringWrite;
|
||||
/**
|
||||
* The directory for used for the temporary file during write. If this
|
||||
* is NULL, the default system directory is used
|
||||
*/
|
||||
private File temporaryFileDuringWriteDirectory;
|
||||
/**
|
||||
* The locale. Normally this is the same as the system locale, but there
|
||||
* may be cases (eg. where you are uploading many spreadsheets from foreign
|
||||
* sources) where you may want to specify the locale on an individual
|
||||
* worksheet basis
|
||||
* The locale may also be specified on the command line using the lang and
|
||||
* country System properties eg. -Djxl.lang=en -Djxl.country=UK for UK
|
||||
* English
|
||||
*/
|
||||
private Locale locale;
|
||||
/**
|
||||
* The locale specific function names for this workbook
|
||||
*/
|
||||
private FunctionNames functionNames;
|
||||
/**
|
||||
* The character encoding used for reading non-unicode strings. This can
|
||||
* be different from the default platform encoding if processing spreadsheets
|
||||
* from abroad. This may also be set using the system property jxl.encoding
|
||||
*/
|
||||
private String encoding;
|
||||
/**
|
||||
* The character set used by the readable spreadsheeet
|
||||
*/
|
||||
private int characterSet;
|
||||
/**
|
||||
* The display language used by Excel (ISO 3166 mnemonic)
|
||||
*/
|
||||
private String excelDisplayLanguage;
|
||||
/**
|
||||
* The regional settings used by Excel (ISO 3166 mnemonic)
|
||||
*/
|
||||
private String excelRegionalSettings;
|
||||
/**
|
||||
* A hash map of function names keyed on locale
|
||||
*/
|
||||
private final HashMap localeFunctionNames;
|
||||
/**
|
||||
* Flag to indicate whether all external data and pivot stuff should
|
||||
* refreshed
|
||||
*/
|
||||
private boolean refreshAll;
|
||||
/**
|
||||
* Flag to indicate whether the file is a template or not (Usually with .xlt
|
||||
* file name extension)
|
||||
*/
|
||||
private boolean template;
|
||||
/**
|
||||
* Flag to indicate whether the file has been written by excel 2000.
|
||||
* <p>
|
||||
* The EXCEL9FILE record indicates the file was written by Excel 2000. It has
|
||||
* no record data field and is C0010000h. Any application other than Excel
|
||||
* 2000 that edits the file should not write out this record.
|
||||
* <p>
|
||||
* However, it seemas that excel 2003 + 2007 still set this flag....
|
||||
*/
|
||||
private boolean excel9file = false;
|
||||
/**
|
||||
* The WINDOWPROTECT record stores an option from the Protect Workbook
|
||||
* dialog box.
|
||||
* <p>
|
||||
* =1 if the workbook windows are protected
|
||||
*/
|
||||
private boolean windowProtected;
|
||||
/**
|
||||
* Write access user name.
|
||||
* When not set (null) then we set it to Java Excel API + Version number
|
||||
*/
|
||||
private String writeAccess;
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab.
|
||||
*/
|
||||
private int hideobj;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public WorkbookSettings() {
|
||||
initialFileSize = DEFAULT_INITIAL_FILE_SIZE;
|
||||
arrayGrowSize = DEFAULT_ARRAY_GROW_SIZE;
|
||||
localeFunctionNames = new HashMap();
|
||||
excelDisplayLanguage = CountryCode.USA.getCode();
|
||||
excelRegionalSettings = CountryCode.UK.getCode();
|
||||
refreshAll = false;
|
||||
template = false;
|
||||
excel9file = false;
|
||||
windowProtected = false;
|
||||
hideobj = HIDEOBJ_SHOW_ALL;
|
||||
|
||||
// Initialize other properties from the system properties
|
||||
try {
|
||||
boolean suppressWarnings = Boolean.getBoolean("jxl.nowarnings");
|
||||
setSuppressWarnings(suppressWarnings);
|
||||
drawingsDisabled = Boolean.getBoolean("jxl.nodrawings");
|
||||
namesDisabled = Boolean.getBoolean("jxl.nonames");
|
||||
gcDisabled = Boolean.getBoolean("jxl.nogc");
|
||||
rationalizationDisabled = Boolean.getBoolean("jxl.norat");
|
||||
mergedCellCheckingDisabled =
|
||||
Boolean.getBoolean("jxl.nomergedcellchecks");
|
||||
formulaReferenceAdjustDisabled =
|
||||
Boolean.getBoolean("jxl.noformulaadjust");
|
||||
propertySetsDisabled = Boolean.getBoolean("jxl.nopropertysets");
|
||||
ignoreBlankCells = Boolean.getBoolean("jxl.ignoreblanks");
|
||||
cellValidationDisabled = Boolean.getBoolean("jxl.nocellvalidation");
|
||||
autoFilterDisabled = !Boolean.getBoolean("jxl.autofilter");
|
||||
// autofilter currently disabled by default
|
||||
useTemporaryFileDuringWrite =
|
||||
Boolean.getBoolean("jxl.usetemporaryfileduringwrite");
|
||||
String tempdir =
|
||||
System.getProperty("jxl.temporaryfileduringwritedirectory");
|
||||
|
||||
if (tempdir != null) {
|
||||
temporaryFileDuringWriteDirectory = new File(tempdir);
|
||||
}
|
||||
|
||||
encoding = System.getProperty("file.encoding");
|
||||
} catch (SecurityException e) {
|
||||
logger.warn("Error accessing system properties.", e);
|
||||
}
|
||||
|
||||
// Initialize the locale to the system locale
|
||||
try {
|
||||
if (System.getProperty("jxl.lang") == null ||
|
||||
System.getProperty("jxl.country") == null) {
|
||||
locale = Locale.getDefault();
|
||||
} else {
|
||||
locale = new Locale(System.getProperty("jxl.lang"),
|
||||
System.getProperty("jxl.country"));
|
||||
}
|
||||
|
||||
if (System.getProperty("jxl.encoding") != null) {
|
||||
encoding = System.getProperty("jxl.encoding");
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
logger.warn("Error accessing system properties.", e);
|
||||
locale = Locale.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the array grow size property
|
||||
*
|
||||
* @return the array grow size
|
||||
*/
|
||||
public int getArrayGrowSize() {
|
||||
return arrayGrowSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of memory by which to increase the amount of
|
||||
* memory allocated to storing the workbook data.
|
||||
* For processeses reading many small workbooks
|
||||
* inside a WAS it might be necessary to reduce the default size
|
||||
* Default value is 1 megabyte
|
||||
*
|
||||
* @param sz the file size in bytes
|
||||
*/
|
||||
public void setArrayGrowSize(int sz) {
|
||||
arrayGrowSize = sz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the initial file size property
|
||||
*
|
||||
* @return the initial file size
|
||||
*/
|
||||
public int getInitialFileSize() {
|
||||
return initialFileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial amount of memory allocated to store the workbook data
|
||||
* when reading a worksheet. For processeses reading many small workbooks
|
||||
* inside a WAS it might be necessary to reduce the default size
|
||||
* Default value is 5 megabytes
|
||||
*
|
||||
* @param sz the file size in bytes
|
||||
*/
|
||||
public void setInitialFileSize(int sz) {
|
||||
initialFileSize = sz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawings disabled flag
|
||||
*
|
||||
* @return TRUE if drawings are disabled, FALSE otherwise
|
||||
*/
|
||||
public boolean getDrawingsDisabled() {
|
||||
return drawingsDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the handling of drawings
|
||||
*
|
||||
* @param b TRUE to disable the names feature, FALSE otherwise
|
||||
*/
|
||||
public void setDrawingsDisabled(boolean b) {
|
||||
drawingsDisabled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the disabling of garbage collection
|
||||
*
|
||||
* @return FALSE if JExcelApi hints for garbage collection, TRUE otherwise
|
||||
*/
|
||||
public boolean getGCDisabled() {
|
||||
return gcDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the garbage collection disabled
|
||||
*
|
||||
* @param disabled TRUE to disable garbage collection, FALSE to enable it
|
||||
*/
|
||||
public void setGCDisabled(boolean disabled) {
|
||||
gcDisabled = disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the disabling of interpretation of named ranges
|
||||
*
|
||||
* @return FALSE if named cells are interpreted, TRUE otherwise
|
||||
*/
|
||||
public boolean getNamesDisabled() {
|
||||
return namesDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the handling of names
|
||||
*
|
||||
* @param b TRUE to disable the names feature, FALSE otherwise
|
||||
*/
|
||||
public void setNamesDisabled(boolean b) {
|
||||
namesDisabled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not to rationalize the cell formats before
|
||||
* writing out the sheet. The default value is true
|
||||
*
|
||||
* @param r the rationalization flag
|
||||
*/
|
||||
public void setRationalization(boolean r) {
|
||||
rationalizationDisabled = !r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to retrieve the rationalization flag
|
||||
*
|
||||
* @return TRUE if rationalization is off, FALSE if rationalization is on
|
||||
*/
|
||||
public boolean getRationalizationDisabled() {
|
||||
return rationalizationDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to retrieve the merged cell checking flag
|
||||
*
|
||||
* @return TRUE if merged cell checking is off, FALSE if it is on
|
||||
*/
|
||||
public boolean getMergedCellCheckingDisabled() {
|
||||
return mergedCellCheckingDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set the merged cell checking
|
||||
*
|
||||
* @param b - TRUE to enable merged cell checking, FALSE otherwise
|
||||
*/
|
||||
public void setMergedCellChecking(boolean b) {
|
||||
mergedCellCheckingDisabled = !b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not to enable any property sets (such as macros)
|
||||
* to be copied along with the workbook
|
||||
* Leaving this feature enabled will result in the JXL process using
|
||||
* more memory
|
||||
*
|
||||
* @param r the property sets flag
|
||||
*/
|
||||
public void setPropertySets(boolean r) {
|
||||
propertySetsDisabled = !r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to retrieve the property sets disabled flag
|
||||
*
|
||||
* @return TRUE if property sets are disabled, FALSE otherwise
|
||||
*/
|
||||
public boolean getPropertySetsDisabled() {
|
||||
return propertySetsDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set the suppress warnings flag. Due to the change
|
||||
* in logging in version 2.4, this will now set the warning
|
||||
* behaviour across the JVM (depending on the type of logger used)
|
||||
*
|
||||
* @param w the flag
|
||||
*/
|
||||
public void setSuppressWarnings(boolean w) {
|
||||
logger.setSuppressWarnings(w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the formula adjust disabled
|
||||
*
|
||||
* @return TRUE if formulas are adjusted following row/column inserts/deletes
|
||||
* FALSE otherwise
|
||||
*/
|
||||
public boolean getFormulaAdjust() {
|
||||
return !formulaReferenceAdjustDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the formula adjust disabled property
|
||||
*
|
||||
* @param b TRUE to adjust formulas, FALSE otherwise
|
||||
*/
|
||||
public void setFormulaAdjust(boolean b) {
|
||||
formulaReferenceAdjustDisabled = !b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale used by JExcelAPI to read the spreadsheet
|
||||
*
|
||||
* @return the locale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale used by JExcelApi to generate the spreadsheet.
|
||||
* Setting this value has no effect on the language or region of
|
||||
* the generated excel file
|
||||
*
|
||||
* @param l the locale
|
||||
*/
|
||||
public void setLocale(Locale l) {
|
||||
locale = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the character encoding
|
||||
*
|
||||
* @return the character encoding for this workbook
|
||||
*/
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the encoding for this workbook
|
||||
*
|
||||
* @param enc the encoding
|
||||
*/
|
||||
public void setEncoding(String enc) {
|
||||
encoding = enc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function names. This is used by the formula parsing package
|
||||
* in order to get the locale specific function names for this particular
|
||||
* workbook
|
||||
*
|
||||
* @return the list of function names
|
||||
*/
|
||||
public FunctionNames getFunctionNames() {
|
||||
if (functionNames == null) {
|
||||
functionNames = (FunctionNames) localeFunctionNames.get(locale);
|
||||
|
||||
// have not previously accessed function names for this locale,
|
||||
// so create a brand new one and add it to the list
|
||||
if (functionNames == null) {
|
||||
functionNames = new FunctionNames(locale);
|
||||
localeFunctionNames.put(locale, functionNames);
|
||||
}
|
||||
}
|
||||
|
||||
return functionNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the character set. This value is only used for reading
|
||||
* and has no effect when writing out the spreadsheet
|
||||
*
|
||||
* @return the character set used by this spreadsheet
|
||||
*/
|
||||
public int getCharacterSet() {
|
||||
return characterSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the character set. This is only used when the spreadsheet is
|
||||
* read, and has no effect when the spreadsheet is written
|
||||
*
|
||||
* @param cs the character set encoding value
|
||||
*/
|
||||
public void setCharacterSet(int cs) {
|
||||
characterSet = cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ignore blanks flag
|
||||
*
|
||||
* @return TRUE if blank cells are being ignored, FALSE otherwise
|
||||
*/
|
||||
public boolean getIgnoreBlanks() {
|
||||
return ignoreBlankCells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ignore blanks flag
|
||||
*
|
||||
* @param ignoreBlanks TRUE to ignore blanks, FALSE to take them into account
|
||||
*/
|
||||
public void setIgnoreBlanks(boolean ignoreBlanks) {
|
||||
ignoreBlankCells = ignoreBlanks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the ignore cell validation
|
||||
*
|
||||
* @return TRUE if cell validation is disabled
|
||||
*/
|
||||
public boolean getCellValidationDisabled() {
|
||||
return cellValidationDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ignore cell validation flag
|
||||
*
|
||||
* @param cv TRUE to disable cell validation, FALSE to enable it
|
||||
*/
|
||||
public void setCellValidationDisabled(boolean cv) {
|
||||
cellValidationDisabled = cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two character ISO 3166 mnemonic used by excel for user
|
||||
* language displayto display
|
||||
*
|
||||
* @return the display language
|
||||
*/
|
||||
public String getExcelDisplayLanguage() {
|
||||
return excelDisplayLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language in which the generated file will display
|
||||
*
|
||||
* @param code the two character ISO 3166 country code
|
||||
*/
|
||||
public void setExcelDisplayLanguage(String code) {
|
||||
excelDisplayLanguage = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two character ISO 3166 mnemonic used by excel for
|
||||
* its regional settings
|
||||
*
|
||||
* @return the regional settings
|
||||
*/
|
||||
public String getExcelRegionalSettings() {
|
||||
return excelRegionalSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the regional settings for the generated excel file
|
||||
*
|
||||
* @param code the two character ISO 3166 country code
|
||||
*/
|
||||
public void setExcelRegionalSettings(String code) {
|
||||
excelRegionalSettings = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the autofilter disabled feature
|
||||
*
|
||||
* @return TRUE if autofilter is disabled, FALSE otherwise
|
||||
*/
|
||||
public boolean getAutoFilterDisabled() {
|
||||
return autoFilterDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the autofilter disabled
|
||||
*
|
||||
* @param disabled
|
||||
*/
|
||||
public void setAutoFilterDisabled(boolean disabled) {
|
||||
autoFilterDisabled = disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the temporary file during write. If this is set, then
|
||||
* when the workbook is written a temporary file will be used to store
|
||||
* the interim binary data, otherwise it will take place in memory. Setting
|
||||
* this flag involves an assessment of the trade-offs between memory usage
|
||||
* and performance
|
||||
*
|
||||
* @return TRUE if a temporary is file is used during writing,
|
||||
* FALSE otherwise
|
||||
*/
|
||||
public boolean getUseTemporaryFileDuringWrite() {
|
||||
return useTemporaryFileDuringWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether a temporary file is used during the generation of
|
||||
* the workbook. If not set, the workbook will take place entirely in
|
||||
* memory. Setting
|
||||
* this flag involves an assessment of the trade-offs between memory usage
|
||||
* and performance
|
||||
*
|
||||
* @return TRUE if a temporary is file is used during writing,
|
||||
* FALSE otherwise
|
||||
*/
|
||||
public void setUseTemporaryFileDuringWrite(boolean temp) {
|
||||
useTemporaryFileDuringWrite = temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in conjunction with the UseTemporaryFileDuringWrite setting to
|
||||
* set the target directory for the temporary files. This value can
|
||||
* be NULL, in which case the normal system default temporary directory
|
||||
* is used instead
|
||||
*
|
||||
* @return the temporary directory used during write, or NULL if it is
|
||||
* not set
|
||||
*/
|
||||
public File getTemporaryFileDuringWriteDirectory() {
|
||||
return temporaryFileDuringWriteDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in conjunction with the UseTemporaryFileDuringWrite setting to
|
||||
* set the target directory for the temporary files. If this is not set,
|
||||
* the system default temporary directory is used.
|
||||
* This has no effect unless the useTemporaryFileDuringWrite setting
|
||||
* is TRUE
|
||||
*
|
||||
* @param dir the directory to which temporary files should be written
|
||||
*/
|
||||
public void setTemporaryFileDuringWriteDirectory(File dir) {
|
||||
temporaryFileDuringWriteDirectory = dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* When true then Refresh All should be done on all external data ranges and
|
||||
* PivotTables when loading the workbook (the default is =0)
|
||||
*
|
||||
* @return the refreshAll value
|
||||
*/
|
||||
public boolean getRefreshAll() {
|
||||
return refreshAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* When true then Refresh All should be done on all external data ranges and
|
||||
* PivotTables when loading the workbook (the default is =0)
|
||||
*
|
||||
* @param refreshAll the refreshAll to set
|
||||
*/
|
||||
public void setRefreshAll(boolean refreshAll) {
|
||||
this.refreshAll = refreshAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workbook Is a Template
|
||||
*
|
||||
* @return the template
|
||||
*/
|
||||
public boolean getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workbook Is a Template
|
||||
*
|
||||
* @param template the template to set
|
||||
*/
|
||||
public void setTemplate(boolean template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this file been written by excel 2000?
|
||||
*
|
||||
* @return the excel9file
|
||||
*/
|
||||
public boolean getExcel9File() {
|
||||
return excel9file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param excel9file the excel9file to set
|
||||
*/
|
||||
public void setExcel9File(boolean excel9file) {
|
||||
this.excel9file = excel9file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the windowprotected
|
||||
*/
|
||||
public boolean getWindowProtected() {
|
||||
return windowProtected;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param windowprotected the windowprotected to set
|
||||
*/
|
||||
public void setWindowProtected(boolean windowprotected) {
|
||||
this.windowProtected = windowProtected;
|
||||
}
|
||||
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab
|
||||
* <p>
|
||||
* Possible values are:
|
||||
* HIDEOBJ_HIDE_ALL, HIDEOBJ_SHOW_ALL and HIDEOBJ_SHOW_PLACEHOLDERS
|
||||
*
|
||||
* @return the hideobj
|
||||
*/
|
||||
public int getHideobj() {
|
||||
return hideobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* The HIDEOBJ record stores options selected in the Options dialog,View tab
|
||||
* <p>
|
||||
* Possible values are:
|
||||
* HIDEOBJ_HIDE_ALL, HIDEOBJ_SHOW_ALL and HIDEOBJ_SHOW_PLACEHOLDERS
|
||||
*
|
||||
* @param hideobj the hideobj to set
|
||||
*/
|
||||
public void setHideobj(int hideobj) {
|
||||
this.hideobj = hideobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the writeAccess
|
||||
*/
|
||||
public String getWriteAccess() {
|
||||
return writeAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param writeAccess the writeAccess to set
|
||||
*/
|
||||
public void setWriteAccess(String writeAccess) {
|
||||
this.writeAccess = writeAccess;
|
||||
}
|
||||
}
|
||||
|
65
datastructures-xslx/src/main/java/jxl/biff/AutoFilter.java
Executable file
65
datastructures-xslx/src/main/java/jxl/biff/AutoFilter.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Information for autofiltering
|
||||
*/
|
||||
public class AutoFilter {
|
||||
private final FilterModeRecord filterMode;
|
||||
private final AutoFilterInfoRecord autoFilterInfo;
|
||||
private AutoFilterRecord autoFilter;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AutoFilter(FilterModeRecord fmr,
|
||||
AutoFilterInfoRecord afir) {
|
||||
filterMode = fmr;
|
||||
autoFilterInfo = afir;
|
||||
}
|
||||
|
||||
public void add(AutoFilterRecord af) {
|
||||
autoFilter = af; // make this into a list sometime
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the data validation
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
if (filterMode != null) {
|
||||
outputFile.write(filterMode);
|
||||
}
|
||||
|
||||
if (autoFilterInfo != null) {
|
||||
outputFile.write(autoFilterInfo);
|
||||
}
|
||||
|
||||
if (autoFilter != null) {
|
||||
outputFile.write(autoFilter);
|
||||
}
|
||||
}
|
||||
}
|
56
datastructures-xslx/src/main/java/jxl/biff/AutoFilterInfoRecord.java
Executable file
56
datastructures-xslx/src/main/java/jxl/biff/AutoFilterInfoRecord.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Range information for conditional formatting
|
||||
*/
|
||||
public class AutoFilterInfoRecord extends WritableRecordData {
|
||||
// The logger
|
||||
private static final Logger logger = Logger.getLogger(AutoFilterInfoRecord.class);
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AutoFilterInfoRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
data = getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
56
datastructures-xslx/src/main/java/jxl/biff/AutoFilterRecord.java
Executable file
56
datastructures-xslx/src/main/java/jxl/biff/AutoFilterRecord.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Range information for conditional formatting
|
||||
*/
|
||||
public class AutoFilterRecord extends WritableRecordData {
|
||||
// The logger
|
||||
private static final Logger logger = Logger.getLogger(AutoFilterRecord.class);
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AutoFilterRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
data = getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
489
datastructures-xslx/src/main/java/jxl/biff/BaseCellFeatures.java
Executable file
489
datastructures-xslx/src/main/java/jxl/biff/BaseCellFeatures.java
Executable file
|
@ -0,0 +1,489 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.util.Collection;
|
||||
import jxl.CellReferenceHelper;
|
||||
import jxl.Range;
|
||||
import jxl.biff.drawing.ComboBox;
|
||||
import jxl.biff.drawing.Comment;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.CellValue;
|
||||
|
||||
/**
|
||||
* Container for any additional cell features
|
||||
*/
|
||||
public class BaseCellFeatures {
|
||||
public static final ValidationCondition BETWEEN =
|
||||
new ValidationCondition(DVParser.BETWEEN);
|
||||
public static final ValidationCondition NOT_BETWEEN =
|
||||
new ValidationCondition(DVParser.NOT_BETWEEN);
|
||||
public static final ValidationCondition EQUAL =
|
||||
new ValidationCondition(DVParser.EQUAL);
|
||||
public static final ValidationCondition NOT_EQUAL =
|
||||
new ValidationCondition(DVParser.NOT_EQUAL);
|
||||
public static final ValidationCondition GREATER_THAN =
|
||||
new ValidationCondition(DVParser.GREATER_THAN);
|
||||
public static final ValidationCondition LESS_THAN =
|
||||
new ValidationCondition(DVParser.LESS_THAN);
|
||||
public static final ValidationCondition GREATER_EQUAL =
|
||||
new ValidationCondition(DVParser.GREATER_EQUAL);
|
||||
public static final ValidationCondition LESS_EQUAL =
|
||||
new ValidationCondition(DVParser.LESS_EQUAL);
|
||||
// Constants
|
||||
private final static double defaultCommentWidth = 3;
|
||||
private final static double defaultCommentHeight = 4;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
public static Logger logger = Logger.getLogger(BaseCellFeatures.class);
|
||||
/**
|
||||
* The comment
|
||||
*/
|
||||
private String comment;
|
||||
/**
|
||||
* The comment width in cells
|
||||
*/
|
||||
private double commentWidth;
|
||||
/**
|
||||
* The comment height in cells
|
||||
*/
|
||||
private double commentHeight;
|
||||
/**
|
||||
* A handle to the drawing object
|
||||
*/
|
||||
private Comment commentDrawing;
|
||||
/**
|
||||
* A handle to the combo box object
|
||||
*/
|
||||
private ComboBox comboBox;
|
||||
/**
|
||||
* The data validation settings
|
||||
*/
|
||||
private DataValiditySettingsRecord validationSettings;
|
||||
/**
|
||||
* The DV Parser used to contain the validation details
|
||||
*/
|
||||
private DVParser dvParser;
|
||||
/**
|
||||
* Indicates whether a drop down is required
|
||||
*/
|
||||
private boolean dropDown;
|
||||
/**
|
||||
* Indicates whether this cell features has data validation
|
||||
*/
|
||||
private boolean dataValidation;
|
||||
/**
|
||||
* The cell to which this is attached, and which may need to be notified
|
||||
*/
|
||||
private CellValue writableCell;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
protected BaseCellFeatures() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param the cell to copy
|
||||
*/
|
||||
public BaseCellFeatures(BaseCellFeatures cf) {
|
||||
// The comment stuff
|
||||
comment = cf.comment;
|
||||
commentWidth = cf.commentWidth;
|
||||
commentHeight = cf.commentHeight;
|
||||
|
||||
// The data validation stuff.
|
||||
dropDown = cf.dropDown;
|
||||
dataValidation = cf.dataValidation;
|
||||
|
||||
validationSettings = cf.validationSettings; // ?
|
||||
|
||||
if (cf.dvParser != null) {
|
||||
dvParser = new DVParser(cf.dvParser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell comment
|
||||
*/
|
||||
protected String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell comment
|
||||
*
|
||||
* @param s the comment
|
||||
*/
|
||||
public void setComment(String s) {
|
||||
setComment(s, defaultCommentWidth, defaultCommentHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the comment width
|
||||
*/
|
||||
public double getCommentWidth() {
|
||||
return commentWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the comment height
|
||||
*/
|
||||
public double getCommentHeight() {
|
||||
return commentHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the cell when the features are added
|
||||
*
|
||||
* @param wc the writable cell
|
||||
*/
|
||||
public final void setWritableCell(CellValue wc) {
|
||||
writableCell = wc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to set the cell comment. Used when reading
|
||||
*/
|
||||
public void setReadComment(String s, double w, double h) {
|
||||
comment = s;
|
||||
commentWidth = w;
|
||||
commentHeight = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to set the data validation. Used when reading
|
||||
*/
|
||||
public void setValidationSettings(DataValiditySettingsRecord dvsr) {
|
||||
Assert.verify(dvsr != null);
|
||||
|
||||
validationSettings = dvsr;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell comment
|
||||
*
|
||||
* @param s the comment
|
||||
* @param height the height of the comment box in cells
|
||||
* @param width the width of the comment box in cells
|
||||
*/
|
||||
public void setComment(String s, double width, double height) {
|
||||
comment = s;
|
||||
commentWidth = width;
|
||||
commentHeight = height;
|
||||
|
||||
if (commentDrawing != null) {
|
||||
commentDrawing.setCommentText(s);
|
||||
commentDrawing.setWidth(width);
|
||||
commentDrawing.setWidth(height);
|
||||
// commentDrawing is set up when trying to modify a copied cell
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the cell comment, if present
|
||||
*/
|
||||
public void removeComment() {
|
||||
// Set the comment string to be empty
|
||||
comment = null;
|
||||
|
||||
// Remove the drawing from the drawing group
|
||||
if (commentDrawing != null) {
|
||||
// do not call DrawingGroup.remove() because comments are not present
|
||||
// on the Workbook DrawingGroup record
|
||||
writableCell.removeComment(commentDrawing);
|
||||
commentDrawing = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function which removes any data validation, if present
|
||||
*/
|
||||
public void removeDataValidation() {
|
||||
if (!dataValidation) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the data validation is shared, then generate a warning
|
||||
DVParser dvp = getDVParser();
|
||||
if (dvp.extendedCellsValidation()) {
|
||||
logger.warn("Cannot remove data validation from " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of the shared reference " +
|
||||
CellReferenceHelper.getCellReference(dvp.getFirstColumn(),
|
||||
dvp.getFirstRow()) +
|
||||
"-" +
|
||||
CellReferenceHelper.getCellReference(dvp.getLastColumn(),
|
||||
dvp.getLastRow()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the validation from the WritableSheet object if present
|
||||
writableCell.removeDataValidation();
|
||||
clearValidationSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function which removes any data validation, including
|
||||
* shared ones, if present. This is called from WritableSheetImpl
|
||||
* in response to a call to removeDataValidation
|
||||
*/
|
||||
public void removeSharedDataValidation() {
|
||||
if (!dataValidation) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the validation from the WritableSheet object if present
|
||||
writableCell.removeDataValidation();
|
||||
clearValidationSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the comment drawing
|
||||
*/
|
||||
public final Comment getCommentDrawing() {
|
||||
return commentDrawing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the comment drawing object
|
||||
*/
|
||||
public final void setCommentDrawing(Comment c) {
|
||||
commentDrawing = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data validation list as a formula. Used only when reading
|
||||
*
|
||||
* @return the validation formula as a list
|
||||
*/
|
||||
public String getDataValidationList() {
|
||||
if (validationSettings == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return validationSettings.getValidationFormula();
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of items to validate for this cell. For each object in the
|
||||
* collection, the toString() method will be called and the data entered
|
||||
* will be validated against that string
|
||||
*
|
||||
* @param c the list of valid values
|
||||
*/
|
||||
public void setDataValidationList(Collection c) {
|
||||
if (dataValidation && getDVParser().extendedCellsValidation()) {
|
||||
logger.warn("Cannot set data validation on " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of a shared data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = new DVParser(c);
|
||||
dropDown = true;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of items to validate for this cell in the form of a cell range.
|
||||
*
|
||||
* @param c the list of valid values
|
||||
*/
|
||||
public void setDataValidationRange(int col1, int r1, int col2, int r2) {
|
||||
if (dataValidation && getDVParser().extendedCellsValidation()) {
|
||||
logger.warn("Cannot set data validation on " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of a shared data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = new DVParser(col1, r1, col2, r2);
|
||||
dropDown = true;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data validation based upon a named range
|
||||
*/
|
||||
public void setDataValidationRange(String namedRange) {
|
||||
if (dataValidation && getDVParser().extendedCellsValidation()) {
|
||||
logger.warn("Cannot set data validation on " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of a shared data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = new DVParser(namedRange);
|
||||
dropDown = true;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data validation based upon a numerical condition
|
||||
*/
|
||||
public void setNumberValidation(double val, ValidationCondition c) {
|
||||
if (dataValidation && getDVParser().extendedCellsValidation()) {
|
||||
logger.warn("Cannot set data validation on " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of a shared data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = new DVParser(val, Double.NaN, c.getCondition());
|
||||
dropDown = false;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
public void setNumberValidation(double val1, double val2,
|
||||
ValidationCondition c) {
|
||||
if (dataValidation && getDVParser().extendedCellsValidation()) {
|
||||
logger.warn("Cannot set data validation on " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" as it is part of a shared data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = new DVParser(val1, val2, c.getCondition());
|
||||
dropDown = false;
|
||||
dataValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the data validation
|
||||
*
|
||||
* @return TRUE if this has a data validation associated with it,
|
||||
* FALSE otherwise
|
||||
*/
|
||||
public boolean hasDataValidation() {
|
||||
return dataValidation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out any existing validation settings
|
||||
*/
|
||||
private void clearValidationSettings() {
|
||||
validationSettings = null;
|
||||
dvParser = null;
|
||||
dropDown = false;
|
||||
comboBox = null;
|
||||
dataValidation = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for whether a drop down is required
|
||||
*
|
||||
* @return TRUE if this requires a drop down, FALSE otherwise
|
||||
*/
|
||||
public boolean hasDropDown() {
|
||||
return dropDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the combo box drawing object for list validations
|
||||
*
|
||||
* @param cb the combo box
|
||||
*/
|
||||
public void setComboBox(ComboBox cb) {
|
||||
comboBox = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dv parser
|
||||
*/
|
||||
public DVParser getDVParser() {
|
||||
// straightforward - this was created as a writable cell
|
||||
if (dvParser != null) {
|
||||
return dvParser;
|
||||
}
|
||||
|
||||
// this was copied from a readable cell, and then copied again
|
||||
if (validationSettings != null) {
|
||||
dvParser = new DVParser(validationSettings.getDVParser());
|
||||
return dvParser;
|
||||
}
|
||||
|
||||
return null; // keep the compiler happy
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the same data validation logic as the specified cell features
|
||||
*
|
||||
* @param cf the data validation to reuse
|
||||
*/
|
||||
public void shareDataValidation(BaseCellFeatures source) {
|
||||
if (dataValidation) {
|
||||
logger.warn("Attempting to share a data validation on cell " +
|
||||
CellReferenceHelper.getCellReference(writableCell) +
|
||||
" which already has a data validation");
|
||||
return;
|
||||
}
|
||||
clearValidationSettings();
|
||||
dvParser = source.getDVParser();
|
||||
validationSettings = null;
|
||||
dataValidation = true;
|
||||
dropDown = source.dropDown;
|
||||
comboBox = source.comboBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the range of cells to which the data validation applies. If the
|
||||
* validation applies to just this cell, this will be reflected in the
|
||||
* returned range
|
||||
*
|
||||
* @return the range to which the same validation extends, or NULL if this
|
||||
* cell doesn't have a validation
|
||||
*/
|
||||
public Range getSharedDataValidationRange() {
|
||||
if (!dataValidation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DVParser dvp = getDVParser();
|
||||
|
||||
return new SheetRangeImpl(writableCell.getSheet(),
|
||||
dvp.getFirstColumn(),
|
||||
dvp.getFirstRow(),
|
||||
dvp.getLastColumn(),
|
||||
dvp.getLastRow());
|
||||
}
|
||||
|
||||
// Validation conditions
|
||||
protected static class ValidationCondition {
|
||||
private static ValidationCondition[] types = new ValidationCondition[0];
|
||||
private final DVParser.Condition condition;
|
||||
|
||||
ValidationCondition(DVParser.Condition c) {
|
||||
condition = c;
|
||||
ValidationCondition[] oldtypes = types;
|
||||
types = new ValidationCondition[oldtypes.length + 1];
|
||||
System.arraycopy(oldtypes, 0, types, 0, oldtypes.length);
|
||||
types[oldtypes.length] = this;
|
||||
}
|
||||
|
||||
public DVParser.Condition getCondition() {
|
||||
return condition;
|
||||
}
|
||||
}
|
||||
}
|
349
datastructures-xslx/src/main/java/jxl/biff/BaseCompoundFile.java
Executable file
349
datastructures-xslx/src/main/java/jxl/biff/BaseCompoundFile.java
Executable file
|
@ -0,0 +1,349 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Contains the common data for a compound file
|
||||
*/
|
||||
public abstract class BaseCompoundFile {
|
||||
/**
|
||||
* The standard property sets
|
||||
*/
|
||||
public final static String ROOT_ENTRY_NAME = "Root Entry";
|
||||
public final static String WORKBOOK_NAME = "Workbook";
|
||||
public final static String SUMMARY_INFORMATION_NAME =
|
||||
"\u0005SummaryInformation";
|
||||
public final static String DOCUMENT_SUMMARY_INFORMATION_NAME =
|
||||
"\u0005DocumentSummaryInformation";
|
||||
public final static String COMP_OBJ_NAME =
|
||||
"\u0001CompObj";
|
||||
public final static String[] STANDARD_PROPERTY_SETS =
|
||||
new String[]{ROOT_ENTRY_NAME, WORKBOOK_NAME,
|
||||
SUMMARY_INFORMATION_NAME,
|
||||
DOCUMENT_SUMMARY_INFORMATION_NAME};
|
||||
/**
|
||||
* Property storage types
|
||||
*/
|
||||
public final static int NONE_PS_TYPE = 0;
|
||||
public final static int DIRECTORY_PS_TYPE = 1;
|
||||
public final static int FILE_PS_TYPE = 2;
|
||||
public final static int ROOT_ENTRY_PS_TYPE = 5;
|
||||
/**
|
||||
* The identifier at the beginning of every OLE file
|
||||
*/
|
||||
protected static final byte[] IDENTIFIER = new byte[]
|
||||
{(byte) 0xd0,
|
||||
(byte) 0xcf,
|
||||
(byte) 0x11,
|
||||
(byte) 0xe0,
|
||||
(byte) 0xa1,
|
||||
(byte) 0xb1,
|
||||
(byte) 0x1a,
|
||||
(byte) 0xe1};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c;
|
||||
|
||||
// property storage offsets
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int NUM_SMALL_BLOCK_DEPOT_BLOCKS_POS = 0x40;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int ROOT_START_BLOCK_POS = 0x30;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int BIG_BLOCK_SIZE = 0x200;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int SMALL_BLOCK_SIZE = 0x40;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int EXTENSION_BLOCK_POS = 0x44;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int NUM_EXTENSION_BLOCK_POS = 0x48;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int PROPERTY_STORAGE_BLOCK_SIZE = 0x80;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static final int SMALL_BLOCK_THRESHOLD = 0x1000;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int SIZE_OF_NAME_POS = 0x40;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int TYPE_POS = 0x42;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int COLOUR_POS = 0x43;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int PREVIOUS_POS = 0x44;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int NEXT_POS = 0x48;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int CHILD_POS = 0x4c;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int START_BLOCK_POS = 0x74;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int SIZE_POS = 0x78;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(BaseCompoundFile.class);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
protected BaseCompoundFile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class to represent the property storage sets. Access is public
|
||||
* to allow access from the PropertySetsReader demo utility
|
||||
*/
|
||||
public class PropertyStorage {
|
||||
/**
|
||||
* The name of this property set
|
||||
*/
|
||||
public String name;
|
||||
/**
|
||||
* The type of the property set
|
||||
*/
|
||||
public int type;
|
||||
/**
|
||||
* The colour of the property set
|
||||
*/
|
||||
public int colour;
|
||||
/**
|
||||
* The block number in the stream which this property sets starts at
|
||||
*/
|
||||
public int startBlock;
|
||||
/**
|
||||
* The size, in bytes, of this property set
|
||||
*/
|
||||
public int size;
|
||||
/**
|
||||
* The previous property set
|
||||
*/
|
||||
public int previous;
|
||||
/**
|
||||
* The next property set
|
||||
*/
|
||||
public int next;
|
||||
/**
|
||||
* The child for this property set
|
||||
*/
|
||||
public int child;
|
||||
|
||||
/**
|
||||
* The data that created this set
|
||||
*/
|
||||
public byte[] data;
|
||||
|
||||
/**
|
||||
* Constructs a property set
|
||||
*
|
||||
* @param d the bytes
|
||||
*/
|
||||
public PropertyStorage(byte[] d) {
|
||||
data = d;
|
||||
int nameSize = IntegerHelper.getInt(data[SIZE_OF_NAME_POS],
|
||||
data[SIZE_OF_NAME_POS + 1]);
|
||||
|
||||
if (nameSize > SIZE_OF_NAME_POS) {
|
||||
logger.warn("property set name exceeds max length - truncating");
|
||||
nameSize = SIZE_OF_NAME_POS;
|
||||
|
||||
}
|
||||
type = data[TYPE_POS];
|
||||
colour = data[COLOUR_POS];
|
||||
|
||||
startBlock = IntegerHelper.getInt
|
||||
(data[START_BLOCK_POS],
|
||||
data[START_BLOCK_POS + 1],
|
||||
data[START_BLOCK_POS + 2],
|
||||
data[START_BLOCK_POS + 3]);
|
||||
size = IntegerHelper.getInt
|
||||
(data[SIZE_POS],
|
||||
data[SIZE_POS + 1],
|
||||
data[SIZE_POS + 2],
|
||||
data[SIZE_POS + 3]);
|
||||
previous = IntegerHelper.getInt
|
||||
(data[PREVIOUS_POS],
|
||||
data[PREVIOUS_POS + 1],
|
||||
data[PREVIOUS_POS + 2],
|
||||
data[PREVIOUS_POS + 3]);
|
||||
next = IntegerHelper.getInt
|
||||
(data[NEXT_POS],
|
||||
data[NEXT_POS + 1],
|
||||
data[NEXT_POS + 2],
|
||||
data[NEXT_POS + 3]);
|
||||
child = IntegerHelper.getInt
|
||||
(data[CHILD_POS],
|
||||
data[CHILD_POS + 1],
|
||||
data[CHILD_POS + 2],
|
||||
data[CHILD_POS + 3]);
|
||||
|
||||
int chars = 0;
|
||||
if (nameSize > 2) {
|
||||
chars = (nameSize - 1) / 2;
|
||||
}
|
||||
|
||||
StringBuffer n = new StringBuffer();
|
||||
for (int i = 0; i < chars; i++) {
|
||||
n.append((char) data[i * 2]);
|
||||
}
|
||||
|
||||
name = n.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty property set. Used when writing the file
|
||||
*
|
||||
* @param name the property storage name
|
||||
*/
|
||||
public PropertyStorage(String name) {
|
||||
data = new byte[PROPERTY_STORAGE_BLOCK_SIZE];
|
||||
|
||||
Assert.verify(name.length() < 32);
|
||||
|
||||
IntegerHelper.getTwoBytes((name.length() + 1) * 2,
|
||||
data,
|
||||
SIZE_OF_NAME_POS);
|
||||
// add one to the name length to allow for the null character at
|
||||
// the end
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
data[i * 2] = (byte) name.charAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type
|
||||
*
|
||||
* @param t the type
|
||||
*/
|
||||
public void setType(int t) {
|
||||
type = t;
|
||||
data[TYPE_POS] = (byte) t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of the start block
|
||||
*
|
||||
* @param sb the number of the start block
|
||||
*/
|
||||
public void setStartBlock(int sb) {
|
||||
startBlock = sb;
|
||||
IntegerHelper.getFourBytes(sb, data, START_BLOCK_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the file
|
||||
*
|
||||
* @param s the size
|
||||
*/
|
||||
public void setSize(int s) {
|
||||
size = s;
|
||||
IntegerHelper.getFourBytes(s, data, SIZE_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the previous block
|
||||
*
|
||||
* @param prev the previous block
|
||||
*/
|
||||
public void setPrevious(int prev) {
|
||||
previous = prev;
|
||||
IntegerHelper.getFourBytes(prev, data, PREVIOUS_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the next block
|
||||
*
|
||||
* @param nxt the next block
|
||||
*/
|
||||
public void setNext(int nxt) {
|
||||
next = nxt;
|
||||
IntegerHelper.getFourBytes(next, data, NEXT_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the child
|
||||
*
|
||||
* @param dir the child
|
||||
*/
|
||||
public void setChild(int dir) {
|
||||
child = dir;
|
||||
IntegerHelper.getFourBytes(child, data, CHILD_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the colour
|
||||
*
|
||||
* @param col colour
|
||||
*/
|
||||
public void setColour(int col) {
|
||||
colour = col == 0 ? 0 : 1;
|
||||
data[COLOUR_POS] = (byte) colour;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
166
datastructures-xslx/src/main/java/jxl/biff/BuiltInFormat.java
Executable file
166
datastructures-xslx/src/main/java/jxl/biff/BuiltInFormat.java
Executable file
|
@ -0,0 +1,166 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.format.Format;
|
||||
|
||||
/**
|
||||
* The excel string for the various built in formats. Used to present
|
||||
* the cell format information back to the user
|
||||
* <p>
|
||||
* The difference between this class and the various format object contained
|
||||
* in the jxl.write package is that this object contains the Excel strings,
|
||||
* not their java equivalents
|
||||
*/
|
||||
final class BuiltInFormat implements Format, DisplayFormat {
|
||||
/**
|
||||
* The list of built in formats
|
||||
*/
|
||||
public static BuiltInFormat[] builtIns = new BuiltInFormat[0x32];
|
||||
|
||||
// Populate the built ins
|
||||
static {
|
||||
builtIns[0x0] = new BuiltInFormat("", 0);
|
||||
builtIns[0x1] = new BuiltInFormat("0", 1);
|
||||
builtIns[0x2] = new BuiltInFormat("0.00", 2);
|
||||
builtIns[0x3] = new BuiltInFormat("#,##0", 3);
|
||||
builtIns[0x4] = new BuiltInFormat("#,##0.00", 4);
|
||||
builtIns[0x5] = new BuiltInFormat("($#,##0_);($#,##0)", 5);
|
||||
builtIns[0x6] = new BuiltInFormat("($#,##0_);[Red]($#,##0)", 6);
|
||||
builtIns[0x7] = new BuiltInFormat("($#,##0_);[Red]($#,##0)", 7);
|
||||
builtIns[0x8] = new BuiltInFormat("($#,##0.00_);[Red]($#,##0.00)", 8);
|
||||
builtIns[0x9] = new BuiltInFormat("0%", 9);
|
||||
builtIns[0xa] = new BuiltInFormat("0.00%", 10);
|
||||
builtIns[0xb] = new BuiltInFormat("0.00E+00", 11);
|
||||
builtIns[0xc] = new BuiltInFormat("# ?/?", 12);
|
||||
builtIns[0xd] = new BuiltInFormat("# ??/??", 13);
|
||||
builtIns[0xe] = new BuiltInFormat("dd/mm/yyyy", 14);
|
||||
builtIns[0xf] = new BuiltInFormat("d-mmm-yy", 15);
|
||||
builtIns[0x10] = new BuiltInFormat("d-mmm", 16);
|
||||
builtIns[0x11] = new BuiltInFormat("mmm-yy", 17);
|
||||
builtIns[0x12] = new BuiltInFormat("h:mm AM/PM", 18);
|
||||
builtIns[0x13] = new BuiltInFormat("h:mm:ss AM/PM", 19);
|
||||
builtIns[0x14] = new BuiltInFormat("h:mm", 20);
|
||||
builtIns[0x15] = new BuiltInFormat("h:mm:ss", 21);
|
||||
builtIns[0x16] = new BuiltInFormat("m/d/yy h:mm", 22);
|
||||
builtIns[0x25] = new BuiltInFormat("(#,##0_);(#,##0)", 0x25);
|
||||
builtIns[0x26] = new BuiltInFormat("(#,##0_);[Red](#,##0)", 0x26);
|
||||
builtIns[0x27] = new BuiltInFormat("(#,##0.00_);(#,##0.00)", 0x27);
|
||||
builtIns[0x28] = new BuiltInFormat("(#,##0.00_);[Red](#,##0.00)", 0x28);
|
||||
builtIns[0x29] = new BuiltInFormat
|
||||
("_(*#,##0_);_(*(#,##0);_(*\"-\"_);(@_)", 0x29);
|
||||
builtIns[0x2a] = new BuiltInFormat
|
||||
("_($*#,##0_);_($*(#,##0);_($*\"-\"_);(@_)", 0x2a);
|
||||
builtIns[0x2b] = new BuiltInFormat
|
||||
("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);(@_)", 0x2b);
|
||||
builtIns[0x2c] = new BuiltInFormat
|
||||
("_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);(@_)", 0x2c);
|
||||
builtIns[0x2d] = new BuiltInFormat("mm:ss", 0x2d);
|
||||
builtIns[0x2e] = new BuiltInFormat("[h]mm:ss", 0x2e);
|
||||
builtIns[0x2f] = new BuiltInFormat("mm:ss.0", 0x2f);
|
||||
builtIns[0x30] = new BuiltInFormat("##0.0E+0", 0x30);
|
||||
builtIns[0x31] = new BuiltInFormat("@", 0x31);
|
||||
}
|
||||
|
||||
/**
|
||||
* The excel format string
|
||||
*/
|
||||
private final String formatString;
|
||||
/**
|
||||
* The index
|
||||
*/
|
||||
private final int formatIndex;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param s the format string
|
||||
* @param i the format index
|
||||
*/
|
||||
private BuiltInFormat(String s, int i) {
|
||||
formatIndex = i;
|
||||
formatString = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesses the excel format string which is applied to the cell
|
||||
* Note that this is the string that excel uses, and not the java
|
||||
* equivalent
|
||||
*
|
||||
* @return the cell format string
|
||||
*/
|
||||
public String getFormatString() {
|
||||
return formatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the index style of this format
|
||||
*
|
||||
* @return the index for this format
|
||||
*/
|
||||
public int getFormatIndex() {
|
||||
return formatIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to see whether this format has been initialized
|
||||
*
|
||||
* @return TRUE if initialized, FALSE otherwise
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this format with the specified index number
|
||||
*
|
||||
* @param pos the position of this format record in the workbook
|
||||
*/
|
||||
public void initialize(int pos) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to determine whether or not this format is built in
|
||||
*
|
||||
* @return TRUE if this format is a built in format, FALSE otherwise
|
||||
*/
|
||||
public boolean isBuiltIn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals method
|
||||
*
|
||||
* @return TRUE if the two built in formats are equal, FALSE otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof BuiltInFormat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BuiltInFormat bif = (BuiltInFormat) o;
|
||||
return (formatIndex == bif.formatIndex);
|
||||
}
|
||||
}
|
||||
|
110
datastructures-xslx/src/main/java/jxl/biff/BuiltInName.java
Executable file
110
datastructures-xslx/src/main/java/jxl/biff/BuiltInName.java
Executable file
|
@ -0,0 +1,110 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Enumeration of built in names
|
||||
*/
|
||||
public class BuiltInName {
|
||||
// The list of built in names
|
||||
public static final BuiltInName CONSOLIDATE_AREA =
|
||||
new BuiltInName("Consolidate_Area", 0x0);
|
||||
public static final BuiltInName AUTO_OPEN =
|
||||
new BuiltInName("Auto_Open", 0x1);
|
||||
public static final BuiltInName AUTO_CLOSE =
|
||||
new BuiltInName("Auto_Open", 0x2);
|
||||
public static final BuiltInName EXTRACT =
|
||||
new BuiltInName("Extract", 0x3);
|
||||
public static final BuiltInName DATABASE =
|
||||
new BuiltInName("Database", 0x4);
|
||||
public static final BuiltInName CRITERIA =
|
||||
new BuiltInName("Criteria", 0x5);
|
||||
public static final BuiltInName PRINT_AREA =
|
||||
new BuiltInName("Print_Area", 0x6);
|
||||
public static final BuiltInName PRINT_TITLES =
|
||||
new BuiltInName("Print_Titles", 0x7);
|
||||
public static final BuiltInName RECORDER =
|
||||
new BuiltInName("Recorder", 0x8);
|
||||
public static final BuiltInName DATA_FORM =
|
||||
new BuiltInName("Data_Form", 0x9);
|
||||
public static final BuiltInName AUTO_ACTIVATE =
|
||||
new BuiltInName("Auto_Activate", 0xa);
|
||||
public static final BuiltInName AUTO_DEACTIVATE =
|
||||
new BuiltInName("Auto_Deactivate", 0xb);
|
||||
public static final BuiltInName SHEET_TITLE =
|
||||
new BuiltInName("Sheet_Title", 0xb);
|
||||
public static final BuiltInName FILTER_DATABASE =
|
||||
new BuiltInName("_FilterDatabase", 0xd);
|
||||
/**
|
||||
* The list of name
|
||||
*/
|
||||
private static BuiltInName[] builtInNames = new BuiltInName[0];
|
||||
/**
|
||||
* The name
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* The value
|
||||
*/
|
||||
private final int value;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private BuiltInName(String n, int v) {
|
||||
name = n;
|
||||
value = v;
|
||||
|
||||
BuiltInName[] oldnames = builtInNames;
|
||||
builtInNames = new BuiltInName[oldnames.length + 1];
|
||||
System.arraycopy(oldnames, 0, builtInNames, 0, oldnames.length);
|
||||
builtInNames[oldnames.length] = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the built in name for the value
|
||||
*/
|
||||
public static BuiltInName getBuiltInName(int val) {
|
||||
BuiltInName ret = FILTER_DATABASE;
|
||||
for (int i = 0; i < builtInNames.length; i++) {
|
||||
if (builtInNames[i].getValue() == val) {
|
||||
ret = builtInNames[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the name
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the value
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
70
datastructures-xslx/src/main/java/jxl/biff/BuiltInStyle.java
Executable file
70
datastructures-xslx/src/main/java/jxl/biff/BuiltInStyle.java
Executable file
|
@ -0,0 +1,70 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Represents a built in, rather than a user defined, style.
|
||||
* This class is used by the FormattingRecords class when writing out the hard*
|
||||
* coded styles
|
||||
*/
|
||||
class BuiltInStyle extends WritableRecordData {
|
||||
/**
|
||||
* The XF index of this style
|
||||
*/
|
||||
private final int xfIndex;
|
||||
/**
|
||||
* The reference number of this style
|
||||
*/
|
||||
private final int styleNumber;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param xfind the xf index of this style
|
||||
* @param sn the style number of this style
|
||||
*/
|
||||
public BuiltInStyle(int xfind, int sn) {
|
||||
super(Type.STYLE);
|
||||
|
||||
xfIndex = xfind;
|
||||
styleNumber = sn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method implementation to get the raw byte data ready to write out
|
||||
*
|
||||
* @return The byte data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
byte[] data = new byte[4];
|
||||
|
||||
IntegerHelper.getTwoBytes(xfIndex, data, 0);
|
||||
|
||||
// Set the built in bit
|
||||
data[1] |= 0x80;
|
||||
|
||||
data[2] = (byte) styleNumber;
|
||||
|
||||
// Set the outline level
|
||||
data[3] = (byte) 0xff;
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
106
datastructures-xslx/src/main/java/jxl/biff/ByteArray.java
Executable file
106
datastructures-xslx/src/main/java/jxl/biff/ByteArray.java
Executable file
|
@ -0,0 +1,106 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* A growable array of bytes
|
||||
*/
|
||||
public class ByteArray {
|
||||
// The default grow size
|
||||
private final static int defaultGrowSize = 1024;
|
||||
/**
|
||||
* The array grow size
|
||||
*/
|
||||
private final int growSize;
|
||||
/**
|
||||
* The current array
|
||||
*/
|
||||
private byte[] bytes;
|
||||
/**
|
||||
* The current position
|
||||
*/
|
||||
private int pos;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ByteArray() {
|
||||
this(defaultGrowSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param gs
|
||||
*/
|
||||
public ByteArray(int gs) {
|
||||
growSize = gs;
|
||||
bytes = new byte[defaultGrowSize];
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a byte onto the array
|
||||
*
|
||||
* @param b the byte
|
||||
*/
|
||||
public void add(byte b) {
|
||||
checkSize(1);
|
||||
bytes[pos] = b;
|
||||
pos++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array of bytes onto the array
|
||||
*
|
||||
* @param b the array of bytes
|
||||
*/
|
||||
public void add(byte[] b) {
|
||||
checkSize(b.length);
|
||||
System.arraycopy(b, 0, bytes, pos, b.length);
|
||||
pos += b.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete array
|
||||
*
|
||||
* @return the array
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
byte[] returnArray = new byte[pos];
|
||||
System.arraycopy(bytes, 0, returnArray, 0, pos);
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is sufficient space left on the array. If not,
|
||||
* then it grows the array
|
||||
*
|
||||
* @param sz the amount of bytes to add
|
||||
*/
|
||||
private void checkSize(int sz) {
|
||||
while (pos + sz >= bytes.length) {
|
||||
// Grow the array
|
||||
byte[] newArray = new byte[bytes.length + growSize];
|
||||
System.arraycopy(bytes, 0, newArray, 0, pos);
|
||||
bytes = newArray;
|
||||
}
|
||||
}
|
||||
}
|
33
datastructures-xslx/src/main/java/jxl/biff/ByteData.java
Executable file
33
datastructures-xslx/src/main/java/jxl/biff/ByteData.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Interface which provides a method for transferring chunks of binary
|
||||
* data from one Excel file (read in) to another (written out)
|
||||
*/
|
||||
public interface ByteData {
|
||||
/**
|
||||
* Used when writing out records
|
||||
*
|
||||
* @return the full data to be included in the final compound file
|
||||
*/
|
||||
byte[] getBytes();
|
||||
}
|
196
datastructures-xslx/src/main/java/jxl/biff/CellFinder.java
Executable file
196
datastructures-xslx/src/main/java/jxl/biff/CellFinder.java
Executable file
|
@ -0,0 +1,196 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import jxl.Cell;
|
||||
import jxl.CellType;
|
||||
import jxl.LabelCell;
|
||||
import jxl.Sheet;
|
||||
|
||||
/**
|
||||
* Refactorisation to provide more sophisticated find cell by contents
|
||||
* functionality
|
||||
*/
|
||||
public class CellFinder {
|
||||
private final Sheet sheet;
|
||||
|
||||
public CellFinder(Sheet s) {
|
||||
sheet = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the string passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @param firstCol the first column within the range
|
||||
* @param firstRow the first row of the range
|
||||
* @param lastCol the last column within the range
|
||||
* @param lastRow the last row within the range
|
||||
* @param reverse indicates whether to perform a reverse search or not
|
||||
* @return the Cell whose contents match the parameter, null if not found
|
||||
*/
|
||||
public Cell findCell(String contents,
|
||||
int firstCol,
|
||||
int firstRow,
|
||||
int lastCol,
|
||||
int lastRow,
|
||||
boolean reverse) {
|
||||
Cell cell = null;
|
||||
boolean found = false;
|
||||
|
||||
int numCols = lastCol - firstCol;
|
||||
int numRows = lastRow - firstRow;
|
||||
|
||||
int row1 = reverse ? lastRow : firstRow;
|
||||
int row2 = reverse ? firstRow : lastRow;
|
||||
int col1 = reverse ? lastCol : firstCol;
|
||||
int col2 = reverse ? firstCol : lastCol;
|
||||
int inc = reverse ? -1 : 1;
|
||||
|
||||
for (int i = 0; i <= numCols && found == false; i++) {
|
||||
for (int j = 0; j <= numRows && found == false; j++) {
|
||||
int curCol = col1 + i * inc;
|
||||
int curRow = row1 + j * inc;
|
||||
if (curCol < sheet.getColumns() && curRow < sheet.getRows()) {
|
||||
Cell c = sheet.getCell(curCol, curRow);
|
||||
if (c.getType() != CellType.EMPTY) {
|
||||
if (c.getContents().equals(contents)) {
|
||||
cell = c;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a cell within a given range of cells
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @return the Cell whose contents match the parameter, null if not found
|
||||
*/
|
||||
public Cell findCell(String contents) {
|
||||
Cell cell = null;
|
||||
boolean found = false;
|
||||
|
||||
for (int i = 0; i < sheet.getRows() && found == false; i++) {
|
||||
Cell[] row = sheet.getRow(i);
|
||||
for (int j = 0; j < row.length && found == false; j++) {
|
||||
if (row[j].getContents().equals(contents)) {
|
||||
cell = row[j];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the regular expressionstring passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform
|
||||
*
|
||||
* @param pattern the regular expression string to match
|
||||
* @param firstCol the first column within the range
|
||||
* @param firstRow the first row of the range
|
||||
* @param lastCol the last column within the range
|
||||
* @param lastRow the last row within the range
|
||||
* @param reverse indicates whether to perform a reverse search or not
|
||||
* @return the Cell whose contents match the parameter, null if not found
|
||||
*/
|
||||
public Cell findCell(Pattern pattern,
|
||||
int firstCol,
|
||||
int firstRow,
|
||||
int lastCol,
|
||||
int lastRow,
|
||||
boolean reverse) {
|
||||
Cell cell = null;
|
||||
boolean found = false;
|
||||
|
||||
int numCols = lastCol - firstCol;
|
||||
int numRows = lastRow - firstRow;
|
||||
|
||||
int row1 = reverse ? lastRow : firstRow;
|
||||
int row2 = reverse ? firstRow : lastRow;
|
||||
int col1 = reverse ? lastCol : firstCol;
|
||||
int col2 = reverse ? firstCol : lastCol;
|
||||
int inc = reverse ? -1 : 1;
|
||||
|
||||
for (int i = 0; i <= numCols && found == false; i++) {
|
||||
for (int j = 0; j <= numRows && found == false; j++) {
|
||||
int curCol = col1 + i * inc;
|
||||
int curRow = row1 + j * inc;
|
||||
if (curCol < sheet.getColumns() && curRow < sheet.getRows()) {
|
||||
Cell c = sheet.getCell(curCol, curRow);
|
||||
if (c.getType() != CellType.EMPTY) {
|
||||
Matcher m = pattern.matcher(c.getContents());
|
||||
if (m.matches()) {
|
||||
cell = c;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell whose contents match the string passed in.
|
||||
* If no match is found, then null is returned. The search is performed
|
||||
* on a row by row basis, so the lower the row number, the more
|
||||
* efficiently the algorithm will perform. This method differs
|
||||
* from the findCell methods in that only cells with labels are
|
||||
* queried - all numerical cells are ignored. This should therefore
|
||||
* improve performance.
|
||||
*
|
||||
* @param contents the string to match
|
||||
* @return the Cell whose contents match the paramter, null if not found
|
||||
*/
|
||||
public LabelCell findLabelCell(String contents) {
|
||||
LabelCell cell = null;
|
||||
boolean found = false;
|
||||
|
||||
for (int i = 0; i < sheet.getRows() && !found; i++) {
|
||||
Cell[] row = sheet.getRow(i);
|
||||
for (int j = 0; j < row.length && !found; j++) {
|
||||
if ((row[j].getType() == CellType.LABEL ||
|
||||
row[j].getType() == CellType.STRING_FORMULA) &&
|
||||
row[j].getContents().equals(contents)) {
|
||||
cell = (LabelCell) row[j];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
313
datastructures-xslx/src/main/java/jxl/biff/CellReferenceHelper.java
Executable file
313
datastructures-xslx/src/main/java/jxl/biff/CellReferenceHelper.java
Executable file
|
@ -0,0 +1,313 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.biff.formula.ExternalSheet;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* A helper to transform between excel cell references and
|
||||
* sheet:column:row notation
|
||||
* Because this function will be called when generating a string
|
||||
* representation of a formula, the cell reference will merely
|
||||
* be appened to the string buffer instead of returning a full
|
||||
* blooded string, for performance reasons
|
||||
*/
|
||||
public final class CellReferenceHelper {
|
||||
/**
|
||||
* The character which indicates whether a reference is fixed
|
||||
*/
|
||||
private static final char fixedInd = '$';
|
||||
/**
|
||||
* The character which indicates the sheet name terminator
|
||||
*/
|
||||
private static final char sheetInd = '!';
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(CellReferenceHelper.class);
|
||||
|
||||
/**
|
||||
* Constructor to prevent instantiation
|
||||
*/
|
||||
private CellReferenceHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell reference
|
||||
*
|
||||
* @param column
|
||||
* @param row
|
||||
* @param buf
|
||||
*/
|
||||
public static void getCellReference(int column, int row, StringBuffer buf) {
|
||||
// Put the column letter into the buffer
|
||||
getColumnReference(column, buf);
|
||||
|
||||
// Add the row into the buffer
|
||||
buf.append(row + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded method which prepends $ for absolute reference
|
||||
*
|
||||
* @param column
|
||||
* @param colabs TRUE if the column reference is absolute
|
||||
* @param row
|
||||
* @param rowabs TRUE if the row reference is absolute
|
||||
* @param buf
|
||||
*/
|
||||
public static void getCellReference(int column, boolean colabs,
|
||||
int row, boolean rowabs,
|
||||
StringBuffer buf) {
|
||||
if (colabs) {
|
||||
buf.append(fixedInd);
|
||||
}
|
||||
|
||||
// Put the column letter into the buffer
|
||||
getColumnReference(column, buf);
|
||||
|
||||
if (rowabs) {
|
||||
buf.append(fixedInd);
|
||||
}
|
||||
|
||||
// Add the row into the buffer
|
||||
buf.append(row + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column letter corresponding to the 0-based column number
|
||||
*
|
||||
* @param column the column number
|
||||
* @return the letter for that column number
|
||||
*/
|
||||
public static String getColumnReference(int column) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getColumnReference(column, buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column letter corresponding to the 0-based column number
|
||||
*
|
||||
* @param column the column number
|
||||
* @param buf the string buffer in which to write the column letter
|
||||
*/
|
||||
public static void getColumnReference(int column, StringBuffer buf) {
|
||||
int v = column / 26;
|
||||
int r = column % 26;
|
||||
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
while (v != 0) {
|
||||
char col = (char) ('A' + r);
|
||||
|
||||
tmp.append(col);
|
||||
|
||||
r = v % 26 - 1; // subtract one because only rows >26 preceded by A
|
||||
v = v / 26;
|
||||
}
|
||||
|
||||
char col = (char) ('A' + r);
|
||||
tmp.append(col);
|
||||
|
||||
// Insert into the proper string buffer in reverse order
|
||||
for (int i = tmp.length() - 1; i >= 0; i--) {
|
||||
buf.append(tmp.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet
|
||||
* @param column
|
||||
* @param row
|
||||
* @param workbook
|
||||
* @param buf
|
||||
*/
|
||||
public static void getCellReference
|
||||
(int sheet, int column, int row,
|
||||
ExternalSheet workbook, StringBuffer buf) {
|
||||
// Quotes are added by the WorkbookParser
|
||||
String name = workbook.getExternalSheetName(sheet);
|
||||
buf.append(StringHelper.replace(name, "'", "''"));
|
||||
buf.append(sheetInd);
|
||||
getCellReference(column, row, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet
|
||||
* @param column
|
||||
* @param colabs TRUE if the column is an absolute reference
|
||||
* @param row
|
||||
* @param rowabs TRUE if the row is an absolute reference
|
||||
* @param workbook
|
||||
* @param buf
|
||||
*/
|
||||
public static void getCellReference
|
||||
(int sheet, int column, boolean colabs,
|
||||
int row, boolean rowabs,
|
||||
ExternalSheet workbook, StringBuffer buf) {
|
||||
// WorkbookParser now appends quotes and escapes apostrophes
|
||||
String name = workbook.getExternalSheetName(sheet);
|
||||
buf.append(name);
|
||||
buf.append(sheetInd);
|
||||
getCellReference(column, colabs, row, rowabs, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified cell reference given the column, row
|
||||
* external sheet reference etc
|
||||
*
|
||||
* @param sheet
|
||||
* @param column
|
||||
* @param row
|
||||
* @param workbook
|
||||
* @return the cell reference in the form 'Sheet 1'!A1
|
||||
*/
|
||||
public static String getCellReference
|
||||
(int sheet, int column, int row,
|
||||
ExternalSheet workbook) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
getCellReference(sheet, column, row, workbook, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the cell reference for the specified column and row
|
||||
*
|
||||
* @param column
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
public static String getCellReference(int column, int row) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getCellReference(column, row, buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the columnn number of the string cell reference
|
||||
*
|
||||
* @param s the string to parse
|
||||
* @return the column portion of the cell reference
|
||||
*/
|
||||
public static int getColumn(String s) {
|
||||
int colnum = 0;
|
||||
int numindex = getNumberIndex(s);
|
||||
|
||||
String s2 = s.toUpperCase();
|
||||
|
||||
int startPos = s.lastIndexOf(sheetInd) + 1;
|
||||
if (s.charAt(startPos) == fixedInd) {
|
||||
startPos++;
|
||||
}
|
||||
|
||||
int endPos = numindex;
|
||||
if (s.charAt(numindex - 1) == fixedInd) {
|
||||
endPos--;
|
||||
}
|
||||
|
||||
for (int i = startPos; i < endPos; i++) {
|
||||
|
||||
if (i != startPos) {
|
||||
colnum = (colnum + 1) * 26;
|
||||
}
|
||||
colnum += (int) s2.charAt(i) - (int) 'A';
|
||||
}
|
||||
|
||||
return colnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the row number of the cell reference
|
||||
*/
|
||||
public static int getRow(String s) {
|
||||
try {
|
||||
return (Integer.parseInt(s.substring(getNumberIndex(s))) - 1);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.warn(e, e);
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the position where the first number occurs in the string
|
||||
*/
|
||||
private static int getNumberIndex(String s) {
|
||||
// Find the position of the first number
|
||||
boolean numberFound = false;
|
||||
int pos = s.lastIndexOf(sheetInd) + 1;
|
||||
char c = '\0';
|
||||
|
||||
while (!numberFound && pos < s.length()) {
|
||||
c = s.charAt(pos);
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
numberFound = true;
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if the column component is relative or not
|
||||
*
|
||||
* @param s
|
||||
* @return TRUE if the column is relative, FALSE otherwise
|
||||
*/
|
||||
public static boolean isColumnRelative(String s) {
|
||||
return s.charAt(0) != fixedInd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if the row component is relative or not
|
||||
*
|
||||
* @param s
|
||||
* @return TRUE if the row is relative, FALSE otherwise
|
||||
*/
|
||||
public static boolean isRowRelative(String s) {
|
||||
return s.charAt(getNumberIndex(s) - 1) != fixedInd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sheet name from the cell reference string
|
||||
*
|
||||
* @param ref
|
||||
* @return the sheet reference
|
||||
*/
|
||||
public static String getSheet(String ref) {
|
||||
int sheetPos = ref.lastIndexOf(sheetInd);
|
||||
if (sheetPos == -1) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return ref.substring(0, sheetPos);
|
||||
}
|
||||
|
||||
}
|
113
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormat.java
Executable file
113
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormat.java
Executable file
|
@ -0,0 +1,113 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Class containing the CONDFMT and CF records for conditionally formatting
|
||||
* a cell
|
||||
*/
|
||||
public class ConditionalFormat {
|
||||
/**
|
||||
* The range of the format
|
||||
*/
|
||||
private final ConditionalFormatRangeRecord range;
|
||||
|
||||
/**
|
||||
* The format conditions
|
||||
*/
|
||||
private final ArrayList conditions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ConditionalFormat(ConditionalFormatRangeRecord cfrr) {
|
||||
range = cfrr;
|
||||
conditions = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition
|
||||
*
|
||||
* @param cond the condition
|
||||
*/
|
||||
public void addCondition(ConditionalFormatRecord cond) {
|
||||
conditions.add(cond);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank column into this spreadsheet. If the column is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to insert
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
range.insertColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column from this spreadsheet. If the column is out of range
|
||||
* of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to remove
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
range.removeColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row from this spreadsheet. If the row is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to remove
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
range.removeRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank row into this spreadsheet. If the row is out of range
|
||||
* of the rows in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
range.insertRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the data validation
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
outputFile.write(range);
|
||||
|
||||
for (Iterator i = conditions.iterator(); i.hasNext(); ) {
|
||||
ConditionalFormatRecord cfr = (ConditionalFormatRecord) i.next();
|
||||
outputFile.write(cfr);
|
||||
}
|
||||
}
|
||||
}
|
344
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormatRangeRecord.java
Executable file
344
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormatRangeRecord.java
Executable file
|
@ -0,0 +1,344 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Range information for conditional formatting
|
||||
*/
|
||||
public class ConditionalFormatRangeRecord extends WritableRecordData {
|
||||
// The logger
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(ConditionalFormatRangeRecord.class);
|
||||
|
||||
/**
|
||||
* The enclosing range
|
||||
*/
|
||||
private Range enclosingRange;
|
||||
|
||||
/**
|
||||
* The discrete ranges
|
||||
*/
|
||||
private Range[] ranges;
|
||||
|
||||
/**
|
||||
* The number of ranges
|
||||
*/
|
||||
private int numRanges;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* Modified flag
|
||||
*/
|
||||
private boolean modified;
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ConditionalFormatRangeRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
initialized = false;
|
||||
modified = false;
|
||||
data = getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization function
|
||||
*/
|
||||
private void initialize() {
|
||||
enclosingRange = new Range();
|
||||
enclosingRange.firstRow = IntegerHelper.getInt(data[4], data[5]);
|
||||
enclosingRange.lastRow = IntegerHelper.getInt(data[6], data[7]);
|
||||
enclosingRange.firstColumn = IntegerHelper.getInt(data[8], data[9]);
|
||||
enclosingRange.lastColumn = IntegerHelper.getInt(data[10], data[11]);
|
||||
numRanges = IntegerHelper.getInt(data[12], data[13]);
|
||||
ranges = new Range[numRanges];
|
||||
|
||||
int pos = 14;
|
||||
|
||||
for (int i = 0; i < numRanges; i++) {
|
||||
ranges[i] = new Range();
|
||||
ranges[i].firstRow = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
ranges[i].lastRow = IntegerHelper.getInt(data[pos + 2], data[pos + 3]);
|
||||
ranges[i].firstColumn = IntegerHelper.getInt(data[pos + 4], data[pos + 5]);
|
||||
ranges[i].lastColumn = IntegerHelper.getInt(data[pos + 6], data[pos + 7]);
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank column into this spreadsheet. If the column is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to insert
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
enclosingRange.insertColumn(col);
|
||||
if (enclosingRange.modified) {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
ranges[i].insertColumn(col);
|
||||
|
||||
if (ranges[i].modified) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank column into this spreadsheet. If the column is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to insert
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
enclosingRange.removeColumn(col);
|
||||
if (enclosingRange.modified) {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
ranges[i].removeColumn(col);
|
||||
|
||||
if (ranges[i].modified) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row from this spreadsheet. If the row is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to remove
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
enclosingRange.removeRow(row);
|
||||
if (enclosingRange.modified) {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
ranges[i].removeRow(row);
|
||||
|
||||
if (ranges[i].modified) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank row into this spreadsheet. If the row is out of range
|
||||
* of the rows in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
enclosingRange.insertRow(row);
|
||||
if (enclosingRange.modified) {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
ranges[i].insertRow(row);
|
||||
|
||||
if (ranges[i].modified) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
if (!modified) {
|
||||
return data;
|
||||
}
|
||||
|
||||
byte[] d = new byte[14 + ranges.length * 8];
|
||||
|
||||
// Copy in the original information
|
||||
System.arraycopy(data, 0, d, 0, 4);
|
||||
|
||||
// Create the new range
|
||||
IntegerHelper.getTwoBytes(enclosingRange.firstRow, d, 4);
|
||||
IntegerHelper.getTwoBytes(enclosingRange.lastRow, d, 6);
|
||||
IntegerHelper.getTwoBytes(enclosingRange.firstColumn, d, 8);
|
||||
IntegerHelper.getTwoBytes(enclosingRange.lastColumn, d, 10);
|
||||
|
||||
IntegerHelper.getTwoBytes(numRanges, d, 12);
|
||||
|
||||
int pos = 14;
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
IntegerHelper.getTwoBytes(ranges[i].firstRow, d, pos);
|
||||
IntegerHelper.getTwoBytes(ranges[i].lastRow, d, pos + 2);
|
||||
IntegerHelper.getTwoBytes(ranges[i].firstColumn, d, pos + 4);
|
||||
IntegerHelper.getTwoBytes(ranges[i].lastColumn, d, pos + 6);
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private static class Range {
|
||||
public int firstRow;
|
||||
public int firstColumn;
|
||||
public int lastRow;
|
||||
public int lastColumn;
|
||||
public boolean modified;
|
||||
|
||||
public Range() {
|
||||
modified = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank column into this spreadsheet. If the column is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to insert
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
if (col > lastColumn) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (col <= firstColumn) {
|
||||
firstColumn++;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (col <= lastColumn) {
|
||||
lastColumn++;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column from this spreadsheet. If the column is out of range
|
||||
* of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param col the column to remove
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
if (col > lastColumn) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (col < firstColumn) {
|
||||
firstColumn--;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (col <= lastColumn) {
|
||||
lastColumn--;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row from this spreadsheet. If the row is out of
|
||||
* range of the columns in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to remove
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
if (row > lastRow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (row < firstRow) {
|
||||
firstRow--;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (row <= lastRow) {
|
||||
lastRow--;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a blank row into this spreadsheet. If the row is out of range
|
||||
* of the rows in the sheet, then no action is taken
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
if (row > lastRow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (row <= firstRow) {
|
||||
firstRow++;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (row <= lastRow) {
|
||||
lastRow++;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
56
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormatRecord.java
Executable file
56
datastructures-xslx/src/main/java/jxl/biff/ConditionalFormatRecord.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* The conditional format conditions
|
||||
*/
|
||||
public class ConditionalFormatRecord extends WritableRecordData {
|
||||
// the logger
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(ConditionalFormatRecord.class);
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ConditionalFormatRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
data = getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
74
datastructures-xslx/src/main/java/jxl/biff/ContinueRecord.java
Executable file
74
datastructures-xslx/src/main/java/jxl/biff/ContinueRecord.java
Executable file
|
@ -0,0 +1,74 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A continue record - only used explicitly in special circumstances, as
|
||||
* the general continuation record is handled directly by the records
|
||||
*/
|
||||
public class ContinueRecord extends WritableRecordData {
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param t the raw bytes
|
||||
*/
|
||||
public ContinueRecord(Record t) {
|
||||
super(t);
|
||||
data = t.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when creating continue records
|
||||
*
|
||||
* @param d the data
|
||||
*/
|
||||
public ContinueRecord(byte[] d) {
|
||||
super(Type.CONTINUE);
|
||||
data = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the binary data - used when copying
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the record. Used when forcibly changing this record
|
||||
* into another type, notably a drawing record, as sometimes Excel appears
|
||||
* to switch to writing Continue records instead of MsoDrawing records
|
||||
*
|
||||
* @return the record
|
||||
*/
|
||||
public Record getRecord() {
|
||||
return super.getRecord();
|
||||
}
|
||||
|
||||
}
|
150
datastructures-xslx/src/main/java/jxl/biff/CountryCode.java
Executable file
150
datastructures-xslx/src/main/java/jxl/biff/CountryCode.java
Executable file
|
@ -0,0 +1,150 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Enumeration type for the excel country codes
|
||||
*/
|
||||
public class CountryCode {
|
||||
// The country codes
|
||||
public final static CountryCode USA = new CountryCode(0x1, "US", "USA");
|
||||
public final static CountryCode CANADA =
|
||||
new CountryCode(0x2, "CA", "Canada");
|
||||
public final static CountryCode GREECE =
|
||||
new CountryCode(0x1e, "GR", "Greece");
|
||||
public final static CountryCode NETHERLANDS =
|
||||
new CountryCode(0x1f, "NE", "Netherlands");
|
||||
public final static CountryCode BELGIUM =
|
||||
new CountryCode(0x20, "BE", "Belgium");
|
||||
public final static CountryCode FRANCE =
|
||||
new CountryCode(0x21, "FR", "France");
|
||||
public final static CountryCode SPAIN = new CountryCode(0x22, "ES", "Spain");
|
||||
public final static CountryCode ITALY = new CountryCode(0x27, "IT", "Italy");
|
||||
public final static CountryCode SWITZERLAND =
|
||||
new CountryCode(0x29, "CH", "Switzerland");
|
||||
public final static CountryCode UK =
|
||||
new CountryCode(0x2c, "UK", "United Kingdowm");
|
||||
public final static CountryCode DENMARK =
|
||||
new CountryCode(0x2d, "DK", "Denmark");
|
||||
public final static CountryCode SWEDEN =
|
||||
new CountryCode(0x2e, "SE", "Sweden");
|
||||
public final static CountryCode NORWAY =
|
||||
new CountryCode(0x2f, "NO", "Norway");
|
||||
public final static CountryCode GERMANY =
|
||||
new CountryCode(0x31, "DE", "Germany");
|
||||
public final static CountryCode PHILIPPINES =
|
||||
new CountryCode(0x3f, "PH", "Philippines");
|
||||
public final static CountryCode CHINA =
|
||||
new CountryCode(0x56, "CN", "China");
|
||||
public final static CountryCode INDIA =
|
||||
new CountryCode(0x5b, "IN", "India");
|
||||
public final static CountryCode UNKNOWN =
|
||||
new CountryCode(0xffff, "??", "Unknown");
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(CountryCode.class);
|
||||
/**
|
||||
* The array of country codes
|
||||
*/
|
||||
private static CountryCode[] codes = new CountryCode[0];
|
||||
/**
|
||||
* The country code
|
||||
*/
|
||||
private final int value;
|
||||
/**
|
||||
* The ISO 3166 two letter country mnemonic (as used by the Locale class)
|
||||
*/
|
||||
private final String code;
|
||||
/**
|
||||
* The long description
|
||||
*/
|
||||
private final String description;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private CountryCode(int v, String c, String d) {
|
||||
value = v;
|
||||
code = c;
|
||||
description = d;
|
||||
|
||||
CountryCode[] newcodes = new CountryCode[codes.length + 1];
|
||||
System.arraycopy(codes, 0, newcodes, 0, codes.length);
|
||||
newcodes[codes.length] = this;
|
||||
codes = newcodes;
|
||||
}
|
||||
/**
|
||||
* Constructor used to create an arbitrary code with a specified value.
|
||||
* Doesn't add the latest value to the static array
|
||||
*/
|
||||
private CountryCode(int v) {
|
||||
value = v;
|
||||
description = "Arbitrary";
|
||||
code = "??";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the country code for the given two character mnemonic string
|
||||
*/
|
||||
public static CountryCode getCountryCode(String s) {
|
||||
if (s == null || s.length() != 2) {
|
||||
logger.warn("Please specify two character ISO 3166 country code");
|
||||
return USA;
|
||||
}
|
||||
|
||||
CountryCode code = UNKNOWN;
|
||||
for (int i = 0; i < codes.length && code == UNKNOWN; i++) {
|
||||
if (codes[i].code.equals(s)) {
|
||||
code = codes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an arbitrary country code with the specified value. Used
|
||||
* when copying sheets, and the country code isn't initialized as part
|
||||
* of the static data below
|
||||
*/
|
||||
public static CountryCode createArbitraryCode(int i) {
|
||||
return new CountryCode(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the excel value
|
||||
*
|
||||
* @return the excel value
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the string
|
||||
*
|
||||
* @return the two character iso 3166 string
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
906
datastructures-xslx/src/main/java/jxl/biff/DVParser.java
Executable file
906
datastructures-xslx/src/main/java/jxl/biff/DVParser.java
Executable file
|
@ -0,0 +1,906 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.formula.ExternalSheet;
|
||||
import jxl.biff.formula.FormulaException;
|
||||
import jxl.biff.formula.FormulaParser;
|
||||
import jxl.biff.formula.ParseContext;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Class which parses the binary data associated with Data Validity (DV)
|
||||
* setting
|
||||
*/
|
||||
public class DVParser {
|
||||
// The values
|
||||
public static final DVType ANY = new DVType(0, "any");
|
||||
public static final DVType INTEGER = new DVType(1, "int");
|
||||
public static final DVType DECIMAL = new DVType(2, "dec");
|
||||
public static final DVType LIST = new DVType(3, "list");
|
||||
public static final DVType DATE = new DVType(4, "date");
|
||||
public static final DVType TIME = new DVType(5, "time");
|
||||
public static final DVType TEXT_LENGTH = new DVType(6, "strlen");
|
||||
public static final DVType FORMULA = new DVType(7, "form");
|
||||
// The error styles
|
||||
public static final ErrorStyle STOP = new ErrorStyle(0);
|
||||
public static final ErrorStyle WARNING = new ErrorStyle(1);
|
||||
public static final ErrorStyle INFO = new ErrorStyle(2);
|
||||
// The conditions
|
||||
public static final Condition BETWEEN = new Condition(0, "{0} <= x <= {1}");
|
||||
public static final Condition NOT_BETWEEN =
|
||||
new Condition(1, "!({0} <= x <= {1}");
|
||||
public static final Condition EQUAL = new Condition(2, "x == {0}");
|
||||
public static final Condition NOT_EQUAL = new Condition(3, "x != {0}");
|
||||
public static final Condition GREATER_THAN = new Condition(4, "x > {0}");
|
||||
public static final Condition LESS_THAN = new Condition(5, "x < {0}");
|
||||
public static final Condition GREATER_EQUAL = new Condition(6, "x >= {0}");
|
||||
public static final Condition LESS_EQUAL = new Condition(7, "x <= {0}");
|
||||
// The masks
|
||||
private static final int STRING_LIST_GIVEN_MASK = 0x80;
|
||||
private static final int EMPTY_CELLS_ALLOWED_MASK = 0x100;
|
||||
private static final int SUPPRESS_ARROW_MASK = 0x200;
|
||||
private static final int SHOW_PROMPT_MASK = 0x40000;
|
||||
private static final int SHOW_ERROR_MASK = 0x80000;
|
||||
// The maximum string length for a data validation list
|
||||
private static final int MAX_VALIDATION_LIST_LENGTH = 254;
|
||||
// The maximum number of rows and columns
|
||||
private static final int MAX_ROWS = 0xffff;
|
||||
private static final int MAX_COLUMNS = 0xff;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(DVParser.class);
|
||||
// The decimal format
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#");
|
||||
/**
|
||||
* The type
|
||||
*/
|
||||
private final DVType type;
|
||||
/**
|
||||
* The error style
|
||||
*/
|
||||
private final ErrorStyle errorStyle;
|
||||
/**
|
||||
* The condition
|
||||
*/
|
||||
private final Condition condition;
|
||||
/**
|
||||
* String list option
|
||||
*/
|
||||
private final boolean stringListGiven;
|
||||
/**
|
||||
* Empty cells allowed
|
||||
*/
|
||||
private final boolean emptyCellsAllowed;
|
||||
/**
|
||||
* Suppress arrow
|
||||
*/
|
||||
private final boolean suppressArrow;
|
||||
/**
|
||||
* Show prompt
|
||||
*/
|
||||
private final boolean showPrompt;
|
||||
/**
|
||||
* Show error
|
||||
*/
|
||||
private final boolean showError;
|
||||
/**
|
||||
* The title of the prompt box
|
||||
*/
|
||||
private String promptTitle;
|
||||
/**
|
||||
* The title of the error box
|
||||
*/
|
||||
private String errorTitle;
|
||||
/**
|
||||
* The text of the prompt box
|
||||
*/
|
||||
private String promptText;
|
||||
/**
|
||||
* The text of the error box
|
||||
*/
|
||||
private String errorText;
|
||||
/**
|
||||
* The first formula
|
||||
*/
|
||||
private FormulaParser formula1;
|
||||
/**
|
||||
* The first formula string
|
||||
*/
|
||||
private String formula1String;
|
||||
/**
|
||||
* The second formula
|
||||
*/
|
||||
private FormulaParser formula2;
|
||||
/**
|
||||
* The second formula string
|
||||
*/
|
||||
private String formula2String;
|
||||
/**
|
||||
* The column number of the cell at the top left of the range
|
||||
*/
|
||||
private int column1;
|
||||
/**
|
||||
* The row number of the cell at the top left of the range
|
||||
*/
|
||||
private int row1;
|
||||
/**
|
||||
* The column index of the cell at the bottom right
|
||||
*/
|
||||
private int column2;
|
||||
/**
|
||||
* The row index of the cell at the bottom right
|
||||
*/
|
||||
private int row2;
|
||||
/**
|
||||
* Flag to indicate that this DV Parser is shared amongst a group
|
||||
* of cells
|
||||
*/
|
||||
private boolean extendedCellsValidation;
|
||||
/**
|
||||
* Flag indicated whether this has been copied
|
||||
*/
|
||||
private final boolean copied;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DVParser(byte[] data,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods nt,
|
||||
WorkbookSettings ws) {
|
||||
Assert.verify(nt != null);
|
||||
|
||||
copied = false;
|
||||
int options = IntegerHelper.getInt(data[0], data[1], data[2], data[3]);
|
||||
|
||||
int typeVal = options & 0xf;
|
||||
type = DVType.getType(typeVal);
|
||||
|
||||
int errorStyleVal = (options & 0x70) >> 4;
|
||||
errorStyle = ErrorStyle.getErrorStyle(errorStyleVal);
|
||||
|
||||
int conditionVal = (options & 0xf00000) >> 20;
|
||||
condition = Condition.getCondition(conditionVal);
|
||||
|
||||
stringListGiven = (options & STRING_LIST_GIVEN_MASK) != 0;
|
||||
emptyCellsAllowed = (options & EMPTY_CELLS_ALLOWED_MASK) != 0;
|
||||
suppressArrow = (options & SUPPRESS_ARROW_MASK) != 0;
|
||||
showPrompt = (options & SHOW_PROMPT_MASK) != 0;
|
||||
showError = (options & SHOW_ERROR_MASK) != 0;
|
||||
|
||||
int pos = 4;
|
||||
int length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
if (length > 0 && data[pos + 2] == 0) {
|
||||
promptTitle = StringHelper.getString(data, length, pos + 3, ws);
|
||||
pos += length + 3;
|
||||
} else if (length > 0) {
|
||||
promptTitle = StringHelper.getUnicodeString(data, length, pos + 3);
|
||||
pos += length * 2 + 3;
|
||||
} else {
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
if (length > 0 && data[pos + 2] == 0) {
|
||||
errorTitle = StringHelper.getString(data, length, pos + 3, ws);
|
||||
pos += length + 3;
|
||||
} else if (length > 0) {
|
||||
errorTitle = StringHelper.getUnicodeString(data, length, pos + 3);
|
||||
pos += length * 2 + 3;
|
||||
} else {
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
if (length > 0 && data[pos + 2] == 0) {
|
||||
promptText = StringHelper.getString(data, length, pos + 3, ws);
|
||||
pos += length + 3;
|
||||
} else if (length > 0) {
|
||||
promptText = StringHelper.getUnicodeString(data, length, pos + 3);
|
||||
pos += length * 2 + 3;
|
||||
} else {
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
if (length > 0 && data[pos + 2] == 0) {
|
||||
errorText = StringHelper.getString(data, length, pos + 3, ws);
|
||||
pos += length + 3;
|
||||
} else if (length > 0) {
|
||||
errorText = StringHelper.getUnicodeString(data, length, pos + 3);
|
||||
pos += length * 2 + 3;
|
||||
} else {
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
int formula1Length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 4;
|
||||
int formula1Pos = pos;
|
||||
pos += formula1Length;
|
||||
|
||||
int formula2Length = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 4;
|
||||
int formula2Pos = pos;
|
||||
pos += formula2Length;
|
||||
|
||||
pos += 2;
|
||||
|
||||
row1 = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 2;
|
||||
|
||||
row2 = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 2;
|
||||
|
||||
column1 = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 2;
|
||||
|
||||
column2 = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
pos += 2;
|
||||
|
||||
extendedCellsValidation = row1 != row2 || column1 != column2;
|
||||
|
||||
// Do the formulas
|
||||
try {
|
||||
// First, create a temporary blank cell for any formula relative
|
||||
// references
|
||||
EmptyCell tmprt = new EmptyCell(column1, row1);
|
||||
|
||||
if (formula1Length != 0) {
|
||||
byte[] tokens = new byte[formula1Length];
|
||||
System.arraycopy(data, formula1Pos, tokens, 0, formula1Length);
|
||||
formula1 = new FormulaParser(tokens, tmprt, es, nt, ws,
|
||||
ParseContext.DATA_VALIDATION);
|
||||
formula1.parse();
|
||||
}
|
||||
|
||||
if (formula2Length != 0) {
|
||||
byte[] tokens = new byte[formula2Length];
|
||||
System.arraycopy(data, formula2Pos, tokens, 0, formula2Length);
|
||||
formula2 = new FormulaParser(tokens, tmprt, es, nt, ws,
|
||||
ParseContext.DATA_VALIDATION);
|
||||
formula2.parse();
|
||||
}
|
||||
} catch (FormulaException e) {
|
||||
logger.warn(e.getMessage() + " for cells " +
|
||||
CellReferenceHelper.getCellReference(column1, row1) + "-" +
|
||||
CellReferenceHelper.getCellReference(column2, row2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when creating a data validation from the API
|
||||
*/
|
||||
public DVParser(Collection strings) {
|
||||
copied = false;
|
||||
type = LIST;
|
||||
errorStyle = STOP;
|
||||
condition = BETWEEN;
|
||||
extendedCellsValidation = false;
|
||||
|
||||
// the options
|
||||
stringListGiven = true;
|
||||
emptyCellsAllowed = true;
|
||||
suppressArrow = false;
|
||||
showPrompt = true;
|
||||
showError = true;
|
||||
|
||||
promptTitle = "\0";
|
||||
errorTitle = "\0";
|
||||
promptText = "\0";
|
||||
errorText = "\0";
|
||||
if (strings.size() == 0) {
|
||||
logger.warn("no validation strings - ignoring");
|
||||
}
|
||||
|
||||
Iterator i = strings.iterator();
|
||||
StringBuffer formulaString = new StringBuffer();
|
||||
|
||||
formulaString.append(i.next().toString());
|
||||
while (i.hasNext()) {
|
||||
formulaString.append('\0');
|
||||
formulaString.append(' ');
|
||||
formulaString.append(i.next().toString());
|
||||
}
|
||||
|
||||
// If the formula string exceeds
|
||||
// the maximum validation list length, then truncate and stop there
|
||||
if (formulaString.length() > MAX_VALIDATION_LIST_LENGTH) {
|
||||
logger.warn("Validation list exceeds maximum number of characters - " +
|
||||
"truncating");
|
||||
formulaString.delete(MAX_VALIDATION_LIST_LENGTH,
|
||||
formulaString.length());
|
||||
}
|
||||
|
||||
// Put the string in quotes
|
||||
formulaString.insert(0, '\"');
|
||||
formulaString.append('\"');
|
||||
formula1String = formulaString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when creating a data validation from the API
|
||||
*/
|
||||
public DVParser(String namedRange) {
|
||||
// Handle the case for an empty string
|
||||
if (namedRange.length() == 0) {
|
||||
copied = false;
|
||||
type = FORMULA;
|
||||
errorStyle = STOP;
|
||||
condition = EQUAL;
|
||||
extendedCellsValidation = false;
|
||||
// the options
|
||||
stringListGiven = false;
|
||||
emptyCellsAllowed = false;
|
||||
suppressArrow = false;
|
||||
showPrompt = true;
|
||||
showError = true;
|
||||
|
||||
promptTitle = "\0";
|
||||
errorTitle = "\0";
|
||||
promptText = "\0";
|
||||
errorText = "\0";
|
||||
formula1String = "\"\"";
|
||||
return;
|
||||
}
|
||||
|
||||
copied = false;
|
||||
type = LIST;
|
||||
errorStyle = STOP;
|
||||
condition = BETWEEN;
|
||||
extendedCellsValidation = false;
|
||||
|
||||
// the options
|
||||
stringListGiven = false;
|
||||
emptyCellsAllowed = true;
|
||||
suppressArrow = false;
|
||||
showPrompt = true;
|
||||
showError = true;
|
||||
|
||||
promptTitle = "\0";
|
||||
errorTitle = "\0";
|
||||
promptText = "\0";
|
||||
errorText = "\0";
|
||||
formula1String = namedRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when creating a data validation from the API
|
||||
*/
|
||||
public DVParser(int c1, int r1, int c2, int r2) {
|
||||
copied = false;
|
||||
type = LIST;
|
||||
errorStyle = STOP;
|
||||
condition = BETWEEN;
|
||||
extendedCellsValidation = false;
|
||||
|
||||
// the options
|
||||
stringListGiven = false;
|
||||
emptyCellsAllowed = true;
|
||||
suppressArrow = false;
|
||||
showPrompt = true;
|
||||
showError = true;
|
||||
|
||||
promptTitle = "\0";
|
||||
errorTitle = "\0";
|
||||
promptText = "\0";
|
||||
errorText = "\0";
|
||||
StringBuffer formulaString = new StringBuffer();
|
||||
CellReferenceHelper.getCellReference(c1, r1, formulaString);
|
||||
formulaString.append(':');
|
||||
CellReferenceHelper.getCellReference(c2, r2, formulaString);
|
||||
formula1String = formulaString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when creating a data validation from the API
|
||||
*/
|
||||
public DVParser(double val1, double val2, Condition c) {
|
||||
copied = false;
|
||||
type = DECIMAL;
|
||||
errorStyle = STOP;
|
||||
condition = c;
|
||||
extendedCellsValidation = false;
|
||||
|
||||
// the options
|
||||
stringListGiven = false;
|
||||
emptyCellsAllowed = true;
|
||||
suppressArrow = false;
|
||||
showPrompt = true;
|
||||
showError = true;
|
||||
|
||||
promptTitle = "\0";
|
||||
errorTitle = "\0";
|
||||
promptText = "\0";
|
||||
errorText = "\0";
|
||||
formula1String = DECIMAL_FORMAT.format(val1);
|
||||
|
||||
if (!Double.isNaN(val2)) {
|
||||
formula2String = DECIMAL_FORMAT.format(val2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when doing a cell deep copy
|
||||
*/
|
||||
public DVParser(DVParser copy) {
|
||||
copied = true;
|
||||
type = copy.type;
|
||||
errorStyle = copy.errorStyle;
|
||||
condition = copy.condition;
|
||||
stringListGiven = copy.stringListGiven;
|
||||
emptyCellsAllowed = copy.emptyCellsAllowed;
|
||||
suppressArrow = copy.suppressArrow;
|
||||
showPrompt = copy.showPrompt;
|
||||
showError = copy.showError;
|
||||
promptTitle = copy.promptTitle;
|
||||
promptText = copy.promptText;
|
||||
errorTitle = copy.errorTitle;
|
||||
errorText = copy.errorText;
|
||||
extendedCellsValidation = copy.extendedCellsValidation;
|
||||
|
||||
row1 = copy.row1;
|
||||
row2 = copy.row2;
|
||||
column1 = copy.column1;
|
||||
column2 = copy.column2;
|
||||
|
||||
// Don't copy the formula parsers - just take their string equivalents
|
||||
if (copy.formula1String != null) {
|
||||
formula1String = copy.formula1String;
|
||||
formula2String = copy.formula2String;
|
||||
} else {
|
||||
try {
|
||||
formula1String = copy.formula1.getFormula();
|
||||
formula2String = (copy.formula2 != null) ?
|
||||
copy.formula2.getFormula() : null;
|
||||
} catch (FormulaException e) {
|
||||
logger.warn("Cannot parse validation formula: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
// Don't copy the cell references - these will be added later
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
// Compute the length of the data
|
||||
byte[] f1Bytes = formula1 != null ? formula1.getBytes() : new byte[0];
|
||||
byte[] f2Bytes = formula2 != null ? formula2.getBytes() : new byte[0];
|
||||
int dataLength =
|
||||
4 + // the options
|
||||
promptTitle.length() * 2 + 3 + // the prompt title
|
||||
errorTitle.length() * 2 + 3 + // the error title
|
||||
promptText.length() * 2 + 3 + // the prompt text
|
||||
errorText.length() * 2 + 3 + // the error text
|
||||
f1Bytes.length + 2 + // first formula
|
||||
f2Bytes.length + 2 + // second formula
|
||||
+4 + // unused bytes
|
||||
10; // cell range
|
||||
|
||||
byte[] data = new byte[dataLength];
|
||||
|
||||
// The position
|
||||
int pos = 0;
|
||||
|
||||
// The options
|
||||
int options = 0;
|
||||
options |= type.getValue();
|
||||
options |= errorStyle.getValue() << 4;
|
||||
options |= condition.getValue() << 20;
|
||||
|
||||
if (stringListGiven) {
|
||||
options |= STRING_LIST_GIVEN_MASK;
|
||||
}
|
||||
|
||||
if (emptyCellsAllowed) {
|
||||
options |= EMPTY_CELLS_ALLOWED_MASK;
|
||||
}
|
||||
|
||||
if (suppressArrow) {
|
||||
options |= SUPPRESS_ARROW_MASK;
|
||||
}
|
||||
|
||||
if (showPrompt) {
|
||||
options |= SHOW_PROMPT_MASK;
|
||||
}
|
||||
|
||||
if (showError) {
|
||||
options |= SHOW_ERROR_MASK;
|
||||
}
|
||||
|
||||
// The text
|
||||
IntegerHelper.getFourBytes(options, data, pos);
|
||||
pos += 4;
|
||||
|
||||
IntegerHelper.getTwoBytes(promptTitle.length(), data, pos);
|
||||
pos += 2;
|
||||
|
||||
data[pos] = (byte) 0x1; // unicode indicator
|
||||
pos++;
|
||||
|
||||
StringHelper.getUnicodeBytes(promptTitle, data, pos);
|
||||
pos += promptTitle.length() * 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(errorTitle.length(), data, pos);
|
||||
pos += 2;
|
||||
|
||||
data[pos] = (byte) 0x1; // unicode indicator
|
||||
pos++;
|
||||
|
||||
StringHelper.getUnicodeBytes(errorTitle, data, pos);
|
||||
pos += errorTitle.length() * 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(promptText.length(), data, pos);
|
||||
pos += 2;
|
||||
|
||||
data[pos] = (byte) 0x1; // unicode indicator
|
||||
pos++;
|
||||
|
||||
StringHelper.getUnicodeBytes(promptText, data, pos);
|
||||
pos += promptText.length() * 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(errorText.length(), data, pos);
|
||||
pos += 2;
|
||||
|
||||
data[pos] = (byte) 0x1; // unicode indicator
|
||||
pos++;
|
||||
|
||||
StringHelper.getUnicodeBytes(errorText, data, pos);
|
||||
pos += errorText.length() * 2;
|
||||
|
||||
// Formula 1
|
||||
IntegerHelper.getTwoBytes(f1Bytes.length, data, pos);
|
||||
pos += 4;
|
||||
|
||||
System.arraycopy(f1Bytes, 0, data, pos, f1Bytes.length);
|
||||
pos += f1Bytes.length;
|
||||
|
||||
// Formula 2
|
||||
IntegerHelper.getTwoBytes(f2Bytes.length, data, pos);
|
||||
pos += 4;
|
||||
|
||||
System.arraycopy(f2Bytes, 0, data, pos, f2Bytes.length);
|
||||
pos += f2Bytes.length;
|
||||
|
||||
// The cell ranges
|
||||
IntegerHelper.getTwoBytes(1, data, pos);
|
||||
pos += 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(row1, data, pos);
|
||||
pos += 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(row2, data, pos);
|
||||
pos += 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(column1, data, pos);
|
||||
pos += 2;
|
||||
|
||||
IntegerHelper.getTwoBytes(column2, data, pos);
|
||||
pos += 2;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a row
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
if (formula1 != null) {
|
||||
formula1.rowInserted(0, row, true);
|
||||
}
|
||||
|
||||
if (formula2 != null) {
|
||||
formula2.rowInserted(0, row, true);
|
||||
}
|
||||
|
||||
if (row1 >= row) {
|
||||
row1++;
|
||||
}
|
||||
|
||||
if (row2 >= row && row2 != MAX_ROWS) {
|
||||
row2++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column
|
||||
*
|
||||
* @param col the column to insert
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
if (formula1 != null) {
|
||||
formula1.columnInserted(0, col, true);
|
||||
}
|
||||
|
||||
if (formula2 != null) {
|
||||
formula2.columnInserted(0, col, true);
|
||||
}
|
||||
|
||||
if (column1 >= col) {
|
||||
column1++;
|
||||
}
|
||||
|
||||
if (column2 >= col && column2 != MAX_COLUMNS) {
|
||||
column2++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
if (formula1 != null) {
|
||||
formula1.rowRemoved(0, row, true);
|
||||
}
|
||||
|
||||
if (formula2 != null) {
|
||||
formula2.rowRemoved(0, row, true);
|
||||
}
|
||||
|
||||
if (row1 > row) {
|
||||
row1--;
|
||||
}
|
||||
|
||||
if (row2 >= row) {
|
||||
row2--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column
|
||||
*
|
||||
* @param col the row to remove
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
if (formula1 != null) {
|
||||
formula1.columnRemoved(0, col, true);
|
||||
}
|
||||
|
||||
if (formula2 != null) {
|
||||
formula2.columnRemoved(0, col, true);
|
||||
}
|
||||
|
||||
if (column1 > col) {
|
||||
column1--;
|
||||
}
|
||||
|
||||
if (column2 >= col && column2 != MAX_COLUMNS) {
|
||||
column2--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for first column
|
||||
*
|
||||
* @return the first column
|
||||
*/
|
||||
public int getFirstColumn() {
|
||||
return column1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last column
|
||||
*
|
||||
* @return the last column
|
||||
*/
|
||||
public int getLastColumn() {
|
||||
return column2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for first row
|
||||
*
|
||||
* @return the first row
|
||||
*/
|
||||
public int getFirstRow() {
|
||||
return row1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last row
|
||||
*
|
||||
* @return the last row
|
||||
*/
|
||||
public int getLastRow() {
|
||||
return row2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formula present in the validation
|
||||
*
|
||||
* @return the validation formula as a string
|
||||
* @throws FormulaException
|
||||
*/
|
||||
String getValidationFormula() throws FormulaException {
|
||||
if (type == LIST) {
|
||||
return formula1.getFormula();
|
||||
}
|
||||
|
||||
String s1 = formula1.getFormula();
|
||||
String s2 = formula2 != null ? formula2.getFormula() : null;
|
||||
return condition.getConditionString(s1, s2) +
|
||||
"; x " + type.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the cell value when the cell features are added to the sheet
|
||||
*/
|
||||
public void setCell(int col,
|
||||
int row,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods nt,
|
||||
WorkbookSettings ws) throws FormulaException {
|
||||
// If this is part of an extended cells validation, then do nothing
|
||||
// as this will already have been called and parsed when the top left
|
||||
// cell was added
|
||||
if (extendedCellsValidation) {
|
||||
return;
|
||||
}
|
||||
|
||||
row1 = row;
|
||||
row2 = row;
|
||||
column1 = col;
|
||||
column2 = col;
|
||||
|
||||
formula1 = new FormulaParser(formula1String,
|
||||
es, nt, ws,
|
||||
ParseContext.DATA_VALIDATION);
|
||||
formula1.parse();
|
||||
|
||||
if (formula2String != null) {
|
||||
formula2 = new FormulaParser(formula2String,
|
||||
es, nt, ws,
|
||||
ParseContext.DATA_VALIDATION);
|
||||
formula2.parse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the data validation extends across several more cells
|
||||
*
|
||||
* @param cols - the number of extra columns
|
||||
* @param rows - the number of extra rows
|
||||
*/
|
||||
public void extendCellValidation(int cols, int rows) {
|
||||
row2 = row1 + rows;
|
||||
column2 = column1 + cols;
|
||||
extendedCellsValidation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor which indicates whether this validation applies across
|
||||
* multiple cels
|
||||
*/
|
||||
public boolean extendedCellsValidation() {
|
||||
return extendedCellsValidation;
|
||||
}
|
||||
|
||||
public boolean copied() {
|
||||
return copied;
|
||||
}
|
||||
|
||||
// DV Type
|
||||
public static class DVType {
|
||||
private static DVType[] types = new DVType[0];
|
||||
private final int value;
|
||||
private final String desc;
|
||||
|
||||
DVType(int v, String d) {
|
||||
value = v;
|
||||
desc = d;
|
||||
DVType[] oldtypes = types;
|
||||
types = new DVType[oldtypes.length + 1];
|
||||
System.arraycopy(oldtypes, 0, types, 0, oldtypes.length);
|
||||
types[oldtypes.length] = this;
|
||||
}
|
||||
|
||||
static DVType getType(int v) {
|
||||
DVType found = null;
|
||||
for (int i = 0; i < types.length && found == null; i++) {
|
||||
if (types[i].value == v) {
|
||||
found = types[i];
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
// Error Style
|
||||
public static class ErrorStyle {
|
||||
private static ErrorStyle[] types = new ErrorStyle[0];
|
||||
private final int value;
|
||||
|
||||
ErrorStyle(int v) {
|
||||
value = v;
|
||||
ErrorStyle[] oldtypes = types;
|
||||
types = new ErrorStyle[oldtypes.length + 1];
|
||||
System.arraycopy(oldtypes, 0, types, 0, oldtypes.length);
|
||||
types[oldtypes.length] = this;
|
||||
}
|
||||
|
||||
static ErrorStyle getErrorStyle(int v) {
|
||||
ErrorStyle found = null;
|
||||
for (int i = 0; i < types.length && found == null; i++) {
|
||||
if (types[i].value == v) {
|
||||
found = types[i];
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// Conditions
|
||||
public static class Condition {
|
||||
private static Condition[] types = new Condition[0];
|
||||
private final int value;
|
||||
private final MessageFormat format;
|
||||
|
||||
Condition(int v, String pattern) {
|
||||
value = v;
|
||||
format = new MessageFormat(pattern);
|
||||
Condition[] oldtypes = types;
|
||||
types = new Condition[oldtypes.length + 1];
|
||||
System.arraycopy(oldtypes, 0, types, 0, oldtypes.length);
|
||||
types[oldtypes.length] = this;
|
||||
}
|
||||
|
||||
static Condition getCondition(int v) {
|
||||
Condition found = null;
|
||||
for (int i = 0; i < types.length && found == null; i++) {
|
||||
if (types[i].value == v) {
|
||||
found = types[i];
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getConditionString(String s1, String s2) {
|
||||
return format.format(new String[]{s1, s2});
|
||||
}
|
||||
}
|
||||
}
|
149
datastructures-xslx/src/main/java/jxl/biff/DValParser.java
Executable file
149
datastructures-xslx/src/main/java/jxl/biff/DValParser.java
Executable file
|
@ -0,0 +1,149 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Class which parses the binary data associated with Data Validity (DVal)
|
||||
* setting
|
||||
*/
|
||||
public class DValParser {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(DValParser.class);
|
||||
|
||||
// The option masks
|
||||
private static final int PROMPT_BOX_VISIBLE_MASK = 0x1;
|
||||
private static final int PROMPT_BOX_AT_CELL_MASK = 0x2;
|
||||
private static final int VALIDITY_DATA_CACHED_MASK = 0x4;
|
||||
|
||||
/**
|
||||
* Prompt box visible
|
||||
*/
|
||||
private boolean promptBoxVisible;
|
||||
|
||||
/**
|
||||
* Empty cells allowed
|
||||
*/
|
||||
private boolean promptBoxAtCell;
|
||||
|
||||
/**
|
||||
* Cell validity data cached in following DV records
|
||||
*/
|
||||
private final boolean validityDataCached;
|
||||
|
||||
/**
|
||||
* The number of following DV records
|
||||
*/
|
||||
private int numDVRecords;
|
||||
|
||||
/**
|
||||
* The object id of the associated down arrow
|
||||
*/
|
||||
private final int objectId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DValParser(byte[] data) {
|
||||
int options = IntegerHelper.getInt(data[0], data[1]);
|
||||
|
||||
promptBoxVisible = (options & PROMPT_BOX_VISIBLE_MASK) != 0;
|
||||
promptBoxAtCell = (options & PROMPT_BOX_AT_CELL_MASK) != 0;
|
||||
validityDataCached = (options & VALIDITY_DATA_CACHED_MASK) != 0;
|
||||
|
||||
objectId = IntegerHelper.getInt(data[10], data[11], data[12], data[13]);
|
||||
numDVRecords = IntegerHelper.getInt(data[14], data[15],
|
||||
data[16], data[17]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DValParser(int objid, int num) {
|
||||
objectId = objid;
|
||||
numDVRecords = num;
|
||||
validityDataCached = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
byte[] data = new byte[18];
|
||||
|
||||
int options = 0;
|
||||
|
||||
if (promptBoxVisible) {
|
||||
options |= PROMPT_BOX_VISIBLE_MASK;
|
||||
}
|
||||
|
||||
if (promptBoxAtCell) {
|
||||
options |= PROMPT_BOX_AT_CELL_MASK;
|
||||
}
|
||||
|
||||
if (validityDataCached) {
|
||||
options |= VALIDITY_DATA_CACHED_MASK;
|
||||
}
|
||||
|
||||
IntegerHelper.getTwoBytes(options, data, 0);
|
||||
|
||||
IntegerHelper.getFourBytes(objectId, data, 10);
|
||||
|
||||
IntegerHelper.getFourBytes(numDVRecords, data, 14);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a remove row or column results in one of DV records being
|
||||
* removed
|
||||
*/
|
||||
public void dvRemoved() {
|
||||
numDVRecords--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of DV records
|
||||
*
|
||||
* @return the number of DV records for this list
|
||||
*/
|
||||
public int getNumberOfDVRecords() {
|
||||
return numDVRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public int getObjectId() {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when adding a DV record on a copied DVal
|
||||
*/
|
||||
public void dvAdded() {
|
||||
numDVRecords++;
|
||||
}
|
||||
}
|
306
datastructures-xslx/src/main/java/jxl/biff/DataValidation.java
Executable file
306
datastructures-xslx/src/main/java/jxl/biff/DataValidation.java
Executable file
|
@ -0,0 +1,306 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.formula.ExternalSheet;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
|
||||
/**
|
||||
* Class which encapsulates a data validation. This encapsulates the
|
||||
* base DVAL record (DataValidityListRecord) and all the individual DV
|
||||
* (DataValiditySettingsRecord) records
|
||||
*/
|
||||
public class DataValidation {
|
||||
public static final int DEFAULT_OBJECT_ID = 0xffffffff;
|
||||
private static final int MAX_NO_OF_VALIDITY_SETTINGS = 0xfffd;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(DataValidation.class);
|
||||
/**
|
||||
* The data validity list
|
||||
*/
|
||||
private DataValidityListRecord validityList;
|
||||
/**
|
||||
* The list of data validity (DV) records
|
||||
*/
|
||||
private ArrayList validitySettings;
|
||||
/**
|
||||
* Handle to the workbook
|
||||
*/
|
||||
private WorkbookMethods workbook;
|
||||
/**
|
||||
* Handle to the external sheet
|
||||
*/
|
||||
private ExternalSheet externalSheet;
|
||||
/**
|
||||
* Handle to the workbook settings
|
||||
*/
|
||||
private WorkbookSettings workbookSettings;
|
||||
/**
|
||||
* The object id of the combo box used for drop downs
|
||||
*/
|
||||
private int comboBoxObjectId;
|
||||
/**
|
||||
* Indicates whether this was copied
|
||||
*/
|
||||
private final boolean copied;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DataValidation(DataValidityListRecord dvlr) {
|
||||
validityList = dvlr;
|
||||
validitySettings = new ArrayList(validityList.getNumberOfSettings());
|
||||
copied = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used to create writable data validations
|
||||
*/
|
||||
public DataValidation(int objId,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods wm,
|
||||
WorkbookSettings ws) {
|
||||
workbook = wm;
|
||||
externalSheet = es;
|
||||
workbookSettings = ws;
|
||||
validitySettings = new ArrayList();
|
||||
comboBoxObjectId = objId;
|
||||
copied = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy from read to write
|
||||
*/
|
||||
public DataValidation(DataValidation dv,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods wm,
|
||||
WorkbookSettings ws) {
|
||||
workbook = wm;
|
||||
externalSheet = es;
|
||||
workbookSettings = ws;
|
||||
copied = true;
|
||||
validityList = new DataValidityListRecord(dv.getDataValidityList());
|
||||
|
||||
validitySettings = new ArrayList();
|
||||
DataValiditySettingsRecord[] settings = dv.getDataValiditySettings();
|
||||
|
||||
for (int i = 0; i < settings.length; i++) {
|
||||
validitySettings.add(new DataValiditySettingsRecord(settings[i],
|
||||
externalSheet,
|
||||
workbook,
|
||||
workbookSettings));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new settings object to this data validation
|
||||
*/
|
||||
public void add(DataValiditySettingsRecord dvsr) {
|
||||
validitySettings.add(dvsr);
|
||||
dvsr.setDataValidation(this);
|
||||
|
||||
if (copied) {
|
||||
// adding a writable dv record to a copied validity list
|
||||
Assert.verify(validityList != null);
|
||||
validityList.dvAdded();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the validity list. Used when copying sheets
|
||||
*/
|
||||
public DataValidityListRecord getDataValidityList() {
|
||||
return validityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the validity settings. Used when copying sheets
|
||||
*/
|
||||
public DataValiditySettingsRecord[] getDataValiditySettings() {
|
||||
DataValiditySettingsRecord[] dvlr = new DataValiditySettingsRecord[0];
|
||||
return (DataValiditySettingsRecord[]) validitySettings.toArray(dvlr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the data validation
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
if (validitySettings.size() > MAX_NO_OF_VALIDITY_SETTINGS) {
|
||||
logger.warn("Maximum number of data validations exceeded - " +
|
||||
"truncating...");
|
||||
validitySettings = new ArrayList
|
||||
(validitySettings.subList(0, MAX_NO_OF_VALIDITY_SETTINGS - 1));
|
||||
Assert.verify(validitySettings.size() <= MAX_NO_OF_VALIDITY_SETTINGS);
|
||||
}
|
||||
|
||||
if (validityList == null) {
|
||||
DValParser dvp = new DValParser(comboBoxObjectId,
|
||||
validitySettings.size());
|
||||
validityList = new DataValidityListRecord(dvp);
|
||||
}
|
||||
|
||||
if (!validityList.hasDVRecords()) {
|
||||
return;
|
||||
}
|
||||
|
||||
outputFile.write(validityList);
|
||||
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dvsr = (DataValiditySettingsRecord) i.next();
|
||||
outputFile.write(dvsr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a row
|
||||
*
|
||||
* @param row the inserted row
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
dv.insertRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes row
|
||||
*
|
||||
* @param row the row to be removed
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
|
||||
if (dv.getFirstRow() == row && dv.getLastRow() == row) {
|
||||
i.remove();
|
||||
validityList.dvRemoved();
|
||||
} else {
|
||||
dv.removeRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column
|
||||
*
|
||||
* @param col the inserted column
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
dv.insertColumn(col);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column
|
||||
*
|
||||
* @param col the inserted column
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
|
||||
if (dv.getFirstColumn() == col && dv.getLastColumn() == col) {
|
||||
i.remove();
|
||||
validityList.dvRemoved();
|
||||
} else {
|
||||
dv.removeColumn(col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the data validation for a specific cell
|
||||
*
|
||||
* @param col the column
|
||||
* @param row the row
|
||||
*/
|
||||
public void removeDataValidation(int col, int row) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
|
||||
if (dv.getFirstColumn() == col && dv.getLastColumn() == col &&
|
||||
dv.getFirstRow() == row && dv.getLastRow() == row) {
|
||||
i.remove();
|
||||
validityList.dvRemoved();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the data validation for a specific cell
|
||||
*
|
||||
* @param col1 the first column
|
||||
* @param row1 the first row
|
||||
*/
|
||||
public void removeSharedDataValidation(int col1, int row1,
|
||||
int col2, int row2) {
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext(); ) {
|
||||
DataValiditySettingsRecord dv = (DataValiditySettingsRecord) i.next();
|
||||
|
||||
if (dv.getFirstColumn() == col1 && dv.getLastColumn() == col2 &&
|
||||
dv.getFirstRow() == row1 && dv.getLastRow() == row2) {
|
||||
i.remove();
|
||||
validityList.dvRemoved();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used during the copy process to retrieve the validity settings for
|
||||
* a particular cell
|
||||
*/
|
||||
public DataValiditySettingsRecord getDataValiditySettings(int col, int row) {
|
||||
boolean found = false;
|
||||
DataValiditySettingsRecord foundRecord = null;
|
||||
for (Iterator i = validitySettings.iterator(); i.hasNext() && !found; ) {
|
||||
DataValiditySettingsRecord dvsr = (DataValiditySettingsRecord) i.next();
|
||||
if (dvsr.getFirstColumn() == col && dvsr.getFirstRow() == row) {
|
||||
found = true;
|
||||
foundRecord = dvsr;
|
||||
}
|
||||
}
|
||||
|
||||
return foundRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the combo box, used when copying sheets
|
||||
*/
|
||||
public int getComboBoxObjectId() {
|
||||
return comboBoxObjectId;
|
||||
}
|
||||
}
|
151
datastructures-xslx/src/main/java/jxl/biff/DataValidityListRecord.java
Executable file
151
datastructures-xslx/src/main/java/jxl/biff/DataValidityListRecord.java
Executable file
|
@ -0,0 +1,151 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Record containing the list of data validation settings for a given sheet
|
||||
*/
|
||||
public class DataValidityListRecord extends WritableRecordData {
|
||||
private static final Logger logger = Logger.getLogger
|
||||
(DataValidityListRecord.class);
|
||||
|
||||
/**
|
||||
* The number of settings records associated with this list
|
||||
*/
|
||||
private int numSettings;
|
||||
|
||||
/**
|
||||
* The object id of the associated down arrow
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The dval parser
|
||||
*/
|
||||
private DValParser dvalParser;
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DataValidityListRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
data = getRecord().getData();
|
||||
objectId = IntegerHelper.getInt(data[10], data[11], data[12], data[13]);
|
||||
numSettings = IntegerHelper.getInt(data[14], data[15], data[16], data[17]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when generating a data validity list from the API
|
||||
*/
|
||||
public DataValidityListRecord(DValParser dval) {
|
||||
super(Type.DVAL);
|
||||
|
||||
dvalParser = dval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param dvlr the record copied from a read only sheet
|
||||
*/
|
||||
DataValidityListRecord(DataValidityListRecord dvlr) {
|
||||
super(Type.DVAL);
|
||||
|
||||
data = dvlr.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of settings records associated with this list
|
||||
*/
|
||||
int getNumberOfSettings() {
|
||||
return numSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
if (dvalParser == null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return dvalParser.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a remove row or column results in one of DV records being
|
||||
* removed
|
||||
*/
|
||||
void dvRemoved() {
|
||||
if (dvalParser == null) {
|
||||
dvalParser = new DValParser(data);
|
||||
}
|
||||
|
||||
dvalParser.dvRemoved();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a writable DV record is added to a copied validity list
|
||||
*/
|
||||
void dvAdded() {
|
||||
if (dvalParser == null) {
|
||||
dvalParser = new DValParser(data);
|
||||
}
|
||||
|
||||
dvalParser.dvAdded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of DV records
|
||||
*
|
||||
* @return the number of DV records for this list
|
||||
*/
|
||||
public boolean hasDVRecords() {
|
||||
if (dvalParser == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return dvalParser.getNumberOfDVRecords() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public int getObjectId() {
|
||||
if (dvalParser == null) {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
return dvalParser.getObjectId();
|
||||
}
|
||||
}
|
282
datastructures-xslx/src/main/java/jxl/biff/DataValiditySettingsRecord.java
Executable file
282
datastructures-xslx/src/main/java/jxl/biff/DataValiditySettingsRecord.java
Executable file
|
@ -0,0 +1,282 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.formula.ExternalSheet;
|
||||
import jxl.biff.formula.FormulaException;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Data validity settings. Contains an individual Data validation (DV).
|
||||
* All the computationa work is delegated to the DVParser object
|
||||
*/
|
||||
public class DataValiditySettingsRecord extends WritableRecordData {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(DataValiditySettingsRecord.class);
|
||||
|
||||
/**
|
||||
* The binary data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* The reader
|
||||
*/
|
||||
private DVParser dvParser;
|
||||
|
||||
/**
|
||||
* Handle to the workbook
|
||||
*/
|
||||
private WorkbookMethods workbook;
|
||||
|
||||
/**
|
||||
* Handle to the externalSheet
|
||||
*/
|
||||
private ExternalSheet externalSheet;
|
||||
|
||||
/**
|
||||
* Handle to the workbook settings
|
||||
*/
|
||||
private WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Handle to the data validation record
|
||||
*/
|
||||
private DataValidation dataValidation;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DataValiditySettingsRecord(Record t,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods wm,
|
||||
WorkbookSettings ws) {
|
||||
super(t);
|
||||
|
||||
data = t.getData();
|
||||
externalSheet = es;
|
||||
workbook = wm;
|
||||
workbookSettings = ws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
DataValiditySettingsRecord(DataValiditySettingsRecord dvsr) {
|
||||
super(Type.DV);
|
||||
|
||||
data = dvsr.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when copying sheets
|
||||
*
|
||||
* @param dvsr the record copied from a writable sheet
|
||||
*/
|
||||
DataValiditySettingsRecord(DataValiditySettingsRecord dvsr,
|
||||
ExternalSheet es,
|
||||
WorkbookMethods w,
|
||||
WorkbookSettings ws) {
|
||||
super(Type.DV);
|
||||
|
||||
workbook = w;
|
||||
externalSheet = es;
|
||||
workbookSettings = ws;
|
||||
|
||||
Assert.verify(w != null);
|
||||
Assert.verify(es != null);
|
||||
|
||||
data = new byte[dvsr.data.length];
|
||||
System.arraycopy(dvsr.data, 0, data, 0, data.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called when the API creates a writable data validation
|
||||
*
|
||||
* @param dvsr the record copied from a writable sheet
|
||||
*/
|
||||
public DataValiditySettingsRecord(DVParser dvp) {
|
||||
super(Type.DV);
|
||||
dvParser = dvp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the dvParser
|
||||
*/
|
||||
private void initialize() {
|
||||
if (dvParser == null) {
|
||||
dvParser = new DVParser(data, externalSheet,
|
||||
workbook, workbookSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
if (dvParser == null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return dvParser.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a row
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void insertRow(int row) {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
dvParser.insertRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row
|
||||
*
|
||||
* @param row the row to insert
|
||||
*/
|
||||
public void removeRow(int row) {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
dvParser.removeRow(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a row
|
||||
*
|
||||
* @param col the row to insert
|
||||
*/
|
||||
public void insertColumn(int col) {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
dvParser.insertColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column
|
||||
*
|
||||
* @param col the row to insert
|
||||
*/
|
||||
public void removeColumn(int col) {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
dvParser.removeColumn(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for first column
|
||||
*
|
||||
* @return the first column
|
||||
*/
|
||||
public int getFirstColumn() {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return dvParser.getFirstColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last column
|
||||
*
|
||||
* @return the last column
|
||||
*/
|
||||
public int getLastColumn() {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return dvParser.getLastColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for first row
|
||||
*
|
||||
* @return the first row
|
||||
*/
|
||||
public int getFirstRow() {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return dvParser.getFirstRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the last row
|
||||
*
|
||||
* @return the last row
|
||||
*/
|
||||
public int getLastRow() {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return dvParser.getLastRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handle to the data validation record
|
||||
*
|
||||
* @param dv the data validation
|
||||
*/
|
||||
void setDataValidation(DataValidation dv) {
|
||||
dataValidation = dv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DVParser. This is used when doing a deep copy of cells
|
||||
* on the writable side of things
|
||||
*/
|
||||
DVParser getDVParser() {
|
||||
return dvParser;
|
||||
}
|
||||
|
||||
public String getValidationFormula() {
|
||||
try {
|
||||
if (dvParser == null) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return dvParser.getValidationFormula();
|
||||
} catch (FormulaException e) {
|
||||
logger.warn("Cannot read drop down range " + e.getMessage());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
55
datastructures-xslx/src/main/java/jxl/biff/DisplayFormat.java
Executable file
55
datastructures-xslx/src/main/java/jxl/biff/DisplayFormat.java
Executable file
|
@ -0,0 +1,55 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* The interface implemented by the various number and date format styles.
|
||||
* The methods on this interface are called internally when generating a
|
||||
* spreadsheet
|
||||
*/
|
||||
public interface DisplayFormat {
|
||||
/**
|
||||
* Accessor for the index style of this format
|
||||
*
|
||||
* @return the index for this format
|
||||
*/
|
||||
int getFormatIndex();
|
||||
|
||||
/**
|
||||
* Accessor to see whether this format has been initialized
|
||||
*
|
||||
* @return TRUE if initialized, FALSE otherwise
|
||||
*/
|
||||
boolean isInitialized();
|
||||
|
||||
/**
|
||||
* Initializes this format with the specified index number
|
||||
*
|
||||
* @param pos the position of this format record in the workbook
|
||||
*/
|
||||
void initialize(int pos);
|
||||
|
||||
/**
|
||||
* Accessor to determine whether or not this format is built in
|
||||
*
|
||||
* @return TRUE if this format is a built in format, FALSE otherwise
|
||||
*/
|
||||
boolean isBuiltIn();
|
||||
}
|
84
datastructures-xslx/src/main/java/jxl/biff/DoubleHelper.java
Executable file
84
datastructures-xslx/src/main/java/jxl/biff/DoubleHelper.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Class to help handle doubles
|
||||
*/
|
||||
public class DoubleHelper {
|
||||
/**
|
||||
* Private constructor to prevent instantiation
|
||||
*/
|
||||
private DoubleHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the IEEE value from the byte array passed in
|
||||
*
|
||||
* @param pos the position in the data block which contains the double value
|
||||
* @param data the data block containing the raw bytes
|
||||
* @return the double value converted from the raw data
|
||||
*/
|
||||
public static double getIEEEDouble(byte[] data, int pos) {
|
||||
int num1 = IntegerHelper.getInt(data[pos], data[pos + 1],
|
||||
data[pos + 2], data[pos + 3]);
|
||||
int num2 = IntegerHelper.getInt(data[pos + 4], data[pos + 5],
|
||||
data[pos + 6], data[pos + 7]);
|
||||
|
||||
// Long.parseLong doesn't like the sign bit, so have to extract this
|
||||
// information and put it in at the end. (Acknowledgment: thanks
|
||||
// to Ruben for pointing this out)
|
||||
boolean negative = ((num2 & 0x80000000) != 0);
|
||||
|
||||
// Thanks to Lyle for the following improved IEEE double processing
|
||||
long val = ((num2 & 0x7fffffff) * 0x100000000L) +
|
||||
(num1 < 0 ? 0x100000000L + num1 : num1);
|
||||
double value = Double.longBitsToDouble(val);
|
||||
|
||||
if (negative) {
|
||||
value = -value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the IEEE representation of the double provided into the array
|
||||
* at the designated position
|
||||
*
|
||||
* @param target the data block into which the binary representation is to
|
||||
* be placed
|
||||
* @param pos the position in target in which to place the bytes
|
||||
* @param d the double value to convert to raw bytes
|
||||
*/
|
||||
public static void getIEEEBytes(double d, byte[] target, int pos) {
|
||||
long val = Double.doubleToLongBits(d);
|
||||
target[pos] = (byte) (val & 0xff);
|
||||
target[pos + 1] = (byte) ((val & 0xff00) >> 8);
|
||||
target[pos + 2] = (byte) ((val & 0xff0000) >> 16);
|
||||
target[pos + 3] = (byte) ((val & 0xff000000) >> 24);
|
||||
target[pos + 4] = (byte) ((val & 0xff00000000L) >> 32);
|
||||
target[pos + 5] = (byte) ((val & 0xff0000000000L) >> 40);
|
||||
target[pos + 6] = (byte) ((val & 0xff000000000000L) >> 48);
|
||||
target[pos + 7] = (byte) ((val & 0xff00000000000000L) >> 56);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
207
datastructures-xslx/src/main/java/jxl/biff/EmptyCell.java
Executable file
207
datastructures-xslx/src/main/java/jxl/biff/EmptyCell.java
Executable file
|
@ -0,0 +1,207 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.CellFeatures;
|
||||
import jxl.CellType;
|
||||
import jxl.format.Alignment;
|
||||
import jxl.format.Border;
|
||||
import jxl.format.BorderLineStyle;
|
||||
import jxl.format.CellFormat;
|
||||
import jxl.format.VerticalAlignment;
|
||||
import jxl.write.WritableCell;
|
||||
import jxl.write.WritableCellFeatures;
|
||||
|
||||
/**
|
||||
* An empty cell. Represents an empty, as opposed to a blank cell
|
||||
* in the workbook
|
||||
*/
|
||||
public class EmptyCell implements WritableCell {
|
||||
/**
|
||||
* The row of this empty cell
|
||||
*/
|
||||
private final int row;
|
||||
/**
|
||||
* The column number of this empty cell
|
||||
*/
|
||||
private final int col;
|
||||
|
||||
/**
|
||||
* Constructs an empty cell at the specified position
|
||||
*
|
||||
* @param c the zero based column
|
||||
* @param r the zero based row
|
||||
*/
|
||||
public EmptyCell(int c, int r) {
|
||||
row = r;
|
||||
col = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row number of this cell
|
||||
*
|
||||
* @return the row number of this cell
|
||||
*/
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column number of this cell
|
||||
*
|
||||
* @return the column number of this cell
|
||||
*/
|
||||
public int getColumn() {
|
||||
return col;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content type of this cell
|
||||
*
|
||||
* @return the content type for this cell
|
||||
*/
|
||||
public CellType getType() {
|
||||
return CellType.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick and dirty function to return the contents of this cell as a string.
|
||||
*
|
||||
* @return an empty string
|
||||
*/
|
||||
public String getContents() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the format which is applied to this cell
|
||||
*
|
||||
* @return the format applied to this cell
|
||||
*/
|
||||
public CellFormat getCellFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param cf dummy
|
||||
*/
|
||||
public void setCellFormat(CellFormat cf) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param cf dummy
|
||||
* @deprecated
|
||||
*/
|
||||
public void setCellFormat(jxl.CellFormat cf) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param flag dummy
|
||||
*/
|
||||
public void setLocked(boolean flag) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param align dummy
|
||||
*/
|
||||
public void setAlignment(Alignment align) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param valign dummy
|
||||
*/
|
||||
public void setVerticalAlignment(VerticalAlignment valign) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param line dummy
|
||||
* @param border dummy
|
||||
*/
|
||||
public void setBorder(Border border, BorderLineStyle line) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not this cell is hidden, by virtue of either
|
||||
* the entire row or column being collapsed
|
||||
*
|
||||
* @return TRUE if this cell is hidden, FALSE otherwise
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy override
|
||||
*
|
||||
* @param flag the hidden flag
|
||||
*/
|
||||
public void setHidden(boolean flag) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the deep copy function
|
||||
*
|
||||
* @param c the column which the new cell will occupy
|
||||
* @param r the row which the new cell will occupy
|
||||
* @return a copy of this cell, which can then be added to the sheet
|
||||
*/
|
||||
public WritableCell copyTo(int c, int r) {
|
||||
return new EmptyCell(c, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell features
|
||||
*
|
||||
* @return the cell features or NULL if this cell doesn't have any
|
||||
*/
|
||||
public CellFeatures getCellFeatures() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell features
|
||||
*/
|
||||
public void setCellFeatures(WritableCellFeatures wcf) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the cell features
|
||||
*
|
||||
* @return the cell features or NULL if this cell doesn't have any
|
||||
*/
|
||||
public WritableCellFeatures getWritableCellFeatures() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
117
datastructures-xslx/src/main/java/jxl/biff/EncodedURLHelper.java
Executable file
117
datastructures-xslx/src/main/java/jxl/biff/EncodedURLHelper.java
Executable file
|
@ -0,0 +1,117 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Helper to get the Microsoft encoded URL from the given string
|
||||
*/
|
||||
public class EncodedURLHelper {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(EncodedURLHelper.class);
|
||||
|
||||
// The control codes
|
||||
private static final byte msDosDriveLetter = 0x01;
|
||||
private static final byte sameDrive = 0x02;
|
||||
private static final byte endOfSubdirectory = 0x03;
|
||||
private static final byte parentDirectory = 0x04;
|
||||
private static final byte unencodedUrl = 0x05;
|
||||
|
||||
public static byte[] getEncodedURL(String s, WorkbookSettings ws) {
|
||||
if (s.startsWith("http:")) {
|
||||
return getURL(s, ws);
|
||||
} else {
|
||||
return getFile(s, ws);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getFile(String s, WorkbookSettings ws) {
|
||||
ByteArray byteArray = new ByteArray();
|
||||
|
||||
int pos = 0;
|
||||
if (s.charAt(1) == ':') {
|
||||
// we have a drive letter
|
||||
byteArray.add(msDosDriveLetter);
|
||||
byteArray.add((byte) s.charAt(0));
|
||||
pos = 2;
|
||||
} else if (s.charAt(pos) == '\\' ||
|
||||
s.charAt(pos) == '/') {
|
||||
byteArray.add(sameDrive);
|
||||
}
|
||||
|
||||
while (s.charAt(pos) == '\\' ||
|
||||
s.charAt(pos) == '/') {
|
||||
pos++;
|
||||
}
|
||||
|
||||
while (pos < s.length()) {
|
||||
int nextSepIndex1 = s.indexOf('/', pos);
|
||||
int nextSepIndex2 = s.indexOf('\\', pos);
|
||||
int nextSepIndex = 0;
|
||||
String nextFileNameComponent = null;
|
||||
|
||||
if (nextSepIndex1 != -1 && nextSepIndex2 != -1) {
|
||||
// choose the smallest (ie. nearest) separator
|
||||
nextSepIndex = Math.min(nextSepIndex1, nextSepIndex2);
|
||||
} else if (nextSepIndex1 == -1 || nextSepIndex2 == -1) {
|
||||
// chose the maximum separator
|
||||
nextSepIndex = Math.max(nextSepIndex1, nextSepIndex2);
|
||||
}
|
||||
|
||||
if (nextSepIndex == -1) {
|
||||
// no more separators
|
||||
nextFileNameComponent = s.substring(pos);
|
||||
pos = s.length();
|
||||
} else {
|
||||
nextFileNameComponent = s.substring(pos, nextSepIndex);
|
||||
pos = nextSepIndex + 1;
|
||||
}
|
||||
|
||||
if (nextFileNameComponent.equals(".")) {
|
||||
// current directory - do nothing
|
||||
} else if (nextFileNameComponent.equals("..")) {
|
||||
// parent directory
|
||||
byteArray.add(parentDirectory);
|
||||
} else {
|
||||
// add the filename component
|
||||
byteArray.add(StringHelper.getBytes(nextFileNameComponent,
|
||||
ws));
|
||||
}
|
||||
|
||||
if (pos < s.length()) {
|
||||
byteArray.add(endOfSubdirectory);
|
||||
}
|
||||
}
|
||||
|
||||
return byteArray.getBytes();
|
||||
}
|
||||
|
||||
private static byte[] getURL(String s, WorkbookSettings ws) {
|
||||
ByteArray byteArray = new ByteArray();
|
||||
byteArray.add(unencodedUrl);
|
||||
byteArray.add((byte) s.length());
|
||||
byteArray.add(StringHelper.getBytes(s, ws));
|
||||
return byteArray.getBytes();
|
||||
}
|
||||
}
|
56
datastructures-xslx/src/main/java/jxl/biff/FilterModeRecord.java
Executable file
56
datastructures-xslx/src/main/java/jxl/biff/FilterModeRecord.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Range information for conditional formatting
|
||||
*/
|
||||
public class FilterModeRecord extends WritableRecordData {
|
||||
// The logger
|
||||
private static final Logger logger = Logger.getLogger(FilterModeRecord.class);
|
||||
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private final byte[] data;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public FilterModeRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
data = getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data for output to binary file
|
||||
*
|
||||
* @return the data to be written
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
501
datastructures-xslx/src/main/java/jxl/biff/FontRecord.java
Executable file
501
datastructures-xslx/src/main/java/jxl/biff/FontRecord.java
Executable file
|
@ -0,0 +1,501 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.format.Colour;
|
||||
import jxl.format.Font;
|
||||
import jxl.format.ScriptStyle;
|
||||
import jxl.format.UnderlineStyle;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A record containing the necessary data for the font information
|
||||
*/
|
||||
public class FontRecord extends WritableRecordData implements Font {
|
||||
public static final Biff7 biff7 = new Biff7();
|
||||
/**
|
||||
* The conversion factor between microsoft internal units and point size
|
||||
*/
|
||||
private static final int EXCEL_UNITS_PER_POINT = 20;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(FontRecord.class);
|
||||
/**
|
||||
* The point height of this font
|
||||
*/
|
||||
private int pointHeight;
|
||||
/**
|
||||
* The index into the colour palette
|
||||
*/
|
||||
private int colourIndex;
|
||||
/**
|
||||
* The bold weight for this font (normal or bold)
|
||||
*/
|
||||
private int boldWeight;
|
||||
/**
|
||||
* The style of the script (italic or normal)
|
||||
*/
|
||||
private int scriptStyle;
|
||||
/**
|
||||
* The underline style for this font (none, single, double etc)
|
||||
*/
|
||||
private int underlineStyle;
|
||||
/**
|
||||
* The font family
|
||||
*/
|
||||
private byte fontFamily;
|
||||
/**
|
||||
* The character set
|
||||
*/
|
||||
private byte characterSet;
|
||||
/**
|
||||
* Indicates whether or not this font is italic
|
||||
*/
|
||||
private boolean italic;
|
||||
/**
|
||||
* Indicates whether or not this font is struck out
|
||||
*/
|
||||
private boolean struckout;
|
||||
/**
|
||||
* The name of this font
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* Flag to indicate whether the derived data (such as the font index) has
|
||||
* been initialized or not
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* The index of this font in the font list
|
||||
*/
|
||||
private int fontIndex;
|
||||
|
||||
/**
|
||||
* Constructor, used when creating a new font for writing out.
|
||||
*
|
||||
* @param bold the bold indicator
|
||||
* @param ps the point size
|
||||
* @param us the underline style
|
||||
* @param fn the name
|
||||
* @param it italicised indicator
|
||||
* @param ss the script style
|
||||
* @param ci the colour index
|
||||
*/
|
||||
protected FontRecord(String fn, int ps, int bold, boolean it,
|
||||
int us, int ci, int ss) {
|
||||
super(Type.FONT);
|
||||
boldWeight = bold;
|
||||
underlineStyle = us;
|
||||
name = fn;
|
||||
pointHeight = ps;
|
||||
italic = it;
|
||||
scriptStyle = ss;
|
||||
colourIndex = ci;
|
||||
initialized = false;
|
||||
struckout = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data. Used when reading in a
|
||||
* format record
|
||||
*
|
||||
* @param t the raw data
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public FontRecord(Record t, WorkbookSettings ws) {
|
||||
super(t);
|
||||
|
||||
byte[] data = getRecord().getData();
|
||||
|
||||
pointHeight = IntegerHelper.getInt(data[0], data[1]) /
|
||||
EXCEL_UNITS_PER_POINT;
|
||||
colourIndex = IntegerHelper.getInt(data[4], data[5]);
|
||||
boldWeight = IntegerHelper.getInt(data[6], data[7]);
|
||||
scriptStyle = IntegerHelper.getInt(data[8], data[9]);
|
||||
underlineStyle = data[10];
|
||||
fontFamily = data[11];
|
||||
characterSet = data[12];
|
||||
initialized = false;
|
||||
|
||||
if ((data[2] & 0x02) != 0) {
|
||||
italic = true;
|
||||
}
|
||||
|
||||
if ((data[2] & 0x08) != 0) {
|
||||
struckout = true;
|
||||
}
|
||||
|
||||
int numChars = data[14];
|
||||
if (data[15] == 0) {
|
||||
name = StringHelper.getString(data, numChars, 16, ws);
|
||||
} else if (data[15] == 1) {
|
||||
name = StringHelper.getUnicodeString(data, numChars, 16);
|
||||
} else {
|
||||
// Some font names don't have the unicode indicator
|
||||
name = StringHelper.getString(data, numChars, 15, ws);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data. Used when reading in a
|
||||
* format record
|
||||
*
|
||||
* @param t the raw data
|
||||
* @param ws the workbook settings
|
||||
* @param dummy dummy overload
|
||||
*/
|
||||
public FontRecord(Record t, WorkbookSettings ws, Biff7 dummy) {
|
||||
super(t);
|
||||
|
||||
byte[] data = getRecord().getData();
|
||||
|
||||
pointHeight = IntegerHelper.getInt(data[0], data[1]) /
|
||||
EXCEL_UNITS_PER_POINT;
|
||||
colourIndex = IntegerHelper.getInt(data[4], data[5]);
|
||||
boldWeight = IntegerHelper.getInt(data[6], data[7]);
|
||||
scriptStyle = IntegerHelper.getInt(data[8], data[9]);
|
||||
underlineStyle = data[10];
|
||||
fontFamily = data[11];
|
||||
initialized = false;
|
||||
|
||||
if ((data[2] & 0x02) != 0) {
|
||||
italic = true;
|
||||
}
|
||||
|
||||
if ((data[2] & 0x08) != 0) {
|
||||
struckout = true;
|
||||
}
|
||||
|
||||
int numChars = data[14];
|
||||
name = StringHelper.getString(data, numChars, 15, ws);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publicly available copy constructor
|
||||
*
|
||||
* @param f the font to copy
|
||||
*/
|
||||
protected FontRecord(Font f) {
|
||||
super(Type.FONT);
|
||||
|
||||
Assert.verify(f != null);
|
||||
|
||||
pointHeight = f.getPointSize();
|
||||
colourIndex = f.getColour().getValue();
|
||||
boldWeight = f.getBoldWeight();
|
||||
scriptStyle = f.getScriptStyle().getValue();
|
||||
underlineStyle = f.getUnderlineStyle().getValue();
|
||||
italic = f.isItalic();
|
||||
name = f.getName();
|
||||
struckout = f.isStruckout();
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byte data for writing out
|
||||
*
|
||||
* @return the raw data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
byte[] data = new byte[16 + name.length() * 2];
|
||||
|
||||
// Excel expects font heights in 1/20ths of a point
|
||||
IntegerHelper.getTwoBytes(pointHeight * EXCEL_UNITS_PER_POINT, data, 0);
|
||||
|
||||
// Set the font attributes to be zero for now
|
||||
if (italic) {
|
||||
data[2] |= 0x2;
|
||||
}
|
||||
|
||||
if (struckout) {
|
||||
data[2] |= 0x08;
|
||||
}
|
||||
|
||||
// Set the index to the colour palette
|
||||
IntegerHelper.getTwoBytes(colourIndex, data, 4);
|
||||
|
||||
// Bold style
|
||||
IntegerHelper.getTwoBytes(boldWeight, data, 6);
|
||||
|
||||
// Script style
|
||||
IntegerHelper.getTwoBytes(scriptStyle, data, 8);
|
||||
|
||||
// Underline style
|
||||
data[10] = (byte) underlineStyle;
|
||||
|
||||
// Set the font family to be 0
|
||||
data[11] = fontFamily;
|
||||
|
||||
// Set the character set to be zero
|
||||
data[12] = characterSet;
|
||||
|
||||
// Set the reserved bit to be zero
|
||||
data[13] = 0;
|
||||
|
||||
// Set the length of the font name
|
||||
data[14] = (byte) name.length();
|
||||
|
||||
data[15] = (byte) 1;
|
||||
|
||||
// Copy in the string
|
||||
StringHelper.getUnicodeBytes(name, data, 16);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to see whether this object is initialized or not.
|
||||
*
|
||||
* @return TRUE if this font record has been initialized, FALSE otherwise
|
||||
*/
|
||||
public final boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font index of this record. Called from the FormattingRecords
|
||||
* object
|
||||
*
|
||||
* @param pos the position of this font in the workbooks font list
|
||||
*/
|
||||
public final void initialize(int pos) {
|
||||
fontIndex = pos;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the initialize flag. This is called by the constructor of
|
||||
* WritableWorkbookImpl to reset the statically declared fonts
|
||||
*/
|
||||
public final void uninitialize() {
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the font index
|
||||
*
|
||||
* @return the font index
|
||||
*/
|
||||
public final int getFontIndex() {
|
||||
return fontIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the point size for this font, if the font hasn't been initialized
|
||||
*
|
||||
* @param ps the point size
|
||||
*/
|
||||
protected void setFontPointSize(int ps) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
pointHeight = ps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the point size for this font, if the font hasn't been initialized
|
||||
*
|
||||
* @return the point size
|
||||
*/
|
||||
public int getPointSize() {
|
||||
return pointHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bold style for this font, if the font hasn't been initialized
|
||||
*
|
||||
* @param bs the bold style
|
||||
*/
|
||||
protected void setFontBoldStyle(int bs) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
boldWeight = bs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bold weight for this font
|
||||
*
|
||||
* @return the bold weight for this font
|
||||
*/
|
||||
public int getBoldWeight() {
|
||||
return boldWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the italic indicator for this font, if the font hasn't been
|
||||
* initialized
|
||||
*
|
||||
* @param i the italic flag
|
||||
*/
|
||||
protected void setFontItalic(boolean i) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
italic = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the italic flag
|
||||
*
|
||||
* @return TRUE if this font is italic, FALSE otherwise
|
||||
*/
|
||||
public boolean isItalic() {
|
||||
return italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the underline style for this font, if the font hasn't been
|
||||
* initialized
|
||||
*
|
||||
* @param us the underline style
|
||||
*/
|
||||
protected void setFontUnderlineStyle(int us) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
underlineStyle = us;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underline style for this font
|
||||
*
|
||||
* @return the underline style
|
||||
*/
|
||||
public UnderlineStyle getUnderlineStyle() {
|
||||
return UnderlineStyle.getStyle(underlineStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the colour for this font, if the font hasn't been
|
||||
* initialized
|
||||
*
|
||||
* @param c the colour
|
||||
*/
|
||||
protected void setFontColour(int c) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
colourIndex = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the colour for this font
|
||||
*
|
||||
* @return the colour
|
||||
*/
|
||||
public Colour getColour() {
|
||||
return Colour.getInternalColour(colourIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the script style (eg. superscript, subscript) for this font,
|
||||
* if the font hasn't been initialized
|
||||
*
|
||||
* @param ss the colour
|
||||
*/
|
||||
protected void setFontScriptStyle(int ss) {
|
||||
Assert.verify(!initialized);
|
||||
|
||||
scriptStyle = ss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the script style
|
||||
*
|
||||
* @return the script style
|
||||
*/
|
||||
public ScriptStyle getScriptStyle() {
|
||||
return ScriptStyle.getStyle(scriptStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this font
|
||||
*
|
||||
* @return the name of this font
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard hash code method
|
||||
*
|
||||
* @return the hash code for this object
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard equals method
|
||||
*
|
||||
* @param o the object to compare
|
||||
* @return TRUE if the objects are equal, FALSE otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof FontRecord)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FontRecord font = (FontRecord) o;
|
||||
|
||||
return pointHeight == font.pointHeight &&
|
||||
colourIndex == font.colourIndex &&
|
||||
boldWeight == font.boldWeight &&
|
||||
scriptStyle == font.scriptStyle &&
|
||||
underlineStyle == font.underlineStyle &&
|
||||
italic == font.italic &&
|
||||
struckout == font.struckout &&
|
||||
fontFamily == font.fontFamily &&
|
||||
characterSet == font.characterSet &&
|
||||
name.equals(font.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the strike out flag
|
||||
*
|
||||
* @return TRUE if this font is struck out, FALSE otherwise
|
||||
*/
|
||||
public boolean isStruckout() {
|
||||
return struckout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the struck out flag
|
||||
*
|
||||
* @param os TRUE if the font is struck out, false otherwise
|
||||
*/
|
||||
protected void setFontStruckout(boolean os) {
|
||||
struckout = os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy indicators for overloading the constructor
|
||||
*/
|
||||
private static class Biff7 {
|
||||
}
|
||||
}
|
||||
|
||||
|
162
datastructures-xslx/src/main/java/jxl/biff/Fonts.java
Executable file
162
datastructures-xslx/src/main/java/jxl/biff/Fonts.java
Executable file
|
@ -0,0 +1,162 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import jxl.common.Assert;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* A container for the list of fonts used in this workbook
|
||||
*/
|
||||
public class Fonts {
|
||||
/**
|
||||
* The default number of fonts
|
||||
*/
|
||||
private static final int numDefaultFonts = 4;
|
||||
/**
|
||||
* The list of fonts
|
||||
*/
|
||||
private ArrayList fonts;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Fonts() {
|
||||
fonts = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a font record to this workbook. If the FontRecord passed in has not
|
||||
* been initialized, then its font index is determined based upon the size
|
||||
* of the fonts list. The FontRecord's initialized method is called, and
|
||||
* it is added to the list of fonts.
|
||||
*
|
||||
* @param f the font to add
|
||||
*/
|
||||
public void addFont(FontRecord f) {
|
||||
if (!f.isInitialized()) {
|
||||
int pos = fonts.size();
|
||||
|
||||
// Remember that the pos with index 4 is skipped
|
||||
if (pos >= 4) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
f.initialize(pos);
|
||||
fonts.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by FormattingRecord for retrieving the fonts for the
|
||||
* hardcoded styles
|
||||
*
|
||||
* @param index the index of the font to return
|
||||
* @return the font with the specified font index
|
||||
*/
|
||||
public FontRecord getFont(int index) {
|
||||
// remember to allow for the fact that font index 4 is not used
|
||||
if (index > 4) {
|
||||
index--;
|
||||
}
|
||||
|
||||
return (FontRecord) fonts.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the list of fonts
|
||||
*
|
||||
* @param outputFile the compound file to write the data to
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
Iterator i = fonts.iterator();
|
||||
|
||||
FontRecord font = null;
|
||||
while (i.hasNext()) {
|
||||
font = (FontRecord) i.next();
|
||||
outputFile.write(font);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rationalizes all the fonts, removing any duplicates
|
||||
*
|
||||
* @return the mappings between new indexes and old ones
|
||||
*/
|
||||
IndexMapping rationalize() {
|
||||
IndexMapping mapping = new IndexMapping(fonts.size() + 1);
|
||||
// allow for skipping record 4
|
||||
|
||||
ArrayList newfonts = new ArrayList();
|
||||
FontRecord fr = null;
|
||||
int numremoved = 0;
|
||||
|
||||
// Preserve the default fonts
|
||||
for (int i = 0; i < numDefaultFonts; i++) {
|
||||
fr = (FontRecord) fonts.get(i);
|
||||
newfonts.add(fr);
|
||||
mapping.setMapping(fr.getFontIndex(), fr.getFontIndex());
|
||||
}
|
||||
|
||||
// Now do the rest
|
||||
Iterator it = null;
|
||||
FontRecord fr2 = null;
|
||||
boolean duplicate = false;
|
||||
for (int i = numDefaultFonts; i < fonts.size(); i++) {
|
||||
fr = (FontRecord) fonts.get(i);
|
||||
|
||||
// Compare to all the fonts currently on the list
|
||||
duplicate = false;
|
||||
it = newfonts.iterator();
|
||||
while (it.hasNext() && !duplicate) {
|
||||
fr2 = (FontRecord) it.next();
|
||||
if (fr.equals(fr2)) {
|
||||
duplicate = true;
|
||||
mapping.setMapping(fr.getFontIndex(),
|
||||
mapping.getNewIndex(fr2.getFontIndex()));
|
||||
numremoved++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!duplicate) {
|
||||
// Add to the new list
|
||||
newfonts.add(fr);
|
||||
int newindex = fr.getFontIndex() - numremoved;
|
||||
Assert.verify(newindex > 4);
|
||||
mapping.setMapping(fr.getFontIndex(), newindex);
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through the remaining fonts, updating all the font indices
|
||||
it = newfonts.iterator();
|
||||
while (it.hasNext()) {
|
||||
fr = (FontRecord) it.next();
|
||||
fr.initialize(mapping.getNewIndex(fr.getFontIndex()));
|
||||
}
|
||||
|
||||
fonts = newfonts;
|
||||
|
||||
return mapping;
|
||||
}
|
||||
}
|
551
datastructures-xslx/src/main/java/jxl/biff/FormatRecord.java
Executable file
551
datastructures-xslx/src/main/java/jxl/biff/FormatRecord.java
Executable file
|
@ -0,0 +1,551 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.common.Logger;
|
||||
import jxl.format.Format;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A non-built in format record
|
||||
*/
|
||||
public class FormatRecord extends WritableRecordData
|
||||
implements DisplayFormat, Format {
|
||||
public static final BiffType biff8 = new BiffType();
|
||||
public static final BiffType biff7 = new BiffType();
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
public static Logger logger = Logger.getLogger(FormatRecord.class);
|
||||
/**
|
||||
* The date strings to look for
|
||||
*/
|
||||
private static final String[] dateStrings = new String[]
|
||||
{
|
||||
"dd",
|
||||
"mm",
|
||||
"yy",
|
||||
"hh",
|
||||
"ss",
|
||||
"m/",
|
||||
"/d"
|
||||
};
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized;
|
||||
/**
|
||||
* The raw data
|
||||
*/
|
||||
private byte[] data;
|
||||
/**
|
||||
* The index code
|
||||
*/
|
||||
private int indexCode;
|
||||
/**
|
||||
* The formatting string
|
||||
*/
|
||||
private String formatString;
|
||||
/**
|
||||
* Indicates whether this is a date formatting record
|
||||
*/
|
||||
private boolean date;
|
||||
/**
|
||||
* Indicates whether this a number formatting record
|
||||
*/
|
||||
private boolean number;
|
||||
/**
|
||||
* The format object
|
||||
*/
|
||||
private java.text.Format format;
|
||||
/**
|
||||
* Constructor invoked when copying sheets
|
||||
*
|
||||
* @param fmt the format string
|
||||
* @param refno the index code
|
||||
*/
|
||||
FormatRecord(String fmt, int refno) {
|
||||
super(Type.FORMAT);
|
||||
formatString = fmt;
|
||||
indexCode = refno;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used by writable formats
|
||||
*/
|
||||
protected FormatRecord() {
|
||||
super(Type.FORMAT);
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor - can be invoked by public access
|
||||
*
|
||||
* @param fr the format to copy
|
||||
*/
|
||||
protected FormatRecord(FormatRecord fr) {
|
||||
super(Type.FORMAT);
|
||||
initialized = false;
|
||||
|
||||
formatString = fr.formatString;
|
||||
date = fr.date;
|
||||
number = fr.number;
|
||||
// format = (java.text.Format) fr.format.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data. Used when reading in a
|
||||
* format record
|
||||
*
|
||||
* @param t the raw data
|
||||
* @param ws the workbook settings
|
||||
* @param biffType biff type dummy overload
|
||||
*/
|
||||
public FormatRecord(Record t, WorkbookSettings ws, BiffType biffType) {
|
||||
super(t);
|
||||
|
||||
byte[] data = getRecord().getData();
|
||||
indexCode = IntegerHelper.getInt(data[0], data[1]);
|
||||
initialized = true;
|
||||
|
||||
if (biffType == biff8) {
|
||||
int numchars = IntegerHelper.getInt(data[2], data[3]);
|
||||
if (data[4] == 0) {
|
||||
formatString = StringHelper.getString(data, numchars, 5, ws);
|
||||
} else {
|
||||
formatString = StringHelper.getUnicodeString(data, numchars, 5);
|
||||
}
|
||||
} else {
|
||||
int numchars = data[2];
|
||||
byte[] chars = new byte[numchars];
|
||||
System.arraycopy(data, 3, chars, 0, chars.length);
|
||||
formatString = new String(chars);
|
||||
}
|
||||
|
||||
date = false;
|
||||
number = false;
|
||||
|
||||
// First see if this is a date format
|
||||
for (int i = 0; i < dateStrings.length; i++) {
|
||||
String dateString = dateStrings[i];
|
||||
if (formatString.indexOf(dateString) != -1 ||
|
||||
formatString.indexOf(dateString.toUpperCase()) != -1) {
|
||||
date = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is number format - look for the # or 0 characters
|
||||
if (!date) {
|
||||
if (formatString.indexOf('#') != -1 ||
|
||||
formatString.indexOf('0') != -1) {
|
||||
number = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the data when writing out the format record
|
||||
*
|
||||
* @return the raw data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
data = new byte[formatString.length() * 2 + 3 + 2];
|
||||
|
||||
IntegerHelper.getTwoBytes(indexCode, data, 0);
|
||||
IntegerHelper.getTwoBytes(formatString.length(), data, 2);
|
||||
data[4] = (byte) 1; // unicode indicator
|
||||
StringHelper.getUnicodeBytes(formatString, data, 5);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format index of this record
|
||||
*
|
||||
* @return the format index of this record
|
||||
*/
|
||||
public int getFormatIndex() {
|
||||
return indexCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to see whether this object is initialized or not.
|
||||
*
|
||||
* @return TRUE if this font record has been initialized, FALSE otherwise
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index of this record. Called from the FormattingRecords
|
||||
* object
|
||||
*
|
||||
* @param pos the position of this font in the workbooks font list
|
||||
*/
|
||||
|
||||
public void initialize(int pos) {
|
||||
indexCode = pos;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all instances of search with replace in the input. Used for
|
||||
* replacing microsoft number formatting characters with java equivalents
|
||||
*
|
||||
* @param input the format string
|
||||
* @param search the Excel character to be replaced
|
||||
* @param replace the java equivalent
|
||||
* @return the input string with the specified substring replaced
|
||||
*/
|
||||
protected final String replace(String input, String search, String replace) {
|
||||
String fmtstr = input;
|
||||
int pos = fmtstr.indexOf(search);
|
||||
while (pos != -1) {
|
||||
StringBuffer tmp = new StringBuffer(fmtstr.substring(0, pos));
|
||||
tmp.append(replace);
|
||||
tmp.append(fmtstr.substring(pos + search.length()));
|
||||
fmtstr = tmp.toString();
|
||||
pos = fmtstr.indexOf(search);
|
||||
}
|
||||
return fmtstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if this format is a date format
|
||||
*
|
||||
* @return TRUE if this format is a date
|
||||
*/
|
||||
public final boolean isDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if this format is a number format
|
||||
*
|
||||
* @return TRUE if this format is a number
|
||||
*/
|
||||
public final boolean isNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the java equivalent number format for the formatString
|
||||
*
|
||||
* @return The java equivalent of the number format for this object
|
||||
*/
|
||||
public final NumberFormat getNumberFormat() {
|
||||
if (format != null && format instanceof NumberFormat) {
|
||||
return (NumberFormat) format;
|
||||
}
|
||||
|
||||
try {
|
||||
String fs = formatString;
|
||||
|
||||
// Replace the Excel formatting characters with java equivalents
|
||||
fs = replace(fs, "E+", "E");
|
||||
fs = replace(fs, "_)", "");
|
||||
fs = replace(fs, "_", "");
|
||||
fs = replace(fs, "[Red]", "");
|
||||
fs = replace(fs, "\\", "");
|
||||
|
||||
format = new DecimalFormat(fs);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Something went wrong with the date format - fail silently
|
||||
// and return a default value
|
||||
format = new DecimalFormat("#.###");
|
||||
}
|
||||
|
||||
return (NumberFormat) format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the java equivalent date format for the formatString
|
||||
*
|
||||
* @return The java equivalent of the date format for this object
|
||||
*/
|
||||
public final DateFormat getDateFormat() {
|
||||
if (format != null && format instanceof DateFormat) {
|
||||
return (DateFormat) format;
|
||||
}
|
||||
|
||||
String fmt = formatString;
|
||||
|
||||
// Replace the AM/PM indicator with an a
|
||||
int pos = fmt.indexOf("AM/PM");
|
||||
while (pos != -1) {
|
||||
StringBuffer sb = new StringBuffer(fmt.substring(0, pos));
|
||||
sb.append('a');
|
||||
sb.append(fmt.substring(pos + 5));
|
||||
fmt = sb.toString();
|
||||
pos = fmt.indexOf("AM/PM");
|
||||
}
|
||||
|
||||
// Replace ss.0 with ss.SSS (necessary to always specify milliseconds
|
||||
// because of NT)
|
||||
pos = fmt.indexOf("ss.0");
|
||||
while (pos != -1) {
|
||||
StringBuffer sb = new StringBuffer(fmt.substring(0, pos));
|
||||
sb.append("ss.SSS");
|
||||
|
||||
// Keep going until we run out of zeros
|
||||
pos += 4;
|
||||
while (pos < fmt.length() && fmt.charAt(pos) == '0') {
|
||||
pos++;
|
||||
}
|
||||
|
||||
sb.append(fmt.substring(pos));
|
||||
fmt = sb.toString();
|
||||
pos = fmt.indexOf("ss.0");
|
||||
}
|
||||
|
||||
|
||||
// Filter out the backslashes
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < fmt.length(); i++) {
|
||||
if (fmt.charAt(i) != '\\') {
|
||||
sb.append(fmt.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
fmt = sb.toString();
|
||||
|
||||
// If the date format starts with anything inside square brackets then
|
||||
// filter tham out
|
||||
if (fmt.charAt(0) == '[') {
|
||||
int end = fmt.indexOf(']');
|
||||
if (end != -1) {
|
||||
fmt = fmt.substring(end + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Get rid of some spurious characters that can creep in
|
||||
fmt = replace(fmt, ";@", "");
|
||||
|
||||
// We need to convert the month indicator m, to upper case when we
|
||||
// are dealing with dates
|
||||
char[] formatBytes = fmt.toCharArray();
|
||||
|
||||
for (int i = 0; i < formatBytes.length; i++) {
|
||||
if (formatBytes[i] == 'm') {
|
||||
// Firstly, see if the preceding character is also an m. If so,
|
||||
// copy that
|
||||
if (i > 0 && (formatBytes[i - 1] == 'm' || formatBytes[i - 1] == 'M')) {
|
||||
formatBytes[i] = formatBytes[i - 1];
|
||||
} else {
|
||||
// There is no easy way out. We have to deduce whether this an
|
||||
// minute or a month? See which is closest out of the
|
||||
// letters H d s or y
|
||||
// First, h
|
||||
int minuteDist = Integer.MAX_VALUE;
|
||||
for (int j = i - 1; j > 0; j--) {
|
||||
if (formatBytes[j] == 'h') {
|
||||
minuteDist = i - j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < formatBytes.length; j++) {
|
||||
if (formatBytes[j] == 'h') {
|
||||
minuteDist = Math.min(minuteDist, j - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = i - 1; j > 0; j--) {
|
||||
if (formatBytes[j] == 'H') {
|
||||
minuteDist = i - j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < formatBytes.length; j++) {
|
||||
if (formatBytes[j] == 'H') {
|
||||
minuteDist = Math.min(minuteDist, j - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now repeat for s
|
||||
for (int j = i - 1; j > 0; j--) {
|
||||
if (formatBytes[j] == 's') {
|
||||
minuteDist = Math.min(minuteDist, i - j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = i + 1; j < formatBytes.length; j++) {
|
||||
if (formatBytes[j] == 's') {
|
||||
minuteDist = Math.min(minuteDist, j - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We now have the distance of the closest character which could
|
||||
// indicate the the m refers to a minute
|
||||
// Repeat for d and y
|
||||
int monthDist = Integer.MAX_VALUE;
|
||||
for (int j = i - 1; j > 0; j--) {
|
||||
if (formatBytes[j] == 'd') {
|
||||
monthDist = i - j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < formatBytes.length; j++) {
|
||||
if (formatBytes[j] == 'd') {
|
||||
monthDist = Math.min(monthDist, j - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Now repeat for y
|
||||
for (int j = i - 1; j > 0; j--) {
|
||||
if (formatBytes[j] == 'y') {
|
||||
monthDist = Math.min(monthDist, i - j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = i + 1; j < formatBytes.length; j++) {
|
||||
if (formatBytes[j] == 'y') {
|
||||
monthDist = Math.min(monthDist, j - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (monthDist < minuteDist) {
|
||||
// The month indicator is closer, so convert to a capital M
|
||||
formatBytes[i] = Character.toUpperCase(formatBytes[i]);
|
||||
} else if ((monthDist == minuteDist) &&
|
||||
(monthDist != Integer.MAX_VALUE)) {
|
||||
// They are equidistant. As a tie-breaker, take the formatting
|
||||
// character which precedes the m
|
||||
char ind = formatBytes[i - monthDist];
|
||||
if (ind == 'y' || ind == 'd') {
|
||||
// The preceding item indicates a month measure, so convert
|
||||
formatBytes[i] = Character.toUpperCase(formatBytes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.format = new SimpleDateFormat(new String(formatBytes));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There was a spurious character - fail silently
|
||||
this.format = new SimpleDateFormat("dd MM yyyy hh:mm:ss");
|
||||
}
|
||||
return (DateFormat) this.format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index code, for use as a hash value
|
||||
*
|
||||
* @return the ifmt code for this cell
|
||||
*/
|
||||
public int getIndexCode() {
|
||||
return indexCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatting string.
|
||||
*
|
||||
* @return the excel format string
|
||||
*/
|
||||
public String getFormatString() {
|
||||
return formatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the immediate subclass to set the string
|
||||
* once the Java-Excel replacements have been done
|
||||
*
|
||||
* @param s the format string
|
||||
*/
|
||||
protected final void setFormatString(String s) {
|
||||
formatString = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this formula is a built in
|
||||
*
|
||||
* @return FALSE
|
||||
*/
|
||||
public boolean isBuiltIn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard hash code method
|
||||
*
|
||||
* @return the hash code value for this object
|
||||
*/
|
||||
public int hashCode() {
|
||||
return formatString.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard equals method. This compares the contents of two
|
||||
* format records, and not their indexCodes, which are ignored
|
||||
*
|
||||
* @param o the object to compare
|
||||
* @return TRUE if the two objects are equal, FALSE otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof FormatRecord)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FormatRecord fr = (FormatRecord) o;
|
||||
|
||||
// Initialized format comparison
|
||||
if (initialized && fr.initialized) {
|
||||
// Must be either a number or a date format
|
||||
if (date != fr.date ||
|
||||
number != fr.number) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return formatString.equals(fr.formatString);
|
||||
}
|
||||
|
||||
// Uninitialized format comparison
|
||||
return formatString.equals(fr.formatString);
|
||||
}
|
||||
|
||||
// Type to distinguish between biff7 and biff8
|
||||
private static class BiffType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
512
datastructures-xslx/src/main/java/jxl/biff/FormattingRecords.java
Executable file
512
datastructures-xslx/src/main/java/jxl/biff/FormattingRecords.java
Executable file
|
@ -0,0 +1,512 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.format.Colour;
|
||||
import jxl.format.RGB;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* The list of XF records and formatting records for the workbook
|
||||
*/
|
||||
public class FormattingRecords {
|
||||
/**
|
||||
* The start index number for custom format records
|
||||
*/
|
||||
private static final int customFormatStartIndex = 0xa4;
|
||||
/**
|
||||
* The maximum number of format records. This is some weird internal
|
||||
* Excel constraint
|
||||
*/
|
||||
private static final int maxFormatRecordsIndex = 0x1b9;
|
||||
/**
|
||||
* The minimum number of XF records for a sheet. The rationalization
|
||||
* processes commences immediately after this number
|
||||
*/
|
||||
private static final int minXFRecords = 21;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(FormattingRecords.class);
|
||||
/**
|
||||
* A hash map of FormatRecords, for random access retrieval when reading
|
||||
* in a spreadsheet
|
||||
*/
|
||||
private final HashMap formats;
|
||||
/**
|
||||
* A list of formats, used when writing out a spreadsheet
|
||||
*/
|
||||
private ArrayList formatsList;
|
||||
/**
|
||||
* The list of extended format records
|
||||
*/
|
||||
private ArrayList xfRecords;
|
||||
/**
|
||||
* The next available index number for custom format records
|
||||
*/
|
||||
private int nextCustomIndexNumber;
|
||||
/**
|
||||
* A handle to the available fonts
|
||||
*/
|
||||
private final Fonts fonts;
|
||||
/**
|
||||
* The colour palette
|
||||
*/
|
||||
private PaletteRecord palette;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param f the container for the fonts
|
||||
*/
|
||||
public FormattingRecords(Fonts f) {
|
||||
xfRecords = new ArrayList(10);
|
||||
formats = new HashMap(10);
|
||||
formatsList = new ArrayList(10);
|
||||
fonts = f;
|
||||
nextCustomIndexNumber = customFormatStartIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an extended formatting record to the list. If the XF record passed
|
||||
* in has not been initialized, its index is determined based on the
|
||||
* xfRecords list, and
|
||||
* this position is passed to the XF records initialize method
|
||||
*
|
||||
* @param xf the xf record to add
|
||||
* @throws NumFormatRecordsException
|
||||
*/
|
||||
public final void addStyle(XFRecord xf)
|
||||
throws NumFormatRecordsException {
|
||||
if (!xf.isInitialized()) {
|
||||
int pos = xfRecords.size();
|
||||
xf.initialize(pos, this, fonts);
|
||||
xfRecords.add(xf);
|
||||
} else {
|
||||
// The XF record has probably been read in. If the index is greater
|
||||
// Than the size of the list, then it is not a preset format,
|
||||
// so add it
|
||||
if (xf.getXFIndex() >= xfRecords.size()) {
|
||||
xfRecords.add(xf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cell format to the hash map, keyed on its index. If the format
|
||||
* record is not initialized, then its index number is determined and its
|
||||
* initialize method called. If the font is not a built in format, then it
|
||||
* is added to the list of formats for writing out
|
||||
*
|
||||
* @param fr the format record
|
||||
*/
|
||||
public final void addFormat(DisplayFormat fr)
|
||||
throws NumFormatRecordsException {
|
||||
// Handle the case the where the index number in the read Excel
|
||||
// file exhibits some major weirdness
|
||||
if (fr.isInitialized() &&
|
||||
fr.getFormatIndex() >= maxFormatRecordsIndex) {
|
||||
logger.warn("Format index exceeds Excel maximum - assigning custom " +
|
||||
"number");
|
||||
fr.initialize(nextCustomIndexNumber);
|
||||
nextCustomIndexNumber++;
|
||||
}
|
||||
|
||||
// Initialize the format record with a custom index number
|
||||
if (!fr.isInitialized()) {
|
||||
fr.initialize(nextCustomIndexNumber);
|
||||
nextCustomIndexNumber++;
|
||||
}
|
||||
|
||||
if (nextCustomIndexNumber > maxFormatRecordsIndex) {
|
||||
nextCustomIndexNumber = maxFormatRecordsIndex;
|
||||
throw new NumFormatRecordsException();
|
||||
}
|
||||
|
||||
if (fr.getFormatIndex() >= nextCustomIndexNumber) {
|
||||
nextCustomIndexNumber = fr.getFormatIndex() + 1;
|
||||
}
|
||||
|
||||
if (!fr.isBuiltIn()) {
|
||||
formatsList.add(fr);
|
||||
formats.put(new Integer(fr.getFormatIndex()), fr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees if the extended formatting record at the specified position
|
||||
* represents a date. First checks against the built in formats, and
|
||||
* then checks against the hash map of FormatRecords
|
||||
*
|
||||
* @param pos the xf format index
|
||||
* @return TRUE if this format index is formatted as a Date
|
||||
*/
|
||||
public final boolean isDate(int pos) {
|
||||
XFRecord xfr = (XFRecord) xfRecords.get(pos);
|
||||
|
||||
if (xfr.isDate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FormatRecord fr = (FormatRecord)
|
||||
formats.get(new Integer(xfr.getFormatRecord()));
|
||||
|
||||
return fr != null && fr.isDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DateFormat used to format the cell.
|
||||
*
|
||||
* @param pos the xf format index
|
||||
* @return the DateFormat object used to format the date in the original
|
||||
* excel cell
|
||||
*/
|
||||
public final DateFormat getDateFormat(int pos) {
|
||||
XFRecord xfr = (XFRecord) xfRecords.get(pos);
|
||||
|
||||
if (xfr.isDate()) {
|
||||
return xfr.getDateFormat();
|
||||
}
|
||||
|
||||
FormatRecord fr = (FormatRecord)
|
||||
formats.get(new Integer(xfr.getFormatRecord()));
|
||||
|
||||
if (fr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fr.isDate() ? fr.getDateFormat() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NumberFormat used to format the cell.
|
||||
*
|
||||
* @param pos the xf format index
|
||||
* @return the DateFormat object used to format the date in the original
|
||||
* excel cell
|
||||
*/
|
||||
public final NumberFormat getNumberFormat(int pos) {
|
||||
XFRecord xfr = (XFRecord) xfRecords.get(pos);
|
||||
|
||||
if (xfr.isNumber()) {
|
||||
return xfr.getNumberFormat();
|
||||
}
|
||||
|
||||
FormatRecord fr = (FormatRecord)
|
||||
formats.get(new Integer(xfr.getFormatRecord()));
|
||||
|
||||
if (fr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fr.isNumber() ? fr.getNumberFormat() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format record
|
||||
*
|
||||
* @param index the formatting record index to retrieve
|
||||
* @return the format record at the specified index
|
||||
*/
|
||||
FormatRecord getFormatRecord(int index) {
|
||||
return (FormatRecord)
|
||||
formats.get(new Integer(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out all the format records and the XF records
|
||||
*
|
||||
* @param outputFile the file to write to
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
// Write out all the formats
|
||||
Iterator i = formatsList.iterator();
|
||||
FormatRecord fr = null;
|
||||
while (i.hasNext()) {
|
||||
fr = (FormatRecord) i.next();
|
||||
outputFile.write(fr);
|
||||
}
|
||||
|
||||
// Write out the styles
|
||||
i = xfRecords.iterator();
|
||||
XFRecord xfr = null;
|
||||
while (i.hasNext()) {
|
||||
xfr = (XFRecord) i.next();
|
||||
outputFile.write(xfr);
|
||||
}
|
||||
|
||||
// Write out the style records
|
||||
BuiltInStyle style = new BuiltInStyle(0x10, 3);
|
||||
outputFile.write(style);
|
||||
|
||||
style = new BuiltInStyle(0x11, 6);
|
||||
outputFile.write(style);
|
||||
|
||||
style = new BuiltInStyle(0x12, 4);
|
||||
outputFile.write(style);
|
||||
|
||||
style = new BuiltInStyle(0x13, 7);
|
||||
outputFile.write(style);
|
||||
|
||||
style = new BuiltInStyle(0x0, 0);
|
||||
outputFile.write(style);
|
||||
|
||||
style = new BuiltInStyle(0x14, 5);
|
||||
outputFile.write(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the fonts used by this workbook
|
||||
*
|
||||
* @return the fonts container
|
||||
*/
|
||||
protected final Fonts getFonts() {
|
||||
return fonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the XFRecord for the specified index. Used when copying individual
|
||||
* cells
|
||||
*
|
||||
* @param index the XF record to retrieve
|
||||
* @return the XF record at the specified index
|
||||
*/
|
||||
public final XFRecord getXFRecord(int index) {
|
||||
return (XFRecord) xfRecords.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of formatting records on the list. This is used by the
|
||||
* writable subclass because there is an upper limit on the amount of
|
||||
* format records that are allowed to be present in an excel sheet
|
||||
*
|
||||
* @return the number of format records present
|
||||
*/
|
||||
protected final int getNumberOfFormatRecords() {
|
||||
return formatsList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rationalizes all the fonts, removing duplicate entries
|
||||
*
|
||||
* @return the list of new font index number
|
||||
*/
|
||||
public IndexMapping rationalizeFonts() {
|
||||
return fonts.rationalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rationalizes the cell formats. Duplicate
|
||||
* formats are removed and the format indexed of the cells
|
||||
* adjusted accordingly
|
||||
*
|
||||
* @param fontMapping the font mapping index numbers
|
||||
* @param formatMapping the format mapping index numbers
|
||||
* @return the list of new font index number
|
||||
*/
|
||||
public IndexMapping rationalize(IndexMapping fontMapping,
|
||||
IndexMapping formatMapping) {
|
||||
// Update the index codes for the XF records using the format
|
||||
// mapping and the font mapping
|
||||
// at the same time
|
||||
XFRecord xfr = null;
|
||||
for (Iterator it = xfRecords.iterator(); it.hasNext(); ) {
|
||||
xfr = (XFRecord) it.next();
|
||||
|
||||
if (xfr.getFormatRecord() >= customFormatStartIndex) {
|
||||
xfr.setFormatIndex(formatMapping.getNewIndex(xfr.getFormatRecord()));
|
||||
}
|
||||
|
||||
xfr.setFontIndex(fontMapping.getNewIndex(xfr.getFontIndex()));
|
||||
}
|
||||
|
||||
ArrayList newrecords = new ArrayList(minXFRecords);
|
||||
IndexMapping mapping = new IndexMapping(xfRecords.size());
|
||||
int numremoved = 0;
|
||||
|
||||
int numXFRecords = Math.min(minXFRecords, xfRecords.size());
|
||||
// Copy across the fundamental styles
|
||||
for (int i = 0; i < numXFRecords; i++) {
|
||||
newrecords.add(xfRecords.get(i));
|
||||
mapping.setMapping(i, i);
|
||||
}
|
||||
|
||||
if (numXFRecords < minXFRecords) {
|
||||
logger.warn("There are less than the expected minimum number of " +
|
||||
"XF records");
|
||||
return mapping;
|
||||
}
|
||||
|
||||
// Iterate through the old list
|
||||
for (int i = minXFRecords; i < xfRecords.size(); i++) {
|
||||
XFRecord xf = (XFRecord) xfRecords.get(i);
|
||||
|
||||
// Compare against formats already on the list
|
||||
boolean duplicate = false;
|
||||
for (Iterator it = newrecords.iterator();
|
||||
it.hasNext() && !duplicate; ) {
|
||||
XFRecord xf2 = (XFRecord) it.next();
|
||||
if (xf2.equals(xf)) {
|
||||
duplicate = true;
|
||||
mapping.setMapping(i, mapping.getNewIndex(xf2.getXFIndex()));
|
||||
numremoved++;
|
||||
}
|
||||
}
|
||||
|
||||
// If this format is not a duplicate then add it to the new list
|
||||
if (!duplicate) {
|
||||
newrecords.add(xf);
|
||||
mapping.setMapping(i, i - numremoved);
|
||||
}
|
||||
}
|
||||
|
||||
// It is sufficient to merely change the xf index field on all XFRecords
|
||||
// In this case, CellValues which refer to defunct format records
|
||||
// will nevertheless be written out with the correct index number
|
||||
for (Iterator i = xfRecords.iterator(); i.hasNext(); ) {
|
||||
XFRecord xf = (XFRecord) i.next();
|
||||
xf.rationalize(mapping);
|
||||
}
|
||||
|
||||
// Set the new list
|
||||
xfRecords = newrecords;
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rationalizes the display formats. Duplicate
|
||||
* formats are removed and the format indices of the cells
|
||||
* adjusted accordingly. It is invoked immediately prior to writing
|
||||
* writing out the sheet
|
||||
*
|
||||
* @return the index mapping between the old display formats and the
|
||||
* rationalized ones
|
||||
*/
|
||||
public IndexMapping rationalizeDisplayFormats() {
|
||||
ArrayList newformats = new ArrayList();
|
||||
int numremoved = 0;
|
||||
IndexMapping mapping = new IndexMapping(nextCustomIndexNumber);
|
||||
|
||||
// Iterate through the old list
|
||||
Iterator i = formatsList.iterator();
|
||||
DisplayFormat df = null;
|
||||
DisplayFormat df2 = null;
|
||||
boolean duplicate = false;
|
||||
while (i.hasNext()) {
|
||||
df = (DisplayFormat) i.next();
|
||||
|
||||
Assert.verify(!df.isBuiltIn());
|
||||
|
||||
// Compare against formats already on the list
|
||||
Iterator i2 = newformats.iterator();
|
||||
duplicate = false;
|
||||
while (i2.hasNext() && !duplicate) {
|
||||
df2 = (DisplayFormat) i2.next();
|
||||
if (df2.equals(df)) {
|
||||
duplicate = true;
|
||||
mapping.setMapping(df.getFormatIndex(),
|
||||
mapping.getNewIndex(df2.getFormatIndex()));
|
||||
numremoved++;
|
||||
}
|
||||
}
|
||||
|
||||
// If this format is not a duplicate then add it to the new list
|
||||
if (!duplicate) {
|
||||
newformats.add(df);
|
||||
int indexnum = df.getFormatIndex() - numremoved;
|
||||
if (indexnum > maxFormatRecordsIndex) {
|
||||
logger.warn("Too many number formats - using default format.");
|
||||
indexnum = 0; // the default number format index
|
||||
}
|
||||
mapping.setMapping(df.getFormatIndex(),
|
||||
df.getFormatIndex() - numremoved);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the new list
|
||||
formatsList = newformats;
|
||||
|
||||
// Update the index codes for the remaining formats
|
||||
i = formatsList.iterator();
|
||||
|
||||
while (i.hasNext()) {
|
||||
df = (DisplayFormat) i.next();
|
||||
df.initialize(mapping.getNewIndex(df.getFormatIndex()));
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the colour palette
|
||||
*
|
||||
* @return the palette
|
||||
*/
|
||||
public PaletteRecord getPalette() {
|
||||
return palette;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the WorkbookParser to set the colour palette
|
||||
*
|
||||
* @param pr the palette
|
||||
*/
|
||||
public void setPalette(PaletteRecord pr) {
|
||||
palette = pr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RGB value for the specified colour for this workbook
|
||||
*
|
||||
* @param c the colour whose RGB value is to be overwritten
|
||||
* @param r the red portion to set (0-255)
|
||||
* @param g the green portion to set (0-255)
|
||||
* @param b the blue portion to set (0-255)
|
||||
*/
|
||||
public void setColourRGB(Colour c, int r, int g, int b) {
|
||||
if (palette == null) {
|
||||
palette = new PaletteRecord();
|
||||
}
|
||||
palette.setColourRGB(c, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the RGB value for the specified colour
|
||||
*
|
||||
* @return the RGB for the specified colour
|
||||
*/
|
||||
public RGB getColourRGB(Colour c) {
|
||||
if (palette == null) {
|
||||
return c.getDefaultRGB();
|
||||
}
|
||||
|
||||
return palette.getColourRGB(c);
|
||||
}
|
||||
}
|
39
datastructures-xslx/src/main/java/jxl/biff/FormulaData.java
Executable file
39
datastructures-xslx/src/main/java/jxl/biff/FormulaData.java
Executable file
|
@ -0,0 +1,39 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.Cell;
|
||||
import jxl.biff.formula.FormulaException;
|
||||
|
||||
/**
|
||||
* Interface which is used for copying formulas from a read only
|
||||
* to a writable spreadsheet
|
||||
*/
|
||||
public interface FormulaData extends Cell {
|
||||
/**
|
||||
* Gets the raw bytes for the formula. This will include the
|
||||
* parsed tokens array EXCLUDING the standard cell information
|
||||
* (row, column, xfindex)
|
||||
*
|
||||
* @return the raw record data
|
||||
* @throws FormulaException
|
||||
*/
|
||||
byte[] getFormulaData() throws FormulaException;
|
||||
}
|
615
datastructures-xslx/src/main/java/jxl/biff/HeaderFooter.java
Executable file
615
datastructures-xslx/src/main/java/jxl/biff/HeaderFooter.java
Executable file
|
@ -0,0 +1,615 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan, Eric Jung
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Class which represents an Excel header or footer. Information for this
|
||||
* class came from Microsoft Knowledge Base Article 142136
|
||||
* (previously Q142136).
|
||||
* <p>
|
||||
* This class encapsulates three internal structures representing the header
|
||||
* or footer contents which appear on the left, right or central part of the
|
||||
* page
|
||||
*/
|
||||
public abstract class HeaderFooter {
|
||||
/**
|
||||
* Turns bold printing on or off
|
||||
*/
|
||||
private static final String BOLD_TOGGLE = "&B";
|
||||
|
||||
// Codes to format text
|
||||
/**
|
||||
* Turns underline printing on or off
|
||||
*/
|
||||
private static final String UNDERLINE_TOGGLE = "&U";
|
||||
/**
|
||||
* Turns italic printing on or off
|
||||
*/
|
||||
private static final String ITALICS_TOGGLE = "&I";
|
||||
/**
|
||||
* Turns strikethrough printing on or off
|
||||
*/
|
||||
private static final String STRIKETHROUGH_TOGGLE = "&S";
|
||||
/**
|
||||
* Turns double-underline printing on or off
|
||||
*/
|
||||
private static final String DOUBLE_UNDERLINE_TOGGLE = "&E";
|
||||
/**
|
||||
* Turns superscript printing on or off
|
||||
*/
|
||||
private static final String SUPERSCRIPT_TOGGLE = "&X";
|
||||
/**
|
||||
* Turns subscript printing on or off
|
||||
*/
|
||||
private static final String SUBSCRIPT_TOGGLE = "&Y";
|
||||
/**
|
||||
* Turns outline printing on or off (Macintosh only)
|
||||
*/
|
||||
private static final String OUTLINE_TOGGLE = "&O";
|
||||
/**
|
||||
* Turns shadow printing on or off (Macintosh only)
|
||||
*/
|
||||
private static final String SHADOW_TOGGLE = "&H";
|
||||
/**
|
||||
* Left-aligns the characters that follow
|
||||
*/
|
||||
private static final String LEFT_ALIGN = "&L";
|
||||
/**
|
||||
* Centres the characters that follow
|
||||
*/
|
||||
private static final String CENTRE = "&C";
|
||||
/**
|
||||
* Right-aligns the characters that follow
|
||||
*/
|
||||
private static final String RIGHT_ALIGN = "&R";
|
||||
/**
|
||||
* Prints the page number
|
||||
*/
|
||||
private static final String PAGENUM = "&P";
|
||||
|
||||
// Codes to insert specific data
|
||||
/**
|
||||
* Prints the total number of pages in the document
|
||||
*/
|
||||
private static final String TOTAL_PAGENUM = "&N";
|
||||
/**
|
||||
* Prints the current date
|
||||
*/
|
||||
private static final String DATE = "&D";
|
||||
/**
|
||||
* Prints the current time
|
||||
*/
|
||||
private static final String TIME = "&T";
|
||||
/**
|
||||
* Prints the name of the workbook
|
||||
*/
|
||||
private static final String WORKBOOK_NAME = "&F";
|
||||
/**
|
||||
* Prints the name of the worksheet
|
||||
*/
|
||||
private static final String WORKSHEET_NAME = "&A";
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(HeaderFooter.class);
|
||||
/**
|
||||
* The left aligned header/footer contents
|
||||
*/
|
||||
private Contents left;
|
||||
/**
|
||||
* The right aligned header/footer contents
|
||||
*/
|
||||
private Contents right;
|
||||
/**
|
||||
* The centrally aligned header/footer contents
|
||||
*/
|
||||
private Contents centre;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
protected HeaderFooter() {
|
||||
left = createContents();
|
||||
right = createContents();
|
||||
centre = createContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param c the item to copy
|
||||
*/
|
||||
protected HeaderFooter(HeaderFooter hf) {
|
||||
left = createContents(hf.left);
|
||||
right = createContents(hf.right);
|
||||
centre = createContents(hf.centre);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when reading workbooks to separate the left, right
|
||||
* a central part of the strings into their constituent parts
|
||||
*/
|
||||
protected HeaderFooter(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
left = createContents();
|
||||
right = createContents();
|
||||
centre = createContents();
|
||||
return;
|
||||
}
|
||||
|
||||
int leftPos = s.indexOf(LEFT_ALIGN);
|
||||
int rightPos = s.indexOf(RIGHT_ALIGN);
|
||||
int centrePos = s.indexOf(CENTRE);
|
||||
|
||||
if (leftPos == -1 && rightPos == -1 && centrePos == -1) {
|
||||
// When no part is specified, it is the center part
|
||||
centre = createContents(s);
|
||||
} else {
|
||||
// Left part?
|
||||
if (leftPos != -1) {
|
||||
// We have a left part, find end of left part
|
||||
int endLeftPos = s.length();
|
||||
if (centrePos > leftPos) {
|
||||
// Case centre part behind left part
|
||||
endLeftPos = centrePos;
|
||||
if (rightPos > leftPos && endLeftPos > rightPos) {
|
||||
// LRC case
|
||||
endLeftPos = rightPos;
|
||||
} else {
|
||||
// LCR case
|
||||
}
|
||||
} else {
|
||||
// Case centre part before left part
|
||||
if (rightPos > leftPos) {
|
||||
// LR case
|
||||
endLeftPos = rightPos;
|
||||
} else {
|
||||
// *L case
|
||||
// Left pos is last
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
left = createContents(s.substring(leftPos + 2, endLeftPos));
|
||||
}
|
||||
|
||||
// Right part?
|
||||
if (rightPos != -1) {
|
||||
// Find end of right part
|
||||
int endRightPos = s.length();
|
||||
if (centrePos > rightPos) {
|
||||
// centre part behind right part
|
||||
endRightPos = centrePos;
|
||||
if (leftPos > rightPos && endRightPos > leftPos) {
|
||||
// RLC case
|
||||
endRightPos = leftPos;
|
||||
} else {
|
||||
// RCL case
|
||||
}
|
||||
} else {
|
||||
if (leftPos > rightPos) {
|
||||
// RL case
|
||||
endRightPos = leftPos;
|
||||
} else {
|
||||
// *R case
|
||||
// Right pos is last
|
||||
}
|
||||
}
|
||||
right = createContents(s.substring(rightPos + 2, endRightPos));
|
||||
}
|
||||
|
||||
// Centre part?
|
||||
if (centrePos != -1) {
|
||||
// Find end of centre part
|
||||
int endCentrePos = s.length();
|
||||
if (rightPos > centrePos) {
|
||||
// right part behind centre part
|
||||
endCentrePos = rightPos;
|
||||
if (leftPos > centrePos && endCentrePos > leftPos) {
|
||||
// CLR case
|
||||
endCentrePos = leftPos;
|
||||
} else {
|
||||
// CRL case
|
||||
}
|
||||
} else {
|
||||
if (leftPos > centrePos) {
|
||||
// CL case
|
||||
endCentrePos = leftPos;
|
||||
} else {
|
||||
// *C case
|
||||
// Centre pos is last
|
||||
}
|
||||
}
|
||||
centre = createContents(s.substring(centrePos + 2, endCentrePos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (left == null) {
|
||||
left = createContents();
|
||||
}
|
||||
|
||||
if (centre == null) {
|
||||
centre = createContents();
|
||||
}
|
||||
|
||||
if (right == null) {
|
||||
right = createContents();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>String</code>ified
|
||||
* version of this object
|
||||
*
|
||||
* @return the header string
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer hf = new StringBuffer();
|
||||
if (!left.empty()) {
|
||||
hf.append(LEFT_ALIGN);
|
||||
hf.append(left.getContents());
|
||||
}
|
||||
|
||||
if (!centre.empty()) {
|
||||
hf.append(CENTRE);
|
||||
hf.append(centre.getContents());
|
||||
}
|
||||
|
||||
if (!right.empty()) {
|
||||
hf.append(RIGHT_ALIGN);
|
||||
hf.append(right.getContents());
|
||||
}
|
||||
|
||||
return hf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which appear on the right hand side of the page
|
||||
*
|
||||
* @return the right aligned contents
|
||||
*/
|
||||
protected Contents getRightText() {
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which in the centre of the page
|
||||
*
|
||||
* @return the centrally aligned contents
|
||||
*/
|
||||
protected Contents getCentreText() {
|
||||
return centre;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the contents which appear on the left hand side of the page
|
||||
*
|
||||
* @return the left aligned contents
|
||||
*/
|
||||
protected Contents getLeftText() {
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of the header/footer
|
||||
*/
|
||||
protected void clear() {
|
||||
left.clear();
|
||||
right.clear();
|
||||
centre.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*/
|
||||
protected abstract Contents createContents();
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*/
|
||||
protected abstract Contents createContents(String s);
|
||||
|
||||
/**
|
||||
* Creates internal class of the appropriate type
|
||||
*/
|
||||
protected abstract Contents createContents(Contents c);
|
||||
|
||||
/**
|
||||
* The contents - a simple wrapper around a string buffer
|
||||
*/
|
||||
protected static class Contents {
|
||||
/**
|
||||
* The buffer containing the header/footer string
|
||||
*/
|
||||
private StringBuffer contents;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
protected Contents() {
|
||||
contents = new StringBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when reading worksheets. The string contains all
|
||||
* the formatting (but not alignment characters
|
||||
*
|
||||
* @param s the format string
|
||||
*/
|
||||
protected Contents(String s) {
|
||||
contents = new StringBuffer(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @param copy the contents to copy
|
||||
*/
|
||||
protected Contents(Contents copy) {
|
||||
contents = new StringBuffer(copy.getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>String</code>ified
|
||||
* version of this object
|
||||
*
|
||||
* @return the header string
|
||||
*/
|
||||
protected String getContents() {
|
||||
return contents != null ? contents.toString() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method which appends the text to the string buffer
|
||||
*
|
||||
* @param txt
|
||||
*/
|
||||
private void appendInternal(String txt) {
|
||||
if (contents == null) {
|
||||
contents = new StringBuffer();
|
||||
}
|
||||
|
||||
contents.append(txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method which appends the text to the string buffer
|
||||
*
|
||||
* @param ch
|
||||
*/
|
||||
private void appendInternal(char ch) {
|
||||
if (contents == null) {
|
||||
contents = new StringBuffer();
|
||||
}
|
||||
|
||||
contents.append(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the text to the string buffer
|
||||
*
|
||||
* @param txt
|
||||
*/
|
||||
protected void append(String txt) {
|
||||
appendInternal(txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns bold printing on or off. Bold printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be bolded until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleBold() {
|
||||
appendInternal(BOLD_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns underline printing on or off. Underline printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be underlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleUnderline() {
|
||||
appendInternal(UNDERLINE_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns italics printing on or off. Italics printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be italicized until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleItalics() {
|
||||
appendInternal(ITALICS_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns strikethrough printing on or off. Strikethrough printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be striked out until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleStrikethrough() {
|
||||
appendInternal(STRIKETHROUGH_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns double-underline printing on or off. Double-underline printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be double-underlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleDoubleUnderline() {
|
||||
appendInternal(DOUBLE_UNDERLINE_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns superscript printing on or off. Superscript printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be superscripted until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleSuperScript() {
|
||||
appendInternal(SUPERSCRIPT_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns subscript printing on or off. Subscript printing
|
||||
* is initially off. Text subsequently appended to
|
||||
* this object will be subscripted until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleSubScript() {
|
||||
appendInternal(SUBSCRIPT_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns outline printing on or off (Macintosh only).
|
||||
* Outline printing is initially off. Text subsequently appended
|
||||
* to this object will be outlined until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleOutline() {
|
||||
appendInternal(OUTLINE_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns shadow printing on or off (Macintosh only).
|
||||
* Shadow printing is initially off. Text subsequently appended
|
||||
* to this object will be shadowed until this method is
|
||||
* called again.
|
||||
*/
|
||||
protected void toggleShadow() {
|
||||
appendInternal(SHADOW_TOGGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font of text subsequently appended to this
|
||||
* object.. Previously appended text is not affected.
|
||||
* <p/>
|
||||
* <strong>Note:</strong> no checking is performed to
|
||||
* determine if fontName is a valid font.
|
||||
*
|
||||
* @param fontName name of the font to use
|
||||
*/
|
||||
protected void setFontName(String fontName) {
|
||||
// Font name must be in quotations
|
||||
appendInternal("&\"");
|
||||
appendInternal(fontName);
|
||||
appendInternal('\"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font size of text subsequently appended to this
|
||||
* object. Previously appended text is not affected.
|
||||
* <p/>
|
||||
* Valid point sizes are between 1 and 99 (inclusive). If
|
||||
* size is outside this range, this method returns false
|
||||
* and does not change font size. If size is within this
|
||||
* range, the font size is changed and true is returned.
|
||||
*
|
||||
* @param size The size in points. Valid point sizes are
|
||||
* between 1 and 99 (inclusive).
|
||||
* @return true if the font size was changed, false if font
|
||||
* size was not changed because 1 > size > 99.
|
||||
*/
|
||||
protected boolean setFontSize(int size) {
|
||||
if (size < 1 || size > 99) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A two digit number should be used -- even if the
|
||||
// leading number is just a zero.
|
||||
String fontSize;
|
||||
if (size < 10) {
|
||||
// single-digit -- make two digit
|
||||
fontSize = "0" + size;
|
||||
} else {
|
||||
fontSize = Integer.toString(size);
|
||||
}
|
||||
|
||||
appendInternal('&');
|
||||
appendInternal(fontSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the page number
|
||||
*/
|
||||
protected void appendPageNumber() {
|
||||
appendInternal(PAGENUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the total number of pages
|
||||
*/
|
||||
protected void appendTotalPages() {
|
||||
appendInternal(TOTAL_PAGENUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the current date
|
||||
*/
|
||||
protected void appendDate() {
|
||||
appendInternal(DATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the current time
|
||||
*/
|
||||
protected void appendTime() {
|
||||
appendInternal(TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the workbook name
|
||||
*/
|
||||
protected void appendWorkbookName() {
|
||||
appendInternal(WORKBOOK_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the worksheet name
|
||||
*/
|
||||
protected void appendWorkSheetName() {
|
||||
appendInternal(WORKSHEET_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of this portion
|
||||
*/
|
||||
protected void clear() {
|
||||
contents = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries if the contents are empty
|
||||
*
|
||||
* @return TRUE if the contents are empty, FALSE otherwise
|
||||
*/
|
||||
protected boolean empty() {
|
||||
return contents == null || contents.length() == 0;
|
||||
}
|
||||
}
|
||||
}
|
68
datastructures-xslx/src/main/java/jxl/biff/IndexMapping.java
Executable file
68
datastructures-xslx/src/main/java/jxl/biff/IndexMapping.java
Executable file
|
@ -0,0 +1,68 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* This class is a wrapper for a list of mappings between indices.
|
||||
* It is used when removing duplicate records and specifies the new
|
||||
* index for cells which have the duplicate format
|
||||
*/
|
||||
public final class IndexMapping {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(IndexMapping.class);
|
||||
|
||||
/**
|
||||
* The array of new indexes for an old one
|
||||
*/
|
||||
private final int[] newIndices;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param size the number of index numbers to be mapped
|
||||
*/
|
||||
public IndexMapping(int size) {
|
||||
newIndices = new int[size];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a mapping
|
||||
*
|
||||
* @param oldIndex the old index
|
||||
* @param newIndex the new index
|
||||
*/
|
||||
public void setMapping(int oldIndex, int newIndex) {
|
||||
newIndices[oldIndex] = newIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new cell format index
|
||||
*
|
||||
* @param oldIndex the existing index number
|
||||
* @return the new index number
|
||||
*/
|
||||
public int getNewIndex(int oldIndex) {
|
||||
return newIndices[oldIndex];
|
||||
}
|
||||
}
|
140
datastructures-xslx/src/main/java/jxl/biff/IntegerHelper.java
Executable file
140
datastructures-xslx/src/main/java/jxl/biff/IntegerHelper.java
Executable file
|
@ -0,0 +1,140 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Converts excel byte representations into integers
|
||||
*/
|
||||
public final class IntegerHelper {
|
||||
/**
|
||||
* Private constructor disables the instantiation of this object
|
||||
*/
|
||||
private IntegerHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an int from two bytes
|
||||
*
|
||||
* @param b2 the second byte
|
||||
* @param b1 the first byte
|
||||
* @return The integer value
|
||||
*/
|
||||
public static int getInt(byte b1, byte b2) {
|
||||
int i1 = b1 & 0xff;
|
||||
int i2 = b2 & 0xff;
|
||||
int val = i2 << 8 | i1;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an short from two bytes
|
||||
*
|
||||
* @param b2 the second byte
|
||||
* @param b1 the first byte
|
||||
* @return The short value
|
||||
*/
|
||||
public static short getShort(byte b1, byte b2) {
|
||||
short i1 = (short) (b1 & 0xff);
|
||||
short i2 = (short) (b2 & 0xff);
|
||||
short val = (short) (i2 << 8 | i1);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an int from four bytes, doing all the necessary swapping
|
||||
*
|
||||
* @param b1 a byte
|
||||
* @param b2 a byte
|
||||
* @param b3 a byte
|
||||
* @param b4 a byte
|
||||
* @return the integer value represented by the four bytes
|
||||
*/
|
||||
public static int getInt(byte b1, byte b2, byte b3, byte b4) {
|
||||
int i1 = getInt(b1, b2);
|
||||
int i2 = getInt(b3, b4);
|
||||
|
||||
int val = i2 << 16 | i1;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a two byte array from an integer
|
||||
*
|
||||
* @param i the integer
|
||||
* @return the two bytes
|
||||
*/
|
||||
public static byte[] getTwoBytes(int i) {
|
||||
byte[] bytes = new byte[2];
|
||||
|
||||
bytes[0] = (byte) (i & 0xff);
|
||||
bytes[1] = (byte) ((i & 0xff00) >> 8);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a four byte array from an integer
|
||||
*
|
||||
* @param i the integer
|
||||
* @return a four byte array
|
||||
*/
|
||||
public static byte[] getFourBytes(int i) {
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
int i1 = i & 0xffff;
|
||||
int i2 = (i & 0xffff0000) >> 16;
|
||||
|
||||
getTwoBytes(i1, bytes, 0);
|
||||
getTwoBytes(i2, bytes, 2);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an integer into two bytes, and places it in the array at the
|
||||
* specified position
|
||||
*
|
||||
* @param target the array to place the byte data into
|
||||
* @param pos the position at which to place the data
|
||||
* @param i the integer value to convert
|
||||
*/
|
||||
public static void getTwoBytes(int i, byte[] target, int pos) {
|
||||
target[pos] = (byte) (i & 0xff);
|
||||
target[pos + 1] = (byte) ((i & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an integer into four bytes, and places it in the array at the
|
||||
* specified position
|
||||
*
|
||||
* @param target the array which is to contain the converted data
|
||||
* @param pos the position in the array in which to place the data
|
||||
* @param i the integer to convert
|
||||
*/
|
||||
public static void getFourBytes(int i, byte[] target, int pos) {
|
||||
byte[] bytes = getFourBytes(i);
|
||||
target[pos] = bytes[0];
|
||||
target[pos + 1] = bytes[1];
|
||||
target[pos + 2] = bytes[2];
|
||||
target[pos + 3] = bytes[3];
|
||||
}
|
||||
}
|
35
datastructures-xslx/src/main/java/jxl/biff/NameRangeException.java
Executable file
35
datastructures-xslx/src/main/java/jxl/biff/NameRangeException.java
Executable file
|
@ -0,0 +1,35 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.JXLException;
|
||||
|
||||
/**
|
||||
* A properly typed exception in case consumers of the API specifically
|
||||
* wish to handle the case when the workbook is password protected
|
||||
*/
|
||||
public class NameRangeException extends JXLException {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public NameRangeException() {
|
||||
super("");
|
||||
}
|
||||
}
|
34
datastructures-xslx/src/main/java/jxl/biff/NumFormatRecordsException.java
Executable file
34
datastructures-xslx/src/main/java/jxl/biff/NumFormatRecordsException.java
Executable file
|
@ -0,0 +1,34 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* Excel places a constraint on the number of format records that
|
||||
* are allowed. This exception is thrown when that number is exceeded
|
||||
* This is a static exception and should be handled internally
|
||||
*/
|
||||
public class NumFormatRecordsException extends Exception {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public NumFormatRecordsException() {
|
||||
super("Internal error: max number of FORMAT records exceeded");
|
||||
}
|
||||
}
|
207
datastructures-xslx/src/main/java/jxl/biff/PaletteRecord.java
Executable file
207
datastructures-xslx/src/main/java/jxl/biff/PaletteRecord.java
Executable file
|
@ -0,0 +1,207 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.format.Colour;
|
||||
import jxl.format.RGB;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A record representing the RGB colour palette
|
||||
*/
|
||||
public class PaletteRecord extends WritableRecordData {
|
||||
/**
|
||||
* The number of colours in the palette
|
||||
*/
|
||||
private static final int numColours = 56;
|
||||
/**
|
||||
* The list of bespoke rgb colours used by this sheet
|
||||
*/
|
||||
private final RGB[] rgbColours = new RGB[numColours];
|
||||
/**
|
||||
* A dirty flag indicating that this palette has been tampered with
|
||||
* in some way
|
||||
*/
|
||||
private boolean dirty;
|
||||
/**
|
||||
* Flag indicating that the palette was read in
|
||||
*/
|
||||
private final boolean read;
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param t the raw bytes
|
||||
*/
|
||||
public PaletteRecord(Record t) {
|
||||
super(t);
|
||||
|
||||
initialized = false;
|
||||
dirty = false;
|
||||
read = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor - used when there is no palette specified
|
||||
*/
|
||||
public PaletteRecord() {
|
||||
super(Type.PALETTE);
|
||||
|
||||
initialized = true;
|
||||
dirty = false;
|
||||
read = false;
|
||||
|
||||
// Initialize the array with all the default colours
|
||||
Colour[] colours = Colour.getAllColours();
|
||||
|
||||
for (int i = 0; i < colours.length; i++) {
|
||||
Colour c = colours[i];
|
||||
setColourRGB(c,
|
||||
c.getDefaultRGB().getRed(),
|
||||
c.getDefaultRGB().getGreen(),
|
||||
c.getDefaultRGB().getBlue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the binary data - used when copying
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
// Palette was read in, but has not been changed
|
||||
if (read && !dirty) {
|
||||
return getRecord().getData();
|
||||
}
|
||||
|
||||
byte[] data = new byte[numColours * 4 + 2];
|
||||
int pos = 0;
|
||||
|
||||
// Set the number of records
|
||||
IntegerHelper.getTwoBytes(numColours, data, pos);
|
||||
|
||||
// Set the rgb content
|
||||
for (int i = 0; i < numColours; i++) {
|
||||
pos = i * 4 + 2;
|
||||
data[pos] = (byte) rgbColours[i].getRed();
|
||||
data[pos + 1] = (byte) rgbColours[i].getGreen();
|
||||
data[pos + 2] = (byte) rgbColours[i].getBlue();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the record data
|
||||
*/
|
||||
private void initialize() {
|
||||
byte[] data = getRecord().getData();
|
||||
|
||||
int numrecords = IntegerHelper.getInt(data[0], data[1]);
|
||||
|
||||
for (int i = 0; i < numrecords; i++) {
|
||||
int pos = i * 4 + 2;
|
||||
int red = IntegerHelper.getInt(data[pos], (byte) 0);
|
||||
int green = IntegerHelper.getInt(data[pos + 1], (byte) 0);
|
||||
int blue = IntegerHelper.getInt(data[pos + 2], (byte) 0);
|
||||
rgbColours[i] = new RGB(red, green, blue);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the dirty flag, which indicates if this palette has been
|
||||
* modified
|
||||
*
|
||||
* @return TRUE if the palette has been modified, FALSE if it is the default
|
||||
*/
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RGB value for the specified colour for this workbook
|
||||
*
|
||||
* @param c the colour whose RGB value is to be overwritten
|
||||
* @param r the red portion to set (0-255)
|
||||
* @param g the green portion to set (0-255)
|
||||
* @param b the blue portion to set (0-255)
|
||||
*/
|
||||
public void setColourRGB(Colour c, int r, int g, int b) {
|
||||
// Only colours on the standard palette with values 8-64 are acceptable
|
||||
int pos = c.getValue() - 8;
|
||||
if (pos < 0 || pos >= numColours) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
// Force the colours into the range 0-255
|
||||
r = setValueRange(r, 0, 0xff);
|
||||
g = setValueRange(g, 0, 0xff);
|
||||
b = setValueRange(b, 0, 0xff);
|
||||
|
||||
rgbColours[pos] = new RGB(r, g, b);
|
||||
|
||||
// Indicate that the palette has been modified
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the colour RGB from the palette
|
||||
*
|
||||
* @param c the colour
|
||||
* @return an RGB structure
|
||||
*/
|
||||
public RGB getColourRGB(Colour c) {
|
||||
// Only colours on the standard palette with values 8-64 are acceptable
|
||||
int pos = c.getValue() - 8;
|
||||
if (pos < 0 || pos >= numColours) {
|
||||
return c.getDefaultRGB();
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return rgbColours[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the value passed in to be between the range passed in
|
||||
*
|
||||
* @param val the value to constrain
|
||||
* @param min the minimum acceptable value
|
||||
* @param max the maximum acceptable value
|
||||
* @return the constrained value
|
||||
*/
|
||||
private int setValueRange(int val, int min, int max) {
|
||||
val = Math.max(val, min);
|
||||
val = Math.min(val, max);
|
||||
return val;
|
||||
}
|
||||
}
|
157
datastructures-xslx/src/main/java/jxl/biff/RangeImpl.java
Executable file
157
datastructures-xslx/src/main/java/jxl/biff/RangeImpl.java
Executable file
|
@ -0,0 +1,157 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.Cell;
|
||||
import jxl.Range;
|
||||
import jxl.Sheet;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Implementation class for the Range interface. This merely
|
||||
* holds the raw range information, and when the time comes, it
|
||||
* interrogates the workbook for the object.
|
||||
* This does not keep handles to the objects for performance reasons,
|
||||
* as this could impact garbage collection on larger spreadsheets
|
||||
*/
|
||||
public class RangeImpl implements Range {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(RangeImpl.class);
|
||||
|
||||
/**
|
||||
* A handle to the workbook
|
||||
*/
|
||||
private final WorkbookMethods workbook;
|
||||
|
||||
/**
|
||||
* The sheet index containing the column at the top left
|
||||
*/
|
||||
private final int sheet1;
|
||||
|
||||
/**
|
||||
* The column number of the cell at the top left of the range
|
||||
*/
|
||||
private final int column1;
|
||||
|
||||
/**
|
||||
* The row number of the cell at the top left of the range
|
||||
*/
|
||||
private final int row1;
|
||||
|
||||
/**
|
||||
* The sheet index of the cell at the bottom right
|
||||
*/
|
||||
private final int sheet2;
|
||||
|
||||
/**
|
||||
* The column index of the cell at the bottom right
|
||||
*/
|
||||
private final int column2;
|
||||
|
||||
/**
|
||||
* The row index of the cell at the bottom right
|
||||
*/
|
||||
private final int row2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param w the workbook
|
||||
* @param es the external sheet
|
||||
* @param s1 the sheet of the top left cell of the range
|
||||
* @param c1 the column number of the top left cell of the range
|
||||
* @param r1 the row number of the top left cell of the range
|
||||
* @param s2 the sheet of the bottom right cell
|
||||
* @param c2 the column number of the bottom right cell of the range
|
||||
* @param r2 the row number of the bottomr right cell of the range
|
||||
*/
|
||||
public RangeImpl(WorkbookMethods w,
|
||||
int s1, int c1, int r1,
|
||||
int s2, int c2, int r2) {
|
||||
workbook = w;
|
||||
sheet1 = s1;
|
||||
sheet2 = s2;
|
||||
row1 = r1;
|
||||
row2 = r2;
|
||||
column1 = c1;
|
||||
column2 = c2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell at the top left of this range
|
||||
*
|
||||
* @return the cell at the top left
|
||||
*/
|
||||
public Cell getTopLeft() {
|
||||
Sheet s = workbook.getReadSheet(sheet1);
|
||||
|
||||
if (column1 < s.getColumns() &&
|
||||
row1 < s.getRows()) {
|
||||
return s.getCell(column1, row1);
|
||||
} else {
|
||||
return new EmptyCell(column1, row1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell at the bottom right of this range
|
||||
*
|
||||
* @return the cell at the bottom right
|
||||
*/
|
||||
public Cell getBottomRight() {
|
||||
Sheet s = workbook.getReadSheet(sheet2);
|
||||
|
||||
if (column2 < s.getColumns() &&
|
||||
row2 < s.getRows()) {
|
||||
return s.getCell(column2, row2);
|
||||
} else {
|
||||
return new EmptyCell(column2, row2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the first sheet in the range
|
||||
*
|
||||
* @return the index of the first sheet in the range
|
||||
*/
|
||||
public int getFirstSheetIndex() {
|
||||
return sheet1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the last sheet in the range
|
||||
*
|
||||
* @return the index of the last sheet in the range
|
||||
*/
|
||||
public int getLastSheetIndex() {
|
||||
return sheet2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
83
datastructures-xslx/src/main/java/jxl/biff/RecordData.java
Executable file
83
datastructures-xslx/src/main/java/jxl/biff/RecordData.java
Executable file
|
@ -0,0 +1,83 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* The record data within a record
|
||||
*/
|
||||
public abstract class RecordData {
|
||||
/**
|
||||
* The raw data
|
||||
*/
|
||||
private Record record;
|
||||
|
||||
/**
|
||||
* The Biff code for this record. This is set up when the record is
|
||||
* used for writing
|
||||
*/
|
||||
private final int code;
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data
|
||||
*
|
||||
* @param r the raw data
|
||||
*/
|
||||
protected RecordData(Record r) {
|
||||
record = r;
|
||||
code = r.getCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used by the writable records
|
||||
*
|
||||
* @param t the type
|
||||
*/
|
||||
protected RecordData(Type t) {
|
||||
code = t.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data to its subclasses
|
||||
*
|
||||
* @return the raw data
|
||||
*/
|
||||
protected Record getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the code
|
||||
*
|
||||
* @return the code
|
||||
*/
|
||||
protected final int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
293
datastructures-xslx/src/main/java/jxl/biff/SheetRangeImpl.java
Executable file
293
datastructures-xslx/src/main/java/jxl/biff/SheetRangeImpl.java
Executable file
|
@ -0,0 +1,293 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.Cell;
|
||||
import jxl.Range;
|
||||
import jxl.Sheet;
|
||||
|
||||
/**
|
||||
* Implementation class for the Range interface. This merely
|
||||
* holds the raw range information. This implementation is used
|
||||
* for ranges which are present on the current working sheet, so the
|
||||
* getSheetIndex merely returns -1
|
||||
*/
|
||||
public class SheetRangeImpl implements Range {
|
||||
/**
|
||||
* A handle to the sheet containing this range
|
||||
*/
|
||||
private final Sheet sheet;
|
||||
|
||||
/**
|
||||
* The column number of the cell at the top left of the range
|
||||
*/
|
||||
private int column1;
|
||||
|
||||
/**
|
||||
* The row number of the cell at the top left of the range
|
||||
*/
|
||||
private int row1;
|
||||
|
||||
/**
|
||||
* The column index of the cell at the bottom right
|
||||
*/
|
||||
private int column2;
|
||||
|
||||
/**
|
||||
* The row index of the cell at the bottom right
|
||||
*/
|
||||
private int row2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param s the sheet containing the range
|
||||
* @param c1 the column number of the top left cell of the range
|
||||
* @param r1 the row number of the top left cell of the range
|
||||
* @param c2 the column number of the bottom right cell of the range
|
||||
* @param r2 the row number of the bottomr right cell of the range
|
||||
*/
|
||||
public SheetRangeImpl(Sheet s, int c1, int r1,
|
||||
int c2, int r2) {
|
||||
sheet = s;
|
||||
row1 = r1;
|
||||
row2 = r2;
|
||||
column1 = c1;
|
||||
column2 = c2;
|
||||
}
|
||||
|
||||
/**
|
||||
* A copy constructor used for copying ranges between sheets
|
||||
*
|
||||
* @param c the range to copy from
|
||||
* @param s the writable sheet
|
||||
*/
|
||||
public SheetRangeImpl(SheetRangeImpl c, Sheet s) {
|
||||
sheet = s;
|
||||
row1 = c.row1;
|
||||
row2 = c.row2;
|
||||
column1 = c.column1;
|
||||
column2 = c.column2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell at the top left of this range
|
||||
*
|
||||
* @return the cell at the top left
|
||||
*/
|
||||
public Cell getTopLeft() {
|
||||
// If the print area exceeds the bounds of the sheet, then handle
|
||||
// it here. The sheet implementation will give a NPE
|
||||
if (column1 >= sheet.getColumns() ||
|
||||
row1 >= sheet.getRows()) {
|
||||
return new EmptyCell(column1, row1);
|
||||
}
|
||||
|
||||
return sheet.getCell(column1, row1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell at the bottom right of this range
|
||||
*
|
||||
* @return the cell at the bottom right
|
||||
*/
|
||||
public Cell getBottomRight() {
|
||||
// If the print area exceeds the bounds of the sheet, then handle
|
||||
// it here. The sheet implementation will give a NPE
|
||||
if (column2 >= sheet.getColumns() ||
|
||||
row2 >= sheet.getRows()) {
|
||||
return new EmptyCell(column2, row2);
|
||||
}
|
||||
|
||||
return sheet.getCell(column2, row2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported. Returns -1, indicating that it refers to the current
|
||||
* sheet
|
||||
*
|
||||
* @return -1
|
||||
*/
|
||||
public int getFirstSheetIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported. Returns -1, indicating that it refers to the current
|
||||
* sheet
|
||||
*
|
||||
* @return -1
|
||||
*/
|
||||
public int getLastSheetIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sees whether there are any intersections between this range and the
|
||||
* range passed in. This method is used internally by the WritableSheet to
|
||||
* verify the integrity of merged cells, hyperlinks etc. Ranges are
|
||||
* only ever compared for the same sheet
|
||||
*
|
||||
* @param range the range to compare against
|
||||
* @return TRUE if the ranges intersect, FALSE otherwise
|
||||
*/
|
||||
public boolean intersects(SheetRangeImpl range) {
|
||||
if (range == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return row2 >= range.row1 &&
|
||||
row1 <= range.row2 &&
|
||||
column2 >= range.column1 &&
|
||||
column1 <= range.column2;
|
||||
}
|
||||
|
||||
/**
|
||||
* To string method - primarily used during debugging
|
||||
*
|
||||
* @return the string version of this object
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
CellReferenceHelper.getCellReference(column1, row1, sb);
|
||||
sb.append('-');
|
||||
CellReferenceHelper.getCellReference(column2, row2, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A row has been inserted, so adjust the range objects accordingly
|
||||
*
|
||||
* @param r the row which has been inserted
|
||||
*/
|
||||
public void insertRow(int r) {
|
||||
if (r > row2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (r <= row1) {
|
||||
row1++;
|
||||
}
|
||||
|
||||
if (r <= row2) {
|
||||
row2++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A column has been inserted, so adjust the range objects accordingly
|
||||
*
|
||||
* @param c the column which has been inserted
|
||||
*/
|
||||
public void insertColumn(int c) {
|
||||
if (c > column2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (c <= column1) {
|
||||
column1++;
|
||||
}
|
||||
|
||||
if (c <= column2) {
|
||||
column2++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A row has been removed, so adjust the range objects accordingly
|
||||
*
|
||||
* @param r the row which has been inserted
|
||||
*/
|
||||
public void removeRow(int r) {
|
||||
if (r > row2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (r < row1) {
|
||||
row1--;
|
||||
}
|
||||
|
||||
if (r < row2) {
|
||||
row2--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A column has been removed, so adjust the range objects accordingly
|
||||
*
|
||||
* @param c the column which has been removed
|
||||
*/
|
||||
public void removeColumn(int c) {
|
||||
if (c > column2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (c < column1) {
|
||||
column1--;
|
||||
}
|
||||
|
||||
if (c < column2) {
|
||||
column2--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard hash code method
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 0xffff ^ row1 ^ row2 ^ column1 ^ column2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard equals method
|
||||
*
|
||||
* @param o the object to compare
|
||||
* @return TRUE if the two objects are the same, FALSE otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SheetRangeImpl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SheetRangeImpl compare = (SheetRangeImpl) o;
|
||||
|
||||
return (column1 == compare.column1 &&
|
||||
column2 == compare.column2 &&
|
||||
row1 == compare.row1 &&
|
||||
row2 == compare.row2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
199
datastructures-xslx/src/main/java/jxl/biff/StringHelper.java
Executable file
199
datastructures-xslx/src/main/java/jxl/biff/StringHelper.java
Executable file
|
@ -0,0 +1,199 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Helper function to convert Java string objects to and from the byte
|
||||
* representations
|
||||
*/
|
||||
public final class StringHelper {
|
||||
// Due to a a Sun bug in some versions of JVM 1.4, the UnicodeLittle
|
||||
// encoding doesn't always work. Making this a public static field
|
||||
// enables client code access to this (but in an undocumented and
|
||||
// unsupported fashion). Suggested alternative values for this
|
||||
// are "UTF-16LE" or "UnicodeLittleUnmarked"
|
||||
public static String UNICODE_ENCODING = "UnicodeLittle";
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(StringHelper.class);
|
||||
|
||||
/**
|
||||
* Private default constructor to prevent instantiation
|
||||
*/
|
||||
private StringHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bytes of the specified string. This will simply return the ASCII
|
||||
* values of the characters in the string
|
||||
*
|
||||
* @param s the string to convert into bytes
|
||||
* @return the ASCII values of the characters in the string
|
||||
* @deprecated
|
||||
*/
|
||||
public static byte[] getBytes(String s) {
|
||||
return s.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bytes of the specified string. This will simply return the ASCII
|
||||
* values of the characters in the string
|
||||
*
|
||||
* @param s the string to convert into bytes
|
||||
* @return the ASCII values of the characters in the string
|
||||
*/
|
||||
public static byte[] getBytes(String s, WorkbookSettings ws) {
|
||||
try {
|
||||
return s.getBytes(ws.getEncoding());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// fail silently
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the string into a little-endian array of Unicode bytes
|
||||
*
|
||||
* @param s the string to convert
|
||||
* @return the unicode values of the characters in the string
|
||||
*/
|
||||
public static byte[] getUnicodeBytes(String s) {
|
||||
try {
|
||||
byte[] b = s.getBytes(UNICODE_ENCODING);
|
||||
|
||||
// Sometimes this method writes out the unicode
|
||||
// identifier
|
||||
if (b.length == (s.length() * 2 + 2)) {
|
||||
byte[] b2 = new byte[b.length - 2];
|
||||
System.arraycopy(b, 2, b2, 0, b2.length);
|
||||
b = b2;
|
||||
}
|
||||
return b;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Fail silently
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the ASCII bytes from the specified string and places them in the
|
||||
* array at the specified position
|
||||
*
|
||||
* @param pos the position at which to place the converted data
|
||||
* @param s the string to convert
|
||||
* @param d the byte array which will contain the converted string data
|
||||
*/
|
||||
public static void getBytes(String s, byte[] d, int pos) {
|
||||
byte[] b = getBytes(s);
|
||||
System.arraycopy(b, 0, d, pos, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the unicode byte representation of the specified string into the
|
||||
* array passed in
|
||||
*
|
||||
* @param pos the position at which to insert the converted data
|
||||
* @param s the string to convert
|
||||
* @param d the byte array which will hold the string data
|
||||
*/
|
||||
public static void getUnicodeBytes(String s, byte[] d, int pos) {
|
||||
byte[] b = getUnicodeBytes(s);
|
||||
System.arraycopy(b, 0, d, pos, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string from the data array using the character encoding for
|
||||
* this workbook
|
||||
*
|
||||
* @param pos The start position of the string
|
||||
* @param length The number of bytes to transform into a string
|
||||
* @param d The byte data
|
||||
* @param ws the workbook settings
|
||||
* @return the string built up from the raw bytes
|
||||
*/
|
||||
public static String getString(byte[] d, int length, int pos,
|
||||
WorkbookSettings ws) {
|
||||
if (length == 0) {
|
||||
return ""; // Reduces number of new Strings
|
||||
}
|
||||
|
||||
try {
|
||||
return new String(d, pos, length, ws.getEncoding());
|
||||
// byte[] b = new byte[length];
|
||||
// System.arraycopy(d, pos, b, 0, length);
|
||||
// return new String(b, ws.getEncoding());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.warn(e.toString());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string from the data array
|
||||
*
|
||||
* @param pos The start position of the string
|
||||
* @param length The number of characters to be converted into a string
|
||||
* @param d The byte data
|
||||
* @return the string built up from the unicode characters
|
||||
*/
|
||||
public static String getUnicodeString(byte[] d, int length, int pos) {
|
||||
try {
|
||||
byte[] b = new byte[length * 2];
|
||||
System.arraycopy(d, pos, b, 0, length * 2);
|
||||
return new String(b, UNICODE_ENCODING);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Fail silently
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all instances of search with replace in the input.
|
||||
* Even though later versions of java can use string.replace()
|
||||
* this is included Java 1.2 compatibility
|
||||
*
|
||||
* @param input the format string
|
||||
* @param search the Excel character to be replaced
|
||||
* @param replace the java equivalent
|
||||
* @return the input string with the specified substring replaced
|
||||
*/
|
||||
public static final String replace(String input,
|
||||
String search,
|
||||
String replace) {
|
||||
String fmtstr = input;
|
||||
int pos = fmtstr.indexOf(search);
|
||||
while (pos != -1) {
|
||||
StringBuffer tmp = new StringBuffer(fmtstr.substring(0, pos));
|
||||
tmp.append(replace);
|
||||
tmp.append(fmtstr.substring(pos + search.length()));
|
||||
fmtstr = tmp.toString();
|
||||
pos = fmtstr.indexOf(search, pos + replace.length());
|
||||
}
|
||||
return fmtstr;
|
||||
}
|
||||
}
|
||||
|
||||
|
612
datastructures-xslx/src/main/java/jxl/biff/Type.java
Executable file
612
datastructures-xslx/src/main/java/jxl/biff/Type.java
Executable file
|
@ -0,0 +1,612 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
/**
|
||||
* An enumeration class which contains the biff types
|
||||
*/
|
||||
public final class Type {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BOF = new Type(0x809);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type EOF = new Type(0x0a);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BOUNDSHEET = new Type(0x85);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SUPBOOK = new Type(0x1ae);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type EXTERNSHEET = new Type(0x17);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DIMENSION = new Type(0x200);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BLANK = new Type(0x201);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MULBLANK = new Type(0xbe);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type ROW = new Type(0x208);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type NOTE = new Type(0x1c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type TXO = new Type(0x1b6);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type RK = new Type(0x7e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type RK2 = new Type(0x27e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MULRK = new Type(0xbd);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type INDEX = new Type(0x20b);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DBCELL = new Type(0xd7);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SST = new Type(0xfc);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type COLINFO = new Type(0x7d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type EXTSST = new Type(0xff);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CONTINUE = new Type(0x3c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type LABEL = new Type(0x204);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type RSTRING = new Type(0xd6);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type LABELSST = new Type(0xfd);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type NUMBER = new Type(0x203);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type NAME = new Type(0x18);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type TABID = new Type(0x13d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type ARRAY = new Type(0x221);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type STRING = new Type(0x207);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FORMULA = new Type(0x406);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FORMULA2 = new Type(0x6);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SHAREDFORMULA = new Type(0x4bc);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FORMAT = new Type(0x41e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type XF = new Type(0xe0);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BOOLERR = new Type(0x205);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type INTERFACEHDR = new Type(0xe1);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SAVERECALC = new Type(0x5f);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type INTERFACEEND = new Type(0xe2);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type XCT = new Type(0x59);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CRN = new Type(0x5a);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DEFCOLWIDTH = new Type(0x55);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DEFAULTROWHEIGHT = new Type(0x225);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WRITEACCESS = new Type(0x5c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WSBOOL = new Type(0x81);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CODEPAGE = new Type(0x42);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DSF = new Type(0x161);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FNGROUPCOUNT = new Type(0x9c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FILTERMODE = new Type(0x9b);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type AUTOFILTERINFO = new Type(0x9d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type AUTOFILTER = new Type(0x9e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type COUNTRY = new Type(0x8c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PROTECT = new Type(0x12);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SCENPROTECT = new Type(0xdd);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type OBJPROTECT = new Type(0x63);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PRINTHEADERS = new Type(0x2a);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type HEADER = new Type(0x14);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FOOTER = new Type(0x15);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type HCENTER = new Type(0x83);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type VCENTER = new Type(0x84);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FILEPASS = new Type(0x2f);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SETUP = new Type(0xa1);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PRINTGRIDLINES = new Type(0x2b);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type GRIDSET = new Type(0x82);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type GUTS = new Type(0x80);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WINDOWPROTECT = new Type(0x19);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PROT4REV = new Type(0x1af);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PROT4REVPASS = new Type(0x1bc);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PASSWORD = new Type(0x13);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type REFRESHALL = new Type(0x1b7);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WINDOW1 = new Type(0x3d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WINDOW2 = new Type(0x23e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BACKUP = new Type(0x40);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type HIDEOBJ = new Type(0x8d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type NINETEENFOUR = new Type(0x22);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PRECISION = new Type(0xe);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BOOKBOOL = new Type(0xda);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FONT = new Type(0x31);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MMS = new Type(0xc1);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CALCMODE = new Type(0x0d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CALCCOUNT = new Type(0x0c);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type REFMODE = new Type(0x0f);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type TEMPLATE = new Type(0x60);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type OBJPROJ = new Type(0xd3);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DELTA = new Type(0x10);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MERGEDCELLS = new Type(0xe5);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type ITERATION = new Type(0x11);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type STYLE = new Type(0x293);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type USESELFS = new Type(0x160);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type VERTICALPAGEBREAKS = new Type(0x1a);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type HORIZONTALPAGEBREAKS = new Type(0x1b);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SELECTION = new Type(0x1d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type HLINK = new Type(0x1b8);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type OBJ = new Type(0x5d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MSODRAWING = new Type(0xec);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type MSODRAWINGGROUP = new Type(0xeb);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type LEFTMARGIN = new Type(0x26);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type RIGHTMARGIN = new Type(0x27);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type TOPMARGIN = new Type(0x28);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BOTTOMMARGIN = new Type(0x29);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type EXTERNNAME = new Type(0x23);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PALETTE = new Type(0x92);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PLS = new Type(0x4d);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SCL = new Type(0xa0);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type PANE = new Type(0x41);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type WEIRD1 = new Type(0xef);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SORT = new Type(0x90);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CONDFMT = new Type(0x1b0);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type CF = new Type(0x1b1);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DV = new Type(0x1be);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type DVAL = new Type(0x1b2);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type BUTTONPROPERTYSET = new Type(0x1ba);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type EXCEL9FILE = new Type(0x1c0);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FONTX = new Type(0x1026);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type IFMT = new Type(0x104e);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type FBI = new Type(0x1060);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type ALRUNS = new Type(0x1050);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SERIES = new Type(0x1003);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SERIESLIST = new Type(0x1016);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type SBASEREF = new Type(0x1048);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final Type UNKNOWN = new Type(0xffff);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// public static final Type R = new Type(0xffff);
|
||||
|
||||
// Unknown types
|
||||
public static final Type U1C0 = new Type(0x1c0);
|
||||
public static final Type U1C1 = new Type(0x1c1);
|
||||
|
||||
// Chart types
|
||||
/**
|
||||
* An array of all types
|
||||
*/
|
||||
private static Type[] types = new Type[0];
|
||||
private static final ArbitraryType arbitrary = new ArbitraryType();
|
||||
/**
|
||||
* The biff value for this type
|
||||
*/
|
||||
public final int value;
|
||||
/**
|
||||
* Constructor
|
||||
* Sets the biff value and adds this type to the array of all types
|
||||
*
|
||||
* @param v the biff code for the type
|
||||
*/
|
||||
private Type(int v) {
|
||||
value = v;
|
||||
|
||||
// Add to the list of available types
|
||||
Type[] newTypes = new Type[types.length + 1];
|
||||
System.arraycopy(types, 0, newTypes, 0, types.length);
|
||||
newTypes[types.length] = this;
|
||||
types = newTypes;
|
||||
}
|
||||
/**
|
||||
* Constructor used for the creation of arbitrary types
|
||||
*/
|
||||
private Type(int v, ArbitraryType arb) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type object from its integer value
|
||||
*
|
||||
* @param v the internal code
|
||||
* @return the type
|
||||
*/
|
||||
public static Type getType(int v) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].value == v) {
|
||||
return types[i];
|
||||
}
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create an arbitrary record type. This method is only
|
||||
* used during bespoke debugging process. The creation of an
|
||||
* arbitrary type does not add it to the static list of known types
|
||||
*/
|
||||
public static Type createType(int v) {
|
||||
return new Type(v, arbitrary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard hash code method
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Pivot stuff
|
||||
|
||||
/**
|
||||
* Standard equals method
|
||||
*
|
||||
* @param o the object to compare
|
||||
* @return TRUE if the objects are equal, FALSE otherwise
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type t = (Type) o;
|
||||
|
||||
return value == t.value;
|
||||
}
|
||||
|
||||
private static class ArbitraryType {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
54
datastructures-xslx/src/main/java/jxl/biff/WorkbookMethods.java
Executable file
54
datastructures-xslx/src/main/java/jxl/biff/WorkbookMethods.java
Executable file
|
@ -0,0 +1,54 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.Sheet;
|
||||
|
||||
/**
|
||||
* An interface containing some common workbook methods. This so that
|
||||
* objects which are re-used for both readable and writable workbooks
|
||||
* can still make the same method calls on a workbook
|
||||
*/
|
||||
public interface WorkbookMethods {
|
||||
/**
|
||||
* Gets the specified sheet within this workbook
|
||||
*
|
||||
* @param index the zero based index of the required sheet
|
||||
* @return The sheet specified by the index
|
||||
*/
|
||||
Sheet getReadSheet(int index);
|
||||
|
||||
/**
|
||||
* Gets the name at the specified index
|
||||
*
|
||||
* @param index the index into the name table
|
||||
* @return the name of the cell
|
||||
* @throws NameRangeException
|
||||
*/
|
||||
String getName(int index) throws NameRangeException;
|
||||
|
||||
/**
|
||||
* Gets the index of the name record for the name
|
||||
*
|
||||
* @param name the name
|
||||
* @return the index in the name table
|
||||
*/
|
||||
int getNameIndex(String name);
|
||||
}
|
143
datastructures-xslx/src/main/java/jxl/biff/WorkspaceInformationRecord.java
Executable file
143
datastructures-xslx/src/main/java/jxl/biff/WorkspaceInformationRecord.java
Executable file
|
@ -0,0 +1,143 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A record detailing whether the sheet is protected
|
||||
*/
|
||||
public class WorkspaceInformationRecord extends WritableRecordData {
|
||||
// the masks
|
||||
private static final int FIT_TO_PAGES = 0x100;
|
||||
private static final int SHOW_ROW_OUTLINE_SYMBOLS = 0x400;
|
||||
private static final int SHOW_COLUMN_OUTLINE_SYMBOLS = 0x800;
|
||||
private static final int DEFAULT_OPTIONS = 0x4c1;
|
||||
// the logger
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(WorkspaceInformationRecord.class);
|
||||
/**
|
||||
* The options byte
|
||||
*/
|
||||
private int wsoptions;
|
||||
/**
|
||||
* The row outlines
|
||||
*/
|
||||
private boolean rowOutlines;
|
||||
/**
|
||||
* The column outlines
|
||||
*/
|
||||
private boolean columnOutlines;
|
||||
/**
|
||||
* The fit to pages flag
|
||||
*/
|
||||
private boolean fitToPages;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data
|
||||
*
|
||||
* @param t the raw data
|
||||
*/
|
||||
public WorkspaceInformationRecord(Record t) {
|
||||
super(t);
|
||||
byte[] data = getRecord().getData();
|
||||
|
||||
wsoptions = IntegerHelper.getInt(data[0], data[1]);
|
||||
fitToPages = (wsoptions | FIT_TO_PAGES) != 0;
|
||||
rowOutlines = (wsoptions | SHOW_ROW_OUTLINE_SYMBOLS) != 0;
|
||||
columnOutlines = (wsoptions | SHOW_COLUMN_OUTLINE_SYMBOLS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this object from the raw data
|
||||
*/
|
||||
public WorkspaceInformationRecord() {
|
||||
super(Type.WSBOOL);
|
||||
wsoptions = DEFAULT_OPTIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fit to pages flag
|
||||
*
|
||||
* @return TRUE if fit to pages is set
|
||||
*/
|
||||
public boolean getFitToPages() {
|
||||
return fitToPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fit to page flag
|
||||
*
|
||||
* @param b fit to page indicator
|
||||
*/
|
||||
public void setFitToPages(boolean b) {
|
||||
fitToPages = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the outlines
|
||||
*/
|
||||
public void setRowOutlines(boolean ro) {
|
||||
rowOutlines = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the outlines
|
||||
*/
|
||||
public void setColumnOutlines(boolean ro) {
|
||||
rowOutlines = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the binary data for output to file
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
byte[] data = new byte[2];
|
||||
|
||||
if (fitToPages) {
|
||||
wsoptions |= FIT_TO_PAGES;
|
||||
}
|
||||
|
||||
if (rowOutlines) {
|
||||
wsoptions |= SHOW_ROW_OUTLINE_SYMBOLS;
|
||||
}
|
||||
|
||||
if (columnOutlines) {
|
||||
wsoptions |= SHOW_COLUMN_OUTLINE_SYMBOLS;
|
||||
}
|
||||
|
||||
IntegerHelper.getTwoBytes(wsoptions, data, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
139
datastructures-xslx/src/main/java/jxl/biff/WritableRecordData.java
Executable file
139
datastructures-xslx/src/main/java/jxl/biff/WritableRecordData.java
Executable file
|
@ -0,0 +1,139 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* Extension of the standard RecordData which is used to support those
|
||||
* records which, once read, may also be written
|
||||
*/
|
||||
public abstract class WritableRecordData extends RecordData
|
||||
implements ByteData {
|
||||
/**
|
||||
* The maximum length allowed by Excel for any record length
|
||||
*/
|
||||
protected static final int maxRecordLength = 8228;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(WritableRecordData.class);
|
||||
|
||||
/**
|
||||
* Constructor used by the writable records
|
||||
*
|
||||
* @param t the biff type of this record
|
||||
*/
|
||||
protected WritableRecordData(Type t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when reading a record
|
||||
*
|
||||
* @param t the raw data read from the biff file
|
||||
*/
|
||||
protected WritableRecordData(Record t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when writing out records. This portion of the method handles the
|
||||
* biff code and the length of the record and appends on the data retrieved
|
||||
* from the subclasses
|
||||
*
|
||||
* @return the full record data to be written out to the compound file
|
||||
*/
|
||||
public final byte[] getBytes() {
|
||||
byte[] data = getData();
|
||||
|
||||
int dataLength = data.length;
|
||||
|
||||
// Don't the call the automatic continuation code for now
|
||||
// Assert.verify(dataLength <= maxRecordLength - 4);
|
||||
// If the bytes length is greater than the max record length
|
||||
// then split out the data set into continue records
|
||||
if (data.length > maxRecordLength - 4) {
|
||||
dataLength = maxRecordLength - 4;
|
||||
data = handleContinueRecords(data);
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[data.length + 4];
|
||||
|
||||
System.arraycopy(data, 0, bytes, 4, data.length);
|
||||
|
||||
IntegerHelper.getTwoBytes(getCode(), bytes, 0);
|
||||
IntegerHelper.getTwoBytes(dataLength, bytes, 2);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes for this record exceeds the maximum record
|
||||
* length, so a continue is required
|
||||
*
|
||||
* @param data the raw data
|
||||
* @return the continued data
|
||||
*/
|
||||
private byte[] handleContinueRecords(byte[] data) {
|
||||
// Deduce the number of continue records
|
||||
int continuedData = data.length - (maxRecordLength - 4);
|
||||
int numContinueRecords = continuedData / (maxRecordLength - 4) + 1;
|
||||
|
||||
// Create the new byte array, allowing for the continue records
|
||||
// code and length
|
||||
byte[] newdata = new byte[data.length + numContinueRecords * 4];
|
||||
|
||||
// Copy the bona fide record data into the beginning of the super
|
||||
// record
|
||||
System.arraycopy(data, 0, newdata, 0, maxRecordLength - 4);
|
||||
int oldarraypos = maxRecordLength - 4;
|
||||
int newarraypos = maxRecordLength - 4;
|
||||
|
||||
// Now handle all the continue records
|
||||
for (int i = 0; i < numContinueRecords; i++) {
|
||||
// The number of bytes to add into the new array
|
||||
int length = Math.min(data.length - oldarraypos, maxRecordLength - 4);
|
||||
|
||||
// Add in the continue record code
|
||||
IntegerHelper.getTwoBytes(Type.CONTINUE.value, newdata, newarraypos);
|
||||
IntegerHelper.getTwoBytes(length, newdata, newarraypos + 2);
|
||||
|
||||
// Copy in as much of the new data as possible
|
||||
System.arraycopy(data, oldarraypos, newdata, newarraypos + 4, length);
|
||||
|
||||
// Update the position counters
|
||||
oldarraypos += length;
|
||||
newarraypos += length + 4;
|
||||
}
|
||||
|
||||
return newdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method called by the getBytes method. Subclasses implement
|
||||
* this method to incorporate their specific binary data - excluding the
|
||||
* biff code and record length, which is handled by this class
|
||||
*
|
||||
* @return subclass specific biff data
|
||||
*/
|
||||
protected abstract byte[] getData();
|
||||
}
|
48
datastructures-xslx/src/main/java/jxl/biff/XCTRecord.java
Executable file
48
datastructures-xslx/src/main/java/jxl/biff/XCTRecord.java
Executable file
|
@ -0,0 +1,48 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff;
|
||||
|
||||
import jxl.read.biff.Record;
|
||||
|
||||
/**
|
||||
* A record representing the XCT record
|
||||
*/
|
||||
public class XCTRecord extends WritableRecordData {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param t the raw bytes
|
||||
*/
|
||||
public XCTRecord(Record t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the binary data - used when copying
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return getRecord().getData();
|
||||
}
|
||||
|
||||
}
|
1501
datastructures-xslx/src/main/java/jxl/biff/XFRecord.java
Executable file
1501
datastructures-xslx/src/main/java/jxl/biff/XFRecord.java
Executable file
File diff suppressed because it is too large
Load diff
86
datastructures-xslx/src/main/java/jxl/biff/drawing/BStoreContainer.java
Executable file
86
datastructures-xslx/src/main/java/jxl/biff/drawing/BStoreContainer.java
Executable file
|
@ -0,0 +1,86 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* A BStoreContainer escher record
|
||||
*/
|
||||
class BStoreContainer extends EscherContainer {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(BStoreContainer.class);
|
||||
|
||||
/**
|
||||
* The number of blips inside this container
|
||||
*/
|
||||
private int numBlips;
|
||||
|
||||
/**
|
||||
* Constructor used to instantiate this object when reading from an
|
||||
* escher stream
|
||||
*
|
||||
* @param erd the escher data
|
||||
*/
|
||||
public BStoreContainer(EscherRecordData erd) {
|
||||
super(erd);
|
||||
numBlips = getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when writing out an escher record
|
||||
*/
|
||||
public BStoreContainer() {
|
||||
super(EscherRecordType.BSTORE_CONTAINER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of blips
|
||||
*
|
||||
* @return the number of blips
|
||||
*/
|
||||
public int getNumBlips() {
|
||||
return numBlips;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of drawings in this container
|
||||
*
|
||||
* @param count the number of blips
|
||||
*/
|
||||
void setNumBlips(int count) {
|
||||
numBlips = count;
|
||||
setInstance(numBlips);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing
|
||||
*
|
||||
* @param i the index number of the drawing to return
|
||||
* @return the drawing
|
||||
*/
|
||||
public BlipStoreEntry getDrawing(int i) {
|
||||
EscherRecord[] children = getChildren();
|
||||
BlipStoreEntry bse = (BlipStoreEntry) children[i];
|
||||
return bse;
|
||||
}
|
||||
}
|
195
datastructures-xslx/src/main/java/jxl/biff/drawing/BlipStoreEntry.java
Executable file
195
datastructures-xslx/src/main/java/jxl/biff/drawing/BlipStoreEntry.java
Executable file
|
@ -0,0 +1,195 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* The data for this blip store entry. Typically this is the raw image data
|
||||
*/
|
||||
class BlipStoreEntry extends EscherAtom {
|
||||
/**
|
||||
* The start of the image data within this blip entry
|
||||
*/
|
||||
private static final int IMAGE_DATA_OFFSET = 61;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(BlipStoreEntry.class);
|
||||
/**
|
||||
* The type of the blip
|
||||
*/
|
||||
private final BlipType type;
|
||||
/**
|
||||
* The image data read in
|
||||
*/
|
||||
private byte[] data;
|
||||
/**
|
||||
* The length of the image data
|
||||
*/
|
||||
private int imageDataLength;
|
||||
/**
|
||||
* The reference count on this blip
|
||||
*/
|
||||
private int referenceCount;
|
||||
/**
|
||||
* Flag to indicate that this entry was specified by the API, and not
|
||||
* read in
|
||||
*/
|
||||
private final boolean write;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd the escher record data
|
||||
*/
|
||||
public BlipStoreEntry(EscherRecordData erd) {
|
||||
super(erd);
|
||||
type = BlipType.getType(getInstance());
|
||||
write = false;
|
||||
byte[] bytes = getBytes();
|
||||
referenceCount = IntegerHelper.getInt(bytes[24], bytes[25],
|
||||
bytes[26], bytes[27]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param d the drawing
|
||||
* @throws IOException
|
||||
*/
|
||||
public BlipStoreEntry(Drawing d) throws IOException {
|
||||
super(EscherRecordType.BSE);
|
||||
type = BlipType.PNG;
|
||||
setVersion(2);
|
||||
setInstance(type.getValue());
|
||||
|
||||
byte[] imageData = d.getImageBytes();
|
||||
imageDataLength = imageData.length;
|
||||
data = new byte[imageDataLength + IMAGE_DATA_OFFSET];
|
||||
System.arraycopy(imageData, 0, data, IMAGE_DATA_OFFSET, imageDataLength);
|
||||
referenceCount = d.getReferenceCount();
|
||||
write = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip type
|
||||
*
|
||||
* @return the blip type
|
||||
*/
|
||||
public BlipType getBlipType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data for this blip so that it can be written out
|
||||
*
|
||||
* @return the data for the blip
|
||||
*/
|
||||
public byte[] getData() {
|
||||
if (write) {
|
||||
// Drawing has been specified by API
|
||||
|
||||
// Type on win32
|
||||
data[0] = (byte) type.getValue();
|
||||
|
||||
// Type on MacOs
|
||||
data[1] = (byte) type.getValue();
|
||||
|
||||
// The blip identifier
|
||||
// IntegerHelper.getTwoBytes(0xfce1, data, 2);
|
||||
|
||||
// Unused tags - 18 bytes
|
||||
// System.arraycopy(stuff, 0, data, 2, stuff.length);
|
||||
|
||||
// The size of the file
|
||||
IntegerHelper.getFourBytes(imageDataLength + 8 + 17, data, 20);
|
||||
|
||||
// The reference count on the blip
|
||||
IntegerHelper.getFourBytes(referenceCount, data, 24);
|
||||
|
||||
// Offset in the delay stream
|
||||
IntegerHelper.getFourBytes(0, data, 28);
|
||||
|
||||
// Usage byte
|
||||
data[32] = (byte) 0;
|
||||
|
||||
// Length of the blip name
|
||||
data[33] = (byte) 0;
|
||||
|
||||
// Last two bytes unused
|
||||
data[34] = (byte) 0x7e;
|
||||
data[35] = (byte) 0x01;
|
||||
|
||||
// The blip itself
|
||||
data[36] = (byte) 0;
|
||||
data[37] = (byte) 0x6e;
|
||||
|
||||
// The blip identifier
|
||||
IntegerHelper.getTwoBytes(0xf01e, data, 38);
|
||||
|
||||
// The length of the blip. This is the length of the image file plus
|
||||
// 16 bytes
|
||||
IntegerHelper.getFourBytes(imageDataLength + 17, data, 40);
|
||||
|
||||
// Unknown stuff
|
||||
// System.arraycopy(stuff, 0, data, 44, stuff.length);
|
||||
} else {
|
||||
// drawing has been read in
|
||||
data = getBytes();
|
||||
}
|
||||
|
||||
return setHeaderData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the reference count in this blip. Called when a drawing is
|
||||
* removed
|
||||
*/
|
||||
void dereference() {
|
||||
referenceCount--;
|
||||
Assert.verify(referenceCount >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on the blip
|
||||
*
|
||||
* @return the reference count on the blip
|
||||
*/
|
||||
int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data.
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
byte[] getImageData() {
|
||||
byte[] allData = getBytes();
|
||||
byte[] imageData = new byte[allData.length - IMAGE_DATA_OFFSET];
|
||||
System.arraycopy(allData, IMAGE_DATA_OFFSET,
|
||||
imageData, 0, imageData.length);
|
||||
return imageData;
|
||||
}
|
||||
}
|
106
datastructures-xslx/src/main/java/jxl/biff/drawing/BlipType.java
Executable file
106
datastructures-xslx/src/main/java/jxl/biff/drawing/BlipType.java
Executable file
|
@ -0,0 +1,106 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
/**
|
||||
* Enumeration for the BLIP type
|
||||
*/
|
||||
final class BlipType {
|
||||
public static final BlipType ERROR = new BlipType(0, "Error");
|
||||
// An error occured during loading
|
||||
public static final BlipType UNKNOWN = new BlipType(1, "Unknown");
|
||||
// An unknown blip type
|
||||
public static final BlipType EMF = new BlipType(2, "EMF");
|
||||
// Windows Enhanced Metafile
|
||||
public static final BlipType WMF = new BlipType(3, "WMF");
|
||||
// Windows Metafile
|
||||
public static final BlipType PICT = new BlipType(4, "PICT");
|
||||
// Macintosh PICT
|
||||
public static final BlipType JPEG = new BlipType(5, "JPEG"); // JFIF
|
||||
public static final BlipType PNG = new BlipType(6, "PNG"); // PNG
|
||||
public static final BlipType DIB = new BlipType(7, "DIB"); // Windows DIB
|
||||
public static final BlipType FIRST_CLIENT = new BlipType(32, "FIRST");
|
||||
// First client defined blip type
|
||||
public static final BlipType LAST_CLIENT = new BlipType(255, "LAST");
|
||||
/**
|
||||
* All blip types
|
||||
*/
|
||||
private static BlipType[] types = new BlipType[0];
|
||||
/**
|
||||
* The blip type code
|
||||
*/
|
||||
private final int value;
|
||||
/**
|
||||
* The blip type description
|
||||
*/
|
||||
private final String desc;
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param val the code
|
||||
* @param d the description
|
||||
*/
|
||||
private BlipType(int val, String d) {
|
||||
value = val;
|
||||
desc = d;
|
||||
|
||||
BlipType[] newtypes = new BlipType[types.length + 1];
|
||||
System.arraycopy(types, 0, newtypes, 0, types.length);
|
||||
newtypes[types.length] = this;
|
||||
types = newtypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blip type given the value
|
||||
*
|
||||
* @param val get the value
|
||||
* @return the blip type
|
||||
*/
|
||||
public static BlipType getType(int val) {
|
||||
BlipType type = UNKNOWN;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].value == val) {
|
||||
type = types[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the description
|
||||
*
|
||||
* @return the description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the value
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
// Last client defined blip type
|
||||
}
|
790
datastructures-xslx/src/main/java/jxl/biff/drawing/Button.java
Executable file
790
datastructures-xslx/src/main/java/jxl/biff/drawing/Button.java
Executable file
|
@ -0,0 +1,790 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.ContinueRecord;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.biff.StringHelper;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to copy a Button (from the
|
||||
* Form toolbox) between workbook
|
||||
*/
|
||||
public class Button implements DrawingGroupObject {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Button.class);
|
||||
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
|
||||
/**
|
||||
* The spContainer that was generated
|
||||
*/
|
||||
private EscherContainer spContainer;
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private final MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* The ObjRecord associated with the drawing
|
||||
*/
|
||||
private final ObjRecord objRecord;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* The column
|
||||
*/
|
||||
private int column;
|
||||
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private int row;
|
||||
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private final DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private final int drawingNumber;
|
||||
|
||||
/**
|
||||
* An mso drawing record, which sometimes appears
|
||||
*/
|
||||
private MsoDrawingRecord mso;
|
||||
|
||||
/**
|
||||
* The text object record
|
||||
*/
|
||||
private TextObjectRecord txo;
|
||||
|
||||
/**
|
||||
* Text data from the first continue record
|
||||
*/
|
||||
private ContinueRecord text;
|
||||
|
||||
/**
|
||||
* Formatting data from the second continue record
|
||||
*/
|
||||
private ContinueRecord formatting;
|
||||
|
||||
/**
|
||||
* The comment text
|
||||
*/
|
||||
private String commentText;
|
||||
|
||||
/**
|
||||
* The workbook settings
|
||||
*/
|
||||
private final WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param msodr the drawing record
|
||||
* @param obj the object record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public Button(MsoDrawingRecord msodr,
|
||||
ObjRecord obj,
|
||||
DrawingData dd,
|
||||
DrawingGroup dg,
|
||||
WorkbookSettings ws) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = msodr;
|
||||
drawingData = dd;
|
||||
objRecord = obj;
|
||||
initialized = false;
|
||||
workbookSettings = ws;
|
||||
origin = Origin.READ;
|
||||
drawingData.addData(msoDrawingRecord.getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(msoDrawingRecord != null && objRecord != null);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public Button(DrawingGroupObject dgo,
|
||||
DrawingGroup dg,
|
||||
WorkbookSettings ws) {
|
||||
Button d = (Button) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
objRecord = d.objRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
mso = d.mso;
|
||||
txo = d.txo;
|
||||
text = d.text;
|
||||
formatting = d.formatting;
|
||||
workbookSettings = ws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
readSpContainer = drawingData.getSpContainer(drawingNumber);
|
||||
Assert.verify(readSpContainer != null);
|
||||
|
||||
EscherRecord[] children = readSpContainer.getChildren();
|
||||
|
||||
Sp sp = (Sp) readSpContainer.getChildren()[0];
|
||||
objectId = objRecord.getObjectId();
|
||||
shapeId = sp.getShapeId();
|
||||
type = ShapeType.getType(sp.getShapeType());
|
||||
|
||||
if (type == ShapeType.UNKNOWN) {
|
||||
logger.warn("Unknown shape type");
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = null;
|
||||
for (int i = 0; i < children.length && clientAnchor == null; i++) {
|
||||
if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR) {
|
||||
clientAnchor = (ClientAnchor) children[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clientAnchor == null) {
|
||||
logger.warn("Client anchor not found");
|
||||
} else {
|
||||
column = (int) clientAnchor.getX1() - 1;
|
||||
row = (int) clientAnchor.getY1() + 1;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
Assert.verify(false);
|
||||
|
||||
/*
|
||||
if (spContainer == null)
|
||||
{
|
||||
spContainer = new SpContainer();
|
||||
Sp sp = new Sp(type, shapeId, 2560);
|
||||
spContainer.add(sp);
|
||||
Opt opt = new Opt();
|
||||
opt.addProperty(344, false, false, 0); // ?
|
||||
opt.addProperty(385, false, false, 134217808); // fill colour
|
||||
opt.addProperty(387, false, false, 134217808); // background colour
|
||||
opt.addProperty(959, false, false, 131074); // hide
|
||||
spContainer.add(opt);
|
||||
|
||||
ClientAnchor clientAnchor = new ClientAnchor(column + 1.3,
|
||||
Math.max(0, row - 0.6),
|
||||
column+3, row + 4);
|
||||
|
||||
spContainer.add(clientAnchor);
|
||||
|
||||
ClientData clientData = new ClientData();
|
||||
spContainer.add(clientData);
|
||||
|
||||
ClientTextBox clientTextBox = new ClientTextBox();
|
||||
spContainer.add(clientTextBox);
|
||||
}
|
||||
*/
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing. Used when inserting/removing
|
||||
* columns from the spreadsheet
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
column = (int) x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
row = (int) y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text object
|
||||
*
|
||||
* @param t the text object record
|
||||
*/
|
||||
public void setTextObject(TextObjectRecord t) {
|
||||
txo = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the formatting
|
||||
*
|
||||
* @param t continue record
|
||||
*/
|
||||
public void setFormatting(ContinueRecord t) {
|
||||
formatting = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The drawing record
|
||||
*
|
||||
* @param d the drawing record
|
||||
*/
|
||||
public void addMso(MsoDrawingRecord d) {
|
||||
mso = d;
|
||||
drawingData.addRawData(mso.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out any additional records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(objRecord);
|
||||
|
||||
if (mso != null) {
|
||||
outputFile.write(mso);
|
||||
}
|
||||
outputFile.write(txo);
|
||||
outputFile.write(text);
|
||||
if (formatting != null) {
|
||||
outputFile.write(formatting);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.verify(false);
|
||||
|
||||
// Create the obj record
|
||||
ObjRecord objrec = new ObjRecord(objectId,
|
||||
ObjRecord.EXCELNOTE);
|
||||
|
||||
outputFile.write(objrec);
|
||||
|
||||
// Create the mso data record. Write the text box record again,
|
||||
// although it is already included in the SpContainer
|
||||
ClientTextBox textBox = new ClientTextBox();
|
||||
MsoDrawingRecord msod = new MsoDrawingRecord(textBox.getData());
|
||||
outputFile.write(msod);
|
||||
|
||||
TextObjectRecord tor = new TextObjectRecord(getText());
|
||||
outputFile.write(tor);
|
||||
|
||||
// Data for the first continue record
|
||||
byte[] textData = new byte[commentText.length() * 2 + 1];
|
||||
textData[0] = 0x1; // unicode indicator
|
||||
StringHelper.getUnicodeBytes(commentText, textData, 1);
|
||||
//StringHelper.getBytes(commentText, textData, 1);
|
||||
ContinueRecord textContinue = new ContinueRecord(textData);
|
||||
outputFile.write(textContinue);
|
||||
|
||||
// Data for the formatting runs
|
||||
|
||||
byte[] frData = new byte[16];
|
||||
|
||||
// First txo run (the user)
|
||||
IntegerHelper.getTwoBytes(0, frData, 0); // index to the first character
|
||||
IntegerHelper.getTwoBytes(0, frData, 2); // index to the font(default)
|
||||
// Mandatory last txo run
|
||||
IntegerHelper.getTwoBytes(commentText.length(), frData, 8);
|
||||
IntegerHelper.getTwoBytes(0, frData, 10); // index to the font(default)
|
||||
|
||||
ContinueRecord frContinue = new ContinueRecord(frData);
|
||||
outputFile.write(frContinue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Writes out all the note records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row. As buttons are not associated with a cell,
|
||||
* does nothing here
|
||||
*
|
||||
* @return the row number
|
||||
*/
|
||||
public int getRow() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column. As buttons are not associated with a cell,
|
||||
* does nothing here
|
||||
*
|
||||
* @return the column number
|
||||
*/
|
||||
public int getColumn() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the text on the button
|
||||
*
|
||||
* @return the button text
|
||||
*/
|
||||
public String getText() {
|
||||
if (commentText == null) {
|
||||
Assert.verify(text != null);
|
||||
|
||||
byte[] td = text.getData();
|
||||
if (td[0] == 0) {
|
||||
commentText = StringHelper.getString
|
||||
(td, td.length - 1, 1, workbookSettings);
|
||||
} else {
|
||||
commentText = StringHelper.getUnicodeString
|
||||
(td, (td.length - 1) / 2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return commentText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text data
|
||||
*
|
||||
* @param t continuation record
|
||||
*/
|
||||
public void setText(ContinueRecord t) {
|
||||
text = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashing algorithm
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return commentText.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the comment text is changed during the sheet copy process
|
||||
*
|
||||
* @param t the new text
|
||||
*/
|
||||
public void setButtonText(String t) {
|
||||
commentText = t;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return mso.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
249
datastructures-xslx/src/main/java/jxl/biff/drawing/Chart.java
Executable file
249
datastructures-xslx/src/main/java/jxl/biff/drawing/Chart.java
Executable file
|
@ -0,0 +1,249 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.ByteData;
|
||||
import jxl.biff.IndexMapping;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.biff.Type;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.File;
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to insert a chart into a
|
||||
* worksheet
|
||||
*/
|
||||
public class Chart implements ByteData, EscherStream {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Chart.class);
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the chart
|
||||
*/
|
||||
private final MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* The ObjRecord associated with the chart
|
||||
*/
|
||||
private final ObjRecord objRecord;
|
||||
|
||||
/**
|
||||
* The start pos of the chart bof stream in the data file
|
||||
*/
|
||||
private final int startpos;
|
||||
|
||||
/**
|
||||
* The start pos of the chart bof stream in the data file
|
||||
*/
|
||||
private final int endpos;
|
||||
|
||||
/**
|
||||
* A handle to the Excel file
|
||||
*/
|
||||
private final File file;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The drawing number
|
||||
*/
|
||||
private int drawingNumber;
|
||||
|
||||
/**
|
||||
* The chart byte data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Flag which indicates that the byte data has been initialized
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* The workbook settings
|
||||
*/
|
||||
private final WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param mso a <code>MsoDrawingRecord</code> value
|
||||
* @param obj an <code>ObjRecord</code> value
|
||||
* @param dd the drawing data
|
||||
* @param sp an <code>int</code> value
|
||||
* @param ep an <code>int</code> value
|
||||
* @param f a <code>File</code> value
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public Chart(MsoDrawingRecord mso,
|
||||
ObjRecord obj,
|
||||
DrawingData dd,
|
||||
int sp, int ep, File f, WorkbookSettings ws) {
|
||||
msoDrawingRecord = mso;
|
||||
objRecord = obj;
|
||||
startpos = sp;
|
||||
endpos = ep;
|
||||
file = f;
|
||||
workbookSettings = ws;
|
||||
|
||||
// msoDrawingRecord is null if the entire sheet consists of just the
|
||||
// chart. In this case, as there is only one drawing on the page,
|
||||
// it isn't necessary to add to the drawing data record anyway
|
||||
if (msoDrawingRecord != null) {
|
||||
drawingData = dd;
|
||||
drawingData.addData(msoDrawingRecord.getRecord().getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
}
|
||||
|
||||
initialized = false;
|
||||
|
||||
// Note: mso and obj values can be null if we are creating a chart
|
||||
// which takes up an entire worksheet. Check that both are null or both
|
||||
// not null though
|
||||
Assert.verify((mso != null && obj != null) ||
|
||||
(mso == null && obj == null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entire binary record for the chart as a chunk of binary data
|
||||
*
|
||||
* @return the bytes
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the EscherStream method
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return msoDrawingRecord.getRecord().getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the charts byte data
|
||||
*/
|
||||
private void initialize() {
|
||||
data = file.read(startpos, endpos - startpos);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rationalizes the sheet's xf index mapping
|
||||
*
|
||||
* @param xfMapping the index mapping for XFRecords
|
||||
* @param fontMapping the index mapping for fonts
|
||||
* @param formatMapping the index mapping for formats
|
||||
*/
|
||||
public void rationalize(IndexMapping xfMapping,
|
||||
IndexMapping fontMapping,
|
||||
IndexMapping formatMapping) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
// Read through the array, looking for the data types
|
||||
// This is a total hack bodge for now - it will eventually need to be
|
||||
// integrated properly
|
||||
int pos = 0;
|
||||
int code = 0;
|
||||
int length = 0;
|
||||
Type type = null;
|
||||
while (pos < data.length) {
|
||||
code = IntegerHelper.getInt(data[pos], data[pos + 1]);
|
||||
length = IntegerHelper.getInt(data[pos + 2], data[pos + 3]);
|
||||
|
||||
type = Type.getType(code);
|
||||
|
||||
if (type == Type.FONTX) {
|
||||
int fontind = IntegerHelper.getInt(data[pos + 4], data[pos + 5]);
|
||||
IntegerHelper.getTwoBytes(fontMapping.getNewIndex(fontind),
|
||||
data, pos + 4);
|
||||
} else if (type == Type.FBI) {
|
||||
int fontind = IntegerHelper.getInt(data[pos + 12], data[pos + 13]);
|
||||
IntegerHelper.getTwoBytes(fontMapping.getNewIndex(fontind),
|
||||
data, pos + 12);
|
||||
} else if (type == Type.IFMT) {
|
||||
int formind = IntegerHelper.getInt(data[pos + 4], data[pos + 5]);
|
||||
IntegerHelper.getTwoBytes(formatMapping.getNewIndex(formind),
|
||||
data, pos + 4);
|
||||
} else if (type == Type.ALRUNS) {
|
||||
int numRuns = IntegerHelper.getInt(data[pos + 4], data[pos + 5]);
|
||||
int fontPos = pos + 6;
|
||||
for (int i = 0; i < numRuns; i++) {
|
||||
int fontind = IntegerHelper.getInt(data[fontPos + 2],
|
||||
data[fontPos + 3]);
|
||||
IntegerHelper.getTwoBytes(fontMapping.getNewIndex(fontind),
|
||||
data, fontPos + 2);
|
||||
fontPos += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pos += length + 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SpContainer containing the charts drawing information
|
||||
*
|
||||
* @return the spContainer
|
||||
*/
|
||||
EscherContainer getSpContainer() {
|
||||
EscherContainer spContainer = drawingData.getSpContainer(drawingNumber);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the mso drawing record
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the obj record
|
||||
*
|
||||
* @return the obj record
|
||||
*/
|
||||
ObjRecord getObjRecord() {
|
||||
return objRecord;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
716
datastructures-xslx/src/main/java/jxl/biff/drawing/CheckBox.java
Executable file
716
datastructures-xslx/src/main/java/jxl/biff/drawing/CheckBox.java
Executable file
|
@ -0,0 +1,716 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.ContinueRecord;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to copy a CheckBox (from the
|
||||
* Form toolbox) between workbook
|
||||
*/
|
||||
public class CheckBox implements DrawingGroupObject {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(CheckBox.class);
|
||||
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
|
||||
/**
|
||||
* The spContainer that was generated
|
||||
*/
|
||||
private EscherContainer spContainer;
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* The ObjRecord associated with the drawing
|
||||
*/
|
||||
private ObjRecord objRecord;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* The column
|
||||
*/
|
||||
private int column;
|
||||
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private int row;
|
||||
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private int drawingNumber;
|
||||
|
||||
/**
|
||||
* An mso drawing record, which sometimes appears
|
||||
*/
|
||||
private MsoDrawingRecord mso;
|
||||
|
||||
/**
|
||||
* The text object record
|
||||
*/
|
||||
private TextObjectRecord txo;
|
||||
|
||||
/**
|
||||
* Text data from the first continue record
|
||||
*/
|
||||
private ContinueRecord text;
|
||||
|
||||
/**
|
||||
* Formatting data from the second continue record
|
||||
*/
|
||||
private ContinueRecord formatting;
|
||||
|
||||
/**
|
||||
* The workbook settings
|
||||
*/
|
||||
private WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param mso the drawing record
|
||||
* @param obj the object record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public CheckBox(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd,
|
||||
DrawingGroup dg, WorkbookSettings ws) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = mso;
|
||||
drawingData = dd;
|
||||
objRecord = obj;
|
||||
initialized = false;
|
||||
workbookSettings = ws;
|
||||
origin = Origin.READ;
|
||||
drawingData.addData(msoDrawingRecord.getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(mso != null && obj != null);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public CheckBox(DrawingGroupObject dgo,
|
||||
DrawingGroup dg,
|
||||
WorkbookSettings ws) {
|
||||
CheckBox d = (CheckBox) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
objRecord = d.objRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
mso = d.mso;
|
||||
txo = d.txo;
|
||||
text = d.text;
|
||||
formatting = d.formatting;
|
||||
workbookSettings = ws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing images
|
||||
*/
|
||||
public CheckBox() {
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
referenceCount = 1;
|
||||
type = ShapeType.HOST_CONTROL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
readSpContainer = drawingData.getSpContainer(drawingNumber);
|
||||
Assert.verify(readSpContainer != null);
|
||||
|
||||
EscherRecord[] children = readSpContainer.getChildren();
|
||||
|
||||
Sp sp = (Sp) readSpContainer.getChildren()[0];
|
||||
objectId = objRecord.getObjectId();
|
||||
shapeId = sp.getShapeId();
|
||||
type = ShapeType.getType(sp.getShapeType());
|
||||
|
||||
if (type == ShapeType.UNKNOWN) {
|
||||
logger.warn("Unknown shape type");
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = null;
|
||||
for (int i = 0; i < children.length && clientAnchor == null; i++) {
|
||||
if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR) {
|
||||
clientAnchor = (ClientAnchor) children[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clientAnchor == null) {
|
||||
logger.warn("Client anchor not found");
|
||||
} else {
|
||||
column = (int) clientAnchor.getX1();
|
||||
row = (int) clientAnchor.getY1();
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
SpContainer spc = new SpContainer();
|
||||
Sp sp = new Sp(type, shapeId, 2560);
|
||||
spc.add(sp);
|
||||
Opt opt = new Opt();
|
||||
opt.addProperty(127, false, false, 17039620);
|
||||
opt.addProperty(191, false, false, 524296);
|
||||
opt.addProperty(511, false, false, 524288);
|
||||
opt.addProperty(959, false, false, 131072);
|
||||
// opt.addProperty(260, true, false, blipId);
|
||||
// opt.addProperty(261, false, false, 36);
|
||||
spc.add(opt);
|
||||
|
||||
ClientAnchor clientAnchor = new ClientAnchor(column,
|
||||
row,
|
||||
column + 1,
|
||||
row + 1,
|
||||
0x1);
|
||||
spc.add(clientAnchor);
|
||||
ClientData clientData = new ClientData();
|
||||
spc.add(clientData);
|
||||
|
||||
return spc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing. Used when inserting/removing
|
||||
* columns from the spreadsheet
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
column = (int) x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
row = (int) y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the additional records for a combo box
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(objRecord);
|
||||
|
||||
if (mso != null) {
|
||||
outputFile.write(mso);
|
||||
}
|
||||
outputFile.write(txo);
|
||||
outputFile.write(text);
|
||||
if (formatting != null) {
|
||||
outputFile.write(formatting);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the obj record
|
||||
ObjRecord objrec = new ObjRecord(objectId,
|
||||
ObjRecord.CHECKBOX);
|
||||
|
||||
outputFile.write(objrec);
|
||||
|
||||
logger.warn("Writing of additional records for checkboxes not " +
|
||||
"implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Writes out all the note records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public int getRow() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public int getColumn() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashing algorithm
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getClass().getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return msoDrawingRecord.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text object
|
||||
*
|
||||
* @param t the text object record
|
||||
*/
|
||||
public void setTextObject(TextObjectRecord t) {
|
||||
txo = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text data
|
||||
*
|
||||
* @param t continuation record
|
||||
*/
|
||||
public void setText(ContinueRecord t) {
|
||||
text = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the formatting
|
||||
*
|
||||
* @param t continue record
|
||||
*/
|
||||
public void setFormatting(ContinueRecord t) {
|
||||
formatting = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* The drawing record
|
||||
*
|
||||
* @param d the drawing record
|
||||
*/
|
||||
public void addMso(MsoDrawingRecord d) {
|
||||
mso = d;
|
||||
drawingData.addRawData(mso.getData());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
40
datastructures-xslx/src/main/java/jxl/biff/drawing/Chunk.java
Executable file
40
datastructures-xslx/src/main/java/jxl/biff/drawing/Chunk.java
Executable file
|
@ -0,0 +1,40 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
class Chunk {
|
||||
private final int pos;
|
||||
private final int length;
|
||||
private final ChunkType type;
|
||||
private final byte[] data;
|
||||
|
||||
public Chunk(int p, int l, ChunkType ct, byte[] d) {
|
||||
pos = p;
|
||||
length = l;
|
||||
type = ct;
|
||||
data = new byte[length];
|
||||
System.arraycopy(d, pos, data, 0, length);
|
||||
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
64
datastructures-xslx/src/main/java/jxl/biff/drawing/ChunkType.java
Executable file
64
datastructures-xslx/src/main/java/jxl/biff/drawing/ChunkType.java
Executable file
|
@ -0,0 +1,64 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Enumeration for the various chunk types
|
||||
*/
|
||||
class ChunkType {
|
||||
public static ChunkType IHDR = new ChunkType(0x49, 0x48, 0x44, 0x52, "IHDR");
|
||||
public static ChunkType IEND = new ChunkType(0x49, 0x45, 0x4e, 0x44, "IEND");
|
||||
public static ChunkType PHYS = new ChunkType(0x70, 0x48, 0x59, 0x73, "pHYs");
|
||||
public static ChunkType UNKNOWN = new ChunkType(0xff, 0xff, 0xff, 0xff, "UNKNOWN");
|
||||
private static ChunkType[] chunkTypes = new ChunkType[0];
|
||||
private final byte[] id;
|
||||
private final String name;
|
||||
private ChunkType(int d1, int d2, int d3, int d4, String n) {
|
||||
id = new byte[]{(byte) d1, (byte) d2, (byte) d3, (byte) d4};
|
||||
name = n;
|
||||
|
||||
ChunkType[] ct = new ChunkType[chunkTypes.length + 1];
|
||||
System.arraycopy(chunkTypes, 0, ct, 0, chunkTypes.length);
|
||||
ct[chunkTypes.length] = this;
|
||||
chunkTypes = ct;
|
||||
}
|
||||
|
||||
public static ChunkType getChunkType(byte d1, byte d2, byte d3, byte d4) {
|
||||
byte[] cmp = new byte[]{d1, d2, d3, d4};
|
||||
|
||||
boolean found = false;
|
||||
ChunkType chunk = ChunkType.UNKNOWN;
|
||||
|
||||
for (int i = 0; i < chunkTypes.length && !found; i++) {
|
||||
if (Arrays.equals(chunkTypes[i].id, cmp)) {
|
||||
chunk = chunkTypes[i];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
201
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientAnchor.java
Executable file
201
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientAnchor.java
Executable file
|
@ -0,0 +1,201 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* The client anchor record
|
||||
*/
|
||||
class ClientAnchor extends EscherAtom {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(ClientAnchor.class);
|
||||
|
||||
/**
|
||||
* The binary data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* The properties
|
||||
*/
|
||||
private final int properties;
|
||||
|
||||
/**
|
||||
* The x1 position
|
||||
*/
|
||||
private final double x1;
|
||||
|
||||
/**
|
||||
* The y1 position
|
||||
*/
|
||||
private final double y1;
|
||||
|
||||
/**
|
||||
* The x2 position
|
||||
*/
|
||||
private final double x2;
|
||||
|
||||
/**
|
||||
* The y2 position
|
||||
*/
|
||||
private final double y2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd the escher record data
|
||||
*/
|
||||
public ClientAnchor(EscherRecordData erd) {
|
||||
super(erd);
|
||||
byte[] bytes = getBytes();
|
||||
|
||||
// The properties
|
||||
properties = IntegerHelper.getInt(bytes[0], bytes[1]);
|
||||
|
||||
// The x1 cell
|
||||
int x1Cell = IntegerHelper.getInt(bytes[2], bytes[3]);
|
||||
int x1Fraction = IntegerHelper.getInt(bytes[4], bytes[5]);
|
||||
|
||||
x1 = x1Cell + (double) x1Fraction / (double) 1024;
|
||||
|
||||
// The y1 cell
|
||||
int y1Cell = IntegerHelper.getInt(bytes[6], bytes[7]);
|
||||
int y1Fraction = IntegerHelper.getInt(bytes[8], bytes[9]);
|
||||
|
||||
y1 = y1Cell + (double) y1Fraction / (double) 256;
|
||||
|
||||
// The x2 cell
|
||||
int x2Cell = IntegerHelper.getInt(bytes[10], bytes[11]);
|
||||
int x2Fraction = IntegerHelper.getInt(bytes[12], bytes[13]);
|
||||
|
||||
x2 = x2Cell + (double) x2Fraction / (double) 1024;
|
||||
|
||||
// The y1 cell
|
||||
int y2Cell = IntegerHelper.getInt(bytes[14], bytes[15]);
|
||||
int y2Fraction = IntegerHelper.getInt(bytes[16], bytes[17]);
|
||||
|
||||
y2 = y2Cell + (double) y2Fraction / (double) 256;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param x1 the x1 position
|
||||
* @param y1 the y1 position
|
||||
* @param x2 the x2 position
|
||||
* @param y2 the y2 position
|
||||
* @param props the anchor properties
|
||||
*/
|
||||
public ClientAnchor(double x1, double y1, double x2, double y2, int props) {
|
||||
super(EscherRecordType.CLIENT_ANCHOR);
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.x2 = x2;
|
||||
this.y2 = y2;
|
||||
properties = props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client anchor data
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
byte[] getData() {
|
||||
data = new byte[18];
|
||||
IntegerHelper.getTwoBytes(properties, data, 0);
|
||||
|
||||
// The x1 cell
|
||||
IntegerHelper.getTwoBytes((int) x1, data, 2);
|
||||
|
||||
// The x1 fraction into the cell 0-1024
|
||||
int x1fraction = (int) ((x1 - (int) x1) * 1024);
|
||||
IntegerHelper.getTwoBytes(x1fraction, data, 4);
|
||||
|
||||
// The y1 cell
|
||||
IntegerHelper.getTwoBytes((int) y1, data, 6);
|
||||
|
||||
// The y1 fraction into the cell 0-256
|
||||
int y1fraction = (int) ((y1 - (int) y1) * 256);
|
||||
IntegerHelper.getTwoBytes(y1fraction, data, 8);
|
||||
|
||||
// The x2 cell
|
||||
IntegerHelper.getTwoBytes((int) x2, data, 10);
|
||||
|
||||
// The x2 fraction into the cell 0-1024
|
||||
int x2fraction = (int) ((x2 - (int) x2) * 1024);
|
||||
IntegerHelper.getTwoBytes(x2fraction, data, 12);
|
||||
|
||||
// The y2 cell
|
||||
IntegerHelper.getTwoBytes((int) y2, data, 14);
|
||||
|
||||
// The y2 fraction into the cell 0-256
|
||||
int y2fraction = (int) ((y2 - (int) y2) * 256);
|
||||
IntegerHelper.getTwoBytes(y2fraction, data, 16);
|
||||
|
||||
return setHeaderData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the x1 position
|
||||
*
|
||||
* @return the x1 position
|
||||
*/
|
||||
double getX1() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the y1 position
|
||||
*
|
||||
* @return the y1 position
|
||||
*/
|
||||
double getY1() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the x2 position
|
||||
*
|
||||
* @return the x2 position
|
||||
*/
|
||||
double getX2() {
|
||||
return x2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the y2 position
|
||||
*
|
||||
* @return the y2 position
|
||||
*/
|
||||
double getY2() {
|
||||
return y2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the anchor properties
|
||||
*/
|
||||
int getProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
63
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientData.java
Executable file
63
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientData.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* The client data
|
||||
*/
|
||||
class ClientData extends EscherAtom {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(ClientData.class);
|
||||
|
||||
/**
|
||||
* The raw data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd the record data
|
||||
*/
|
||||
public ClientData(EscherRecordData erd) {
|
||||
super(erd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClientData() {
|
||||
super(EscherRecordType.CLIENT_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the raw data
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
byte[] getData() {
|
||||
data = new byte[0];
|
||||
return setHeaderData(data);
|
||||
}
|
||||
}
|
63
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientTextBox.java
Executable file
63
datastructures-xslx/src/main/java/jxl/biff/drawing/ClientTextBox.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* ???
|
||||
*/
|
||||
class ClientTextBox extends EscherAtom {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(ClientTextBox.class);
|
||||
|
||||
/**
|
||||
* The raw data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd
|
||||
*/
|
||||
public ClientTextBox(EscherRecordData erd) {
|
||||
super(erd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClientTextBox() {
|
||||
super(EscherRecordType.CLIENT_TEXT_BOX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the raw data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
byte[] getData() {
|
||||
data = new byte[0];
|
||||
return setHeaderData(data);
|
||||
}
|
||||
}
|
641
datastructures-xslx/src/main/java/jxl/biff/drawing/ComboBox.java
Executable file
641
datastructures-xslx/src/main/java/jxl/biff/drawing/ComboBox.java
Executable file
|
@ -0,0 +1,641 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to copy a ComboBox (from the
|
||||
* Form toolbox) between workbook
|
||||
*/
|
||||
public class ComboBox implements DrawingGroupObject {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(ComboBox.class);
|
||||
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
|
||||
/**
|
||||
* The spContainer that was generated
|
||||
*/
|
||||
private EscherContainer spContainer;
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* The ObjRecord associated with the drawing
|
||||
*/
|
||||
private ObjRecord objRecord;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* The column
|
||||
*/
|
||||
private int column;
|
||||
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private int row;
|
||||
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private int drawingNumber;
|
||||
|
||||
/**
|
||||
* The workbook settings
|
||||
*/
|
||||
private WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param mso the drawing record
|
||||
* @param obj the object record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public ComboBox(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd,
|
||||
DrawingGroup dg, WorkbookSettings ws) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = mso;
|
||||
drawingData = dd;
|
||||
objRecord = obj;
|
||||
initialized = false;
|
||||
workbookSettings = ws;
|
||||
origin = Origin.READ;
|
||||
drawingData.addData(msoDrawingRecord.getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(mso != null && obj != null);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public ComboBox(DrawingGroupObject dgo,
|
||||
DrawingGroup dg,
|
||||
WorkbookSettings ws) {
|
||||
ComboBox d = (ComboBox) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
objRecord = d.objRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
workbookSettings = ws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing images
|
||||
*/
|
||||
public ComboBox() {
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
referenceCount = 1;
|
||||
type = ShapeType.HOST_CONTROL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
readSpContainer = drawingData.getSpContainer(drawingNumber);
|
||||
Assert.verify(readSpContainer != null);
|
||||
|
||||
EscherRecord[] children = readSpContainer.getChildren();
|
||||
|
||||
Sp sp = (Sp) readSpContainer.getChildren()[0];
|
||||
objectId = objRecord.getObjectId();
|
||||
shapeId = sp.getShapeId();
|
||||
type = ShapeType.getType(sp.getShapeType());
|
||||
|
||||
if (type == ShapeType.UNKNOWN) {
|
||||
logger.warn("Unknown shape type");
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = null;
|
||||
for (int i = 0; i < children.length && clientAnchor == null; i++) {
|
||||
if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR) {
|
||||
clientAnchor = (ClientAnchor) children[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clientAnchor == null) {
|
||||
logger.warn("Client anchor not found");
|
||||
} else {
|
||||
column = (int) clientAnchor.getX1();
|
||||
row = (int) clientAnchor.getY1();
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
SpContainer spc = new SpContainer();
|
||||
Sp sp = new Sp(type, shapeId, 2560);
|
||||
spc.add(sp);
|
||||
Opt opt = new Opt();
|
||||
opt.addProperty(127, false, false, 17039620);
|
||||
opt.addProperty(191, false, false, 524296);
|
||||
opt.addProperty(511, false, false, 524288);
|
||||
opt.addProperty(959, false, false, 131072);
|
||||
// opt.addProperty(260, true, false, blipId);
|
||||
// opt.addProperty(261, false, false, 36);
|
||||
spc.add(opt);
|
||||
|
||||
ClientAnchor clientAnchor = new ClientAnchor(column,
|
||||
row,
|
||||
column + 1,
|
||||
row + 1,
|
||||
0x1);
|
||||
spc.add(clientAnchor);
|
||||
ClientData clientData = new ClientData();
|
||||
spc.add(clientData);
|
||||
|
||||
return spc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing. Used when inserting/removing
|
||||
* columns from the spreadsheet
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
column = (int) x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
row = (int) y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the additional records for a combo box
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(objRecord);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the obj record
|
||||
ObjRecord objrec = new ObjRecord(objectId,
|
||||
ObjRecord.COMBOBOX);
|
||||
|
||||
outputFile.write(objrec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Writes out all the note records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public int getRow() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public int getColumn() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashing algorithm
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getClass().getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return msoDrawingRecord.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
829
datastructures-xslx/src/main/java/jxl/biff/drawing/Comment.java
Executable file
829
datastructures-xslx/src/main/java/jxl/biff/drawing/Comment.java
Executable file
|
@ -0,0 +1,829 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.biff.ContinueRecord;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.biff.StringHelper;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to insert a cell note into a
|
||||
* worksheet
|
||||
*/
|
||||
public class Comment implements DrawingGroupObject {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Comment.class);
|
||||
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
|
||||
/**
|
||||
* The spContainer that was generated
|
||||
*/
|
||||
private EscherContainer spContainer;
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* The ObjRecord associated with the drawing
|
||||
*/
|
||||
private ObjRecord objRecord;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* The column
|
||||
*/
|
||||
private int column;
|
||||
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private int row;
|
||||
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private int drawingNumber;
|
||||
|
||||
/**
|
||||
* An mso drawing record, which sometimes appears
|
||||
*/
|
||||
private MsoDrawingRecord mso;
|
||||
|
||||
/**
|
||||
* The text object record
|
||||
*/
|
||||
private TextObjectRecord txo;
|
||||
|
||||
/**
|
||||
* The note record
|
||||
*/
|
||||
private NoteRecord note;
|
||||
|
||||
/**
|
||||
* Text data from the first continue record
|
||||
*/
|
||||
private ContinueRecord text;
|
||||
|
||||
/**
|
||||
* Formatting data from the second continue record
|
||||
*/
|
||||
private ContinueRecord formatting;
|
||||
|
||||
/**
|
||||
* The comment text
|
||||
*/
|
||||
private String commentText;
|
||||
|
||||
/**
|
||||
* The workbook settings
|
||||
*/
|
||||
private WorkbookSettings workbookSettings;
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param msorec the drawing record
|
||||
* @param obj the object record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
public Comment(MsoDrawingRecord msorec, ObjRecord obj, DrawingData dd,
|
||||
DrawingGroup dg, WorkbookSettings ws) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = msorec;
|
||||
drawingData = dd;
|
||||
objRecord = obj;
|
||||
initialized = false;
|
||||
workbookSettings = ws;
|
||||
origin = Origin.READ;
|
||||
drawingData.addData(msoDrawingRecord.getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(msoDrawingRecord != null && objRecord != null);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
* @param ws the workbook settings
|
||||
*/
|
||||
/*protected*/
|
||||
public Comment(DrawingGroupObject dgo,
|
||||
DrawingGroup dg,
|
||||
WorkbookSettings ws) {
|
||||
Comment d = (Comment) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
objRecord = d.objRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
mso = d.mso;
|
||||
txo = d.txo;
|
||||
text = d.text;
|
||||
formatting = d.formatting;
|
||||
note = d.note;
|
||||
width = d.width;
|
||||
height = d.height;
|
||||
workbookSettings = ws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing the images
|
||||
*
|
||||
* @param txt the comment text
|
||||
* @param c the column
|
||||
* @param r the row
|
||||
*/
|
||||
public Comment(String txt, int c, int r) {
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
column = c;
|
||||
row = r;
|
||||
referenceCount = 1;
|
||||
type = ShapeType.TEXT_BOX;
|
||||
commentText = txt;
|
||||
width = 3;
|
||||
height = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
readSpContainer = drawingData.getSpContainer(drawingNumber);
|
||||
Assert.verify(readSpContainer != null);
|
||||
|
||||
EscherRecord[] children = readSpContainer.getChildren();
|
||||
|
||||
Sp sp = (Sp) readSpContainer.getChildren()[0];
|
||||
objectId = objRecord.getObjectId();
|
||||
shapeId = sp.getShapeId();
|
||||
type = ShapeType.getType(sp.getShapeType());
|
||||
|
||||
if (type == ShapeType.UNKNOWN) {
|
||||
logger.warn("Unknown shape type");
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = null;
|
||||
for (int i = 0; i < children.length && clientAnchor == null; i++) {
|
||||
if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR) {
|
||||
clientAnchor = (ClientAnchor) children[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clientAnchor == null) {
|
||||
logger.warn("client anchor not found");
|
||||
} else {
|
||||
column = (int) clientAnchor.getX1() - 1;
|
||||
row = (int) clientAnchor.getY1() + 1;
|
||||
width = clientAnchor.getX2() - clientAnchor.getX1();
|
||||
height = clientAnchor.getY2() - clientAnchor.getY1();
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
if (spContainer == null) {
|
||||
spContainer = new SpContainer();
|
||||
Sp sp = new Sp(type, shapeId, 2560);
|
||||
spContainer.add(sp);
|
||||
Opt opt = new Opt();
|
||||
opt.addProperty(344, false, false, 0); // ?
|
||||
opt.addProperty(385, false, false, 134217808); // fill colour
|
||||
opt.addProperty(387, false, false, 134217808); // background colour
|
||||
opt.addProperty(959, false, false, 131074); // hide
|
||||
spContainer.add(opt);
|
||||
|
||||
ClientAnchor clientAnchor = new ClientAnchor(column + 1.3,
|
||||
Math.max(0, row - 0.6),
|
||||
column + 1.3 + width,
|
||||
row + height,
|
||||
0x1);
|
||||
|
||||
spContainer.add(clientAnchor);
|
||||
|
||||
ClientData clientData = new ClientData();
|
||||
spContainer.add(clientData);
|
||||
|
||||
ClientTextBox clientTextBox = new ClientTextBox();
|
||||
spContainer.add(clientTextBox);
|
||||
}
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing. Used when inserting/removing
|
||||
* columns from the spreadsheet
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
column = (int) x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
row = (int) y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text object
|
||||
*
|
||||
* @param t the text object
|
||||
*/
|
||||
public void setTextObject(TextObjectRecord t) {
|
||||
txo = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the note object
|
||||
*
|
||||
* @param t the note record
|
||||
*/
|
||||
public void setNote(NoteRecord t) {
|
||||
note = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the formatting
|
||||
*
|
||||
* @param t the formatting record
|
||||
*/
|
||||
public void setFormatting(ContinueRecord t) {
|
||||
formatting = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an mso record to this object
|
||||
*
|
||||
* @param d the mso record
|
||||
*/
|
||||
public void addMso(MsoDrawingRecord d) {
|
||||
mso = d;
|
||||
drawingData.addRawData(mso.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out the additional comment records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(objRecord);
|
||||
|
||||
if (mso != null) {
|
||||
outputFile.write(mso);
|
||||
}
|
||||
outputFile.write(txo);
|
||||
outputFile.write(text);
|
||||
if (formatting != null) {
|
||||
outputFile.write(formatting);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the obj record
|
||||
ObjRecord objrec = new ObjRecord(objectId,
|
||||
ObjRecord.EXCELNOTE);
|
||||
|
||||
outputFile.write(objrec);
|
||||
|
||||
// Create the mso data record. Write the text box record again,
|
||||
// although it is already included in the SpContainer
|
||||
ClientTextBox textBox = new ClientTextBox();
|
||||
MsoDrawingRecord msod = new MsoDrawingRecord(textBox.getData());
|
||||
outputFile.write(msod);
|
||||
|
||||
TextObjectRecord txorec = new TextObjectRecord(getText());
|
||||
outputFile.write(txorec);
|
||||
|
||||
// Data for the first continue record
|
||||
byte[] textData = new byte[commentText.length() * 2 + 1];
|
||||
textData[0] = 0x1; // unicode indicator
|
||||
StringHelper.getUnicodeBytes(commentText, textData, 1);
|
||||
//StringHelper.getBytes(commentText, textData, 1);
|
||||
ContinueRecord textContinue = new ContinueRecord(textData);
|
||||
outputFile.write(textContinue);
|
||||
|
||||
// Data for the formatting runs
|
||||
|
||||
byte[] frData = new byte[16];
|
||||
|
||||
// First txo run (the user)
|
||||
IntegerHelper.getTwoBytes(0, frData, 0); // index to the first character
|
||||
IntegerHelper.getTwoBytes(0, frData, 2); // index to the font(default)
|
||||
// Mandatory last txo run
|
||||
IntegerHelper.getTwoBytes(commentText.length(), frData, 8);
|
||||
IntegerHelper.getTwoBytes(0, frData, 10); // index to the font(default)
|
||||
|
||||
ContinueRecord frContinue = new ContinueRecord(frData);
|
||||
outputFile.write(frContinue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Writes out all the note records
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(note);
|
||||
return;
|
||||
}
|
||||
|
||||
// The note record
|
||||
NoteRecord noteRecord = new NoteRecord(column, row, objectId);
|
||||
outputFile.write(noteRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public int getRow() {
|
||||
return note.getRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public int getColumn() {
|
||||
return note.getColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the comment text
|
||||
*
|
||||
* @return the comment text
|
||||
*/
|
||||
public String getText() {
|
||||
if (commentText == null) {
|
||||
Assert.verify(text != null);
|
||||
|
||||
byte[] td = text.getData();
|
||||
if (td[0] == 0) {
|
||||
commentText = StringHelper.getString
|
||||
(td, td.length - 1, 1, workbookSettings);
|
||||
} else {
|
||||
commentText = StringHelper.getUnicodeString
|
||||
(td, (td.length - 1) / 2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return commentText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text data
|
||||
*
|
||||
* @param t the text data
|
||||
*/
|
||||
public void setText(ContinueRecord t) {
|
||||
text = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashing algorithm
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public int hashCode() {
|
||||
return commentText.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the comment text is changed during the sheet copy process
|
||||
*
|
||||
* @param t the new text
|
||||
*/
|
||||
public void setCommentText(String t) {
|
||||
commentText = t;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return msoDrawingRecord.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over several records and require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
105
datastructures-xslx/src/main/java/jxl/biff/drawing/Dg.java
Executable file
105
datastructures-xslx/src/main/java/jxl/biff/drawing/Dg.java
Executable file
|
@ -0,0 +1,105 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.biff.IntegerHelper;
|
||||
|
||||
/**
|
||||
* The Drawing Group
|
||||
*/
|
||||
class Dg extends EscherAtom {
|
||||
/**
|
||||
* The data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* The id of this drawing
|
||||
*/
|
||||
private final int drawingId;
|
||||
|
||||
/**
|
||||
* The number of shapes
|
||||
*/
|
||||
private final int shapeCount;
|
||||
|
||||
/**
|
||||
* The seed for drawing ids
|
||||
*/
|
||||
private final int seed;
|
||||
|
||||
/**
|
||||
* Constructor invoked when reading in an escher stream
|
||||
*
|
||||
* @param erd the escher record
|
||||
*/
|
||||
public Dg(EscherRecordData erd) {
|
||||
super(erd);
|
||||
drawingId = getInstance();
|
||||
|
||||
byte[] bytes = getBytes();
|
||||
shapeCount = IntegerHelper.getInt(bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
seed = IntegerHelper.getInt(bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing out an escher stream
|
||||
*
|
||||
* @param numDrawings the number of drawings
|
||||
*/
|
||||
public Dg(int numDrawings) {
|
||||
super(EscherRecordType.DG);
|
||||
drawingId = 1;
|
||||
shapeCount = numDrawings + 1;
|
||||
seed = 1024 + shapeCount + 1;
|
||||
setInstance(drawingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing id
|
||||
*
|
||||
* @return the drawing id
|
||||
*/
|
||||
public int getDrawingId() {
|
||||
return drawingId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shape count
|
||||
*
|
||||
* @return the shape count
|
||||
*/
|
||||
int getShapeCount() {
|
||||
return shapeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to generate the drawing data
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
byte[] getData() {
|
||||
data = new byte[8];
|
||||
IntegerHelper.getFourBytes(shapeCount, data, 0);
|
||||
IntegerHelper.getFourBytes(seed, data, 4);
|
||||
|
||||
return setHeaderData(data);
|
||||
}
|
||||
}
|
32
datastructures-xslx/src/main/java/jxl/biff/drawing/DgContainer.java
Executable file
32
datastructures-xslx/src/main/java/jxl/biff/drawing/DgContainer.java
Executable file
|
@ -0,0 +1,32 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
/**
|
||||
* A Dg Container
|
||||
*/
|
||||
class DgContainer extends EscherContainer {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DgContainer() {
|
||||
super(EscherRecordType.DG_CONTAINER);
|
||||
}
|
||||
}
|
203
datastructures-xslx/src/main/java/jxl/biff/drawing/Dgg.java
Executable file
203
datastructures-xslx/src/main/java/jxl/biff/drawing/Dgg.java
Executable file
|
@ -0,0 +1,203 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Dgg record
|
||||
*/
|
||||
class Dgg extends EscherAtom {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Dgg.class);
|
||||
|
||||
/**
|
||||
* The binary data
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* The number of clusters
|
||||
*/
|
||||
private int numClusters;
|
||||
|
||||
/**
|
||||
* The maximum shape id
|
||||
*/
|
||||
private int maxShapeId;
|
||||
|
||||
/**
|
||||
* The number of shapes saved
|
||||
*/
|
||||
private final int shapesSaved;
|
||||
|
||||
/**
|
||||
* The number of drawings saved
|
||||
*/
|
||||
private final int drawingsSaved;
|
||||
|
||||
/**
|
||||
* The clusters
|
||||
*/
|
||||
private final ArrayList clusters;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd the read in data
|
||||
*/
|
||||
public Dgg(EscherRecordData erd) {
|
||||
super(erd);
|
||||
clusters = new ArrayList();
|
||||
byte[] bytes = getBytes();
|
||||
maxShapeId = IntegerHelper.getInt
|
||||
(bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
numClusters = IntegerHelper.getInt
|
||||
(bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
shapesSaved = IntegerHelper.getInt
|
||||
(bytes[8], bytes[9], bytes[10], bytes[11]);
|
||||
drawingsSaved = IntegerHelper.getInt
|
||||
(bytes[12], bytes[13], bytes[14], bytes[15]);
|
||||
|
||||
int pos = 16;
|
||||
for (int i = 0; i < numClusters; i++) {
|
||||
int dgId = IntegerHelper.getInt(bytes[pos], bytes[pos + 1]);
|
||||
int sids = IntegerHelper.getInt(bytes[pos + 2], bytes[pos + 3]);
|
||||
Cluster c = new Cluster(dgId, sids);
|
||||
clusters.add(c);
|
||||
pos += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param numShapes the number of shapes
|
||||
* @param numDrawings the number of drawings
|
||||
*/
|
||||
public Dgg(int numShapes, int numDrawings) {
|
||||
super(EscherRecordType.DGG);
|
||||
shapesSaved = numShapes;
|
||||
drawingsSaved = numDrawings;
|
||||
clusters = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cluster to this record
|
||||
*
|
||||
* @param dgid the id
|
||||
* @param sids the sid
|
||||
*/
|
||||
void addCluster(int dgid, int sids) {
|
||||
Cluster c = new Cluster(dgid, sids);
|
||||
clusters.add(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data for writing out
|
||||
*
|
||||
* @return the binary data
|
||||
*/
|
||||
byte[] getData() {
|
||||
numClusters = clusters.size();
|
||||
data = new byte[16 + numClusters * 4];
|
||||
|
||||
// The max shape id
|
||||
IntegerHelper.getFourBytes(1024 + shapesSaved, data, 0);
|
||||
|
||||
// The number of clusters
|
||||
IntegerHelper.getFourBytes(numClusters, data, 4);
|
||||
|
||||
// The number of shapes saved
|
||||
IntegerHelper.getFourBytes(shapesSaved, data, 8);
|
||||
|
||||
// The number of drawings saved
|
||||
// IntegerHelper.getFourBytes(drawingsSaved, data, 12);
|
||||
IntegerHelper.getFourBytes(1, data, 12);
|
||||
|
||||
int pos = 16;
|
||||
for (int i = 0; i < numClusters; i++) {
|
||||
Cluster c = (Cluster) clusters.get(i);
|
||||
IntegerHelper.getTwoBytes(c.drawingGroupId, data, pos);
|
||||
IntegerHelper.getTwoBytes(c.shapeIdsUsed, data, pos + 2);
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
return setHeaderData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of shapes saved
|
||||
*
|
||||
* @return the number of shapes saved
|
||||
*/
|
||||
int getShapesSaved() {
|
||||
return shapesSaved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of drawings saved
|
||||
*
|
||||
* @return the number of drawings saved
|
||||
*/
|
||||
int getDrawingsSaved() {
|
||||
return drawingsSaved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for a particular cluster
|
||||
*
|
||||
* @param i the cluster number
|
||||
* @return the cluster
|
||||
*/
|
||||
Cluster getCluster(int i) {
|
||||
return (Cluster) clusters.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cluster structure
|
||||
*/
|
||||
static final class Cluster {
|
||||
/**
|
||||
* The drawing group id
|
||||
*/
|
||||
int drawingGroupId;
|
||||
|
||||
/**
|
||||
* The something or other
|
||||
*/
|
||||
int shapeIdsUsed;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param dgId the drawing group id
|
||||
* @param sids the sids
|
||||
*/
|
||||
Cluster(int dgId, int sids) {
|
||||
drawingGroupId = dgId;
|
||||
shapeIdsUsed = sids;
|
||||
}
|
||||
}
|
||||
}
|
32
datastructures-xslx/src/main/java/jxl/biff/drawing/DggContainer.java
Executable file
32
datastructures-xslx/src/main/java/jxl/biff/drawing/DggContainer.java
Executable file
|
@ -0,0 +1,32 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
/**
|
||||
* Container for Dgg objects
|
||||
*/
|
||||
class DggContainer extends EscherContainer {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DggContainer() {
|
||||
super(EscherRecordType.DGG_CONTAINER);
|
||||
}
|
||||
}
|
990
datastructures-xslx/src/main/java/jxl/biff/drawing/Drawing.java
Executable file
990
datastructures-xslx/src/main/java/jxl/biff/drawing/Drawing.java
Executable file
|
@ -0,0 +1,990 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import jxl.CellView;
|
||||
import jxl.Image;
|
||||
import jxl.Sheet;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.LengthConverter;
|
||||
import jxl.common.LengthUnit;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to insert a drawing into a
|
||||
* worksheet
|
||||
*/
|
||||
public class Drawing implements DrawingGroupObject, Image {
|
||||
/**
|
||||
* The default font size for columns
|
||||
*/
|
||||
private static final double DEFAULT_FONT_SIZE = 10;
|
||||
// The image anchor properties
|
||||
public static ImageAnchorProperties MOVE_AND_SIZE_WITH_CELLS =
|
||||
new ImageAnchorProperties(1);
|
||||
public static ImageAnchorProperties MOVE_WITH_CELLS =
|
||||
new ImageAnchorProperties(2);
|
||||
public static ImageAnchorProperties NO_MOVE_OR_SIZE_WITH_CELLS =
|
||||
new ImageAnchorProperties(3);
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Drawing.class);
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private MsoDrawingRecord msoDrawingRecord;
|
||||
/**
|
||||
* The ObjRecord associated with the drawing
|
||||
*/
|
||||
private ObjRecord objRecord;
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
/**
|
||||
* The file containing the image
|
||||
*/
|
||||
private java.io.File imageFile;
|
||||
/**
|
||||
* The raw image data, used instead of an image file
|
||||
*/
|
||||
private byte[] imageData;
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
/**
|
||||
* The column position of the image
|
||||
*/
|
||||
private double x;
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private double y;
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private int drawingNumber;
|
||||
/**
|
||||
* A reference to the sheet containing this drawing. Used to calculate
|
||||
* the drawing dimensions in pixels
|
||||
*/
|
||||
private Sheet sheet;
|
||||
/**
|
||||
* Reader for the raw image data
|
||||
*/
|
||||
private PNGReader pngReader;
|
||||
/**
|
||||
* The client anchor properties
|
||||
*/
|
||||
private ImageAnchorProperties imageAnchorProperties;
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param mso the drawing record
|
||||
* @param obj the object record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public Drawing(MsoDrawingRecord mso,
|
||||
ObjRecord obj,
|
||||
DrawingData dd,
|
||||
DrawingGroup dg,
|
||||
Sheet s) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = mso;
|
||||
drawingData = dd;
|
||||
objRecord = obj;
|
||||
sheet = s;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData.addData(msoDrawingRecord.getData());
|
||||
drawingNumber = drawingData.getNumDrawings() - 1;
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(mso != null && obj != null);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
protected Drawing(DrawingGroupObject dgo, DrawingGroup dg) {
|
||||
Drawing d = (Drawing) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
objRecord = d.objRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing the images
|
||||
*
|
||||
* @param x the column
|
||||
* @param y the row
|
||||
* @param w the width in cells
|
||||
* @param h the height in cells
|
||||
* @param image the image file
|
||||
*/
|
||||
public Drawing(double x,
|
||||
double y,
|
||||
double w,
|
||||
double h,
|
||||
java.io.File image) {
|
||||
imageFile = image;
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
referenceCount = 1;
|
||||
imageAnchorProperties = MOVE_WITH_CELLS;
|
||||
type = ShapeType.PICTURE_FRAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing the images
|
||||
*
|
||||
* @param x the column
|
||||
* @param y the row
|
||||
* @param w the width in cells
|
||||
* @param h the height in cells
|
||||
* @param image the image data
|
||||
*/
|
||||
public Drawing(double x,
|
||||
double y,
|
||||
double w,
|
||||
double h,
|
||||
byte[] image) {
|
||||
imageData = image;
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
referenceCount = 1;
|
||||
imageAnchorProperties = MOVE_WITH_CELLS;
|
||||
type = ShapeType.PICTURE_FRAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
readSpContainer = drawingData.getSpContainer(drawingNumber);
|
||||
Assert.verify(readSpContainer != null);
|
||||
|
||||
EscherRecord[] children = readSpContainer.getChildren();
|
||||
|
||||
Sp sp = (Sp) readSpContainer.getChildren()[0];
|
||||
shapeId = sp.getShapeId();
|
||||
objectId = objRecord.getObjectId();
|
||||
type = ShapeType.getType(sp.getShapeType());
|
||||
|
||||
if (type == ShapeType.UNKNOWN) {
|
||||
logger.warn("Unknown shape type");
|
||||
}
|
||||
|
||||
Opt opt = (Opt) readSpContainer.getChildren()[1];
|
||||
|
||||
if (opt.getProperty(260) != null) {
|
||||
blipId = opt.getProperty(260).value;
|
||||
}
|
||||
|
||||
if (opt.getProperty(261) != null) {
|
||||
imageFile = new java.io.File(opt.getProperty(261).stringValue);
|
||||
} else {
|
||||
if (type == ShapeType.PICTURE_FRAME) {
|
||||
logger.warn("no filename property for drawing");
|
||||
imageFile = new java.io.File(Integer.toString(blipId));
|
||||
}
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = null;
|
||||
for (int i = 0; i < children.length && clientAnchor == null; i++) {
|
||||
if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR) {
|
||||
clientAnchor = (ClientAnchor) children[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clientAnchor == null) {
|
||||
logger.warn("client anchor not found");
|
||||
} else {
|
||||
x = clientAnchor.getX1();
|
||||
y = clientAnchor.getY1();
|
||||
width = clientAnchor.getX2() - x;
|
||||
height = clientAnchor.getY2() - y;
|
||||
imageAnchorProperties = ImageAnchorProperties.getImageAnchorProperties
|
||||
(clientAnchor.getProperties());
|
||||
}
|
||||
|
||||
if (blipId == 0) {
|
||||
logger.warn("linked drawings are not supported");
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file
|
||||
*
|
||||
* @return the image file
|
||||
*/
|
||||
public java.io.File getImageFile() {
|
||||
return imageFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
if (imageFile == null) {
|
||||
// return the blip id, if it exists
|
||||
return blipId != 0 ? Integer.toString(blipId) : "__new__image__";
|
||||
}
|
||||
|
||||
return imageFile.getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the shape id
|
||||
*/
|
||||
public int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
SpContainer spContainer = new SpContainer();
|
||||
Sp sp = new Sp(type, shapeId, 2560);
|
||||
spContainer.add(sp);
|
||||
Opt opt = new Opt();
|
||||
opt.addProperty(260, true, false, blipId);
|
||||
|
||||
if (type == ShapeType.PICTURE_FRAME) {
|
||||
String filePath = imageFile != null ? imageFile.getPath() : "";
|
||||
opt.addProperty(261, true, true, filePath.length() * 2, filePath);
|
||||
opt.addProperty(447, false, false, 65536);
|
||||
opt.addProperty(959, false, false, 524288);
|
||||
spContainer.add(opt);
|
||||
}
|
||||
|
||||
ClientAnchor clientAnchor = new ClientAnchor
|
||||
(x, y, x + width, y + height,
|
||||
imageAnchorProperties.getValue());
|
||||
spContainer.add(clientAnchor);
|
||||
ClientData clientData = new ClientData();
|
||||
spContainer.add(clientData);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() throws IOException {
|
||||
if (origin == Origin.READ || origin == Origin.READ_WRITE) {
|
||||
return getImageData();
|
||||
}
|
||||
|
||||
Assert.verify(origin == Origin.WRITE);
|
||||
|
||||
if (imageFile == null) {
|
||||
Assert.verify(imageData != null);
|
||||
return imageData;
|
||||
}
|
||||
|
||||
byte[] data = new byte[(int) imageFile.length()];
|
||||
FileInputStream fis = new FileInputStream(imageFile);
|
||||
fis.read(data, 0, data.length);
|
||||
fis.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any other records associated with this drawing group object
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
if (origin == Origin.READ) {
|
||||
outputFile.write(objRecord);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the obj record
|
||||
ObjRecord objrec = new ObjRecord(objectId,
|
||||
ObjRecord.PICTURE);
|
||||
outputFile.write(objrec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Does nothing here
|
||||
*
|
||||
* @param outputFile the output file
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) throws IOException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface method
|
||||
*
|
||||
* @return the column number at which the image is positioned
|
||||
*/
|
||||
public double getColumn() {
|
||||
return getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface method
|
||||
*
|
||||
* @return the row number at which the image is positions
|
||||
*/
|
||||
public double getRow() {
|
||||
return getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return msoDrawingRecord.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row
|
||||
*
|
||||
* @param r the row to be removed
|
||||
*/
|
||||
public void removeRow(int r) {
|
||||
if (y > r) {
|
||||
setY(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image dimensions. See technotes for Bill's explanation
|
||||
* of the calculation logic
|
||||
*
|
||||
* @return approximate drawing size in pixels
|
||||
*/
|
||||
private double getWidthInPoints() {
|
||||
if (sheet == null) {
|
||||
logger.warn("calculating image width: sheet is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The start and end row numbers
|
||||
int firstCol = (int) x;
|
||||
int lastCol = (int) Math.ceil(x + width) - 1;
|
||||
|
||||
// **** MAGIC NUMBER ALERT ***
|
||||
// multiply the point size of the font by 0.59 to give the point size
|
||||
// I know of no explanation for this yet, other than that it seems to
|
||||
// give the right answer
|
||||
|
||||
// Get the width of the image within the first col, allowing for
|
||||
// fractional offsets
|
||||
CellView cellView = sheet.getColumnView(firstCol);
|
||||
int firstColWidth = cellView.getSize();
|
||||
double firstColImageWidth = (1 - (x - firstCol)) * firstColWidth;
|
||||
double pointSize = (cellView.getFormat() != null) ?
|
||||
cellView.getFormat().getFont().getPointSize() : DEFAULT_FONT_SIZE;
|
||||
double firstColWidthInPoints = firstColImageWidth * 0.59 * pointSize / 256;
|
||||
|
||||
// Get the height of the image within the last row, allowing for
|
||||
// fractional offsets
|
||||
int lastColWidth = 0;
|
||||
double lastColImageWidth = 0;
|
||||
double lastColWidthInPoints = 0;
|
||||
if (lastCol != firstCol) {
|
||||
cellView = sheet.getColumnView(lastCol);
|
||||
lastColWidth = cellView.getSize();
|
||||
lastColImageWidth = (x + width - lastCol) * lastColWidth;
|
||||
pointSize = (cellView.getFormat() != null) ?
|
||||
cellView.getFormat().getFont().getPointSize() : DEFAULT_FONT_SIZE;
|
||||
lastColWidthInPoints = lastColImageWidth * 0.59 * pointSize / 256;
|
||||
}
|
||||
|
||||
// Now get all the columns in between
|
||||
double width = 0;
|
||||
for (int i = 0; i < lastCol - firstCol - 1; i++) {
|
||||
cellView = sheet.getColumnView(firstCol + 1 + i);
|
||||
pointSize = (cellView.getFormat() != null) ?
|
||||
cellView.getFormat().getFont().getPointSize() : DEFAULT_FONT_SIZE;
|
||||
width += cellView.getSize() * 0.59 * pointSize / 256;
|
||||
}
|
||||
|
||||
// Add on the first and last row contributions to get the height in twips
|
||||
double widthInPoints = width +
|
||||
firstColWidthInPoints + lastColWidthInPoints;
|
||||
|
||||
return widthInPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image dimensions. See technotes for Bill's explanation
|
||||
* of the calculation logic
|
||||
*
|
||||
* @return approximate drawing size in pixels
|
||||
*/
|
||||
private double getHeightInPoints() {
|
||||
if (sheet == null) {
|
||||
logger.warn("calculating image height: sheet is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The start and end row numbers
|
||||
int firstRow = (int) y;
|
||||
int lastRow = (int) Math.ceil(y + height) - 1;
|
||||
|
||||
// Get the height of the image within the first row, allowing for
|
||||
// fractional offsets
|
||||
int firstRowHeight = sheet.getRowView(firstRow).getSize();
|
||||
double firstRowImageHeight = (1 - (y - firstRow)) * firstRowHeight;
|
||||
|
||||
// Get the height of the image within the last row, allowing for
|
||||
// fractional offsets
|
||||
int lastRowHeight = 0;
|
||||
double lastRowImageHeight = 0;
|
||||
if (lastRow != firstRow) {
|
||||
lastRowHeight = sheet.getRowView(lastRow).getSize();
|
||||
lastRowImageHeight = (y + height - lastRow) * lastRowHeight;
|
||||
}
|
||||
|
||||
// Now get all the rows in between
|
||||
double height = 0;
|
||||
for (int i = 0; i < lastRow - firstRow - 1; i++) {
|
||||
height += sheet.getRowView(firstRow + 1 + i).getSize();
|
||||
}
|
||||
|
||||
// Add on the first and last row contributions to get the height in twips
|
||||
double heightInTwips = height + firstRowHeight + lastRowHeight;
|
||||
|
||||
// Now divide by the magic number to converts twips into pixels and
|
||||
// return the value
|
||||
double heightInPoints = heightInTwips / 20.0;
|
||||
|
||||
return heightInPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of this image as rendered within Excel
|
||||
*
|
||||
* @param unit the unit of measurement
|
||||
* @return the width of the image within Excel
|
||||
*/
|
||||
public double getWidth(LengthUnit unit) {
|
||||
double widthInPoints = getWidthInPoints();
|
||||
return widthInPoints * LengthConverter.getConversionFactor
|
||||
(LengthUnit.POINTS, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of this image as rendered within Excel
|
||||
*
|
||||
* @param unit the unit of measurement
|
||||
* @return the height of the image within Excel
|
||||
*/
|
||||
public double getHeight(LengthUnit unit) {
|
||||
double heightInPoints = getHeightInPoints();
|
||||
return heightInPoints * LengthConverter.getConversionFactor
|
||||
(LengthUnit.POINTS, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the image. Note that this is the width of the
|
||||
* underlying image, and does not take into account any size manipulations
|
||||
* that may have occurred when the image was added into Excel
|
||||
*
|
||||
* @return the image width in pixels
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return getPngReader().getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the image. Note that this is the height of the
|
||||
* underlying image, and does not take into account any size manipulations
|
||||
* that may have occurred when the image was added into Excel
|
||||
*
|
||||
* @return the image width in pixels
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return getPngReader().getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal resolution of the image, if that information
|
||||
* is available.
|
||||
*
|
||||
* @return the number of dots per unit specified, if available, 0 otherwise
|
||||
*/
|
||||
public double getHorizontalResolution(LengthUnit unit) {
|
||||
int res = getPngReader().getHorizontalResolution();
|
||||
return res / LengthConverter.getConversionFactor(LengthUnit.METRES, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vertical resolution of the image, if that information
|
||||
* is available.
|
||||
*
|
||||
* @return the number of dots per unit specified, if available, 0 otherwise
|
||||
*/
|
||||
public double getVerticalResolution(LengthUnit unit) {
|
||||
int res = getPngReader().getVerticalResolution();
|
||||
return res / LengthConverter.getConversionFactor(LengthUnit.METRES, unit);
|
||||
}
|
||||
|
||||
private PNGReader getPngReader() {
|
||||
if (pngReader != null) {
|
||||
return pngReader;
|
||||
}
|
||||
|
||||
byte[] imdata = null;
|
||||
if (origin == Origin.READ || origin == Origin.READ_WRITE) {
|
||||
imdata = getImageData();
|
||||
} else {
|
||||
try {
|
||||
imdata = getImageBytes();
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not read image file");
|
||||
imdata = new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
pngReader = new PNGReader(imdata);
|
||||
pngReader.read();
|
||||
return pngReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the anchor properties
|
||||
*/
|
||||
protected ImageAnchorProperties getImageAnchor() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return imageAnchorProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the anchor properties
|
||||
*/
|
||||
protected void setImageAnchor(ImageAnchorProperties iap) {
|
||||
imageAnchorProperties = iap;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
// Enumeration type for the image anchor properties
|
||||
protected static class ImageAnchorProperties {
|
||||
private static ImageAnchorProperties[] o = new ImageAnchorProperties[0];
|
||||
private final int value;
|
||||
|
||||
ImageAnchorProperties(int v) {
|
||||
value = v;
|
||||
|
||||
ImageAnchorProperties[] oldArray = o;
|
||||
o = new ImageAnchorProperties[oldArray.length + 1];
|
||||
System.arraycopy(oldArray, 0, o, 0, oldArray.length);
|
||||
o[oldArray.length] = this;
|
||||
}
|
||||
|
||||
static ImageAnchorProperties getImageAnchorProperties(int val) {
|
||||
ImageAnchorProperties iap = MOVE_AND_SIZE_WITH_CELLS;
|
||||
int pos = 0;
|
||||
while (pos < o.length) {
|
||||
if (o[pos].getValue() == val) {
|
||||
iap = o[pos];
|
||||
break;
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return iap;
|
||||
}
|
||||
|
||||
int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
629
datastructures-xslx/src/main/java/jxl/biff/drawing/Drawing2.java
Executable file
629
datastructures-xslx/src/main/java/jxl/biff/drawing/Drawing2.java
Executable file
|
@ -0,0 +1,629 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
|
||||
/**
|
||||
* Contains the various biff records used to insert a drawing into a
|
||||
* worksheet. This type of image does not have an associated object
|
||||
* record
|
||||
*/
|
||||
public class Drawing2 implements DrawingGroupObject {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(Drawing.class);
|
||||
|
||||
/**
|
||||
* The spContainer that was read in
|
||||
*/
|
||||
private EscherContainer readSpContainer;
|
||||
|
||||
/**
|
||||
* The MsoDrawingRecord associated with the drawing
|
||||
*/
|
||||
private MsoDrawingRecord msoDrawingRecord;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The file containing the image
|
||||
*/
|
||||
private java.io.File imageFile;
|
||||
|
||||
/**
|
||||
* The raw image data, used instead of an image file
|
||||
*/
|
||||
private byte[] imageData;
|
||||
|
||||
/**
|
||||
* The object id, assigned by the drawing group
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The blip id
|
||||
*/
|
||||
private int blipId;
|
||||
|
||||
/**
|
||||
* The column position of the image
|
||||
*/
|
||||
private double x;
|
||||
|
||||
/**
|
||||
* The row position of the image
|
||||
*/
|
||||
private double y;
|
||||
|
||||
/**
|
||||
* The width of the image in cells
|
||||
*/
|
||||
private double width;
|
||||
|
||||
/**
|
||||
* The height of the image in cells
|
||||
*/
|
||||
private double height;
|
||||
|
||||
/**
|
||||
* The number of places this drawing is referenced
|
||||
*/
|
||||
private int referenceCount;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* Where this image came from (read, written or a copy)
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* The drawing group for all the images
|
||||
*/
|
||||
private DrawingGroup drawingGroup;
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private DrawingData drawingData;
|
||||
|
||||
/**
|
||||
* The type of this drawing object
|
||||
*/
|
||||
private ShapeType type;
|
||||
|
||||
/**
|
||||
* The shape id
|
||||
*/
|
||||
private int shapeId;
|
||||
|
||||
/**
|
||||
* The drawing position on the sheet
|
||||
*/
|
||||
private int drawingNumber;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor used when reading images
|
||||
*
|
||||
* @param mso the drawing record
|
||||
* @param dd the drawing data for all drawings on this sheet
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public Drawing2(MsoDrawingRecord mso,
|
||||
DrawingData dd,
|
||||
DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
msoDrawingRecord = mso;
|
||||
drawingData = dd;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
// there is no drawing number associated with this drawing
|
||||
drawingData.addRawData(msoDrawingRecord.getData());
|
||||
drawingGroup.addDrawing(this);
|
||||
|
||||
Assert.verify(mso != null);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor used to copy drawings from read to write
|
||||
*
|
||||
* @param dgo the drawing group object
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
protected Drawing2(DrawingGroupObject dgo, DrawingGroup dg) {
|
||||
Drawing2 d = (Drawing2) dgo;
|
||||
Assert.verify(d.origin == Origin.READ);
|
||||
msoDrawingRecord = d.msoDrawingRecord;
|
||||
initialized = false;
|
||||
origin = Origin.READ;
|
||||
drawingData = d.drawingData;
|
||||
drawingGroup = dg;
|
||||
drawingNumber = d.drawingNumber;
|
||||
drawingGroup.addDrawing(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing the images
|
||||
*
|
||||
* @param x the column
|
||||
* @param y the row
|
||||
* @param w the width in cells
|
||||
* @param h the height in cells
|
||||
* @param image the image file
|
||||
*/
|
||||
public Drawing2(double x,
|
||||
double y,
|
||||
double w,
|
||||
double h,
|
||||
java.io.File image) {
|
||||
imageFile = image;
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
referenceCount = 1;
|
||||
type = ShapeType.PICTURE_FRAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor invoked when writing the images
|
||||
*
|
||||
* @param x the column
|
||||
* @param y the row
|
||||
* @param w the width in cells
|
||||
* @param h the height in cells
|
||||
* @param image the image data
|
||||
*/
|
||||
public Drawing2(double x,
|
||||
double y,
|
||||
double w,
|
||||
double h,
|
||||
byte[] image) {
|
||||
imageData = image;
|
||||
initialized = true;
|
||||
origin = Origin.WRITE;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
referenceCount = 1;
|
||||
type = ShapeType.PICTURE_FRAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the member variables from the Escher stream data
|
||||
*/
|
||||
private void initialize() {
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
public final void setObjectId(int objid, int bip, int sid) {
|
||||
objectId = objid;
|
||||
blipId = bip;
|
||||
shapeId = sid;
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
public final int getObjectId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return objectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the shape id
|
||||
*/
|
||||
public int getShapeId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return shapeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
public final int getBlipId() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return blipId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
public MsoDrawingRecord getMsoDrawingRecord() {
|
||||
return msoDrawingRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
public EscherContainer getSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
Assert.verify(origin == Origin.READ);
|
||||
|
||||
return getReadSpContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
public DrawingGroup getDrawingGroup() {
|
||||
return drawingGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
public void setDrawingGroup(DrawingGroup dg) {
|
||||
drawingGroup = dg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
public int getReferenceCount() {
|
||||
return referenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
public void setReferenceCount(int r) {
|
||||
referenceCount = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public double getX() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
public void setX(double x) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
public double getY() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
public void setY(double y) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
public double getWidth() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
public void setWidth(double w) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
width = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
public double getHeight() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
public void setHeight(double h) {
|
||||
if (origin == Origin.READ) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
origin = Origin.READ_WRITE;
|
||||
}
|
||||
|
||||
height = h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SpContainer that was read in
|
||||
*
|
||||
* @return the read sp container
|
||||
*/
|
||||
private EscherContainer getReadSpContainer() {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return readSpContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageData() {
|
||||
Assert.verify(false);
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
return drawingGroup.getImageData(blipId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
public byte[] getImageBytes() throws IOException {
|
||||
Assert.verify(false);
|
||||
if (origin == Origin.READ || origin == Origin.READ_WRITE) {
|
||||
return getImageData();
|
||||
}
|
||||
|
||||
Assert.verify(origin == Origin.WRITE);
|
||||
|
||||
if (imageFile == null) {
|
||||
Assert.verify(imageData != null);
|
||||
return imageData;
|
||||
}
|
||||
|
||||
byte[] data = new byte[(int) imageFile.length()];
|
||||
FileInputStream fis = new FileInputStream(imageFile);
|
||||
fis.read(data, 0, data.length);
|
||||
fis.close();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ShapeType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any other records associated with this drawing group object
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeAdditionalRecords(File outputFile) throws IOException {
|
||||
// no records to write
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
* Does nothing here
|
||||
*
|
||||
* @param outputFile the output file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeTailRecords(File outputFile) throws IOException {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface method
|
||||
*
|
||||
* @return the column number at which the image is positioned
|
||||
*/
|
||||
public double getColumn() {
|
||||
return getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface method
|
||||
*
|
||||
* @return the row number at which the image is positions
|
||||
*/
|
||||
public double getRow() {
|
||||
return getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return msoDrawingRecord.isFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
public boolean isFormObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a row
|
||||
*
|
||||
* @param r the row to be removed
|
||||
*/
|
||||
public void removeRow(int r) {
|
||||
if (y > r) {
|
||||
setY(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
public String getImageFilePath() {
|
||||
Assert.verify(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
206
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingData.java
Executable file
206
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingData.java
Executable file
|
@ -0,0 +1,206 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Class used to concatenate all the data for the various drawing objects
|
||||
* into one continuous stream
|
||||
*/
|
||||
public class DrawingData implements EscherStream {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(DrawingData.class);
|
||||
|
||||
/**
|
||||
* The drawing data
|
||||
*/
|
||||
private byte[] drawingData;
|
||||
|
||||
/**
|
||||
* The number of drawings
|
||||
*/
|
||||
private int numDrawings;
|
||||
|
||||
/**
|
||||
* Initialized flag
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* The spgr container. The contains the SpContainer for each drawing
|
||||
*/
|
||||
private EscherRecord[] spContainers;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DrawingData() {
|
||||
numDrawings = 0;
|
||||
drawingData = null;
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*/
|
||||
private void initialize() {
|
||||
EscherRecordData er = new EscherRecordData(this, 0);
|
||||
Assert.verify(er.isContainer());
|
||||
|
||||
EscherContainer dgContainer = new EscherContainer(er);
|
||||
EscherRecord[] children = dgContainer.getChildren();
|
||||
|
||||
children = dgContainer.getChildren();
|
||||
// Dg dg = (Dg) children[0];
|
||||
|
||||
EscherContainer spgrContainer = null;
|
||||
|
||||
for (int i = 0; i < children.length && spgrContainer == null; i++) {
|
||||
EscherRecord child = children[i];
|
||||
if (child.getType() == EscherRecordType.SPGR_CONTAINER) {
|
||||
spgrContainer = (EscherContainer) child;
|
||||
}
|
||||
}
|
||||
Assert.verify(spgrContainer != null);
|
||||
|
||||
EscherRecord[] spgrChildren = spgrContainer.getChildren();
|
||||
|
||||
// See if any of the spgrChildren are SpgrContainer
|
||||
boolean nestedContainers = false;
|
||||
for (int i = 0; i < spgrChildren.length && !nestedContainers; i++) {
|
||||
if (spgrChildren[i].getType() == EscherRecordType.SPGR_CONTAINER) {
|
||||
nestedContainers = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no nested containers, simply set the spContainer list
|
||||
// to be the list of children
|
||||
if (!nestedContainers) {
|
||||
spContainers = spgrChildren;
|
||||
} else {
|
||||
// Go through the hierarchy and dig out all the Sp containers
|
||||
ArrayList sps = new ArrayList();
|
||||
getSpContainers(spgrContainer, sps);
|
||||
spContainers = new EscherRecord[sps.size()];
|
||||
spContainers = (EscherRecord[]) sps.toArray(spContainers);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sp container from the internal data
|
||||
*
|
||||
* @param spgrContainer the spgr container
|
||||
* @param sps the list of sp records
|
||||
*/
|
||||
private void getSpContainers(EscherContainer spgrContainer, ArrayList sps) {
|
||||
EscherRecord[] spgrChildren = spgrContainer.getChildren();
|
||||
for (int i = 0; i < spgrChildren.length; i++) {
|
||||
if (spgrChildren[i].getType() == EscherRecordType.SP_CONTAINER) {
|
||||
sps.add(spgrChildren[i]);
|
||||
} else if (spgrChildren[i].getType() == EscherRecordType.SPGR_CONTAINER) {
|
||||
getSpContainers((EscherContainer) spgrChildren[i], sps);
|
||||
} else {
|
||||
logger.warn("Spgr Containers contains a record other than Sp/Spgr " +
|
||||
"containers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the byte stream to the drawing data
|
||||
*
|
||||
* @param data the data to add
|
||||
*/
|
||||
public void addData(byte[] data) {
|
||||
addRawData(data);
|
||||
numDrawings++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the data to the array without incrementing the drawing number.
|
||||
* This is used by comments, which for some bizarre and inexplicable
|
||||
* reason split out the data
|
||||
*
|
||||
* @param data the data to add
|
||||
*/
|
||||
public void addRawData(byte[] data) {
|
||||
if (drawingData == null) {
|
||||
drawingData = data;
|
||||
return;
|
||||
}
|
||||
|
||||
// Resize the array
|
||||
byte[] newArray = new byte[drawingData.length + data.length];
|
||||
System.arraycopy(drawingData, 0, newArray, 0, drawingData.length);
|
||||
System.arraycopy(data, 0, newArray, drawingData.length, data.length);
|
||||
drawingData = newArray;
|
||||
|
||||
// Dirty up this object
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of drawings
|
||||
*
|
||||
* @return the current count of drawings
|
||||
*/
|
||||
final int getNumDrawings() {
|
||||
return numDrawings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sp container for the specified drawing number
|
||||
*
|
||||
* @param drawingNum the drawing number for which to return the spContainer
|
||||
* @return the spcontainer
|
||||
*/
|
||||
EscherContainer getSpContainer(int drawingNum) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
if ((drawingNum + 1) >= spContainers.length) {
|
||||
throw new DrawingDataException();
|
||||
}
|
||||
|
||||
EscherContainer spContainer =
|
||||
(EscherContainer) spContainers[drawingNum + 1];
|
||||
|
||||
Assert.verify(spContainer != null);
|
||||
|
||||
return spContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data which was read in for the drawings
|
||||
*
|
||||
* @return the drawing data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return drawingData;
|
||||
}
|
||||
}
|
35
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingDataException.java
Executable file
35
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingDataException.java
Executable file
|
@ -0,0 +1,35 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
/**
|
||||
* Checked exception thrown when the drawing data is corrupt eg. when
|
||||
* the drawing number exceeds the number of SpContainers. This exception
|
||||
* is handled within the drawing package, and usually causes drawings to be
|
||||
* disabled for the remainder of the workbook
|
||||
*/
|
||||
public class DrawingDataException extends RuntimeException {
|
||||
private static final String message =
|
||||
"Drawing number exceeds available SpContainers";
|
||||
|
||||
DrawingDataException() {
|
||||
super(message);
|
||||
}
|
||||
}
|
534
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingGroup.java
Executable file
534
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingGroup.java
Executable file
|
@ -0,0 +1,534 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import jxl.common.Assert;
|
||||
import jxl.common.Logger;
|
||||
import jxl.read.biff.Record;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* This class contains the Excel picture data in Escher format for the
|
||||
* entire workbook
|
||||
*/
|
||||
public class DrawingGroup implements EscherStream {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(DrawingGroup.class);
|
||||
|
||||
/**
|
||||
* The escher data read in from file
|
||||
*/
|
||||
private byte[] drawingData;
|
||||
|
||||
/**
|
||||
* The top level escher container
|
||||
*/
|
||||
private EscherContainer escherData;
|
||||
|
||||
/**
|
||||
* The Bstore container, which contains all the drawing data
|
||||
*/
|
||||
private BStoreContainer bstoreContainer;
|
||||
|
||||
/**
|
||||
* The initialized flag
|
||||
*/
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* The list of user added drawings
|
||||
*/
|
||||
private final ArrayList drawings;
|
||||
|
||||
/**
|
||||
* The number of blips
|
||||
*/
|
||||
private int numBlips;
|
||||
|
||||
/**
|
||||
* The number of charts
|
||||
*/
|
||||
private int numCharts;
|
||||
|
||||
/**
|
||||
* The number of shape ids used on the second Dgg cluster
|
||||
*/
|
||||
private int drawingGroupId;
|
||||
|
||||
/**
|
||||
* Flag which indicates that at least one of the drawings has been omitted
|
||||
* from the worksheet
|
||||
*/
|
||||
private boolean drawingsOmitted;
|
||||
|
||||
/**
|
||||
* The origin of this drawing group
|
||||
*/
|
||||
private Origin origin;
|
||||
|
||||
/**
|
||||
* A hash map of images keyed on the file path, containing the
|
||||
* reference count
|
||||
*/
|
||||
private final HashMap imageFiles;
|
||||
|
||||
/**
|
||||
* A count of the next available object id
|
||||
*/
|
||||
private int maxObjectId;
|
||||
|
||||
/**
|
||||
* The maximum shape id so far encountered
|
||||
*/
|
||||
private int maxShapeId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param o the origin of this drawing group
|
||||
*/
|
||||
public DrawingGroup(Origin o) {
|
||||
origin = o;
|
||||
initialized = o == Origin.WRITE;
|
||||
drawings = new ArrayList();
|
||||
imageFiles = new HashMap();
|
||||
drawingsOmitted = false;
|
||||
maxObjectId = 1;
|
||||
maxShapeId = 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
* Uses a shallow copy for most things, since as soon as anything
|
||||
* is changed, the drawing group is invalidated and all the data blocks
|
||||
* regenerated
|
||||
*
|
||||
* @param dg the drawing group to copy
|
||||
*/
|
||||
public DrawingGroup(DrawingGroup dg) {
|
||||
drawingData = dg.drawingData;
|
||||
escherData = dg.escherData;
|
||||
bstoreContainer = dg.bstoreContainer;
|
||||
initialized = dg.initialized;
|
||||
drawingData = dg.drawingData;
|
||||
escherData = dg.escherData;
|
||||
bstoreContainer = dg.bstoreContainer;
|
||||
numBlips = dg.numBlips;
|
||||
numCharts = dg.numCharts;
|
||||
drawingGroupId = dg.drawingGroupId;
|
||||
drawingsOmitted = dg.drawingsOmitted;
|
||||
origin = dg.origin;
|
||||
imageFiles = (HashMap) dg.imageFiles.clone();
|
||||
maxObjectId = dg.maxObjectId;
|
||||
maxShapeId = dg.maxShapeId;
|
||||
|
||||
// Create this as empty, because all drawings will get added later
|
||||
// as part of the sheet copy process
|
||||
drawings = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* /**
|
||||
* Adds in a drawing group record to this drawing group. The binary
|
||||
* data is extracted from the drawing group and added to a single
|
||||
* byte array
|
||||
*
|
||||
* @param mso the drawing group record to add
|
||||
*/
|
||||
public void add(MsoDrawingGroupRecord mso) {
|
||||
addData(mso.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a continue record to this drawing group. the binary data is
|
||||
* extracted and appended to the byte array
|
||||
*
|
||||
* @param cont the continue record
|
||||
*/
|
||||
public void add(Record cont) {
|
||||
addData(cont.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the mso record data to the drawing data
|
||||
*
|
||||
* @param msodata the raw mso data
|
||||
*/
|
||||
private void addData(byte[] msodata) {
|
||||
if (drawingData == null) {
|
||||
drawingData = new byte[msodata.length];
|
||||
System.arraycopy(msodata, 0, drawingData, 0, msodata.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Grow the array
|
||||
byte[] newdata = new byte[drawingData.length + msodata.length];
|
||||
System.arraycopy(drawingData, 0, newdata, 0, drawingData.length);
|
||||
System.arraycopy(msodata, 0, newdata, drawingData.length, msodata.length);
|
||||
drawingData = newdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a drawing to the drawing group
|
||||
*
|
||||
* @param d the drawing to add
|
||||
*/
|
||||
final void addDrawing(DrawingGroupObject d) {
|
||||
drawings.add(d);
|
||||
maxObjectId = Math.max(maxObjectId, d.getObjectId());
|
||||
maxShapeId = Math.max(maxShapeId, d.getShapeId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a chart to the drawing group
|
||||
*
|
||||
* @param c the chart
|
||||
*/
|
||||
public void add(Chart c) {
|
||||
numCharts++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a drawing from the public, writable interface
|
||||
*
|
||||
* @param d the drawing to add
|
||||
*/
|
||||
public void add(DrawingGroupObject d) {
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
BStoreContainer bsc = getBStoreContainer(); // force initialization
|
||||
Dgg dgg = (Dgg) escherData.getChildren()[0];
|
||||
drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1;
|
||||
numBlips = bsc != null ? bsc.getNumBlips() : 0;
|
||||
|
||||
if (bsc != null) {
|
||||
Assert.verify(numBlips == bsc.getNumBlips());
|
||||
}
|
||||
}
|
||||
|
||||
if (!(d instanceof Drawing)) {
|
||||
// Assign a new object id and add it to the list
|
||||
// drawings.add(d);
|
||||
maxObjectId++;
|
||||
maxShapeId++;
|
||||
d.setDrawingGroup(this);
|
||||
d.setObjectId(maxObjectId, numBlips + 1, maxShapeId);
|
||||
if (drawings.size() > maxObjectId) {
|
||||
logger.warn("drawings length " + drawings.size() +
|
||||
" exceeds the max object id " + maxObjectId);
|
||||
}
|
||||
// numBlips++;
|
||||
return;
|
||||
}
|
||||
|
||||
Drawing drawing = (Drawing) d;
|
||||
|
||||
// See if this is referenced elsewhere
|
||||
Drawing refImage =
|
||||
(Drawing) imageFiles.get(d.getImageFilePath());
|
||||
|
||||
if (refImage == null) {
|
||||
// There are no other references to this drawing, so assign
|
||||
// a new object id and put it on the hash map
|
||||
maxObjectId++;
|
||||
maxShapeId++;
|
||||
drawings.add(drawing);
|
||||
drawing.setDrawingGroup(this);
|
||||
drawing.setObjectId(maxObjectId, numBlips + 1, maxShapeId);
|
||||
numBlips++;
|
||||
imageFiles.put(drawing.getImageFilePath(), drawing);
|
||||
} else {
|
||||
// This drawing is used elsewhere in the workbook. Increment the
|
||||
// reference count on the drawing, and set the object id of the drawing
|
||||
// passed in
|
||||
refImage.setReferenceCount(refImage.getReferenceCount() + 1);
|
||||
drawing.setDrawingGroup(this);
|
||||
drawing.setObjectId(refImage.getObjectId(),
|
||||
refImage.getBlipId(),
|
||||
refImage.getShapeId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface method to remove a drawing from the group
|
||||
*
|
||||
* @param d the drawing to remove
|
||||
*/
|
||||
public void remove(DrawingGroupObject d) {
|
||||
// Unless there are real images or some such, it is possible that
|
||||
// a BStoreContainer will not be present. In that case simply return
|
||||
if (getBStoreContainer() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (origin == Origin.READ) {
|
||||
origin = Origin.READ_WRITE;
|
||||
numBlips = getBStoreContainer().getNumBlips();
|
||||
Dgg dgg = (Dgg) escherData.getChildren()[0];
|
||||
drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1;
|
||||
}
|
||||
|
||||
// Get the blip
|
||||
EscherRecord[] children = getBStoreContainer().getChildren();
|
||||
BlipStoreEntry bse = (BlipStoreEntry) children[d.getBlipId() - 1];
|
||||
|
||||
bse.dereference();
|
||||
|
||||
if (bse.getReferenceCount() == 0) {
|
||||
// Remove the blip
|
||||
getBStoreContainer().remove(bse);
|
||||
|
||||
// Adjust blipId on the other blips
|
||||
for (Iterator i = drawings.iterator(); i.hasNext(); ) {
|
||||
DrawingGroupObject drawing = (DrawingGroupObject) i.next();
|
||||
|
||||
if (drawing.getBlipId() > d.getBlipId()) {
|
||||
drawing.setObjectId(drawing.getObjectId(),
|
||||
drawing.getBlipId() - 1,
|
||||
drawing.getShapeId());
|
||||
}
|
||||
}
|
||||
|
||||
numBlips--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the drawing data from the escher record read in
|
||||
*/
|
||||
private void initialize() {
|
||||
EscherRecordData er = new EscherRecordData(this, 0);
|
||||
|
||||
Assert.verify(er.isContainer());
|
||||
|
||||
escherData = new EscherContainer(er);
|
||||
|
||||
Assert.verify(escherData.getLength() == drawingData.length);
|
||||
Assert.verify(escherData.getType() == EscherRecordType.DGG_CONTAINER);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets hold of the BStore container from the Escher data
|
||||
*
|
||||
* @return the BStore container
|
||||
*/
|
||||
private BStoreContainer getBStoreContainer() {
|
||||
if (bstoreContainer == null) {
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
EscherRecord[] children = escherData.getChildren();
|
||||
if (children.length > 1 &&
|
||||
children[1].getType() == EscherRecordType.BSTORE_CONTAINER) {
|
||||
bstoreContainer = (BStoreContainer) children[1];
|
||||
}
|
||||
}
|
||||
|
||||
return bstoreContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets hold of the binary data
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return drawingData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the drawing group to the output file
|
||||
*
|
||||
* @param outputFile the file to write to
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(File outputFile) throws IOException {
|
||||
if (origin == Origin.WRITE) {
|
||||
DggContainer dggContainer = new DggContainer();
|
||||
|
||||
Dgg dgg = new Dgg(numBlips + numCharts + 1, numBlips);
|
||||
|
||||
dgg.addCluster(1, 0);
|
||||
dgg.addCluster(numBlips + 1, 0);
|
||||
|
||||
dggContainer.add(dgg);
|
||||
|
||||
int drawingsAdded = 0;
|
||||
BStoreContainer bstoreCont = new BStoreContainer();
|
||||
|
||||
// Create a blip entry for each drawing
|
||||
for (Iterator i = drawings.iterator(); i.hasNext(); ) {
|
||||
Object o = i.next();
|
||||
if (o instanceof Drawing) {
|
||||
Drawing d = (Drawing) o;
|
||||
BlipStoreEntry bse = new BlipStoreEntry(d);
|
||||
|
||||
bstoreCont.add(bse);
|
||||
drawingsAdded++;
|
||||
}
|
||||
}
|
||||
if (drawingsAdded > 0) {
|
||||
bstoreCont.setNumBlips(drawingsAdded);
|
||||
dggContainer.add(bstoreCont);
|
||||
}
|
||||
|
||||
Opt opt = new Opt();
|
||||
|
||||
dggContainer.add(opt);
|
||||
|
||||
SplitMenuColors splitMenuColors = new SplitMenuColors();
|
||||
dggContainer.add(splitMenuColors);
|
||||
|
||||
drawingData = dggContainer.getData();
|
||||
} else if (origin == Origin.READ_WRITE) {
|
||||
DggContainer dggContainer = new DggContainer();
|
||||
|
||||
Dgg dgg = new Dgg(numBlips + numCharts + 1, numBlips);
|
||||
|
||||
dgg.addCluster(1, 0);
|
||||
dgg.addCluster(drawingGroupId + numBlips + 1, 0);
|
||||
|
||||
dggContainer.add(dgg);
|
||||
|
||||
BStoreContainer bstoreCont = new BStoreContainer();
|
||||
bstoreCont.setNumBlips(numBlips);
|
||||
|
||||
// Create a blip entry for each drawing that was read in
|
||||
BStoreContainer readBStoreContainer = getBStoreContainer();
|
||||
|
||||
if (readBStoreContainer != null) {
|
||||
EscherRecord[] children = readBStoreContainer.getChildren();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
BlipStoreEntry bse = (BlipStoreEntry) children[i];
|
||||
bstoreCont.add(bse);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a blip entry for each drawing that has been added
|
||||
for (Iterator i = drawings.iterator(); i.hasNext(); ) {
|
||||
DrawingGroupObject dgo = (DrawingGroupObject) i.next();
|
||||
if (dgo instanceof Drawing) {
|
||||
Drawing d = (Drawing) dgo;
|
||||
if (d.getOrigin() == Origin.WRITE) {
|
||||
BlipStoreEntry bse = new BlipStoreEntry(d);
|
||||
bstoreCont.add(bse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dggContainer.add(bstoreCont);
|
||||
|
||||
Opt opt = new Opt();
|
||||
|
||||
opt.addProperty(191, false, false, 524296);
|
||||
opt.addProperty(385, false, false, 134217737);
|
||||
opt.addProperty(448, false, false, 134217792);
|
||||
|
||||
dggContainer.add(opt);
|
||||
|
||||
SplitMenuColors splitMenuColors = new SplitMenuColors();
|
||||
dggContainer.add(splitMenuColors);
|
||||
|
||||
drawingData = dggContainer.getData();
|
||||
}
|
||||
|
||||
MsoDrawingGroupRecord msodg = new MsoDrawingGroupRecord(drawingData);
|
||||
outputFile.write(msodg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the number of blips in the drawing group
|
||||
*
|
||||
* @return the number of blips
|
||||
*/
|
||||
final int getNumberOfBlips() {
|
||||
return numBlips;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the drawing data for the given blip id. Called by the Drawing
|
||||
* object
|
||||
*
|
||||
* @param blipId the blipId
|
||||
* @return the drawing data
|
||||
*/
|
||||
byte[] getImageData(int blipId) {
|
||||
numBlips = getBStoreContainer().getNumBlips();
|
||||
|
||||
Assert.verify(blipId <= numBlips);
|
||||
Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
|
||||
|
||||
// Get the blip
|
||||
EscherRecord[] children = getBStoreContainer().getChildren();
|
||||
BlipStoreEntry bse = (BlipStoreEntry) children[blipId - 1];
|
||||
|
||||
return bse.getImageData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that at least one of the drawings has been omitted from
|
||||
* the worksheet
|
||||
*
|
||||
* @param mso the mso record
|
||||
* @param obj the obj record
|
||||
*/
|
||||
public void setDrawingsOmitted(MsoDrawingRecord mso, ObjRecord obj) {
|
||||
drawingsOmitted = true;
|
||||
|
||||
if (obj != null) {
|
||||
maxObjectId = Math.max(maxObjectId, obj.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the drawingsOmitted flag
|
||||
*
|
||||
* @return TRUE if a drawing has been omitted, FALSE otherwise
|
||||
*/
|
||||
public boolean hasDrawingsOmitted() {
|
||||
return drawingsOmitted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this with the appropriate data from the drawing group passed in
|
||||
* This is called during the copy process: this is first initialised as
|
||||
* an empty object, but during the copy, the source DrawingGroup may
|
||||
* change. After the copy process, this method is then called to update
|
||||
* the relevant fields. Unfortunately, the copy process required the
|
||||
* presence of a drawing group
|
||||
*
|
||||
* @param dg the drawing group containing the updated data
|
||||
*/
|
||||
public void updateData(DrawingGroup dg) {
|
||||
drawingsOmitted = dg.drawingsOmitted;
|
||||
maxObjectId = dg.maxObjectId;
|
||||
maxShapeId = dg.maxShapeId;
|
||||
}
|
||||
}
|
231
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingGroupObject.java
Executable file
231
datastructures-xslx/src/main/java/jxl/biff/drawing/DrawingGroupObject.java
Executable file
|
@ -0,0 +1,231 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import java.io.IOException;
|
||||
import jxl.write.biff.File;
|
||||
|
||||
/**
|
||||
* Interface for the various object types that can be added to a drawing
|
||||
* group
|
||||
*/
|
||||
public interface DrawingGroupObject {
|
||||
/**
|
||||
* Sets the object id. Invoked by the drawing group when the object is
|
||||
* added to id
|
||||
*
|
||||
* @param objid the object id
|
||||
* @param bip the blip id
|
||||
* @param sid the shape id
|
||||
*/
|
||||
void setObjectId(int objid, int bip, int sid);
|
||||
|
||||
/**
|
||||
* Accessor for the object id
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
int getObjectId();
|
||||
|
||||
/**
|
||||
* Accessor for the blip id
|
||||
*
|
||||
* @return the blip id
|
||||
*/
|
||||
int getBlipId();
|
||||
|
||||
/**
|
||||
* Accessor for the shape id
|
||||
*
|
||||
* @return the shape id
|
||||
*/
|
||||
int getShapeId();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the drawing record which was read in
|
||||
*
|
||||
* @return the drawing record
|
||||
*/
|
||||
MsoDrawingRecord getMsoDrawingRecord();
|
||||
|
||||
/**
|
||||
* Creates the main Sp container for the drawing
|
||||
*
|
||||
* @return the SP container
|
||||
*/
|
||||
EscherContainer getSpContainer();
|
||||
|
||||
/**
|
||||
* Accessor for the drawing group
|
||||
*
|
||||
* @return the drawing group
|
||||
*/
|
||||
DrawingGroup getDrawingGroup();
|
||||
|
||||
/**
|
||||
* Sets the drawing group for this drawing. Called by the drawing group
|
||||
* when this drawing is added to it
|
||||
*
|
||||
* @param dg the drawing group
|
||||
*/
|
||||
void setDrawingGroup(DrawingGroup dg);
|
||||
|
||||
/**
|
||||
* Gets the origin of this drawing
|
||||
*
|
||||
* @return where this drawing came from
|
||||
*/
|
||||
Origin getOrigin();
|
||||
|
||||
/**
|
||||
* Accessor for the reference count on this drawing
|
||||
*
|
||||
* @return the reference count
|
||||
*/
|
||||
int getReferenceCount();
|
||||
|
||||
/**
|
||||
* Sets the new reference count on the drawing
|
||||
*
|
||||
* @param r the new reference count
|
||||
*/
|
||||
void setReferenceCount(int r);
|
||||
|
||||
/**
|
||||
* Accessor for the column of this drawing
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
double getX();
|
||||
|
||||
/**
|
||||
* Sets the column position of this drawing
|
||||
*
|
||||
* @param x the column
|
||||
*/
|
||||
void setX(double x);
|
||||
|
||||
/**
|
||||
* Accessor for the row of this drawing
|
||||
*
|
||||
* @return the row
|
||||
*/
|
||||
double getY();
|
||||
|
||||
/**
|
||||
* Accessor for the row of the drawing
|
||||
*
|
||||
* @param y the row
|
||||
*/
|
||||
void setY(double y);
|
||||
|
||||
/**
|
||||
* Accessor for the width of this drawing
|
||||
*
|
||||
* @return the number of columns spanned by this image
|
||||
*/
|
||||
double getWidth();
|
||||
|
||||
/**
|
||||
* Accessor for the width
|
||||
*
|
||||
* @param w the number of columns to span
|
||||
*/
|
||||
void setWidth(double w);
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @return the number of rows spanned by this image
|
||||
*/
|
||||
double getHeight();
|
||||
|
||||
/**
|
||||
* Accessor for the height of this drawing
|
||||
*
|
||||
* @param h the number of rows spanned by this image
|
||||
*/
|
||||
void setHeight(double h);
|
||||
|
||||
|
||||
/**
|
||||
* Accessor for the type
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
ShapeType getType();
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
byte[] getImageData();
|
||||
|
||||
/**
|
||||
* Accessor for the image data
|
||||
*
|
||||
* @return the image data
|
||||
*/
|
||||
byte[] getImageBytes() throws IOException;
|
||||
|
||||
/**
|
||||
* Accessor for the image file path. Normally this is the absolute path
|
||||
* of a file on the directory system, but if this drawing was constructed
|
||||
* using an byte[] then the blip id is returned
|
||||
*
|
||||
* @return the image file path, or the blip id
|
||||
*/
|
||||
String getImageFilePath();
|
||||
|
||||
/**
|
||||
* Writes any other records associated with this drawing group object
|
||||
*/
|
||||
void writeAdditionalRecords(File outputFile) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes any records that need to be written after all the drawing group
|
||||
* objects have been written
|
||||
*/
|
||||
void writeTailRecords(File outputFile) throws IOException;
|
||||
|
||||
/**
|
||||
* Accessor for the first drawing on the sheet. This is used when
|
||||
* copying unmodified sheets to indicate that this drawing contains
|
||||
* the first time Escher gubbins
|
||||
*
|
||||
* @return TRUE if this MSORecord is the first drawing on the sheet
|
||||
*/
|
||||
boolean isFirst();
|
||||
|
||||
/**
|
||||
* Queries whether this object is a form object. Form objects have their
|
||||
* drawings records spread over TXO and CONTINUE records and
|
||||
* require special handling
|
||||
*
|
||||
* @return TRUE if this is a form object, FALSE otherwise
|
||||
*/
|
||||
boolean isFormObject();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
63
datastructures-xslx/src/main/java/jxl/biff/drawing/EscherAtom.java
Executable file
63
datastructures-xslx/src/main/java/jxl/biff/drawing/EscherAtom.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 Andrew Khan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************/
|
||||
|
||||
package jxl.biff.drawing;
|
||||
|
||||
import jxl.common.Logger;
|
||||
|
||||
/**
|
||||
* Class for atoms. This may be instantiated as is for unknown/uncared about
|
||||
* atoms, or subclassed if we have some semantic interest in the contents
|
||||
*/
|
||||
class EscherAtom extends EscherRecord {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger(EscherAtom.class);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param erd the escher record data
|
||||
*/
|
||||
public EscherAtom(EscherRecordData erd) {
|
||||
super(erd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param type the type
|
||||
*/
|
||||
protected EscherAtom(EscherRecordType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data for writing
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
byte[] getData() {
|
||||
logger.warn("escher atom getData called on object of type " +
|
||||
getClass().getName() + " code " +
|
||||
Integer.toString(getType().getValue(), 16));
|
||||
return null;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue