first commit

This commit is contained in:
2025-07-28 13:56:49 +05:30
commit e9eb805edb
3438 changed files with 520990 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class BOFRecord extends WritableRecordData {
private byte[] data;
private static class WorkbookGlobalsBOF {
private WorkbookGlobalsBOF() {}
}
private static class SheetBOF {
private SheetBOF() {}
}
public static final WorkbookGlobalsBOF workbookGlobals = new WorkbookGlobalsBOF();
public static final SheetBOF sheet = new SheetBOF();
public BOFRecord(WorkbookGlobalsBOF dummy) {
super(Type.BOF);
this.data = new byte[] {
0, 6, 5, 0, -14, 21, -52, 7, 0, 0,
0, 0, 6, 0, 0, 0 };
}
public BOFRecord(SheetBOF dummy) {
super(Type.BOF);
this.data = new byte[] {
0, 6, 16, 0, -14, 21, -52, 7, 0, 0,
0, 0, 6, 0, 0, 0 };
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class BackupRecord extends WritableRecordData {
private boolean backup;
private byte[] data;
public BackupRecord(boolean bu) {
super(Type.BACKUP);
this.backup = bu;
this.data = new byte[2];
if (this.backup)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,35 @@
package jxl.write.biff;
import common.Logger;
import jxl.Cell;
import jxl.CellType;
import jxl.biff.Type;
import jxl.format.CellFormat;
public abstract class BlankRecord extends CellValue {
private static Logger logger = Logger.getLogger(BlankRecord.class);
protected BlankRecord(int c, int r) {
super(Type.BLANK, c, r);
}
protected BlankRecord(int c, int r, CellFormat st) {
super(Type.BLANK, c, r, st);
}
protected BlankRecord(Cell c) {
super(Type.BLANK, c);
}
protected BlankRecord(int c, int r, BlankRecord br) {
super(Type.BLANK, c, r, br);
}
public CellType getType() {
return CellType.EMPTY;
}
public String getContents() {
return "";
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class BookboolRecord extends WritableRecordData {
private boolean externalLink;
private byte[] data;
public BookboolRecord(boolean extlink) {
super(Type.BOOKBOOL);
this.externalLink = extlink;
this.data = new byte[2];
if (!this.externalLink)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,56 @@
package jxl.write.biff;
import jxl.BooleanCell;
import jxl.Cell;
import jxl.CellType;
import jxl.biff.Type;
import jxl.format.CellFormat;
public abstract class BooleanRecord extends CellValue {
private boolean value;
protected BooleanRecord(int c, int r, boolean val) {
super(Type.BOOLERR, c, r);
this.value = val;
}
protected BooleanRecord(int c, int r, boolean val, CellFormat st) {
super(Type.BOOLERR, c, r, st);
this.value = val;
}
protected BooleanRecord(BooleanCell nc) {
super(Type.BOOLERR, (Cell)nc);
this.value = nc.getValue();
}
protected BooleanRecord(int c, int r, BooleanRecord br) {
super(Type.BOOLERR, c, r, br);
this.value = br.value;
}
public boolean getValue() {
return this.value;
}
public String getContents() {
return (new Boolean(this.value)).toString();
}
public CellType getType() {
return CellType.BOOLEAN;
}
protected void setValue(boolean val) {
this.value = val;
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] data = new byte[celldata.length + 2];
System.arraycopy(celldata, 0, data, 0, celldata.length);
if (this.value)
data[celldata.length] = 1;
return data;
}
}

View File

@@ -0,0 +1,9 @@
package jxl.write.biff;
import jxl.biff.Type;
class BottomMarginRecord extends MarginRecord {
BottomMarginRecord(double v) {
super(Type.BOTTOMMARGIN, v);
}
}

View File

@@ -0,0 +1,47 @@
package jxl.write.biff;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class BoundsheetRecord extends WritableRecordData {
private boolean hidden;
private boolean chartOnly;
private String name;
private byte[] data;
public BoundsheetRecord(String n) {
super(Type.BOUNDSHEET);
this.name = n;
this.hidden = false;
this.chartOnly = false;
}
void setHidden() {
this.hidden = true;
}
void setChartOnly() {
this.chartOnly = true;
}
public byte[] getData() {
this.data = new byte[this.name.length() * 2 + 8];
if (this.chartOnly) {
this.data[5] = 2;
} else {
this.data[5] = 0;
}
if (this.hidden) {
this.data[4] = 1;
this.data[5] = 0;
}
this.data[6] = (byte)this.name.length();
this.data[7] = 1;
StringHelper.getUnicodeBytes(this.name, this.data, 8);
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ButtonPropertySetRecord extends WritableRecordData {
private byte[] data;
public ButtonPropertySetRecord(jxl.read.biff.ButtonPropertySetRecord bps) {
super(Type.BUTTONPROPERTYSET);
this.data = bps.getData();
}
public ButtonPropertySetRecord(ButtonPropertySetRecord bps) {
super(Type.BUTTONPROPERTYSET);
this.data = bps.getData();
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class CalcCountRecord extends WritableRecordData {
private int calcCount;
private byte[] data;
public CalcCountRecord(int cnt) {
super(Type.CALCCOUNT);
this.calcCount = cnt;
}
public byte[] getData() {
byte[] data = new byte[2];
IntegerHelper.getTwoBytes(this.calcCount, data, 0);
return data;
}
}

View File

@@ -0,0 +1,34 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class CalcModeRecord extends WritableRecordData {
private CalcMode calculationMode;
private static class CalcMode {
int value;
public CalcMode(int m) {
this.value = m;
}
}
static CalcMode manual = new CalcMode(0);
static CalcMode automatic = new CalcMode(1);
static CalcMode automaticNoTables = new CalcMode(-1);
public CalcModeRecord(CalcMode cm) {
super(Type.CALCMODE);
this.calculationMode = cm;
}
public byte[] getData() {
byte[] data = new byte[2];
IntegerHelper.getTwoBytes(this.calculationMode.value, data, 0);
return data;
}
}

View File

@@ -0,0 +1,240 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.Cell;
import jxl.CellFeatures;
import jxl.Sheet;
import jxl.biff.FormattingRecords;
import jxl.biff.IntegerHelper;
import jxl.biff.NumFormatRecordsException;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.biff.XFRecord;
import jxl.biff.drawing.Comment;
import jxl.biff.drawing.DrawingGroupObject;
import jxl.format.CellFormat;
import jxl.write.WritableCell;
import jxl.write.WritableCellFeatures;
import jxl.write.WritableWorkbook;
public abstract class CellValue extends WritableRecordData implements WritableCell {
private static Logger logger = Logger.getLogger(CellValue.class);
private int row;
private int column;
private XFRecord format;
private FormattingRecords formattingRecords;
private boolean referenced;
private WritableSheetImpl sheet;
private WritableCellFeatures features;
private boolean copied;
protected CellValue(Type t, int c, int r) {
this(t, c, r, (CellFormat)WritableWorkbook.NORMAL_STYLE);
this.copied = false;
}
protected CellValue(Type t, Cell c) {
this(t, c.getColumn(), c.getRow());
this.copied = true;
this.format = (XFRecord)c.getCellFormat();
if (c.getCellFeatures() != null) {
this.features = new WritableCellFeatures(c.getCellFeatures());
this.features.setWritableCell(this);
}
}
protected CellValue(Type t, int c, int r, CellFormat st) {
super(t);
this.row = r;
this.column = c;
this.format = (XFRecord)st;
this.referenced = false;
this.copied = false;
}
protected CellValue(Type t, int c, int r, CellValue cv) {
super(t);
this.row = r;
this.column = c;
this.format = cv.format;
this.referenced = false;
this.copied = false;
if (cv.features != null) {
this.features = new WritableCellFeatures((CellFeatures)cv.features);
this.features.setWritableCell(this);
}
}
public void setCellFormat(CellFormat cf) {
this.format = (XFRecord)cf;
if (!this.referenced)
return;
Assert.verify((this.formattingRecords != null));
addCellFormat();
}
public int getRow() {
return this.row;
}
public int getColumn() {
return this.column;
}
public boolean isHidden() {
ColumnInfoRecord cir = this.sheet.getColumnInfo(this.column);
if (cir != null && cir.getWidth() == 0)
return true;
RowRecord rr = this.sheet.getRowInfo(this.row);
if (rr != null && (rr.getRowHeight() == 0 || rr.isCollapsed()))
return true;
return false;
}
public byte[] getData() {
byte[] mydata = new byte[6];
IntegerHelper.getTwoBytes(this.row, mydata, 0);
IntegerHelper.getTwoBytes(this.column, mydata, 2);
IntegerHelper.getTwoBytes(this.format.getXFIndex(), mydata, 4);
return mydata;
}
void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) {
this.referenced = true;
this.sheet = s;
this.formattingRecords = fr;
addCellFormat();
addCellFeatures();
}
final boolean isReferenced() {
return this.referenced;
}
final int getXFIndex() {
return this.format.getXFIndex();
}
public CellFormat getCellFormat() {
return (CellFormat)this.format;
}
void incrementRow() {
this.row++;
if (this.features != null) {
Comment c = this.features.getCommentDrawing();
if (c != null) {
c.setX(this.column);
c.setY(this.row);
}
}
}
void decrementRow() {
this.row--;
if (this.features != null) {
Comment c = this.features.getCommentDrawing();
if (c != null) {
c.setX(this.column);
c.setY(this.row);
}
}
}
void incrementColumn() {
this.column++;
if (this.features != null) {
Comment c = this.features.getCommentDrawing();
if (c != null) {
c.setX(this.column);
c.setY(this.row);
}
}
}
void decrementColumn() {
this.column--;
if (this.features != null) {
Comment c = this.features.getCommentDrawing();
if (c != null) {
c.setX(this.column);
c.setY(this.row);
}
}
}
void columnInserted(Sheet s, int sheetIndex, int col) {}
void columnRemoved(Sheet s, int sheetIndex, int col) {}
void rowInserted(Sheet s, int sheetIndex, int row) {}
void rowRemoved(Sheet s, int sheetIndex, int row) {}
protected WritableSheetImpl getSheet() {
return this.sheet;
}
private void addCellFormat() {
Styles styles = this.sheet.getWorkbook().getStyles();
this.format = styles.getFormat(this.format);
try {
if (!this.format.isInitialized())
this.formattingRecords.addStyle(this.format);
} catch (NumFormatRecordsException e) {
logger.warn("Maximum number of format records exceeded. Using default format.");
this.format = (XFRecord)styles.getNormalStyle();
}
}
public CellFeatures getCellFeatures() {
return (CellFeatures)this.features;
}
public WritableCellFeatures getWritableCellFeatures() {
return this.features;
}
public void setCellFeatures(WritableCellFeatures cf) {
if (this.features != null)
logger.warn("current cell features not null - overwriting");
this.features = cf;
cf.setWritableCell(this);
if (this.referenced)
addCellFeatures();
}
public final void addCellFeatures() {
if (this.features == null)
return;
if (this.copied == true) {
this.copied = false;
return;
}
if (this.features.getComment() != null) {
Comment comment = new Comment(this.features.getComment(), this.column, this.row);
comment.setWidth(this.features.getCommentWidth());
comment.setHeight(this.features.getCommentHeight());
this.sheet.addDrawing((DrawingGroupObject)comment);
this.sheet.getWorkbook().addDrawing((DrawingGroupObject)comment);
this.features.setCommentDrawing(comment);
}
}
public final void removeComment(Comment c) {
this.sheet.removeDrawing((DrawingGroupObject)c);
}
final void setCopied(boolean c) {
this.copied = c;
}
}

View File

@@ -0,0 +1,100 @@
package jxl.write.biff;
import jxl.biff.DisplayFormat;
import jxl.biff.FontRecord;
import jxl.biff.XFRecord;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.CellFormat;
import jxl.format.Colour;
import jxl.format.Orientation;
import jxl.format.Pattern;
import jxl.format.VerticalAlignment;
import jxl.write.WriteException;
public class CellXFRecord extends XFRecord {
protected CellXFRecord(FontRecord fnt, DisplayFormat form) {
super(fnt, form);
setXFDetails(XFRecord.cell, 0);
}
CellXFRecord(XFRecord fmt) {
super(fmt);
setXFDetails(XFRecord.cell, 0);
}
protected CellXFRecord(CellFormat format) {
super(format);
}
public void setAlignment(Alignment a) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFAlignment(a);
}
public void setBackground(Colour c, Pattern p) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFBackground(c, p);
setXFCellOptions(16384);
}
public void setLocked(boolean l) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFLocked(l);
setXFCellOptions(32768);
}
public void setIndentation(int i) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFIndentation(i);
}
public void setShrinkToFit(boolean s) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFShrinkToFit(s);
}
public void setVerticalAlignment(VerticalAlignment va) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFVerticalAlignment(va);
}
public void setOrientation(Orientation o) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFOrientation(o);
}
public void setWrap(boolean w) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
setXFWrap(w);
}
public void setBorder(Border b, BorderLineStyle ls, Colour c) throws WriteException {
if (isInitialized())
throw new JxlWriteException(JxlWriteException.formatInitialized);
if (b == Border.ALL) {
setXFBorder(Border.LEFT, ls, c);
setXFBorder(Border.RIGHT, ls, c);
setXFBorder(Border.TOP, ls, c);
setXFBorder(Border.BOTTOM, ls, c);
return;
}
if (b == Border.NONE) {
setXFBorder(Border.LEFT, BorderLineStyle.NONE, Colour.BLACK);
setXFBorder(Border.RIGHT, BorderLineStyle.NONE, Colour.BLACK);
setXFBorder(Border.TOP, BorderLineStyle.NONE, Colour.BLACK);
setXFBorder(Border.BOTTOM, BorderLineStyle.NONE, Colour.BLACK);
return;
}
setXFBorder(b, ls, c);
}
}

View File

@@ -0,0 +1,17 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class CodepageRecord extends WritableRecordData {
private byte[] data;
public CodepageRecord() {
super(Type.CODEPAGE);
this.data = new byte[] { -28, 4 };
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,109 @@
package jxl.write.biff;
import jxl.biff.FormattingRecords;
import jxl.biff.IndexMapping;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.biff.XFRecord;
class ColumnInfoRecord extends WritableRecordData {
private byte[] data;
private int column;
private XFRecord style;
private int xfIndex;
private int width;
private boolean hidden;
public ColumnInfoRecord(int col, int w, XFRecord xf) {
super(Type.COLINFO);
this.column = col;
this.width = w;
this.style = xf;
this.xfIndex = this.style.getXFIndex();
this.hidden = false;
}
public ColumnInfoRecord(jxl.read.biff.ColumnInfoRecord cir, int col, FormattingRecords fr) {
super(Type.COLINFO);
this.column = col;
this.width = cir.getWidth();
this.xfIndex = cir.getXFIndex();
this.style = fr.getXFRecord(this.xfIndex);
}
public int getColumn() {
return this.column;
}
public void incrementColumn() {
this.column++;
}
public void decrementColumn() {
this.column--;
}
int getWidth() {
return this.width;
}
public byte[] getData() {
this.data = new byte[12];
IntegerHelper.getTwoBytes(this.column, this.data, 0);
IntegerHelper.getTwoBytes(this.column, this.data, 2);
IntegerHelper.getTwoBytes(this.width, this.data, 4);
IntegerHelper.getTwoBytes(this.xfIndex, this.data, 6);
int options = 6;
if (this.hidden)
options |= 0x1;
IntegerHelper.getTwoBytes(options, this.data, 8);
return this.data;
}
public XFRecord getCellFormat() {
return this.style;
}
void rationalize(IndexMapping xfmapping) {
this.xfIndex = xfmapping.getNewIndex(this.xfIndex);
}
void setHidden(boolean h) {
this.hidden = h;
}
boolean getHidden() {
return this.hidden;
}
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof ColumnInfoRecord))
return false;
ColumnInfoRecord cir = (ColumnInfoRecord)o;
if (this.column != cir.column || this.xfIndex != cir.xfIndex || this.width != cir.width || this.hidden != cir.hidden)
return false;
if ((this.style == null && cir.style != null) || (this.style != null && cir.style == null))
return false;
return this.style.equals(cir.style);
}
public int hashCode() {
int hashValue = 137;
int oddPrimeNumber = 79;
hashValue = hashValue * oddPrimeNumber + this.column;
hashValue = hashValue * oddPrimeNumber + this.xfIndex;
hashValue = hashValue * oddPrimeNumber + this.width;
hashValue = hashValue * oddPrimeNumber + (this.hidden ? 1 : 0);
if (this.style != null)
hashValue ^= this.style.hashCode();
return hashValue;
}
}

View File

@@ -0,0 +1,539 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import jxl.biff.BaseCompoundFile;
import jxl.biff.IntegerHelper;
import jxl.read.biff.BiffException;
final class CompoundFile extends BaseCompoundFile {
private static Logger logger = Logger.getLogger(CompoundFile.class);
private OutputStream out;
private byte[] excelData;
private int size;
private int requiredSize;
private int numBigBlockDepotBlocks;
private int numSmallBlockDepotChainBlocks;
private int numSmallBlockDepotBlocks;
private int numExtensionBlocks;
private int extensionBlock;
private int excelDataBlocks;
private int rootStartBlock;
private int excelDataStartBlock;
private int bbdStartBlock;
private int sbdStartBlockChain;
private int sbdStartBlock;
private int additionalPropertyBlocks;
private int numSmallBlocks;
private int numPropertySets;
private int numRootEntryBlocks;
private ArrayList additionalPropertySets;
private HashMap standardPropertySets;
private int bbdPos;
private byte[] bigBlockDepot;
private static final class ReadPropertyStorage {
BaseCompoundFile.PropertyStorage propertyStorage;
byte[] data;
int number;
ReadPropertyStorage(BaseCompoundFile.PropertyStorage ps, byte[] d, int n) {
this.propertyStorage = ps;
this.data = d;
this.number = n;
}
}
public CompoundFile(byte[] data, int l, OutputStream os, jxl.read.biff.CompoundFile rcf) throws CopyAdditionalPropertySetsException, IOException {
this.size = l;
this.excelData = data;
readAdditionalPropertySets(rcf);
this.numRootEntryBlocks = 1;
this.numPropertySets = 4 + ((this.additionalPropertySets != null) ? this.additionalPropertySets.size() : 0);
if (this.additionalPropertySets != null) {
this.numSmallBlockDepotChainBlocks = getBigBlocksRequired(this.numSmallBlocks * 4);
this.numSmallBlockDepotBlocks = getBigBlocksRequired(this.numSmallBlocks * 64);
this.numRootEntryBlocks += getBigBlocksRequired(this.additionalPropertySets.size() * 128);
}
int blocks = getBigBlocksRequired(l);
if (l < 4096) {
this.requiredSize = 4096;
} else {
this.requiredSize = blocks * 512;
}
this.out = os;
this.excelDataBlocks = this.requiredSize / 512;
this.numBigBlockDepotBlocks = 1;
int blockChainLength = 109;
int startTotalBlocks = this.excelDataBlocks + 8 + 8 + this.additionalPropertyBlocks + this.numSmallBlockDepotBlocks + this.numSmallBlockDepotChainBlocks + this.numRootEntryBlocks;
int totalBlocks = startTotalBlocks + this.numBigBlockDepotBlocks;
this.numBigBlockDepotBlocks = (int)Math.ceil(totalBlocks / 128.0D);
totalBlocks = startTotalBlocks + this.numBigBlockDepotBlocks;
this.numBigBlockDepotBlocks = (int)Math.ceil(totalBlocks / 128.0D);
totalBlocks = startTotalBlocks + this.numBigBlockDepotBlocks;
if (this.numBigBlockDepotBlocks > blockChainLength - 1) {
this.extensionBlock = 0;
int bbdBlocksLeft = this.numBigBlockDepotBlocks - blockChainLength + 1;
this.numExtensionBlocks = (int)Math.ceil(bbdBlocksLeft / 127.0D);
totalBlocks = startTotalBlocks + this.numExtensionBlocks + this.numBigBlockDepotBlocks;
this.numBigBlockDepotBlocks = (int)Math.ceil(totalBlocks / 128.0D);
totalBlocks = startTotalBlocks + this.numExtensionBlocks + this.numBigBlockDepotBlocks;
} else {
this.extensionBlock = -2;
this.numExtensionBlocks = 0;
}
this.excelDataStartBlock = this.numExtensionBlocks;
this.sbdStartBlock = -2;
if (this.additionalPropertySets != null && this.numSmallBlockDepotBlocks != 0)
this.sbdStartBlock = this.excelDataStartBlock + this.excelDataBlocks + this.additionalPropertyBlocks + 16;
this.sbdStartBlockChain = -2;
if (this.sbdStartBlock != -2)
this.sbdStartBlockChain = this.sbdStartBlock + this.numSmallBlockDepotBlocks;
if (this.sbdStartBlockChain != -2) {
this.bbdStartBlock = this.sbdStartBlockChain + this.numSmallBlockDepotChainBlocks;
} else {
this.bbdStartBlock = this.excelDataStartBlock + this.excelDataBlocks + this.additionalPropertyBlocks + 16;
}
this.rootStartBlock = this.bbdStartBlock + this.numBigBlockDepotBlocks;
if (totalBlocks != this.rootStartBlock + this.numRootEntryBlocks) {
logger.warn("Root start block and total blocks are inconsistent generated file may be corrupt");
logger.warn("RootStartBlock " + this.rootStartBlock + " totalBlocks " + totalBlocks);
}
}
private void readAdditionalPropertySets(jxl.read.biff.CompoundFile readCompoundFile) throws CopyAdditionalPropertySetsException, IOException {
if (readCompoundFile == null)
return;
this.additionalPropertySets = new ArrayList();
this.standardPropertySets = new HashMap();
int blocksRequired = 0;
int numPropertySets = readCompoundFile.getNumberOfPropertySets();
for (int i = 0; i < numPropertySets; i++) {
BaseCompoundFile.PropertyStorage ps = readCompoundFile.getPropertySet(i);
boolean standard = false;
if (ps.name.equalsIgnoreCase("Root Entry")) {
standard = true;
ReadPropertyStorage rps = new ReadPropertyStorage(ps, null, i);
this.standardPropertySets.put("Root Entry", rps);
}
for (int j = 0; j < STANDARD_PROPERTY_SETS.length && !standard; j++) {
if (ps.name.equalsIgnoreCase(STANDARD_PROPERTY_SETS[j])) {
BaseCompoundFile.PropertyStorage ps2 = readCompoundFile.findPropertyStorage(ps.name);
Assert.verify((ps2 != null));
if (ps2 == ps) {
standard = true;
ReadPropertyStorage rps = new ReadPropertyStorage(ps, null, i);
this.standardPropertySets.put(STANDARD_PROPERTY_SETS[j], rps);
}
}
}
if (!standard)
try {
byte[] data = null;
if (ps.size > 0) {
data = readCompoundFile.getStream(i);
} else {
data = new byte[0];
}
ReadPropertyStorage rps = new ReadPropertyStorage(ps, data, i);
this.additionalPropertySets.add(rps);
if (data.length > 4096) {
int blocks = getBigBlocksRequired(data.length);
blocksRequired += blocks;
} else {
int blocks = getSmallBlocksRequired(data.length);
this.numSmallBlocks += blocks;
}
} catch (BiffException e) {
logger.error(e);
throw new CopyAdditionalPropertySetsException();
}
}
this.additionalPropertyBlocks = blocksRequired;
}
public void write() throws IOException {
writeHeader();
writeExcelData();
writeDocumentSummaryData();
writeSummaryData();
writeAdditionalPropertySets();
writeSmallBlockDepot();
writeSmallBlockDepotChain();
writeBigBlockDepot();
writePropertySets();
}
private void writeAdditionalPropertySets() throws IOException {
if (this.additionalPropertySets == null)
return;
for (Iterator i = this.additionalPropertySets.iterator(); i.hasNext(); ) {
ReadPropertyStorage rps = i.next();
byte[] data = rps.data;
if (data.length > 4096) {
int numBlocks = getBigBlocksRequired(data.length);
int requiredSize = numBlocks * 512;
this.out.write(data, 0, data.length);
byte[] padding = new byte[requiredSize - data.length];
this.out.write(padding, 0, padding.length);
}
}
}
private void writeExcelData() throws IOException {
this.out.write(this.excelData, 0, this.size);
byte[] padding = new byte[this.requiredSize - this.size];
this.out.write(padding);
}
private void writeDocumentSummaryData() throws IOException {
byte[] padding = new byte[4096];
this.out.write(padding);
}
private void writeSummaryData() throws IOException {
byte[] padding = new byte[4096];
this.out.write(padding);
}
private void writeHeader() throws IOException {
byte[] headerBlock = new byte[512];
byte[] extensionBlockData = new byte[512 * this.numExtensionBlocks];
System.arraycopy(IDENTIFIER, 0, headerBlock, 0, IDENTIFIER.length);
headerBlock[24] = 62;
headerBlock[26] = 3;
headerBlock[28] = -2;
headerBlock[29] = -1;
headerBlock[30] = 9;
headerBlock[32] = 6;
headerBlock[57] = 16;
IntegerHelper.getFourBytes(this.numBigBlockDepotBlocks, headerBlock, 44);
IntegerHelper.getFourBytes(this.sbdStartBlockChain, headerBlock, 60);
IntegerHelper.getFourBytes(this.numSmallBlockDepotChainBlocks, headerBlock, 64);
IntegerHelper.getFourBytes(this.extensionBlock, headerBlock, 68);
IntegerHelper.getFourBytes(this.numExtensionBlocks, headerBlock, 72);
IntegerHelper.getFourBytes(this.rootStartBlock, headerBlock, 48);
int pos = 76;
int blocksToWrite = Math.min(this.numBigBlockDepotBlocks, 109);
int blocksWritten = 0;
int i;
for (i = 0; i < blocksToWrite; i++) {
IntegerHelper.getFourBytes(this.bbdStartBlock + i, headerBlock, pos);
pos += 4;
blocksWritten++;
}
for (i = pos; i < 512; i++)
headerBlock[i] = -1;
this.out.write(headerBlock);
pos = 0;
for (int extBlock = 0; extBlock < this.numExtensionBlocks; extBlock++) {
blocksToWrite = Math.min(this.numBigBlockDepotBlocks - blocksWritten, 127);
for (int j = 0; j < blocksToWrite; j++) {
IntegerHelper.getFourBytes(this.bbdStartBlock + blocksWritten + j, extensionBlockData, pos);
pos += 4;
}
blocksWritten += blocksToWrite;
int nextBlock = (blocksWritten == this.numBigBlockDepotBlocks) ? -2 : (extBlock + 1);
IntegerHelper.getFourBytes(nextBlock, extensionBlockData, pos);
pos += 4;
}
if (this.numExtensionBlocks > 0) {
for (int j = pos; j < extensionBlockData.length; j++)
extensionBlockData[j] = -1;
this.out.write(extensionBlockData);
}
}
private void checkBbdPos() throws IOException {
if (this.bbdPos >= 512) {
this.out.write(this.bigBlockDepot);
this.bigBlockDepot = new byte[512];
this.bbdPos = 0;
}
}
private void writeBlockChain(int startBlock, int numBlocks) throws IOException {
int blocksToWrite = numBlocks - 1;
int blockNumber = startBlock + 1;
while (blocksToWrite > 0) {
int bbdBlocks = Math.min(blocksToWrite, (512 - this.bbdPos) / 4);
for (int i = 0; i < bbdBlocks; i++) {
IntegerHelper.getFourBytes(blockNumber, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
blockNumber++;
}
blocksToWrite -= bbdBlocks;
checkBbdPos();
}
IntegerHelper.getFourBytes(-2, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
}
private void writeAdditionalPropertySetBlockChains() throws IOException {
if (this.additionalPropertySets == null)
return;
int blockNumber = this.excelDataStartBlock + this.excelDataBlocks + 16;
for (Iterator i = this.additionalPropertySets.iterator(); i.hasNext(); ) {
ReadPropertyStorage rps = i.next();
if (rps.data.length > 4096) {
int numBlocks = getBigBlocksRequired(rps.data.length);
writeBlockChain(blockNumber, numBlocks);
blockNumber += numBlocks;
}
}
}
private void writeSmallBlockDepotChain() throws IOException {
if (this.sbdStartBlockChain == -2)
return;
byte[] smallBlockDepotChain = new byte[this.numSmallBlockDepotChainBlocks * 512];
int pos = 0;
int sbdBlockNumber = 1;
for (Iterator i = this.additionalPropertySets.iterator(); i.hasNext(); ) {
ReadPropertyStorage rps = i.next();
if (rps.data.length <= 4096 && rps.data.length != 0) {
int numSmallBlocks = getSmallBlocksRequired(rps.data.length);
for (int j = 0; j < numSmallBlocks - 1; j++) {
IntegerHelper.getFourBytes(sbdBlockNumber, smallBlockDepotChain, pos);
pos += 4;
sbdBlockNumber++;
}
IntegerHelper.getFourBytes(-2, smallBlockDepotChain, pos);
pos += 4;
sbdBlockNumber++;
}
}
this.out.write(smallBlockDepotChain);
}
private void writeSmallBlockDepot() throws IOException {
if (this.additionalPropertySets == null)
return;
byte[] smallBlockDepot = new byte[this.numSmallBlockDepotBlocks * 512];
int pos = 0;
for (Iterator i = this.additionalPropertySets.iterator(); i.hasNext(); ) {
ReadPropertyStorage rps = i.next();
if (rps.data.length <= 4096) {
int smallBlocks = getSmallBlocksRequired(rps.data.length);
int length = smallBlocks * 64;
System.arraycopy(rps.data, 0, smallBlockDepot, pos, rps.data.length);
pos += length;
}
}
this.out.write(smallBlockDepot);
}
private void writeBigBlockDepot() throws IOException {
this.bigBlockDepot = new byte[512];
this.bbdPos = 0;
for (int i = 0; i < this.numExtensionBlocks; i++) {
IntegerHelper.getFourBytes(-3, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
}
writeBlockChain(this.excelDataStartBlock, this.excelDataBlocks);
int summaryInfoBlock = this.excelDataStartBlock + this.excelDataBlocks + this.additionalPropertyBlocks;
int j;
for (j = summaryInfoBlock; j < summaryInfoBlock + 7; j++) {
IntegerHelper.getFourBytes(j + 1, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
}
IntegerHelper.getFourBytes(-2, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
for (j = summaryInfoBlock + 8; j < summaryInfoBlock + 15; j++) {
IntegerHelper.getFourBytes(j + 1, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
}
IntegerHelper.getFourBytes(-2, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
writeAdditionalPropertySetBlockChains();
if (this.sbdStartBlock != -2) {
writeBlockChain(this.sbdStartBlock, this.numSmallBlockDepotBlocks);
writeBlockChain(this.sbdStartBlockChain, this.numSmallBlockDepotChainBlocks);
}
for (j = 0; j < this.numBigBlockDepotBlocks; j++) {
IntegerHelper.getFourBytes(-3, this.bigBlockDepot, this.bbdPos);
this.bbdPos += 4;
checkBbdPos();
}
writeBlockChain(this.rootStartBlock, this.numRootEntryBlocks);
if (this.bbdPos != 0) {
for (j = this.bbdPos; j < 512; j++)
this.bigBlockDepot[j] = -1;
this.out.write(this.bigBlockDepot);
}
}
private int getBigBlocksRequired(int length) {
int blocks = length / 512;
return (length % 512 > 0) ? (blocks + 1) : blocks;
}
private int getSmallBlocksRequired(int length) {
int blocks = length / 64;
return (length % 64 > 0) ? (blocks + 1) : blocks;
}
private void writePropertySets() throws IOException {
byte[] propertySetStorage = new byte[512 * this.numRootEntryBlocks];
int pos = 0;
int[] mappings = null;
if (this.additionalPropertySets != null) {
mappings = new int[this.numPropertySets];
for (int j = 0; j < STANDARD_PROPERTY_SETS.length; j++) {
ReadPropertyStorage rps = (ReadPropertyStorage)this.standardPropertySets.get(STANDARD_PROPERTY_SETS[j]);
if (rps != null) {
mappings[rps.number] = j;
} else {
logger.warn("Standard property set " + STANDARD_PROPERTY_SETS[j] + " not present in source file");
}
}
int newMapping = STANDARD_PROPERTY_SETS.length;
for (Iterator iterator = this.additionalPropertySets.iterator(); iterator.hasNext(); ) {
ReadPropertyStorage rps = iterator.next();
mappings[rps.number] = newMapping;
newMapping++;
}
}
int child = 0;
int previous = 0;
int next = 0;
int size = 0;
if (this.additionalPropertySets != null) {
size += getBigBlocksRequired(this.requiredSize) * 512;
size += getBigBlocksRequired(4096) * 512;
size += getBigBlocksRequired(4096) * 512;
for (Iterator iterator = this.additionalPropertySets.iterator(); iterator.hasNext(); ) {
ReadPropertyStorage rps = iterator.next();
if (rps.propertyStorage.type != 1) {
if (rps.propertyStorage.size >= 4096) {
size += getBigBlocksRequired(rps.propertyStorage.size) * 512;
continue;
}
size += getSmallBlocksRequired(rps.propertyStorage.size) * 64;
}
}
}
BaseCompoundFile.PropertyStorage ps = new BaseCompoundFile.PropertyStorage(this, "Root Entry");
ps.setType(5);
ps.setStartBlock(this.sbdStartBlock);
ps.setSize(size);
ps.setPrevious(-1);
ps.setNext(-1);
ps.setColour(0);
child = 1;
if (this.additionalPropertySets != null) {
ReadPropertyStorage rps = (ReadPropertyStorage)this.standardPropertySets.get("Root Entry");
child = mappings[rps.propertyStorage.child];
}
ps.setChild(child);
System.arraycopy(ps.data, 0, propertySetStorage, pos, 128);
pos += 128;
ps = new BaseCompoundFile.PropertyStorage(this, "Workbook");
ps.setType(2);
ps.setStartBlock(this.excelDataStartBlock);
ps.setSize(this.requiredSize);
previous = 3;
next = -1;
if (this.additionalPropertySets != null) {
ReadPropertyStorage rps = (ReadPropertyStorage)this.standardPropertySets.get("Workbook");
previous = (rps.propertyStorage.previous != -1) ? mappings[rps.propertyStorage.previous] : -1;
next = (rps.propertyStorage.next != -1) ? mappings[rps.propertyStorage.next] : -1;
}
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(-1);
System.arraycopy(ps.data, 0, propertySetStorage, pos, 128);
pos += 128;
ps = new BaseCompoundFile.PropertyStorage(this, "\005SummaryInformation");
ps.setType(2);
ps.setStartBlock(this.excelDataStartBlock + this.excelDataBlocks);
ps.setSize(4096);
previous = 1;
next = 3;
if (this.additionalPropertySets != null) {
ReadPropertyStorage rps = (ReadPropertyStorage)this.standardPropertySets.get("\005SummaryInformation");
if (rps != null) {
previous = (rps.propertyStorage.previous != -1) ? mappings[rps.propertyStorage.previous] : -1;
next = (rps.propertyStorage.next != -1) ? mappings[rps.propertyStorage.next] : -1;
}
}
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(-1);
System.arraycopy(ps.data, 0, propertySetStorage, pos, 128);
pos += 128;
ps = new BaseCompoundFile.PropertyStorage(this, "\005DocumentSummaryInformation");
ps.setType(2);
ps.setStartBlock(this.excelDataStartBlock + this.excelDataBlocks + 8);
ps.setSize(4096);
ps.setPrevious(-1);
ps.setNext(-1);
ps.setChild(-1);
System.arraycopy(ps.data, 0, propertySetStorage, pos, 128);
pos += 128;
if (this.additionalPropertySets == null) {
this.out.write(propertySetStorage);
return;
}
int bigBlock = this.excelDataStartBlock + this.excelDataBlocks + 16;
int smallBlock = 0;
for (Iterator i = this.additionalPropertySets.iterator(); i.hasNext(); ) {
ReadPropertyStorage rps = i.next();
int block = (rps.data.length > 4096) ? bigBlock : smallBlock;
ps = new BaseCompoundFile.PropertyStorage(this, rps.propertyStorage.name);
ps.setType(rps.propertyStorage.type);
ps.setStartBlock(block);
ps.setSize(rps.propertyStorage.size);
previous = (rps.propertyStorage.previous != -1) ? mappings[rps.propertyStorage.previous] : -1;
next = (rps.propertyStorage.next != -1) ? mappings[rps.propertyStorage.next] : -1;
child = (rps.propertyStorage.child != -1) ? mappings[rps.propertyStorage.child] : -1;
ps.setPrevious(previous);
ps.setNext(next);
ps.setChild(child);
System.arraycopy(ps.data, 0, propertySetStorage, pos, 128);
pos += 128;
if (rps.data.length > 4096) {
bigBlock += getBigBlocksRequired(rps.data.length);
continue;
}
smallBlock += getSmallBlocksRequired(rps.data.length);
}
this.out.write(propertySetStorage);
}
}

View File

@@ -0,0 +1,7 @@
package jxl.write.biff;
public class CopyAdditionalPropertySetsException extends JxlWriteException {
public CopyAdditionalPropertySetsException() {
super(copyPropertySets);
}
}

View File

@@ -0,0 +1,31 @@
package jxl.write.biff;
import jxl.biff.CountryCode;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class CountryRecord extends WritableRecordData {
private int language;
private int regionalSettings;
public CountryRecord(CountryCode lang, CountryCode r) {
super(Type.COUNTRY);
this.language = lang.getValue();
this.regionalSettings = r.getValue();
}
public CountryRecord(jxl.read.biff.CountryRecord cr) {
super(Type.COUNTRY);
this.language = cr.getLanguageCode();
this.regionalSettings = cr.getRegionalSettingsCode();
}
public byte[] getData() {
byte[] data = new byte[4];
IntegerHelper.getTwoBytes(this.language, data, 0);
IntegerHelper.getTwoBytes(this.regionalSettings, data, 2);
return data;
}
}

View File

@@ -0,0 +1,50 @@
package jxl.write.biff;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DBCellRecord extends WritableRecordData {
private int rowPos;
private int cellOffset;
private ArrayList cellRowPositions;
private int position;
public DBCellRecord(int rp) {
super(Type.DBCELL);
this.rowPos = rp;
this.cellRowPositions = new ArrayList(10);
}
void setCellOffset(int pos) {
this.cellOffset = pos;
}
void addCellRowPosition(int pos) {
this.cellRowPositions.add(new Integer(pos));
}
void setPosition(int pos) {
this.position = pos;
}
protected byte[] getData() {
byte[] data = new byte[4 + 2 * this.cellRowPositions.size()];
IntegerHelper.getFourBytes(this.position - this.rowPos, data, 0);
int pos = 4;
int lastCellPos = this.cellOffset;
Iterator i = this.cellRowPositions.iterator();
while (i.hasNext()) {
int cellPos = ((Integer)i.next()).intValue();
IntegerHelper.getTwoBytes(cellPos - lastCellPos, data, pos);
lastCellPos = cellPos;
pos += 2;
}
return data;
}
}

View File

@@ -0,0 +1,17 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DSFRecord extends WritableRecordData {
private byte[] data;
public DSFRecord() {
super(Type.DSF);
this.data = new byte[] { 0, 0 };
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,92 @@
package jxl.write.biff;
import common.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.WorkbookSettings;
import jxl.biff.ByteData;
import jxl.read.biff.DataValiditySettingsRecord;
public class DataValidation {
private static final Logger logger = Logger.getLogger(DataValidation.class);
private DataValidityListRecord validityList;
private ArrayList validitySettings;
private int pos;
private WritableWorkbookImpl workbook;
private WorkbookSettings workbookSettings;
DataValidation(jxl.read.biff.DataValidation dv, WritableWorkbookImpl w, WorkbookSettings ws) {
this.workbook = w;
this.workbookSettings = ws;
this.validityList = new DataValidityListRecord(dv.getDataValidityList());
DataValiditySettingsRecord[] settings = dv.getDataValiditySettings();
this.validitySettings = new ArrayList(settings.length);
for (int i = 0; i < settings.length; i++)
this.validitySettings.add(new DataValiditySettingsRecord(settings[i], this.workbook, this.workbookSettings));
}
DataValidation(DataValidation dv, WritableWorkbookImpl w, WorkbookSettings ws) {
this.workbook = w;
this.workbookSettings = ws;
this.validityList = new DataValidityListRecord(dv.validityList);
this.validitySettings = new ArrayList(dv.validitySettings.size());
for (Iterator i = dv.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dvsr = i.next();
this.validitySettings.add(new DataValiditySettingsRecord(dvsr, this.workbook, this.workbookSettings));
}
}
public void write(File outputFile) throws IOException {
if (!this.validityList.hasDVRecords())
return;
outputFile.write((ByteData)this.validityList);
for (Iterator i = this.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dv = i.next();
outputFile.write((ByteData)dv);
}
}
public void insertRow(int row) {
for (Iterator i = this.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dv = i.next();
dv.insertRow(row);
}
}
public void removeRow(int row) {
for (Iterator i = this.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dv = i.next();
if (dv.getFirstRow() == row && dv.getLastRow() == row) {
i.remove();
this.validityList.dvRemoved();
continue;
}
dv.removeRow(row);
}
}
public void insertColumn(int col) {
for (Iterator i = this.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dv = i.next();
dv.insertColumn(col);
}
}
public void removeColumn(int col) {
for (Iterator i = this.validitySettings.iterator(); i.hasNext(); ) {
DataValiditySettingsRecord dv = i.next();
if (dv.getFirstColumn() == col && dv.getLastColumn() == col) {
i.remove();
this.validityList.dvRemoved();
continue;
}
dv.removeColumn(col);
}
}
}

View File

@@ -0,0 +1,40 @@
package jxl.write.biff;
import jxl.biff.DValParser;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DataValidityListRecord extends WritableRecordData {
private byte[] data;
private DValParser dvalParser;
DataValidityListRecord(jxl.read.biff.DataValidityListRecord dvlr) {
super(Type.DVAL);
this.data = dvlr.getData();
}
DataValidityListRecord(DataValidityListRecord dvlr) {
super(Type.DVAL);
this.data = new byte[dvlr.data.length];
System.arraycopy(dvlr.data, 0, this.data, 0, this.data.length);
}
public byte[] getData() {
if (this.dvalParser == null)
return this.data;
return this.dvalParser.getData();
}
void dvRemoved() {
if (this.dvalParser == null)
this.dvalParser = new DValParser(this.data);
this.dvalParser.dvRemoved();
}
public boolean hasDVRecords() {
if (this.dvalParser == null)
return true;
return (this.dvalParser.getNumberOfDVRecords() > 0);
}
}

View File

@@ -0,0 +1,99 @@
package jxl.write.biff;
import common.Logger;
import jxl.WorkbookSettings;
import jxl.biff.DVParser;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.biff.formula.FormulaException;
class DataValiditySettingsRecord extends WritableRecordData {
private static final Logger logger = Logger.getLogger(DataValiditySettingsRecord.class);
private byte[] data;
private DVParser dvParser;
private WritableWorkbookImpl workbook;
private WorkbookSettings workbookSettings;
DataValiditySettingsRecord(jxl.read.biff.DataValiditySettingsRecord dvsr, WritableWorkbookImpl w, WorkbookSettings ws) {
super(Type.DV);
this.workbook = w;
this.workbookSettings = ws;
this.data = dvsr.getData();
}
DataValiditySettingsRecord(DataValiditySettingsRecord dvsr, WritableWorkbookImpl w, WorkbookSettings ws) {
super(Type.DV);
this.workbook = w;
this.workbookSettings = ws;
this.data = new byte[dvsr.data.length];
System.arraycopy(dvsr.data, 0, this.data, 0, this.data.length);
}
private void initialize() {
try {
if (this.dvParser == null)
this.dvParser = new DVParser(this.data, this.workbook, this.workbook, this.workbookSettings);
} catch (FormulaException e) {
logger.warn("Cannot read drop down range " + e.getMessage());
e.printStackTrace();
}
}
public byte[] getData() {
if (this.dvParser == null)
return this.data;
return this.dvParser.getData();
}
public void insertRow(int row) {
if (this.dvParser == null)
initialize();
this.dvParser.insertRow(row);
}
public void removeRow(int row) {
if (this.dvParser == null)
initialize();
this.dvParser.removeRow(row);
}
public void insertColumn(int col) {
if (this.dvParser == null)
initialize();
this.dvParser.insertColumn(col);
}
public void removeColumn(int col) {
if (this.dvParser == null)
initialize();
this.dvParser.removeColumn(col);
}
public int getFirstColumn() {
if (this.dvParser == null)
initialize();
return this.dvParser.getFirstColumn();
}
public int getLastColumn() {
if (this.dvParser == null)
initialize();
return this.dvParser.getLastColumn();
}
public int getFirstRow() {
if (this.dvParser == null)
initialize();
return this.dvParser.getFirstRow();
}
public int getLastRow() {
if (this.dvParser == null)
initialize();
return this.dvParser.getLastRow();
}
}

View File

@@ -0,0 +1,12 @@
package jxl.write.biff;
import jxl.biff.FormatRecord;
public class DateFormatRecord extends FormatRecord {
protected DateFormatRecord(String fmt) {
String fs = fmt;
fs = replace(fs, "a", "AM/PM");
fs = replace(fs, "S", "0");
setFormatString(fs);
}
}

View File

@@ -0,0 +1,131 @@
package jxl.write.biff;
import common.Logger;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;
import jxl.biff.DoubleHelper;
import jxl.biff.Type;
import jxl.format.CellFormat;
import jxl.write.DateFormats;
import jxl.write.WritableCellFormat;
public abstract class DateRecord extends CellValue {
private static Logger logger = Logger.getLogger(DateRecord.class);
private double value;
private Date date;
private boolean time;
private static final int utcOffsetDays = 25569;
private static final long msInADay = 86400000L;
static final WritableCellFormat defaultDateFormat = new WritableCellFormat(DateFormats.DEFAULT);
private static final int nonLeapDay = 61;
protected static final class GMTDate {}
protected DateRecord(int c, int r, Date d) {
this(c, r, d, (CellFormat)defaultDateFormat, true);
}
protected DateRecord(int c, int r, Date d, GMTDate a) {
this(c, r, d, (CellFormat)defaultDateFormat, false);
}
protected DateRecord(int c, int r, Date d, CellFormat st) {
super(Type.NUMBER, c, r, st);
this.date = d;
calculateValue(true);
}
protected DateRecord(int c, int r, Date d, CellFormat st, GMTDate a) {
super(Type.NUMBER, c, r, st);
this.date = d;
calculateValue(false);
}
protected DateRecord(int c, int r, Date d, CellFormat st, boolean tim) {
super(Type.NUMBER, c, r, st);
this.date = d;
this.time = tim;
calculateValue(false);
}
protected DateRecord(DateCell dc) {
super(Type.NUMBER, (Cell)dc);
this.date = dc.getDate();
this.time = dc.isTime();
calculateValue(false);
}
protected DateRecord(int c, int r, DateRecord dr) {
super(Type.NUMBER, c, r, dr);
this.value = dr.value;
this.time = dr.time;
this.date = dr.date;
}
private void calculateValue(boolean adjust) {
long zoneOffset = 0L;
long dstOffset = 0L;
if (adjust) {
Calendar cal = Calendar.getInstance();
cal.setTime(this.date);
zoneOffset = cal.get(15);
dstOffset = cal.get(16);
}
long utcValue = this.date.getTime() + zoneOffset + dstOffset;
double utcDays = utcValue / 8.64E7D;
this.value = utcDays + 25569.0D;
if (!this.time && this.value < 61.0D)
this.value--;
if (this.time)
this.value -= (int)this.value;
}
public CellType getType() {
return CellType.DATE;
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] data = new byte[celldata.length + 8];
System.arraycopy(celldata, 0, data, 0, celldata.length);
DoubleHelper.getIEEEBytes(this.value, data, celldata.length);
return data;
}
public String getContents() {
return this.date.toString();
}
protected void setDate(Date d) {
this.date = d;
calculateValue(true);
}
protected void setDate(Date d, GMTDate a) {
this.date = d;
calculateValue(false);
}
public Date getDate() {
return this.date;
}
public boolean isTime() {
return this.time;
}
public DateFormat getDateFormat() {
return null;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DefaultColumnWidth extends WritableRecordData {
private int width;
private byte[] data;
public DefaultColumnWidth(int w) {
super(Type.DEFCOLWIDTH);
this.width = w;
this.data = new byte[2];
IntegerHelper.getTwoBytes(this.width, this.data, 0);
}
protected byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,27 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DefaultRowHeightRecord extends WritableRecordData {
private byte[] data;
private int rowHeight;
private boolean changed;
public DefaultRowHeightRecord(int h, boolean ch) {
super(Type.DEFAULTROWHEIGHT);
this.data = new byte[4];
this.rowHeight = h;
this.changed = ch;
}
public byte[] getData() {
if (this.changed)
this.data[0] = (byte)(this.data[0] | 0x1);
IntegerHelper.getTwoBytes(this.rowHeight, this.data, 2);
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.DoubleHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DeltaRecord extends WritableRecordData {
private byte[] data;
private double iterationValue;
public DeltaRecord(double itval) {
super(Type.DELTA);
this.iterationValue = itval;
this.data = new byte[8];
}
public byte[] getData() {
DoubleHelper.getIEEEBytes(this.iterationValue, this.data, 0);
return this.data;
}
}

View File

@@ -0,0 +1,26 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class DimensionRecord extends WritableRecordData {
private int numRows;
private int numCols;
private byte[] data;
public DimensionRecord(int r, int c) {
super(Type.DIMENSION);
this.numRows = r;
this.numCols = c;
this.data = new byte[14];
IntegerHelper.getFourBytes(this.numRows, this.data, 4);
IntegerHelper.getTwoBytes(this.numCols, this.data, 10);
}
protected byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,14 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class EOFRecord extends WritableRecordData {
public EOFRecord() {
super(Type.EOF);
}
public byte[] getData() {
return new byte[0];
}
}

View File

@@ -0,0 +1,53 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ExtendedSSTRecord extends WritableRecordData {
private static final int infoRecordSize = 8;
private int numberOfStrings;
private int[] absoluteStreamPositions;
private int[] relativeStreamPositions;
private int currentStringIndex = 0;
public ExtendedSSTRecord(int newNumberOfStrings) {
super(Type.EXTSST);
this.numberOfStrings = newNumberOfStrings;
int numberOfBuckets = getNumberOfBuckets();
this.absoluteStreamPositions = new int[numberOfBuckets];
this.relativeStreamPositions = new int[numberOfBuckets];
this.currentStringIndex = 0;
}
public int getNumberOfBuckets() {
int numberOfStringsPerBucket = getNumberOfStringsPerBucket();
return (numberOfStringsPerBucket != 0) ? ((this.numberOfStrings + numberOfStringsPerBucket - 1) / numberOfStringsPerBucket) : 0;
}
public int getNumberOfStringsPerBucket() {
int bucketLimit = 128;
return (this.numberOfStrings + 128 - 1) / 128;
}
public void addString(int absoluteStreamPosition, int relativeStreamPosition) {
this.absoluteStreamPositions[this.currentStringIndex] = absoluteStreamPosition + relativeStreamPosition;
this.relativeStreamPositions[this.currentStringIndex] = relativeStreamPosition;
this.currentStringIndex++;
}
public byte[] getData() {
int numberOfBuckets = getNumberOfBuckets();
byte[] data = new byte[2 + 8 * numberOfBuckets];
IntegerHelper.getTwoBytes(getNumberOfStringsPerBucket(), data, 0);
for (int i = 0; i < numberOfBuckets; i++) {
IntegerHelper.getFourBytes(this.absoluteStreamPositions[i], data, 2 + i * 8);
IntegerHelper.getTwoBytes(this.relativeStreamPositions[i], data, 6 + i * 8);
}
return data;
}
}

View File

@@ -0,0 +1,126 @@
package jxl.write.biff;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ExternalSheetRecord extends WritableRecordData {
private byte[] data;
private ArrayList xtis;
private static class XTI {
int supbookIndex;
int firstTab;
int lastTab;
XTI(int s, int f, int l) {
this.supbookIndex = s;
this.firstTab = f;
this.lastTab = l;
}
void sheetInserted(int index) {
if (this.firstTab >= index)
this.firstTab++;
if (this.lastTab >= index)
this.lastTab++;
}
void sheetRemoved(int index) {
if (this.firstTab == index)
this.firstTab = 0;
if (this.lastTab == index)
this.lastTab = 0;
if (this.firstTab > index)
this.firstTab--;
if (this.lastTab > index)
this.lastTab--;
}
}
public ExternalSheetRecord(jxl.read.biff.ExternalSheetRecord esf) {
super(Type.EXTERNSHEET);
this.xtis = new ArrayList(esf.getNumRecords());
XTI xti = null;
for (int i = 0; i < esf.getNumRecords(); i++) {
xti = new XTI(esf.getSupbookIndex(i), esf.getFirstTabIndex(i), esf.getLastTabIndex(i));
this.xtis.add(xti);
}
}
public ExternalSheetRecord() {
super(Type.EXTERNSHEET);
this.xtis = new ArrayList();
}
int getIndex(int supbookind, int sheetind) {
Iterator i = this.xtis.iterator();
XTI xti = null;
boolean found = false;
int pos = 0;
while (i.hasNext() && !found) {
xti = i.next();
if (xti.supbookIndex == supbookind && xti.firstTab == sheetind) {
found = true;
continue;
}
pos++;
}
if (!found) {
xti = new XTI(supbookind, sheetind, sheetind);
this.xtis.add(xti);
pos = this.xtis.size() - 1;
}
return pos;
}
public byte[] getData() {
byte[] data = new byte[2 + this.xtis.size() * 6];
int pos = 0;
IntegerHelper.getTwoBytes(this.xtis.size(), data, 0);
pos += 2;
Iterator i = this.xtis.iterator();
XTI xti = null;
while (i.hasNext()) {
xti = i.next();
IntegerHelper.getTwoBytes(xti.supbookIndex, data, pos);
IntegerHelper.getTwoBytes(xti.firstTab, data, pos + 2);
IntegerHelper.getTwoBytes(xti.lastTab, data, pos + 4);
pos += 6;
}
return data;
}
public int getSupbookIndex(int index) {
return ((XTI)this.xtis.get(index)).supbookIndex;
}
public int getFirstTabIndex(int index) {
return ((XTI)this.xtis.get(index)).firstTab;
}
public int getLastTabIndex(int index) {
return ((XTI)this.xtis.get(index)).lastTab;
}
void sheetInserted(int index) {
XTI xti = null;
for (Iterator i = this.xtis.iterator(); i.hasNext(); ) {
xti = i.next();
xti.sheetInserted(index);
}
}
void sheetRemoved(int index) {
XTI xti = null;
for (Iterator i = this.xtis.iterator(); i.hasNext(); ) {
xti = i.next();
xti.sheetRemoved(index);
}
}
}

View File

@@ -0,0 +1,79 @@
package jxl.write.biff;
import common.Logger;
import java.io.IOException;
import java.io.OutputStream;
import jxl.WorkbookSettings;
import jxl.biff.ByteData;
import jxl.read.biff.CompoundFile;
public final class File {
private static Logger logger = Logger.getLogger(File.class);
private byte[] data;
private int pos;
private OutputStream outputStream;
private int initialFileSize;
private int arrayGrowSize;
private WorkbookSettings workbookSettings;
CompoundFile readCompoundFile;
File(OutputStream os, WorkbookSettings ws, CompoundFile rcf) {
this.initialFileSize = ws.getInitialFileSize();
this.arrayGrowSize = ws.getArrayGrowSize();
this.data = new byte[this.initialFileSize];
this.pos = 0;
this.outputStream = os;
this.workbookSettings = ws;
this.readCompoundFile = rcf;
}
void close(boolean cs) throws IOException, JxlWriteException {
CompoundFile cf = new CompoundFile(this.data, this.pos, this.outputStream, this.readCompoundFile);
cf.write();
this.outputStream.flush();
if (cs)
this.outputStream.close();
this.data = null;
if (!this.workbookSettings.getGCDisabled())
System.gc();
}
public void write(ByteData record) throws IOException {
try {
byte[] bytes = record.getBytes();
while (this.pos + bytes.length > this.data.length) {
byte[] newdata = new byte[this.data.length + this.arrayGrowSize];
System.arraycopy(this.data, 0, newdata, 0, this.pos);
this.data = newdata;
}
System.arraycopy(bytes, 0, this.data, this.pos, bytes.length);
this.pos += bytes.length;
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException(t);
}
}
int getPos() {
return this.pos;
}
void setData(byte[] newdata, int pos) {
System.arraycopy(newdata, 0, this.data, pos, newdata.length);
}
public void setOutputFile(OutputStream os) {
if (this.data != null)
logger.warn("Rewriting a workbook with non-empty data");
this.outputStream = os;
this.data = new byte[this.initialFileSize];
this.pos = 0;
}
}

View File

@@ -0,0 +1,34 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class FooterRecord extends WritableRecordData {
private byte[] data;
private String footer;
public FooterRecord(String s) {
super(Type.FOOTER);
this.footer = s;
}
public FooterRecord(FooterRecord fr) {
super(Type.FOOTER);
this.footer = fr.footer;
}
public byte[] getData() {
if (this.footer == null || this.footer.length() == 0) {
this.data = new byte[0];
return this.data;
}
this.data = new byte[this.footer.length() * 2 + 3];
IntegerHelper.getTwoBytes(this.footer.length(), this.data, 0);
this.data[2] = 1;
StringHelper.getUnicodeBytes(this.footer, this.data, 3);
return this.data;
}
}

View File

@@ -0,0 +1,168 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.Cell;
import jxl.CellReferenceHelper;
import jxl.CellType;
import jxl.Sheet;
import jxl.WorkbookSettings;
import jxl.biff.FormattingRecords;
import jxl.biff.FormulaData;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WorkbookMethods;
import jxl.biff.formula.ExternalSheet;
import jxl.biff.formula.FormulaException;
import jxl.biff.formula.FormulaParser;
import jxl.format.CellFormat;
import jxl.write.WritableCell;
public class FormulaRecord extends CellValue implements FormulaData {
private static Logger logger = Logger.getLogger(FormulaRecord.class);
private String formulaToParse;
private FormulaParser parser;
private String formulaString;
private byte[] formulaBytes;
private CellValue copiedFrom;
public FormulaRecord(int c, int r, String f) {
super(Type.FORMULA2, c, r);
this.formulaToParse = f;
this.copiedFrom = null;
}
public FormulaRecord(int c, int r, String f, CellFormat st) {
super(Type.FORMULA, c, r, st);
this.formulaToParse = f;
this.copiedFrom = null;
}
protected FormulaRecord(int c, int r, FormulaRecord fr) {
super(Type.FORMULA, c, r, fr);
this.copiedFrom = fr;
this.formulaBytes = new byte[fr.formulaBytes.length];
System.arraycopy(fr.formulaBytes, 0, this.formulaBytes, 0, this.formulaBytes.length);
}
protected FormulaRecord(int c, int r, ReadFormulaRecord rfr) {
super(Type.FORMULA, c, r, rfr);
try {
this.copiedFrom = rfr;
byte[] readFormulaData = rfr.getFormulaData();
this.formulaBytes = new byte[readFormulaData.length - 16];
System.arraycopy(readFormulaData, 16, this.formulaBytes, 0, this.formulaBytes.length);
} catch (FormulaException e) {
logger.error("", (Throwable)e);
}
}
private void initialize(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) {
if (this.copiedFrom != null) {
initializeCopiedFormula(ws, es, nt);
return;
}
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
try {
this.parser.parse();
this.formulaString = this.parser.getFormula();
this.formulaBytes = this.parser.getBytes();
} catch (FormulaException e) {
logger.warn(e.getMessage() + " when parsing formula " + this.formulaToParse + " in cell " + getSheet().getName() + "!" + CellReferenceHelper.getCellReference(getColumn(), getRow()));
try {
this.formulaToParse = "ERROR(1)";
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
this.parser.parse();
this.formulaString = this.parser.getFormula();
this.formulaBytes = this.parser.getBytes();
} catch (FormulaException e2) {
logger.error("", (Throwable)e2);
}
}
}
private void initializeCopiedFormula(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) {
try {
this.parser = new FormulaParser(this.formulaBytes, (Cell)this, es, nt, ws);
this.parser.parse();
this.parser.adjustRelativeCellReferences(getColumn() - this.copiedFrom.getColumn(), getRow() - this.copiedFrom.getRow());
this.formulaString = this.parser.getFormula();
this.formulaBytes = this.parser.getBytes();
} catch (FormulaException e) {
try {
this.formulaToParse = "ERROR(1)";
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
this.parser.parse();
this.formulaString = this.parser.getFormula();
this.formulaBytes = this.parser.getBytes();
} catch (FormulaException e2) {
logger.error("", (Throwable)e2);
}
}
}
void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) {
super.setCellDetails(fr, ss, s);
initialize(s.getWorkbookSettings(), s.getWorkbook(), s.getWorkbook());
s.getWorkbook().addRCIRCell(this);
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] formulaData = getFormulaData();
byte[] data = new byte[formulaData.length + celldata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(formulaData, 0, data, celldata.length, formulaData.length);
return data;
}
public CellType getType() {
return CellType.ERROR;
}
public String getContents() {
return this.formulaString;
}
public byte[] getFormulaData() {
byte[] data = new byte[this.formulaBytes.length + 16];
System.arraycopy(this.formulaBytes, 0, data, 16, this.formulaBytes.length);
data[6] = 16;
data[7] = 64;
data[12] = -32;
data[13] = -4;
data[8] = (byte)(data[8] | 0x2);
IntegerHelper.getTwoBytes(this.formulaBytes.length, data, 14);
return data;
}
public WritableCell copyTo(int col, int row) {
Assert.verify(false);
return null;
}
void columnInserted(Sheet s, int sheetIndex, int col) {
this.parser.columnInserted(sheetIndex, col, (s == getSheet()));
this.formulaBytes = this.parser.getBytes();
}
void columnRemoved(Sheet s, int sheetIndex, int col) {
this.parser.columnRemoved(sheetIndex, col, (s == getSheet()));
this.formulaBytes = this.parser.getBytes();
}
void rowInserted(Sheet s, int sheetIndex, int row) {
this.parser.rowInserted(sheetIndex, row, (s == getSheet()));
this.formulaBytes = this.parser.getBytes();
}
void rowRemoved(Sheet s, int sheetIndex, int row) {
this.parser.rowRemoved(sheetIndex, row, (s == getSheet()));
this.formulaBytes = this.parser.getBytes();
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class FunctionGroupCountRecord extends WritableRecordData {
private byte[] data;
private int numFunctionGroups;
public FunctionGroupCountRecord() {
super(Type.FNGROUPCOUNT);
this.numFunctionGroups = 14;
this.data = new byte[2];
IntegerHelper.getTwoBytes(this.numFunctionGroups, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class GridSetRecord extends WritableRecordData {
private byte[] data;
private boolean gridSet;
public GridSetRecord(boolean gs) {
super(Type.GRIDSET);
this.gridSet = gs;
this.data = new byte[2];
if (this.gridSet)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,30 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class GuttersRecord extends WritableRecordData {
private byte[] data;
private int rowGutter;
private int colGutter;
private int maxRowOutline;
private int maxColOutline;
public GuttersRecord() {
super(Type.GUTS);
}
public byte[] getData() {
this.data = new byte[8];
IntegerHelper.getTwoBytes(this.rowGutter, this.data, 0);
IntegerHelper.getTwoBytes(this.colGutter, this.data, 2);
IntegerHelper.getTwoBytes(this.maxRowOutline, this.data, 4);
IntegerHelper.getTwoBytes(this.maxColOutline, this.data, 6);
return this.data;
}
}

View File

@@ -0,0 +1,34 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class HeaderRecord extends WritableRecordData {
private byte[] data;
private String header;
public HeaderRecord(String h) {
super(Type.HEADER);
this.header = h;
}
public HeaderRecord(HeaderRecord hr) {
super(Type.HEADER);
this.header = hr.header;
}
public byte[] getData() {
if (this.header == null || this.header.length() == 0) {
this.data = new byte[0];
return this.data;
}
this.data = new byte[this.header.length() * 2 + 3];
IntegerHelper.getTwoBytes(this.header.length(), this.data, 0);
this.data[2] = 1;
StringHelper.getUnicodeBytes(this.header, this.data, 3);
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class HideobjRecord extends WritableRecordData {
private boolean hideAll;
private byte[] data;
public HideobjRecord(boolean hide) {
super(Type.HIDEOBJ);
this.hideAll = hide;
this.data = new byte[2];
if (this.hideAll)
IntegerHelper.getTwoBytes(2, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class HorizontalCentreRecord extends WritableRecordData {
private byte[] data;
private boolean centre;
public HorizontalCentreRecord(boolean ce) {
super(Type.HCENTER);
this.centre = ce;
this.data = new byte[2];
if (this.centre)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,26 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class HorizontalPageBreaksRecord extends WritableRecordData {
private int[] rowBreaks;
public HorizontalPageBreaksRecord(int[] breaks) {
super(Type.HORIZONTALPAGEBREAKS);
this.rowBreaks = breaks;
}
public byte[] getData() {
byte[] data = new byte[this.rowBreaks.length * 6 + 2];
IntegerHelper.getTwoBytes(this.rowBreaks.length, data, 0);
int pos = 2;
for (int i = 0; i < this.rowBreaks.length; i++) {
IntegerHelper.getTwoBytes(this.rowBreaks[i], data, pos);
IntegerHelper.getTwoBytes(255, data, pos + 4);
pos += 6;
}
return data;
}
}

View File

@@ -0,0 +1,558 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import jxl.CellType;
import jxl.Hyperlink;
import jxl.Range;
import jxl.Sheet;
import jxl.biff.CellReferenceHelper;
import jxl.biff.IntegerHelper;
import jxl.biff.SheetRangeImpl;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableSheet;
public class HyperlinkRecord extends WritableRecordData {
private static Logger logger = Logger.getLogger(HyperlinkRecord.class);
private int firstRow;
private int lastRow;
private int firstColumn;
private int lastColumn;
private URL url;
private File file;
private String location;
private String contents;
private LinkType linkType;
private byte[] data;
private Range range;
private WritableSheet sheet;
private boolean modified;
private static class LinkType {
private LinkType() {}
}
private static final LinkType urlLink = new LinkType();
private static final LinkType fileLink = new LinkType();
private static final LinkType uncLink = new LinkType();
private static final LinkType workbookLink = new LinkType();
private static final LinkType unknown = new LinkType();
protected HyperlinkRecord(Hyperlink h, WritableSheet s) {
super(Type.HLINK);
Assert.verify(h instanceof jxl.read.biff.HyperlinkRecord);
jxl.read.biff.HyperlinkRecord hl = (jxl.read.biff.HyperlinkRecord)h;
this.data = hl.getRecord().getData();
this.sheet = s;
this.firstRow = hl.getRow();
this.firstColumn = hl.getColumn();
this.lastRow = hl.getLastRow();
this.lastColumn = hl.getLastColumn();
this.range = (Range)new SheetRangeImpl((Sheet)s, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
this.linkType = unknown;
if (hl.isFile()) {
this.linkType = fileLink;
this.file = hl.getFile();
} else if (hl.isURL()) {
this.linkType = urlLink;
this.url = hl.getURL();
} else if (hl.isLocation()) {
this.linkType = workbookLink;
this.location = hl.getLocation();
}
this.modified = false;
}
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, URL url, String desc) {
super(Type.HLINK);
this.firstColumn = col;
this.firstRow = row;
this.lastColumn = Math.max(this.firstColumn, lastcol);
this.lastRow = Math.max(this.firstRow, lastrow);
this.url = url;
this.contents = desc;
this.linkType = urlLink;
this.modified = true;
}
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, File file, String desc) {
super(Type.HLINK);
this.firstColumn = col;
this.firstRow = row;
this.lastColumn = Math.max(this.firstColumn, lastcol);
this.lastRow = Math.max(this.firstRow, lastrow);
this.contents = desc;
this.file = file;
if (file.getPath().startsWith("\\\\")) {
this.linkType = uncLink;
} else {
this.linkType = fileLink;
}
this.modified = true;
}
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, String desc, WritableSheet s, int destcol, int destrow, int lastdestcol, int lastdestrow) {
super(Type.HLINK);
this.firstColumn = col;
this.firstRow = row;
this.lastColumn = Math.max(this.firstColumn, lastcol);
this.lastRow = Math.max(this.firstRow, lastrow);
setLocation(s, destcol, destrow, lastdestcol, lastdestrow);
this.contents = desc;
this.linkType = workbookLink;
this.modified = true;
}
public boolean isFile() {
return (this.linkType == fileLink);
}
public boolean isUNC() {
return (this.linkType == uncLink);
}
public boolean isURL() {
return (this.linkType == urlLink);
}
public boolean isLocation() {
return (this.linkType == workbookLink);
}
public int getRow() {
return this.firstRow;
}
public int getColumn() {
return this.firstColumn;
}
public int getLastRow() {
return this.lastRow;
}
public int getLastColumn() {
return this.lastColumn;
}
public URL getURL() {
return this.url;
}
public File getFile() {
return this.file;
}
public byte[] getData() {
if (!this.modified)
return this.data;
byte[] commonData = new byte[32];
IntegerHelper.getTwoBytes(this.firstRow, commonData, 0);
IntegerHelper.getTwoBytes(this.lastRow, commonData, 2);
IntegerHelper.getTwoBytes(this.firstColumn, commonData, 4);
IntegerHelper.getTwoBytes(this.lastColumn, commonData, 6);
commonData[8] = -48;
commonData[9] = -55;
commonData[10] = -22;
commonData[11] = 121;
commonData[12] = -7;
commonData[13] = -70;
commonData[14] = -50;
commonData[15] = 17;
commonData[16] = -116;
commonData[17] = -126;
commonData[18] = 0;
commonData[19] = -86;
commonData[20] = 0;
commonData[21] = 75;
commonData[22] = -87;
commonData[23] = 11;
commonData[24] = 2;
commonData[25] = 0;
commonData[26] = 0;
commonData[27] = 0;
int optionFlags = 0;
if (isURL()) {
optionFlags = 3;
if (this.contents != null)
optionFlags |= 0x14;
} else if (isFile()) {
optionFlags = 3;
if (this.contents == null)
optionFlags |= 0x14;
} else if (isLocation()) {
optionFlags = 8;
} else if (isUNC()) {
optionFlags = 259;
}
IntegerHelper.getFourBytes(optionFlags, commonData, 28);
if (isURL()) {
this.data = getURLData(commonData);
} else if (isFile()) {
this.data = getFileData(commonData);
} else if (isLocation()) {
this.data = getLocationData(commonData);
} else if (isUNC()) {
this.data = getUNCData(commonData);
}
return this.data;
}
public String toString() {
if (isFile())
return this.file.toString();
if (isURL())
return this.url.toString();
if (isUNC())
return this.file.toString();
return "";
}
public Range getRange() {
return this.range;
}
public void setURL(URL url) {
this.linkType = urlLink;
this.file = null;
this.location = null;
this.contents = null;
this.url = url;
this.modified = true;
if (this.sheet == null)
return;
WritableCell wc = this.sheet.getWritableCell(this.firstColumn, this.firstRow);
Assert.verify((wc.getType() == CellType.LABEL));
Label l = (Label)wc;
l.setString(url.toString());
}
public void setFile(File file) {
this.linkType = fileLink;
this.url = null;
this.location = null;
this.contents = null;
this.file = file;
this.modified = true;
if (this.sheet == null)
return;
WritableCell wc = this.sheet.getWritableCell(this.firstColumn, this.firstRow);
Assert.verify((wc.getType() == CellType.LABEL));
Label l = (Label)wc;
l.setString(file.toString());
}
protected void setLocation(String desc, WritableSheet sheet, int destcol, int destrow, int lastdestcol, int lastdestrow) {
this.linkType = workbookLink;
this.url = null;
this.file = null;
this.modified = true;
this.contents = desc;
setLocation(sheet, destcol, destrow, lastdestcol, lastdestrow);
if (sheet == null)
return;
WritableCell wc = sheet.getWritableCell(this.firstColumn, this.firstRow);
Assert.verify((wc.getType() == CellType.LABEL));
Label l = (Label)wc;
l.setString(desc);
}
private void setLocation(WritableSheet sheet, int destcol, int destrow, int lastdestcol, int lastdestrow) {
StringBuffer sb = new StringBuffer();
sb.append('\'');
if (sheet.getName().indexOf('\'') == -1) {
sb.append(sheet.getName());
} else {
String sheetName = sheet.getName();
int pos = 0;
int nextPos = sheetName.indexOf('\'', pos);
while (nextPos != -1 && pos < sheetName.length()) {
sb.append(sheetName.substring(pos, nextPos));
sb.append("''");
pos = nextPos + 1;
nextPos = sheetName.indexOf('\'', pos);
}
sb.append(sheetName.substring(pos));
}
sb.append('\'');
sb.append('!');
lastdestcol = Math.max(destcol, lastdestcol);
lastdestrow = Math.max(destrow, lastdestrow);
CellReferenceHelper.getCellReference(destcol, destrow, sb);
sb.append(':');
CellReferenceHelper.getCellReference(lastdestcol, lastdestrow, sb);
this.location = sb.toString();
}
void insertRow(int r) {
Assert.verify((this.sheet != null && this.range != null));
if (r > this.lastRow)
return;
if (r <= this.firstRow) {
this.firstRow++;
this.modified = true;
}
if (r <= this.lastRow) {
this.lastRow++;
this.modified = true;
}
if (this.modified)
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
}
void insertColumn(int c) {
Assert.verify((this.sheet != null && this.range != null));
if (c > this.lastColumn)
return;
if (c <= this.firstColumn) {
this.firstColumn++;
this.modified = true;
}
if (c <= this.lastColumn) {
this.lastColumn++;
this.modified = true;
}
if (this.modified)
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
}
void removeRow(int r) {
Assert.verify((this.sheet != null && this.range != null));
if (r > this.lastRow)
return;
if (r < this.firstRow) {
this.firstRow--;
this.modified = true;
}
if (r < this.lastRow) {
this.lastRow--;
this.modified = true;
}
if (this.modified) {
Assert.verify((this.range != null));
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
}
}
void removeColumn(int c) {
Assert.verify((this.sheet != null && this.range != null));
if (c > this.lastColumn)
return;
if (c < this.firstColumn) {
this.firstColumn--;
this.modified = true;
}
if (c < this.lastColumn) {
this.lastColumn--;
this.modified = true;
}
if (this.modified) {
Assert.verify((this.range != null));
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
}
}
private byte[] getURLData(byte[] cd) {
String urlString = this.url.toString();
int dataLength = cd.length + 20 + (urlString.length() + 1) * 2;
if (this.contents != null)
dataLength += 4 + (this.contents.length() + 1) * 2;
byte[] d = new byte[dataLength];
System.arraycopy(cd, 0, d, 0, cd.length);
int urlPos = cd.length;
if (this.contents != null) {
IntegerHelper.getFourBytes(this.contents.length() + 1, d, urlPos);
StringHelper.getUnicodeBytes(this.contents, d, urlPos + 4);
urlPos += (this.contents.length() + 1) * 2 + 4;
}
d[urlPos] = -32;
d[urlPos + 1] = -55;
d[urlPos + 2] = -22;
d[urlPos + 3] = 121;
d[urlPos + 4] = -7;
d[urlPos + 5] = -70;
d[urlPos + 6] = -50;
d[urlPos + 7] = 17;
d[urlPos + 8] = -116;
d[urlPos + 9] = -126;
d[urlPos + 10] = 0;
d[urlPos + 11] = -86;
d[urlPos + 12] = 0;
d[urlPos + 13] = 75;
d[urlPos + 14] = -87;
d[urlPos + 15] = 11;
IntegerHelper.getFourBytes((urlString.length() + 1) * 2, d, urlPos + 16);
StringHelper.getUnicodeBytes(urlString, d, urlPos + 20);
return d;
}
private byte[] getUNCData(byte[] cd) {
String uncString = this.file.getPath();
byte[] d = new byte[cd.length + uncString.length() * 2 + 2 + 4];
System.arraycopy(cd, 0, d, 0, cd.length);
int urlPos = cd.length;
int length = uncString.length() + 1;
IntegerHelper.getFourBytes(length, d, urlPos);
StringHelper.getUnicodeBytes(uncString, d, urlPos + 4);
return d;
}
private byte[] getFileData(byte[] cd) {
ArrayList path = new ArrayList();
ArrayList shortFileName = new ArrayList();
path.add(this.file.getName());
shortFileName.add(getShortName(this.file.getName()));
File parent = this.file.getParentFile();
while (parent != null) {
path.add(parent.getName());
shortFileName.add(getShortName(parent.getName()));
parent = parent.getParentFile();
}
int upLevelCount = 0;
int pos = path.size() - 1;
boolean upDir = true;
while (upDir) {
String s = path.get(pos);
if (s.equals("..")) {
upLevelCount++;
path.remove(pos);
shortFileName.remove(pos);
} else {
upDir = false;
}
pos--;
}
StringBuffer filePathSB = new StringBuffer();
StringBuffer shortFilePathSB = new StringBuffer();
if (this.file.getPath().charAt(1) == ':') {
char driveLetter = this.file.getPath().charAt(0);
if (driveLetter != 'C' && driveLetter != 'c') {
filePathSB.append(driveLetter);
filePathSB.append(':');
shortFilePathSB.append(driveLetter);
shortFilePathSB.append(':');
}
}
for (int i = path.size() - 1; i >= 0; i--) {
filePathSB.append(path.get(i));
shortFilePathSB.append(shortFileName.get(i));
if (i != 0) {
filePathSB.append("\\");
shortFilePathSB.append("\\");
}
}
String filePath = filePathSB.toString();
String shortFilePath = shortFilePathSB.toString();
int dataLength = cd.length + 4 + (shortFilePath.length() + 1) * 2 + 16 + 2 + 4 + filePath.length() + 1 + 4 + 24;
if (this.contents != null)
dataLength += 4 + (this.contents.length() + 1) * 2;
byte[] d = new byte[dataLength];
System.arraycopy(cd, 0, d, 0, cd.length);
int filePos = cd.length;
if (this.contents != null) {
IntegerHelper.getFourBytes(this.contents.length() + 1, d, filePos);
StringHelper.getUnicodeBytes(this.contents, d, filePos + 4);
filePos += (this.contents.length() + 1) * 2 + 4;
}
int curPos = filePos;
IntegerHelper.getFourBytes(shortFilePath.length() + 1, d, curPos);
StringHelper.getUnicodeBytes(shortFilePath, d, curPos + 4);
curPos += 4 + (shortFilePath.length() + 1) * 2;
d[curPos] = 3;
d[curPos + 1] = 3;
d[curPos + 2] = 0;
d[curPos + 3] = 0;
d[curPos + 4] = 0;
d[curPos + 5] = 0;
d[curPos + 6] = 0;
d[curPos + 7] = 0;
d[curPos + 8] = -64;
d[curPos + 9] = 0;
d[curPos + 10] = 0;
d[curPos + 11] = 0;
d[curPos + 12] = 0;
d[curPos + 13] = 0;
d[curPos + 14] = 0;
d[curPos + 15] = 70;
curPos += 16;
IntegerHelper.getTwoBytes(upLevelCount, d, curPos);
curPos += 2;
IntegerHelper.getFourBytes(filePath.length() + 1, d, curPos);
curPos += 4;
StringHelper.getBytes(filePath, d, curPos);
curPos += filePath.length() + 1;
d[curPos] = -1;
d[curPos + 1] = -1;
d[curPos + 2] = -83;
d[curPos + 3] = -34;
return d;
}
private String getShortName(String s) {
int sep = s.indexOf('.');
String prefix = null;
String suffix = null;
if (sep == -1) {
prefix = s;
suffix = "";
} else {
prefix = s.substring(0, sep);
suffix = s.substring(sep + 1);
}
if (prefix.length() > 8) {
prefix = prefix.substring(0, 6) + "~" + (prefix.length() - 6);
prefix = prefix.substring(0, 8);
}
suffix = suffix.substring(0, Math.min(3, suffix.length()));
if (suffix.length() > 0)
return prefix + '.' + suffix;
return prefix;
}
private byte[] getLocationData(byte[] cd) {
byte[] d = new byte[cd.length + 4 + (this.location.length() + 1) * 2];
System.arraycopy(cd, 0, d, 0, cd.length);
int locPos = cd.length;
IntegerHelper.getFourBytes(this.location.length() + 1, d, locPos);
StringHelper.getUnicodeBytes(this.location, d, locPos + 4);
return d;
}
void initialize(WritableSheet s) {
this.sheet = s;
this.range = (Range)new SheetRangeImpl((Sheet)s, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
}
String getContents() {
return this.contents;
}
protected void setContents(String desc) {
this.contents = desc;
this.modified = true;
}
}

View File

@@ -0,0 +1,40 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class IndexRecord extends WritableRecordData {
private byte[] data;
private int rows;
private int bofPosition;
private int blocks;
private int dataPos;
public IndexRecord(int pos, int r, int bl) {
super(Type.INDEX);
this.bofPosition = pos;
this.rows = r;
this.blocks = bl;
this.data = new byte[16 + 4 * this.blocks];
this.dataPos = 16;
}
protected byte[] getData() {
IntegerHelper.getFourBytes(this.rows, this.data, 8);
return this.data;
}
void addBlockPosition(int pos) {
IntegerHelper.getFourBytes(pos - this.bofPosition, this.data, this.dataPos);
this.dataPos += 4;
}
void setDataStartPosition(int pos) {
IntegerHelper.getFourBytes(pos - this.bofPosition, this.data, 12);
}
}

View File

@@ -0,0 +1,14 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class InterfaceEndRecord extends WritableRecordData {
public InterfaceEndRecord() {
super(Type.INTERFACEEND);
}
public byte[] getData() {
return new byte[0];
}
}

View File

@@ -0,0 +1,15 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class InterfaceHeaderRecord extends WritableRecordData {
public InterfaceHeaderRecord() {
super(Type.INTERFACEHDR);
}
public byte[] getData() {
byte[] data = { -80, 4 };
return data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class IterationRecord extends WritableRecordData {
private boolean iterate;
private byte[] data;
public IterationRecord(boolean it) {
super(Type.ITERATION);
this.iterate = it;
this.data = new byte[2];
if (this.iterate)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,27 @@
package jxl.write.biff;
import jxl.write.WriteException;
public class JxlWriteException extends WriteException {
private static class WriteMessage {
public String message;
WriteMessage(String m) {
this.message = m;
}
}
static WriteMessage formatInitialized = new WriteMessage("Attempt to modify a referenced format");
static WriteMessage cellReferenced = new WriteMessage("Cell has already been added to a worksheet");
static WriteMessage maxRowsExceeded = new WriteMessage("The maximum number of rows permitted on a worksheet been exceeded");
static WriteMessage maxColumnsExceeded = new WriteMessage("The maximum number of columns permitted on a worksheet has been exceeded");
static WriteMessage copyPropertySets = new WriteMessage("Error encounted when copying additional property sets");
public JxlWriteException(WriteMessage m) {
super(m.message);
}
}

View File

@@ -0,0 +1,85 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.Cell;
import jxl.CellType;
import jxl.LabelCell;
import jxl.biff.FormattingRecords;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.format.CellFormat;
public abstract class LabelRecord extends CellValue {
private static Logger logger = Logger.getLogger(LabelRecord.class);
private String contents;
private SharedStrings sharedStrings;
private int index;
protected LabelRecord(int c, int r, String cont) {
super(Type.LABELSST, c, r);
this.contents = cont;
if (this.contents == null)
this.contents = "";
}
protected LabelRecord(int c, int r, String cont, CellFormat st) {
super(Type.LABELSST, c, r, st);
this.contents = cont;
if (this.contents == null)
this.contents = "";
}
protected LabelRecord(int c, int r, LabelRecord lr) {
super(Type.LABELSST, c, r, lr);
this.contents = lr.contents;
}
protected LabelRecord(LabelCell lc) {
super(Type.LABELSST, (Cell)lc);
this.contents = lc.getString();
if (this.contents == null)
this.contents = "";
}
public CellType getType() {
return CellType.LABEL;
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] data = new byte[celldata.length + 4];
System.arraycopy(celldata, 0, data, 0, celldata.length);
IntegerHelper.getFourBytes(this.index, data, celldata.length);
return data;
}
public String getContents() {
return this.contents;
}
public String getString() {
return this.contents;
}
protected void setString(String s) {
if (s == null)
s = "";
this.contents = s;
if (!isReferenced())
return;
Assert.verify((this.sharedStrings != null));
this.index = this.sharedStrings.getIndex(this.contents);
this.contents = this.sharedStrings.get(this.index);
}
void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) {
super.setCellDetails(fr, ss, s);
this.sharedStrings = ss;
this.index = this.sharedStrings.getIndex(this.contents);
this.contents = this.sharedStrings.get(this.index);
}
}

View File

@@ -0,0 +1,9 @@
package jxl.write.biff;
import jxl.biff.Type;
class LeftMarginRecord extends MarginRecord {
LeftMarginRecord(double v) {
super(Type.LEFTMARGIN, v);
}
}

View File

@@ -0,0 +1,25 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class MMSRecord extends WritableRecordData {
private byte numMenuItemsAdded;
private byte numMenuItemsDeleted;
private byte[] data;
public MMSRecord(int menuItemsAdded, int menuItemsDeleted) {
super(Type.MMS);
this.numMenuItemsAdded = (byte)menuItemsAdded;
this.numMenuItemsDeleted = (byte)menuItemsDeleted;
this.data = new byte[2];
this.data[0] = this.numMenuItemsAdded;
this.data[1] = this.numMenuItemsDeleted;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,20 @@
package jxl.write.biff;
import jxl.biff.DoubleHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
abstract class MarginRecord extends WritableRecordData {
private double margin;
public MarginRecord(Type t, double v) {
super(t);
this.margin = v;
}
public byte[] getData() {
byte[] data = new byte[8];
DoubleHelper.getIEEEBytes(this.margin, data, 0);
return data;
}
}

View File

@@ -0,0 +1,166 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.Cell;
import jxl.CellType;
import jxl.Range;
import jxl.WorkbookSettings;
import jxl.biff.ByteData;
import jxl.biff.SheetRangeImpl;
import jxl.write.Blank;
import jxl.write.WritableCell;
import jxl.write.WritableSheet;
import jxl.write.WriteException;
class MergedCells {
private static Logger logger = Logger.getLogger(MergedCells.class);
private ArrayList ranges;
private WritableSheet sheet;
private static final int maxRangesPerSheet = 1020;
public MergedCells(WritableSheet ws) {
this.ranges = new ArrayList();
this.sheet = ws;
}
void add(Range r) {
this.ranges.add(r);
}
void insertRow(int row) {
SheetRangeImpl sr = null;
Iterator i = this.ranges.iterator();
while (i.hasNext()) {
sr = i.next();
sr.insertRow(row);
}
}
void insertColumn(int col) {
SheetRangeImpl sr = null;
Iterator i = this.ranges.iterator();
while (i.hasNext()) {
sr = i.next();
sr.insertColumn(col);
}
}
void removeColumn(int col) {
SheetRangeImpl sr = null;
Iterator i = this.ranges.iterator();
while (i.hasNext()) {
sr = i.next();
if (sr.getTopLeft().getColumn() == col && sr.getBottomRight().getColumn() == col) {
this.ranges.remove(this.ranges.indexOf(sr));
continue;
}
sr.removeColumn(col);
}
}
void removeRow(int row) {
SheetRangeImpl sr = null;
Iterator i = this.ranges.iterator();
while (i.hasNext()) {
sr = i.next();
if (sr.getTopLeft().getRow() == row && sr.getBottomRight().getRow() == row) {
i.remove();
continue;
}
sr.removeRow(row);
}
}
Range[] getMergedCells() {
Range[] cells = new Range[this.ranges.size()];
for (int i = 0; i < cells.length; i++)
cells[i] = this.ranges.get(i);
return cells;
}
void unmergeCells(Range r) {
int index = this.ranges.indexOf(r);
if (index != -1)
this.ranges.remove(index);
}
private void checkIntersections() {
ArrayList newcells = new ArrayList(this.ranges.size());
for (Iterator mci = this.ranges.iterator(); mci.hasNext(); ) {
SheetRangeImpl r = mci.next();
Iterator i = newcells.iterator();
SheetRangeImpl range = null;
boolean intersects = false;
while (i.hasNext() && !intersects) {
range = i.next();
if (range.intersects(r)) {
logger.warn("Could not merge cells " + r + " as they clash with an existing set of merged cells.");
intersects = true;
}
}
if (!intersects)
newcells.add(r);
}
this.ranges = newcells;
}
private void checkRanges() {
try {
SheetRangeImpl range = null;
for (int i = 0; i < this.ranges.size(); i++) {
range = this.ranges.get(i);
Cell tl = range.getTopLeft();
Cell br = range.getBottomRight();
boolean found = false;
for (int c = tl.getColumn(); c <= br.getColumn(); c++) {
for (int r = tl.getRow(); r <= br.getRow(); r++) {
Cell cell = this.sheet.getCell(c, r);
if (cell.getType() != CellType.EMPTY)
if (!found) {
found = true;
} else {
logger.warn("Range " + range + " contains more than one data cell. " + "Setting the other cells to blank.");
Blank b = new Blank(c, r);
this.sheet.addCell((WritableCell)b);
}
}
}
}
} catch (WriteException e) {
Assert.verify(false);
}
}
void write(File outputFile) throws IOException {
if (this.ranges.size() == 0)
return;
WorkbookSettings ws = ((WritableSheetImpl)this.sheet).getWorkbookSettings();
if (!ws.getMergedCellCheckingDisabled()) {
checkIntersections();
checkRanges();
}
if (this.ranges.size() < 1020) {
MergedCellsRecord mcr = new MergedCellsRecord(this.ranges);
outputFile.write((ByteData)mcr);
return;
}
int numRecordsRequired = this.ranges.size() / 1020 + 1;
int pos = 0;
for (int i = 0; i < numRecordsRequired; i++) {
int numranges = Math.min(1020, this.ranges.size() - pos);
ArrayList cells = new ArrayList(numranges);
for (int j = 0; j < numranges; j++)
cells.add(this.ranges.get(pos + j));
MergedCellsRecord mcr = new MergedCellsRecord(cells);
outputFile.write((ByteData)mcr);
pos += numranges;
}
}
}

View File

@@ -0,0 +1,35 @@
package jxl.write.biff;
import java.util.ArrayList;
import jxl.Cell;
import jxl.Range;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
public class MergedCellsRecord extends WritableRecordData {
private ArrayList ranges;
protected MergedCellsRecord(ArrayList mc) {
super(Type.MERGEDCELLS);
this.ranges = mc;
}
public byte[] getData() {
byte[] data = new byte[this.ranges.size() * 8 + 2];
IntegerHelper.getTwoBytes(this.ranges.size(), data, 0);
int pos = 2;
Range range = null;
for (int i = 0; i < this.ranges.size(); i++) {
range = this.ranges.get(i);
Cell tl = range.getTopLeft();
Cell br = range.getBottomRight();
IntegerHelper.getTwoBytes(tl.getRow(), data, pos);
IntegerHelper.getTwoBytes(br.getRow(), data, pos + 2);
IntegerHelper.getTwoBytes(tl.getColumn(), data, pos + 4);
IntegerHelper.getTwoBytes(br.getColumn(), data, pos + 6);
pos += 8;
}
return data;
}
}

View File

@@ -0,0 +1,50 @@
package jxl.write.biff;
import java.util.List;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.write.Number;
class MulRKRecord extends WritableRecordData {
private int row;
private int colFirst;
private int colLast;
private int[] rknumbers;
private int[] xfIndices;
public MulRKRecord(List numbers) {
super(Type.MULRK);
this.row = ((Number)numbers.get(0)).getRow();
this.colFirst = ((Number)numbers.get(0)).getColumn();
this.colLast = this.colFirst + numbers.size() - 1;
this.rknumbers = new int[numbers.size()];
this.xfIndices = new int[numbers.size()];
for (int i = 0; i < numbers.size(); i++) {
this.rknumbers[i] = (int)((Number)numbers.get(i)).getValue();
this.xfIndices[i] = ((CellValue)numbers.get(i)).getXFIndex();
}
}
public byte[] getData() {
byte[] data = new byte[this.rknumbers.length * 6 + 6];
IntegerHelper.getTwoBytes(this.row, data, 0);
IntegerHelper.getTwoBytes(this.colFirst, data, 2);
int pos = 4;
int rkValue = 0;
byte[] rkBytes = new byte[4];
for (int i = 0; i < this.rknumbers.length; i++) {
IntegerHelper.getTwoBytes(this.xfIndices[i], data, pos);
rkValue = this.rknumbers[i] << 2;
rkValue |= 0x2;
IntegerHelper.getFourBytes(rkValue, data, pos + 2);
pos += 6;
}
IntegerHelper.getTwoBytes(this.colLast, data, pos);
return data;
}
}

View File

@@ -0,0 +1,152 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class NameRecord extends WritableRecordData {
private byte[] data;
private String name;
private int index;
private int sheetRef = 0;
private NameRange[] ranges;
private static final int cellReference = 58;
private static final int areaReference = 59;
private static final int subExpression = 41;
private static final int union = 16;
class NameRange {
private int columnFirst;
private int rowFirst;
private int columnLast;
private int rowLast;
private int externalSheet;
private final NameRecord this$0;
NameRange(NameRecord this$0, jxl.read.biff.NameRecord.NameRange nr) {
this.this$0 = this$0;
this.columnFirst = nr.getFirstColumn();
this.rowFirst = nr.getFirstRow();
this.columnLast = nr.getLastColumn();
this.rowLast = nr.getLastRow();
this.externalSheet = nr.getExternalSheet();
}
NameRange(NameRecord this$0, int theSheet, int theStartRow, int theEndRow, int theStartCol, int theEndCol) {
this.this$0 = this$0;
this.columnFirst = theStartCol;
this.rowFirst = theStartRow;
this.columnLast = theEndCol;
this.rowLast = theEndRow;
this.externalSheet = theSheet;
}
int getFirstColumn() {
return this.columnFirst;
}
int getFirstRow() {
return this.rowFirst;
}
int getLastColumn() {
return this.columnLast;
}
int getLastRow() {
return this.rowLast;
}
int getExternalSheet() {
return this.externalSheet;
}
byte[] getData() {
byte[] d = new byte[10];
IntegerHelper.getTwoBytes(this.this$0.sheetRef, d, 0);
IntegerHelper.getTwoBytes(this.rowFirst, d, 2);
IntegerHelper.getTwoBytes(this.rowLast, d, 4);
IntegerHelper.getTwoBytes(this.columnFirst & 0xFF, d, 6);
IntegerHelper.getTwoBytes(this.columnLast & 0xFF, d, 8);
return d;
}
}
public NameRecord(jxl.read.biff.NameRecord sr, int ind) {
super(Type.NAME);
this.data = sr.getData();
this.name = sr.getName();
this.sheetRef = sr.getSheetRef();
this.index = ind;
jxl.read.biff.NameRecord.NameRange[] r = sr.getRanges();
this.ranges = new NameRange[r.length];
for (int i = 0; i < this.ranges.length; i++)
this.ranges[i] = new NameRange(this, r[i]);
}
NameRecord(String theName, int theIndex, int theSheet, int theStartRow, int theEndRow, int theStartCol, int theEndCol) {
super(Type.NAME);
this.name = theName;
this.index = theIndex;
this.sheetRef = 0;
this.ranges = new NameRange[1];
this.ranges[0] = new NameRange(this, theSheet, theStartRow, theEndRow, theStartCol, theEndCol);
}
public byte[] getData() {
if (this.data != null)
return this.data;
int NAME_HEADER_LENGTH = 15;
byte AREA_RANGE_LENGTH = 11;
byte AREA_REFERENCE = 59;
this.data = new byte[15 + this.name.length() + 11];
int options = 0;
IntegerHelper.getTwoBytes(options, this.data, 0);
this.data[2] = 0;
this.data[3] = (byte)this.name.length();
IntegerHelper.getTwoBytes(11, this.data, 4);
IntegerHelper.getTwoBytes((this.ranges[0]).externalSheet, this.data, 6);
IntegerHelper.getTwoBytes((this.ranges[0]).externalSheet, this.data, 8);
StringHelper.getBytes(this.name, this.data, 15);
int pos = this.name.length() + 15;
this.data[pos] = 59;
byte[] rd = this.ranges[0].getData();
System.arraycopy(rd, 0, this.data, pos + 1, rd.length);
return this.data;
}
public String getName() {
return this.name;
}
public int getIndex() {
return this.index;
}
public int getSheetRef() {
return this.sheetRef;
}
public void setSheetRef(int i) {
this.sheetRef = i;
IntegerHelper.getTwoBytes(this.sheetRef, this.data, 8);
}
public NameRange[] getRanges() {
return this.ranges;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class NineteenFourRecord extends WritableRecordData {
private boolean nineteenFourDate;
private byte[] data;
public NineteenFourRecord(boolean oldDate) {
super(Type.NINETEENFOUR);
this.nineteenFourDate = oldDate;
this.data = new byte[2];
if (this.nineteenFourDate)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,72 @@
package jxl.write.biff;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import jxl.Cell;
import jxl.CellType;
import jxl.NumberCell;
import jxl.biff.DoubleHelper;
import jxl.biff.Type;
import jxl.biff.XFRecord;
import jxl.format.CellFormat;
public abstract class NumberRecord extends CellValue {
private double value;
private NumberFormat format;
private static DecimalFormat defaultFormat = new DecimalFormat("#.###");
protected NumberRecord(int c, int r, double val) {
super(Type.NUMBER, c, r);
this.value = val;
}
protected NumberRecord(int c, int r, double val, CellFormat st) {
super(Type.NUMBER, c, r, st);
this.value = val;
}
protected NumberRecord(NumberCell nc) {
super(Type.NUMBER, (Cell)nc);
this.value = nc.getValue();
}
protected NumberRecord(int c, int r, NumberRecord nr) {
super(Type.NUMBER, c, r, nr);
this.value = nr.value;
}
public CellType getType() {
return CellType.NUMBER;
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] data = new byte[celldata.length + 8];
System.arraycopy(celldata, 0, data, 0, celldata.length);
DoubleHelper.getIEEEBytes(this.value, data, celldata.length);
return data;
}
public String getContents() {
if (this.format == null) {
this.format = ((XFRecord)getCellFormat()).getNumberFormat();
if (this.format == null)
this.format = defaultFormat;
}
return this.format.format(this.value);
}
public double getValue() {
return this.value;
}
public void setValue(double val) {
this.value = val;
}
public NumberFormat getNumberFormat() {
return null;
}
}

View File

@@ -0,0 +1,17 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ObjProjRecord extends WritableRecordData {
private byte[] data;
public ObjProjRecord() {
super(Type.OBJPROJ);
this.data = new byte[4];
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ObjectProtectRecord extends WritableRecordData {
private boolean protection;
private byte[] data;
public ObjectProtectRecord(boolean prot) {
super(Type.OBJPROTECT);
this.protection = prot;
this.data = new byte[2];
if (this.protection)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PLSRecord extends WritableRecordData {
private byte[] data;
public PLSRecord(jxl.read.biff.PLSRecord hr) {
super(Type.PLS);
this.data = hr.getData();
}
public PLSRecord(PLSRecord hr) {
super(Type.PLS);
this.data = new byte[hr.data.length];
System.arraycopy(hr.data, 0, this.data, 0, this.data.length);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,45 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PaneRecord extends WritableRecordData {
private int rowsVisible;
private int columnsVisible;
private static final int topLeftPane = 3;
private static final int bottomLeftPane = 2;
private static final int topRightPane = 1;
private static final int bottomRightPane = 0;
public PaneRecord(int cols, int rows) {
super(Type.PANE);
this.rowsVisible = rows;
this.columnsVisible = cols;
}
public byte[] getData() {
byte[] data = new byte[10];
IntegerHelper.getTwoBytes(this.columnsVisible, data, 0);
IntegerHelper.getTwoBytes(this.rowsVisible, data, 2);
if (this.rowsVisible > 0)
IntegerHelper.getTwoBytes(this.rowsVisible, data, 4);
if (this.columnsVisible > 0)
IntegerHelper.getTwoBytes(this.columnsVisible, data, 6);
int activePane = 3;
if (this.rowsVisible > 0 && this.columnsVisible == 0) {
activePane = 2;
} else if (this.rowsVisible == 0 && this.columnsVisible > 0) {
activePane = 1;
} else if (this.rowsVisible > 0 && this.columnsVisible > 0) {
activePane = 0;
}
IntegerHelper.getTwoBytes(activePane, data, 8);
return data;
}
}

View File

@@ -0,0 +1,53 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PasswordRecord extends WritableRecordData {
private String password;
private byte[] data;
public PasswordRecord(String pw) {
super(Type.PASSWORD);
this.password = pw;
if (pw == null) {
this.data = new byte[2];
IntegerHelper.getTwoBytes(0, this.data, 0);
} else {
byte[] passwordBytes = pw.getBytes();
int passwordHash = 0;
for (int a = 0; a < passwordBytes.length; a++) {
int shifted = rotLeft15Bit(passwordBytes[a], a + 1);
passwordHash ^= shifted;
}
passwordHash ^= passwordBytes.length;
passwordHash ^= 0xCE4B;
this.data = new byte[2];
IntegerHelper.getTwoBytes(passwordHash, this.data, 0);
}
}
public PasswordRecord(int ph) {
super(Type.PASSWORD);
this.data = new byte[2];
IntegerHelper.getTwoBytes(ph, this.data, 0);
}
public byte[] getData() {
return this.data;
}
private int rotLeft15Bit(int val, int rotate) {
val &= 0x7FFF;
for (; rotate > 0; rotate--) {
if ((val & 0x4000) != 0) {
val = (val << 1 & 0x7FFF) + 1;
} else {
val = val << 1 & 0x7FFF;
}
}
return val;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PrecisionRecord extends WritableRecordData {
private boolean asDisplayed;
private byte[] data;
public PrecisionRecord(boolean disp) {
super(Type.PRECISION);
this.asDisplayed = disp;
this.data = new byte[2];
if (!this.asDisplayed)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PrintGridLinesRecord extends WritableRecordData {
private byte[] data;
private boolean printGridLines;
public PrintGridLinesRecord(boolean pgl) {
super(Type.PRINTGRIDLINES);
this.printGridLines = pgl;
this.data = new byte[2];
if (this.printGridLines)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class PrintHeadersRecord extends WritableRecordData {
private byte[] data;
private boolean printHeaders;
public PrintHeadersRecord(boolean ph) {
super(Type.PRINTHEADERS);
this.printHeaders = ph;
this.data = new byte[2];
if (this.printHeaders)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,17 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class Prot4RevPassRecord extends WritableRecordData {
private byte[] data;
public Prot4RevPassRecord() {
super(Type.PROT4REVPASS);
this.data = new byte[2];
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class Prot4RevRecord extends WritableRecordData {
private boolean protection;
private byte[] data;
public Prot4RevRecord(boolean prot) {
super(Type.PROT4REV);
this.protection = prot;
this.data = new byte[2];
if (this.protection)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ProtectRecord extends WritableRecordData {
private boolean protection;
private byte[] data;
public ProtectRecord(boolean prot) {
super(Type.PROTECT);
this.protection = prot;
this.data = new byte[2];
if (this.protection)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,14 @@
package jxl.write.biff;
import jxl.BooleanFormulaCell;
import jxl.biff.FormulaData;
class ReadBooleanFormulaRecord extends ReadFormulaRecord implements BooleanFormulaCell {
public ReadBooleanFormulaRecord(FormulaData f) {
super(f);
}
public boolean getValue() {
return ((BooleanFormulaCell)getReadFormula()).getValue();
}
}

View File

@@ -0,0 +1,24 @@
package jxl.write.biff;
import java.text.DateFormat;
import java.util.Date;
import jxl.DateFormulaCell;
import jxl.biff.FormulaData;
class ReadDateFormulaRecord extends ReadFormulaRecord implements DateFormulaCell {
public ReadDateFormulaRecord(FormulaData f) {
super(f);
}
public Date getDate() {
return ((DateFormulaCell)getReadFormula()).getDate();
}
public boolean isTime() {
return ((DateFormulaCell)getReadFormula()).isTime();
}
public DateFormat getDateFormat() {
return ((DateFormulaCell)getReadFormula()).getDateFormat();
}
}

View File

@@ -0,0 +1,58 @@
package jxl.write.biff;
import common.Logger;
import jxl.ErrorFormulaCell;
import jxl.biff.FormulaData;
import jxl.biff.IntegerHelper;
import jxl.biff.formula.FormulaErrorCode;
import jxl.biff.formula.FormulaException;
import jxl.biff.formula.FormulaParser;
class ReadErrorFormulaRecord extends ReadFormulaRecord implements ErrorFormulaCell {
private static Logger logger = Logger.getLogger(ReadErrorFormulaRecord.class);
public ReadErrorFormulaRecord(FormulaData f) {
super(f);
}
public int getErrorCode() {
return ((ErrorFormulaCell)getReadFormula()).getErrorCode();
}
protected byte[] handleFormulaException() {
logger.debug("ReadErrorFormulaRecord.handleFormulaException");
byte[] expressiondata = null;
byte[] celldata = getCellData();
int errorCode = getErrorCode();
String formulaString = null;
if (errorCode == FormulaErrorCode.DIV0.getCode()) {
formulaString = "1/0";
} else if (errorCode == FormulaErrorCode.VALUE.getCode()) {
formulaString = "\"\"/0";
} else if (errorCode == FormulaErrorCode.REF.getCode()) {
formulaString = "\"#REF!\"";
} else {
formulaString = "\"ERROR\"";
}
WritableWorkbookImpl w = getSheet().getWorkbook();
FormulaParser parser = new FormulaParser(formulaString, w, w, w.getSettings());
try {
parser.parse();
} catch (FormulaException e2) {
logger.warn(e2.getMessage());
}
byte[] formulaBytes = parser.getBytes();
expressiondata = new byte[formulaBytes.length + 16];
IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14);
System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length);
expressiondata[8] = (byte)(expressiondata[8] | 0x2);
byte[] data = new byte[celldata.length + expressiondata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length);
data[6] = 2;
data[12] = -1;
data[13] = -1;
data[8] = (byte)errorCode;
return data;
}
}

View File

@@ -0,0 +1,176 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.Cell;
import jxl.CellReferenceHelper;
import jxl.CellType;
import jxl.FormulaCell;
import jxl.Sheet;
import jxl.biff.FormattingRecords;
import jxl.biff.FormulaData;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.formula.FormulaException;
import jxl.biff.formula.FormulaParser;
import jxl.write.WritableCell;
class ReadFormulaRecord extends CellValue implements FormulaData {
private static Logger logger = Logger.getLogger(ReadFormulaRecord.class);
private FormulaData formula;
private FormulaParser parser;
protected ReadFormulaRecord(FormulaData f) {
super(Type.FORMULA, (Cell)f);
this.formula = f;
}
protected final byte[] getCellData() {
return super.getData();
}
protected byte[] handleFormulaException() {
byte[] expressiondata = null;
byte[] celldata = super.getData();
WritableWorkbookImpl w = getSheet().getWorkbook();
this.parser = new FormulaParser(getContents(), w, w, w.getSettings());
try {
this.parser.parse();
} catch (FormulaException e2) {
logger.warn(e2.getMessage());
this.parser = new FormulaParser("\"ERROR\"", w, w, w.getSettings());
try {
this.parser.parse();
} catch (FormulaException e3) {
Assert.verify(false);
}
}
byte[] formulaBytes = this.parser.getBytes();
expressiondata = new byte[formulaBytes.length + 16];
IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14);
System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length);
expressiondata[8] = (byte)(expressiondata[8] | 0x2);
byte[] data = new byte[celldata.length + expressiondata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length);
return data;
}
public byte[] getData() {
byte[] celldata = super.getData();
byte[] expressiondata = null;
try {
if (this.parser == null) {
expressiondata = this.formula.getFormulaData();
} else {
byte[] formulaBytes = this.parser.getBytes();
expressiondata = new byte[formulaBytes.length + 16];
IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14);
System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length);
}
expressiondata[8] = (byte)(expressiondata[8] | 0x2);
byte[] data = new byte[celldata.length + expressiondata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length);
return data;
} catch (FormulaException e) {
logger.warn(CellReferenceHelper.getCellReference(getColumn(), getRow()) + " " + e.getMessage());
return handleFormulaException();
}
}
public CellType getType() {
return this.formula.getType();
}
public String getContents() {
return this.formula.getContents();
}
public byte[] getFormulaData() throws FormulaException {
byte[] d = this.formula.getFormulaData();
byte[] data = new byte[d.length];
System.arraycopy(d, 0, data, 0, d.length);
data[8] = (byte)(data[8] | 0x2);
return data;
}
public WritableCell copyTo(int col, int row) {
return new FormulaRecord(col, row, this);
}
void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) {
super.setCellDetails(fr, ss, s);
s.getWorkbook().addRCIRCell(this);
}
void columnInserted(Sheet s, int sheetIndex, int col) {
try {
if (this.parser == null) {
byte[] formulaData = this.formula.getFormulaData();
byte[] formulaBytes = new byte[formulaData.length - 16];
System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length);
this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings());
this.parser.parse();
}
this.parser.columnInserted(sheetIndex, col, (s == getSheet()));
} catch (FormulaException e) {
logger.warn("cannot insert column within formula: " + e.getMessage());
}
}
void columnRemoved(Sheet s, int sheetIndex, int col) {
try {
if (this.parser == null) {
byte[] formulaData = this.formula.getFormulaData();
byte[] formulaBytes = new byte[formulaData.length - 16];
System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length);
this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings());
this.parser.parse();
}
this.parser.columnRemoved(sheetIndex, col, (s == getSheet()));
} catch (FormulaException e) {
logger.warn("cannot remove column within formula: " + e.getMessage());
}
}
void rowInserted(Sheet s, int sheetIndex, int row) {
try {
if (this.parser == null) {
byte[] formulaData = this.formula.getFormulaData();
byte[] formulaBytes = new byte[formulaData.length - 16];
System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length);
this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings());
this.parser.parse();
}
this.parser.rowInserted(sheetIndex, row, (s == getSheet()));
} catch (FormulaException e) {
logger.warn("cannot insert row within formula: " + e.getMessage());
}
}
void rowRemoved(Sheet s, int sheetIndex, int row) {
try {
if (this.parser == null) {
byte[] formulaData = this.formula.getFormulaData();
byte[] formulaBytes = new byte[formulaData.length - 16];
System.arraycopy(formulaData, 16, formulaBytes, 0, formulaBytes.length);
this.parser = new FormulaParser(formulaBytes, (Cell)this, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings());
this.parser.parse();
}
this.parser.rowRemoved(sheetIndex, row, (s == getSheet()));
} catch (FormulaException e) {
logger.warn("cannot remove row within formula: " + e.getMessage());
}
}
protected FormulaData getReadFormula() {
return this.formula;
}
public String getFormula() throws FormulaException {
return ((FormulaCell)this.formula).getFormula();
}
}

View File

@@ -0,0 +1,48 @@
package jxl.write.biff;
import common.Logger;
import java.text.NumberFormat;
import jxl.NumberFormulaCell;
import jxl.biff.DoubleHelper;
import jxl.biff.FormulaData;
import jxl.biff.IntegerHelper;
import jxl.biff.formula.FormulaException;
import jxl.biff.formula.FormulaParser;
class ReadNumberFormulaRecord extends ReadFormulaRecord implements NumberFormulaCell {
private static Logger logger = Logger.getLogger(ReadNumberFormulaRecord.class);
public ReadNumberFormulaRecord(FormulaData f) {
super(f);
}
public double getValue() {
return ((NumberFormulaCell)getReadFormula()).getValue();
}
public NumberFormat getNumberFormat() {
return ((NumberFormulaCell)getReadFormula()).getNumberFormat();
}
protected byte[] handleFormulaException() {
byte[] expressiondata = null;
byte[] celldata = getCellData();
WritableWorkbookImpl w = getSheet().getWorkbook();
FormulaParser parser = new FormulaParser(Double.toString(getValue()), w, w, w.getSettings());
try {
parser.parse();
} catch (FormulaException e2) {
logger.warn(e2.getMessage());
}
byte[] formulaBytes = parser.getBytes();
expressiondata = new byte[formulaBytes.length + 16];
IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14);
System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length);
expressiondata[8] = (byte)(expressiondata[8] | 0x2);
byte[] data = new byte[celldata.length + expressiondata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length);
DoubleHelper.getIEEEBytes(getValue(), data, 6);
return data;
}
}

View File

@@ -0,0 +1,51 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.StringFormulaCell;
import jxl.biff.FormulaData;
import jxl.biff.IntegerHelper;
import jxl.biff.formula.FormulaException;
import jxl.biff.formula.FormulaParser;
class ReadStringFormulaRecord extends ReadFormulaRecord implements StringFormulaCell {
private static Logger logger = Logger.getLogger(ReadFormulaRecord.class);
public ReadStringFormulaRecord(FormulaData f) {
super(f);
}
public String getString() {
return ((StringFormulaCell)getReadFormula()).getString();
}
protected byte[] handleFormulaException() {
byte[] expressiondata = null;
byte[] celldata = getCellData();
WritableWorkbookImpl w = getSheet().getWorkbook();
FormulaParser parser = new FormulaParser("\"" + getContents() + "\"", w, w, w.getSettings());
try {
parser.parse();
} catch (FormulaException e2) {
logger.warn(e2.getMessage());
parser = new FormulaParser("\"ERROR\"", w, w, w.getSettings());
try {
parser.parse();
} catch (FormulaException e3) {
Assert.verify(false);
}
}
byte[] formulaBytes = parser.getBytes();
expressiondata = new byte[formulaBytes.length + 16];
IntegerHelper.getTwoBytes(formulaBytes.length, expressiondata, 14);
System.arraycopy(formulaBytes, 0, expressiondata, 16, formulaBytes.length);
expressiondata[8] = (byte)(expressiondata[8] | 0x2);
byte[] data = new byte[celldata.length + expressiondata.length];
System.arraycopy(celldata, 0, data, 0, celldata.length);
System.arraycopy(expressiondata, 0, data, celldata.length, expressiondata.length);
data[6] = 0;
data[12] = -1;
data[13] = -1;
return data;
}
}

View File

@@ -0,0 +1,16 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class RefModeRecord extends WritableRecordData {
public RefModeRecord() {
super(Type.REFMODE);
}
public byte[] getData() {
byte[] data = new byte[2];
data[0] = 1;
return data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class RefreshAllRecord extends WritableRecordData {
private boolean refreshall;
private byte[] data;
public RefreshAllRecord(boolean refresh) {
super(Type.REFRESHALL);
this.refreshall = refresh;
this.data = new byte[2];
if (this.refreshall)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,9 @@
package jxl.write.biff;
import jxl.biff.Type;
class RightMarginRecord extends MarginRecord {
RightMarginRecord(double v) {
super(Type.RIGHTMARGIN, v);
}
}

View File

@@ -0,0 +1,263 @@
package jxl.write.biff;
import common.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.CellType;
import jxl.biff.ByteData;
import jxl.biff.CellReferenceHelper;
import jxl.biff.IndexMapping;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.biff.XFRecord;
import jxl.write.Number;
class RowRecord extends WritableRecordData {
private static final Logger logger = Logger.getLogger(RowRecord.class);
private byte[] data;
private CellValue[] cells;
private int rowHeight;
private boolean collapsed;
private int rowNumber;
private int numColumns;
private int xfIndex;
private XFRecord style;
private boolean defaultFormat;
private boolean matchesDefFontHeight;
private static final int growSize = 10;
private static final int maxRKValue = 536870911;
private static final int minRKValue = -536870912;
private static int defaultHeightIndicator = 255;
private static int maxColumns = 256;
public RowRecord(int rn) {
super(Type.ROW);
this.rowNumber = rn;
this.cells = new CellValue[0];
this.numColumns = 0;
this.rowHeight = defaultHeightIndicator;
this.collapsed = false;
this.matchesDefFontHeight = true;
}
public void setRowHeight(int h) {
if (h == 0) {
setCollapsed(true);
this.matchesDefFontHeight = false;
} else {
this.rowHeight = h;
this.matchesDefFontHeight = false;
}
}
void setRowDetails(int height, boolean mdfh, boolean col, XFRecord xfr) {
this.rowHeight = height;
this.collapsed = col;
this.matchesDefFontHeight = mdfh;
if (xfr != null) {
this.defaultFormat = true;
this.style = xfr;
this.xfIndex = this.style.getXFIndex();
}
}
public void setCollapsed(boolean c) {
this.collapsed = c;
}
public int getRowNumber() {
return this.rowNumber;
}
public void addCell(CellValue cv) {
int col = cv.getColumn();
if (col >= maxColumns) {
logger.warn("Could not add cell at " + CellReferenceHelper.getCellReference(cv.getRow(), cv.getColumn()) + " because it exceeds the maximum column limit");
return;
}
if (col >= this.cells.length) {
CellValue[] oldCells = this.cells;
this.cells = new CellValue[Math.max(oldCells.length + 10, col + 1)];
System.arraycopy(oldCells, 0, this.cells, 0, oldCells.length);
oldCells = null;
}
this.cells[col] = cv;
this.numColumns = Math.max(col + 1, this.numColumns);
}
public void removeCell(int col) {
if (col >= this.numColumns)
return;
this.cells[col] = null;
}
public void write(File outputFile) throws IOException {
outputFile.write((ByteData)this);
}
public void writeCells(File outputFile) throws IOException {
ArrayList integerValues = new ArrayList();
boolean integerValue = false;
for (int i = 0; i < this.numColumns; i++) {
integerValue = false;
if (this.cells[i] != null) {
if (this.cells[i].getType() == CellType.NUMBER) {
Number nc = (Number)this.cells[i];
if (nc.getValue() == (int)nc.getValue() && nc.getValue() < 5.36870911E8D && nc.getValue() > -5.36870912E8D && nc.getCellFeatures() == null)
integerValue = true;
}
if (integerValue) {
integerValues.add(this.cells[i]);
} else {
writeIntegerValues(integerValues, outputFile);
outputFile.write((ByteData)this.cells[i]);
if (this.cells[i].getType() == CellType.STRING_FORMULA) {
StringRecord sr = new StringRecord(this.cells[i].getContents());
outputFile.write((ByteData)sr);
}
}
} else {
writeIntegerValues(integerValues, outputFile);
}
}
writeIntegerValues(integerValues, outputFile);
}
private void writeIntegerValues(ArrayList integerValues, File outputFile) throws IOException {
if (integerValues.size() == 0)
return;
if (integerValues.size() >= 3) {
MulRKRecord mulrk = new MulRKRecord(integerValues);
outputFile.write((ByteData)mulrk);
} else {
Iterator i = integerValues.iterator();
while (i.hasNext())
outputFile.write((ByteData)i.next());
}
integerValues.clear();
}
public byte[] getData() {
byte[] data = new byte[16];
IntegerHelper.getTwoBytes(this.rowNumber, data, 0);
IntegerHelper.getTwoBytes(this.numColumns, data, 4);
IntegerHelper.getTwoBytes(this.rowHeight, data, 6);
int options = 256;
if (this.collapsed)
options |= 0x20;
if (!this.matchesDefFontHeight)
options |= 0x40;
if (this.defaultFormat) {
options |= 0x80;
options |= this.xfIndex << 16;
}
IntegerHelper.getFourBytes(options, data, 12);
return data;
}
public int getMaxColumn() {
return this.numColumns;
}
public CellValue getCell(int col) {
return (col >= 0 && col < this.numColumns) ? this.cells[col] : null;
}
void incrementRow() {
this.rowNumber++;
for (int i = 0; i < this.cells.length; i++) {
if (this.cells[i] != null)
this.cells[i].incrementRow();
}
}
void decrementRow() {
this.rowNumber--;
for (int i = 0; i < this.cells.length; i++) {
if (this.cells[i] != null)
this.cells[i].decrementRow();
}
}
void insertColumn(int col) {
if (col >= this.numColumns)
return;
if (this.numColumns >= maxColumns) {
logger.warn("Could not insert column because maximum column limit has been reached");
return;
}
CellValue[] oldCells = this.cells;
if (this.numColumns >= this.cells.length - 1) {
this.cells = new CellValue[oldCells.length + 10];
} else {
this.cells = new CellValue[oldCells.length];
}
System.arraycopy(oldCells, 0, this.cells, 0, col);
System.arraycopy(oldCells, col, this.cells, col + 1, this.numColumns - col);
for (int i = col + 1; i <= this.numColumns; i++) {
if (this.cells[i] != null)
this.cells[i].incrementColumn();
}
this.numColumns++;
}
void removeColumn(int col) {
if (col >= this.numColumns)
return;
CellValue[] oldCells = this.cells;
this.cells = new CellValue[oldCells.length];
System.arraycopy(oldCells, 0, this.cells, 0, col);
System.arraycopy(oldCells, col + 1, this.cells, col, this.numColumns - col + 1);
for (int i = col; i < this.numColumns; i++) {
if (this.cells[i] != null)
this.cells[i].decrementColumn();
}
this.numColumns--;
}
public boolean isDefaultHeight() {
return (this.rowHeight == defaultHeightIndicator);
}
public int getRowHeight() {
return this.rowHeight;
}
public boolean isCollapsed() {
return this.collapsed;
}
void rationalize(IndexMapping xfmapping) {
if (this.defaultFormat)
this.xfIndex = xfmapping.getNewIndex(this.xfIndex);
}
XFRecord getStyle() {
return this.style;
}
boolean hasDefaultFormat() {
return this.defaultFormat;
}
boolean matchesDefaultFontHeight() {
return this.matchesDefFontHeight;
}
}

View File

@@ -0,0 +1,7 @@
package jxl.write.biff;
public class RowsExceededException extends JxlWriteException {
public RowsExceededException() {
super(maxRowsExceeded);
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SCLRecord extends WritableRecordData {
private int zoomFactor;
public SCLRecord(int zf) {
super(Type.SCL);
this.zoomFactor = zf;
}
public byte[] getData() {
byte[] data = new byte[4];
int numerator = this.zoomFactor;
int denominator = 100;
IntegerHelper.getTwoBytes(numerator, data, 0);
IntegerHelper.getTwoBytes(denominator, data, 2);
return data;
}
}

View File

@@ -0,0 +1,103 @@
package jxl.write.biff;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SSTContinueRecord extends WritableRecordData {
private String firstString;
private boolean includeLength;
private int firstStringLength;
private ArrayList strings;
private ArrayList stringLengths;
private byte[] data;
private int byteCount;
private static int maxBytes = 8224;
public SSTContinueRecord() {
super(Type.CONTINUE);
this.byteCount = 0;
this.strings = new ArrayList(50);
this.stringLengths = new ArrayList(50);
}
public int setFirstString(String s, boolean b) {
this.includeLength = b;
this.firstStringLength = s.length();
int bytes = 0;
if (!this.includeLength) {
bytes = s.length() * 2 + 1;
} else {
bytes = s.length() * 2 + 3;
}
if (bytes <= maxBytes) {
this.firstString = s;
this.byteCount += bytes;
return 0;
}
int charsAvailable = this.includeLength ? ((maxBytes - 4) / 2) : ((maxBytes - 2) / 2);
this.firstString = s.substring(0, charsAvailable);
this.byteCount = maxBytes - 1;
return s.length() - charsAvailable;
}
public int getOffset() {
return this.byteCount;
}
public int add(String s) {
int bytes = s.length() * 2 + 3;
if (this.byteCount >= maxBytes - 5)
return s.length();
this.stringLengths.add(new Integer(s.length()));
if (bytes + this.byteCount < maxBytes) {
this.strings.add(s);
this.byteCount += bytes;
return 0;
}
int bytesLeft = maxBytes - 3 - this.byteCount;
int charsAvailable = (bytesLeft % 2 == 0) ? (bytesLeft / 2) : ((bytesLeft - 1) / 2);
this.strings.add(s.substring(0, charsAvailable));
this.byteCount += charsAvailable * 2 + 3;
return s.length() - charsAvailable;
}
public byte[] getData() {
this.data = new byte[this.byteCount];
int pos = 0;
if (this.includeLength) {
IntegerHelper.getTwoBytes(this.firstStringLength, this.data, 0);
this.data[2] = 1;
pos = 3;
} else {
this.data[0] = 1;
pos = 1;
}
StringHelper.getUnicodeBytes(this.firstString, this.data, pos);
pos += this.firstString.length() * 2;
Iterator i = this.strings.iterator();
String s = null;
int length = 0;
int count = 0;
while (i.hasNext()) {
s = i.next();
length = ((Integer)this.stringLengths.get(count)).intValue();
IntegerHelper.getTwoBytes(length, this.data, pos);
this.data[pos + 2] = 1;
StringHelper.getUnicodeBytes(s, this.data, pos + 3);
pos += s.length() * 2 + 3;
count++;
}
return this.data;
}
}

View File

@@ -0,0 +1,75 @@
package jxl.write.biff;
import java.util.ArrayList;
import java.util.Iterator;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SSTRecord extends WritableRecordData {
private int numReferences;
private int numStrings;
private ArrayList strings;
private ArrayList stringLengths;
private byte[] data;
private int byteCount;
private static int maxBytes = 8216;
public SSTRecord(int numRefs, int s) {
super(Type.SST);
this.numReferences = numRefs;
this.numStrings = s;
this.byteCount = 0;
this.strings = new ArrayList(50);
this.stringLengths = new ArrayList(50);
}
public int add(String s) {
int bytes = s.length() * 2 + 3;
if (this.byteCount >= maxBytes - 5)
return (s.length() > 0) ? s.length() : -1;
this.stringLengths.add(new Integer(s.length()));
if (bytes + this.byteCount < maxBytes) {
this.strings.add(s);
this.byteCount += bytes;
return 0;
}
int bytesLeft = maxBytes - 3 - this.byteCount;
int charsAvailable = (bytesLeft % 2 == 0) ? (bytesLeft / 2) : ((bytesLeft - 1) / 2);
this.strings.add(s.substring(0, charsAvailable));
this.byteCount += charsAvailable * 2 + 3;
return s.length() - charsAvailable;
}
public int getOffset() {
return this.byteCount + 8;
}
public byte[] getData() {
this.data = new byte[this.byteCount + 8];
IntegerHelper.getFourBytes(this.numReferences, this.data, 0);
IntegerHelper.getFourBytes(this.numStrings, this.data, 4);
int pos = 8;
int count = 0;
Iterator i = this.strings.iterator();
String s = null;
int length = 0;
while (i.hasNext()) {
s = i.next();
length = ((Integer)this.stringLengths.get(count)).intValue();
IntegerHelper.getTwoBytes(length, this.data, pos);
this.data[pos + 2] = 1;
StringHelper.getUnicodeBytes(s, this.data, pos + 3);
pos += s.length() * 2 + 3;
count++;
}
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SaveRecalcRecord extends WritableRecordData {
private byte[] data;
private boolean recalc;
public SaveRecalcRecord(boolean r) {
super(Type.SAVERECALC);
this.recalc = r;
this.data = new byte[2];
if (this.recalc)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class ScenarioProtectRecord extends WritableRecordData {
private boolean protection;
private byte[] data;
public ScenarioProtectRecord(boolean prot) {
super(Type.SCENPROTECT);
this.protection = prot;
this.data = new byte[2];
if (this.protection)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,49 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SelectionRecord extends WritableRecordData {
private PaneType pane;
private int column;
private int row;
private static class PaneType {
int val;
PaneType(int v) {
this.val = v;
}
}
public static final PaneType lowerRight = new PaneType(0);
public static final PaneType upperRight = new PaneType(1);
public static final PaneType lowerLeft = new PaneType(2);
public static final PaneType upperLeft = new PaneType(3);
public SelectionRecord(PaneType pt, int col, int r) {
super(Type.SELECTION);
this.column = col;
this.row = r;
this.pane = pt;
}
public byte[] getData() {
byte[] data = new byte[15];
data[0] = (byte)this.pane.val;
IntegerHelper.getTwoBytes(this.row, data, 1);
IntegerHelper.getTwoBytes(this.column, data, 3);
data[7] = 1;
IntegerHelper.getTwoBytes(this.row, data, 9);
IntegerHelper.getTwoBytes(this.row, data, 11);
data[13] = (byte)this.column;
data[14] = (byte)this.column;
return data;
}
}

View File

@@ -0,0 +1,113 @@
package jxl.write.biff;
import common.Logger;
import jxl.SheetSettings;
import jxl.biff.DoubleHelper;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
import jxl.format.PageOrientation;
import jxl.format.PaperSize;
class SetupRecord extends WritableRecordData {
Logger logger = Logger.getLogger(SetupRecord.class);
private byte[] data;
private double headerMargin;
private double footerMargin;
private PageOrientation orientation;
private int paperSize;
private int scaleFactor;
private int pageStart;
private int fitWidth;
private int fitHeight;
private int horizontalPrintResolution;
private int verticalPrintResolution;
private int copies;
public SetupRecord() {
super(Type.SETUP);
this.orientation = PageOrientation.PORTRAIT;
this.headerMargin = 0.5D;
this.footerMargin = 0.5D;
this.paperSize = PaperSize.A4.getValue();
this.horizontalPrintResolution = 300;
this.verticalPrintResolution = 300;
this.copies = 1;
}
public SetupRecord(SheetSettings s) {
super(Type.SETUP);
this.orientation = s.getOrientation();
this.headerMargin = s.getHeaderMargin();
this.footerMargin = s.getFooterMargin();
this.paperSize = s.getPaperSize().getValue();
this.horizontalPrintResolution = s.getHorizontalPrintResolution();
this.verticalPrintResolution = s.getVerticalPrintResolution();
this.fitWidth = s.getFitWidth();
this.fitHeight = s.getFitHeight();
this.pageStart = s.getPageStart();
this.scaleFactor = s.getScaleFactor();
this.copies = s.getCopies();
}
public SetupRecord(jxl.read.biff.SetupRecord sr) {
super(Type.SETUP);
this.orientation = sr.isPortrait() ? PageOrientation.PORTRAIT : PageOrientation.LANDSCAPE;
this.paperSize = sr.getPaperSize();
this.headerMargin = sr.getHeaderMargin();
this.footerMargin = sr.getFooterMargin();
this.scaleFactor = sr.getScaleFactor();
this.pageStart = sr.getPageStart();
this.fitWidth = sr.getFitWidth();
this.fitHeight = sr.getFitHeight();
this.horizontalPrintResolution = sr.getHorizontalPrintResolution();
this.verticalPrintResolution = sr.getVerticalPrintResolution();
this.copies = sr.getCopies();
}
public void setOrientation(PageOrientation o) {
this.orientation = o;
}
public void setMargins(double hm, double fm) {
this.headerMargin = hm;
this.footerMargin = fm;
}
public void setPaperSize(PaperSize ps) {
this.paperSize = ps.getValue();
}
public byte[] getData() {
this.data = new byte[34];
IntegerHelper.getTwoBytes(this.paperSize, this.data, 0);
IntegerHelper.getTwoBytes(this.scaleFactor, this.data, 2);
IntegerHelper.getTwoBytes(this.pageStart, this.data, 4);
IntegerHelper.getTwoBytes(this.fitWidth, this.data, 6);
IntegerHelper.getTwoBytes(this.fitHeight, this.data, 8);
int options = 0;
if (this.orientation == PageOrientation.PORTRAIT)
options |= 0x2;
if (this.pageStart != 0)
options |= 0x80;
IntegerHelper.getTwoBytes(options, this.data, 10);
IntegerHelper.getTwoBytes(this.horizontalPrintResolution, this.data, 12);
IntegerHelper.getTwoBytes(this.verticalPrintResolution, this.data, 14);
DoubleHelper.getIEEEBytes(this.headerMargin, this.data, 16);
DoubleHelper.getIEEEBytes(this.footerMargin, this.data, 24);
IntegerHelper.getTwoBytes(this.copies, this.data, 32);
return this.data;
}
}

View File

@@ -0,0 +1,83 @@
package jxl.write.biff;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import jxl.biff.ByteData;
class SharedStrings {
private HashMap strings = new HashMap(100);
private ArrayList stringList = new ArrayList(100);
private int totalOccurrences = 0;
public int getIndex(String s) {
Integer i = (Integer)this.strings.get(s);
if (i == null) {
i = new Integer(this.strings.size());
this.strings.put(s, i);
this.stringList.add(s);
}
this.totalOccurrences++;
return i.intValue();
}
public String get(int i) {
return this.stringList.get(i);
}
public void write(File outputFile) throws IOException {
int charsLeft = 0;
String curString = null;
SSTRecord sst = new SSTRecord(this.totalOccurrences, this.stringList.size());
ExtendedSSTRecord extsst = new ExtendedSSTRecord(this.stringList.size());
int bucketSize = extsst.getNumberOfStringsPerBucket();
Iterator i = this.stringList.iterator();
int stringIndex = 0;
while (i.hasNext() && charsLeft == 0) {
curString = i.next();
int relativePosition = sst.getOffset() + 4;
charsLeft = sst.add(curString);
if (stringIndex % bucketSize == 0)
extsst.addString(outputFile.getPos(), relativePosition);
stringIndex++;
}
outputFile.write((ByteData)sst);
if (charsLeft != 0 || i.hasNext()) {
SSTContinueRecord cont = createContinueRecord(curString, charsLeft, outputFile);
while (i.hasNext()) {
curString = i.next();
int relativePosition = cont.getOffset() + 4;
charsLeft = cont.add(curString);
if (stringIndex % bucketSize == 0)
extsst.addString(outputFile.getPos(), relativePosition);
stringIndex++;
if (charsLeft != 0) {
outputFile.write((ByteData)cont);
cont = createContinueRecord(curString, charsLeft, outputFile);
}
}
outputFile.write((ByteData)cont);
}
outputFile.write((ByteData)extsst);
}
private SSTContinueRecord createContinueRecord(String curString, int charsLeft, File outputFile) throws IOException {
SSTContinueRecord cont = null;
while (charsLeft != 0) {
cont = new SSTContinueRecord();
if (charsLeft == curString.length() || curString.length() == 0) {
charsLeft = cont.setFirstString(curString, true);
} else {
charsLeft = cont.setFirstString(curString.substring(curString.length() - charsLeft), false);
}
if (charsLeft != 0) {
outputFile.write((ByteData)cont);
cont = new SSTContinueRecord();
}
}
return cont;
}
}

View File

@@ -0,0 +1,475 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
import jxl.Cell;
import jxl.Range;
import jxl.SheetSettings;
import jxl.WorkbookSettings;
import jxl.biff.ByteData;
import jxl.biff.WorkspaceInformationRecord;
import jxl.biff.XFRecord;
import jxl.biff.drawing.Chart;
import jxl.biff.drawing.SheetDrawingWriter;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.CellFormat;
import jxl.format.Colour;
import jxl.write.Blank;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableHyperlink;
import jxl.write.WriteException;
final class SheetWriter {
private static Logger logger = Logger.getLogger(SheetWriter.class);
private File outputFile;
private RowRecord[] rows;
private int numRows;
private int numCols;
private HeaderRecord header;
private FooterRecord footer;
private SheetSettings settings;
private WorkbookSettings workbookSettings;
private ArrayList rowBreaks;
private ArrayList hyperlinks;
private DataValidation dataValidation;
private MergedCells mergedCells;
private PLSRecord plsRecord;
private ButtonPropertySetRecord buttonPropertySet;
private WorkspaceInformationRecord workspaceOptions;
private TreeSet columnFormats;
private SheetDrawingWriter drawingWriter;
private boolean chartOnly;
private WritableSheetImpl sheet;
public SheetWriter(File of, WritableSheetImpl wsi, WorkbookSettings ws) {
this.outputFile = of;
this.sheet = wsi;
this.workspaceOptions = new WorkspaceInformationRecord();
this.workbookSettings = ws;
this.chartOnly = false;
this.drawingWriter = new SheetDrawingWriter(ws);
}
public void write() throws IOException {
Assert.verify((this.rows != null));
if (this.chartOnly) {
this.drawingWriter.write(this.outputFile);
return;
}
BOFRecord bof = new BOFRecord(BOFRecord.sheet);
this.outputFile.write((ByteData)bof);
int numBlocks = this.numRows / 32;
if (this.numRows - numBlocks * 32 != 0)
numBlocks++;
int indexPos = this.outputFile.getPos();
IndexRecord indexRecord = new IndexRecord(0, this.numRows, numBlocks);
this.outputFile.write((ByteData)indexRecord);
if (this.settings.getAutomaticFormulaCalculation()) {
CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.automatic);
this.outputFile.write((ByteData)cmr);
} else {
CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.manual);
this.outputFile.write((ByteData)cmr);
}
CalcCountRecord ccr = new CalcCountRecord(100);
this.outputFile.write((ByteData)ccr);
RefModeRecord rmr = new RefModeRecord();
this.outputFile.write((ByteData)rmr);
IterationRecord itr = new IterationRecord(false);
this.outputFile.write((ByteData)itr);
DeltaRecord dtr = new DeltaRecord(0.001D);
this.outputFile.write((ByteData)dtr);
SaveRecalcRecord srr = new SaveRecalcRecord(this.settings.getRecalculateFormulasBeforeSave());
this.outputFile.write((ByteData)srr);
PrintHeadersRecord phr = new PrintHeadersRecord(this.settings.getPrintHeaders());
this.outputFile.write((ByteData)phr);
PrintGridLinesRecord pglr = new PrintGridLinesRecord(this.settings.getPrintGridLines());
this.outputFile.write((ByteData)pglr);
GridSetRecord gsr = new GridSetRecord(true);
this.outputFile.write((ByteData)gsr);
GuttersRecord gutr = new GuttersRecord();
this.outputFile.write((ByteData)gutr);
DefaultRowHeightRecord drhr = new DefaultRowHeightRecord(this.settings.getDefaultRowHeight(), (this.settings.getDefaultRowHeight() != 255));
this.outputFile.write((ByteData)drhr);
this.workspaceOptions.setFitToPages(this.settings.getFitToPages());
this.outputFile.write((ByteData)this.workspaceOptions);
if (this.rowBreaks.size() > 0) {
int[] rb = new int[this.rowBreaks.size()];
for (int i = 0; i < rb.length; i++)
rb[i] = ((Integer)this.rowBreaks.get(i)).intValue();
HorizontalPageBreaksRecord hpbr = new HorizontalPageBreaksRecord(rb);
this.outputFile.write((ByteData)hpbr);
}
HeaderRecord header = new HeaderRecord(this.settings.getHeader().toString());
this.outputFile.write((ByteData)header);
FooterRecord footer = new FooterRecord(this.settings.getFooter().toString());
this.outputFile.write((ByteData)footer);
HorizontalCentreRecord hcr = new HorizontalCentreRecord(this.settings.isHorizontalCentre());
this.outputFile.write((ByteData)hcr);
VerticalCentreRecord vcr = new VerticalCentreRecord(this.settings.isVerticalCentre());
this.outputFile.write((ByteData)vcr);
if (this.settings.getLeftMargin() != this.settings.getDefaultWidthMargin()) {
MarginRecord mr = new LeftMarginRecord(this.settings.getLeftMargin());
this.outputFile.write((ByteData)mr);
}
if (this.settings.getRightMargin() != this.settings.getDefaultWidthMargin()) {
MarginRecord mr = new RightMarginRecord(this.settings.getRightMargin());
this.outputFile.write((ByteData)mr);
}
if (this.settings.getTopMargin() != this.settings.getDefaultHeightMargin()) {
MarginRecord mr = new TopMarginRecord(this.settings.getTopMargin());
this.outputFile.write((ByteData)mr);
}
if (this.settings.getBottomMargin() != this.settings.getDefaultHeightMargin()) {
MarginRecord mr = new BottomMarginRecord(this.settings.getBottomMargin());
this.outputFile.write((ByteData)mr);
}
if (this.plsRecord != null)
this.outputFile.write((ByteData)this.plsRecord);
SetupRecord setup = new SetupRecord(this.settings);
this.outputFile.write((ByteData)setup);
if (this.settings.isProtected()) {
ProtectRecord pr = new ProtectRecord(this.settings.isProtected());
this.outputFile.write((ByteData)pr);
ScenarioProtectRecord spr = new ScenarioProtectRecord(this.settings.isProtected());
this.outputFile.write((ByteData)spr);
ObjectProtectRecord opr = new ObjectProtectRecord(this.settings.isProtected());
this.outputFile.write((ByteData)opr);
if (this.settings.getPassword() != null) {
PasswordRecord pw = new PasswordRecord(this.settings.getPassword());
this.outputFile.write((ByteData)pw);
} else if (this.settings.getPasswordHash() != 0) {
PasswordRecord pw = new PasswordRecord(this.settings.getPasswordHash());
this.outputFile.write((ByteData)pw);
}
}
indexRecord.setDataStartPosition(this.outputFile.getPos());
DefaultColumnWidth dcw = new DefaultColumnWidth(this.settings.getDefaultColumnWidth());
this.outputFile.write((ByteData)dcw);
WritableCellFormat normalStyle = this.sheet.getWorkbook().getStyles().getNormalStyle();
WritableCellFormat defaultDateFormat = this.sheet.getWorkbook().getStyles().getDefaultDateFormat();
ColumnInfoRecord cir = null;
for (Iterator colit = this.columnFormats.iterator(); colit.hasNext(); ) {
cir = colit.next();
if (cir.getColumn() < 256)
this.outputFile.write((ByteData)cir);
XFRecord xfr = cir.getCellFormat();
if (xfr != normalStyle && cir.getColumn() < 256) {
Cell[] cells = getColumn(cir.getColumn());
for (int i = 0; i < cells.length; i++) {
if (cells[i] != null && (cells[i].getCellFormat() == normalStyle || cells[i].getCellFormat() == defaultDateFormat))
((WritableCell)cells[i]).setCellFormat((CellFormat)xfr);
}
}
}
DimensionRecord dr = new DimensionRecord(this.numRows, this.numCols);
this.outputFile.write((ByteData)dr);
for (int block = 0; block < numBlocks; block++) {
DBCellRecord dbcell = new DBCellRecord(this.outputFile.getPos());
int blockRows = Math.min(32, this.numRows - block * 32);
boolean firstRow = true;
int i;
for (i = block * 32; i < block * 32 + blockRows; i++) {
if (this.rows[i] != null) {
this.rows[i].write(this.outputFile);
if (firstRow) {
dbcell.setCellOffset(this.outputFile.getPos());
firstRow = false;
}
}
}
for (i = block * 32; i < block * 32 + blockRows; i++) {
if (this.rows[i] != null) {
dbcell.addCellRowPosition(this.outputFile.getPos());
this.rows[i].writeCells(this.outputFile);
}
}
indexRecord.addBlockPosition(this.outputFile.getPos());
dbcell.setPosition(this.outputFile.getPos());
this.outputFile.write((ByteData)dbcell);
}
if (this.dataValidation != null)
this.dataValidation.write(this.outputFile);
if (!this.workbookSettings.getDrawingsDisabled())
this.drawingWriter.write(this.outputFile);
Window2Record w2r = new Window2Record(this.settings);
this.outputFile.write((ByteData)w2r);
if (this.settings.getHorizontalFreeze() != 0 || this.settings.getVerticalFreeze() != 0) {
PaneRecord pr = new PaneRecord(this.settings.getHorizontalFreeze(), this.settings.getVerticalFreeze());
this.outputFile.write((ByteData)pr);
SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0);
this.outputFile.write((ByteData)sr);
if (this.settings.getHorizontalFreeze() != 0) {
sr = new SelectionRecord(SelectionRecord.upperRight, this.settings.getHorizontalFreeze(), 0);
this.outputFile.write((ByteData)sr);
}
if (this.settings.getVerticalFreeze() != 0) {
sr = new SelectionRecord(SelectionRecord.lowerLeft, 0, this.settings.getVerticalFreeze());
this.outputFile.write((ByteData)sr);
}
if (this.settings.getHorizontalFreeze() != 0 && this.settings.getVerticalFreeze() != 0) {
sr = new SelectionRecord(SelectionRecord.lowerRight, this.settings.getHorizontalFreeze(), this.settings.getVerticalFreeze());
this.outputFile.write((ByteData)sr);
}
Weird1Record w1r = new Weird1Record();
this.outputFile.write((ByteData)w1r);
} else {
SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0);
this.outputFile.write((ByteData)sr);
}
if (this.settings.getZoomFactor() != 100) {
SCLRecord sclr = new SCLRecord(this.settings.getZoomFactor());
this.outputFile.write((ByteData)sclr);
}
this.mergedCells.write(this.outputFile);
Iterator hi = this.hyperlinks.iterator();
WritableHyperlink hlr = null;
while (hi.hasNext()) {
hlr = hi.next();
this.outputFile.write((ByteData)hlr);
}
if (this.buttonPropertySet != null)
this.outputFile.write((ByteData)this.buttonPropertySet);
EOFRecord eof = new EOFRecord();
this.outputFile.write((ByteData)eof);
this.outputFile.setData(indexRecord.getData(), indexPos + 4);
}
final HeaderRecord getHeader() {
return this.header;
}
final FooterRecord getFooter() {
return this.footer;
}
void setWriteData(RowRecord[] rws, ArrayList rb, ArrayList hl, MergedCells mc, TreeSet cf) {
this.rows = rws;
this.rowBreaks = rb;
this.hyperlinks = hl;
this.mergedCells = mc;
this.columnFormats = cf;
}
void setDimensions(int rws, int cls) {
this.numRows = rws;
this.numCols = cls;
}
void setSettings(SheetSettings sr) {
this.settings = sr;
}
WorkspaceInformationRecord getWorkspaceOptions() {
return this.workspaceOptions;
}
void setWorkspaceOptions(WorkspaceInformationRecord wo) {
if (wo != null)
this.workspaceOptions = wo;
}
void setCharts(Chart[] ch) {
this.drawingWriter.setCharts(ch);
}
void setDrawings(ArrayList dr, boolean mod) {
this.drawingWriter.setDrawings(dr, mod);
}
Chart[] getCharts() {
return this.drawingWriter.getCharts();
}
void checkMergedBorders() {
Range[] mcells = this.mergedCells.getMergedCells();
ArrayList borderFormats = new ArrayList();
for (int mci = 0; mci < mcells.length; mci++) {
Range range = mcells[mci];
Cell topLeft = range.getTopLeft();
XFRecord tlformat = (XFRecord)topLeft.getCellFormat();
if (tlformat != null && tlformat.hasBorders() == true && !tlformat.isRead())
try {
CellXFRecord cf1 = new CellXFRecord(tlformat);
Cell bottomRight = range.getBottomRight();
cf1.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf1.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT));
cf1.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));
if (topLeft.getRow() == bottomRight.getRow())
cf1.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM));
if (topLeft.getColumn() == bottomRight.getColumn())
cf1.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT));
int index = borderFormats.indexOf(cf1);
if (index != -1) {
cf1 = borderFormats.get(index);
} else {
borderFormats.add(cf1);
}
((WritableCell)topLeft).setCellFormat((CellFormat)cf1);
if (bottomRight.getRow() > topLeft.getRow()) {
if (bottomRight.getColumn() != topLeft.getColumn()) {
CellXFRecord cf2 = new CellXFRecord(tlformat);
cf2.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf2.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT));
cf2.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM));
index = borderFormats.indexOf(cf2);
if (index != -1) {
cf2 = borderFormats.get(index);
} else {
borderFormats.add(cf2);
}
this.sheet.addCell((WritableCell)new Blank(topLeft.getColumn(), bottomRight.getRow(), (CellFormat)cf2));
}
for (int i = topLeft.getRow() + 1; i < bottomRight.getRow(); i++) {
CellXFRecord cf3 = new CellXFRecord(tlformat);
cf3.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf3.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT));
if (topLeft.getColumn() == bottomRight.getColumn())
cf3.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT));
index = borderFormats.indexOf(cf3);
if (index != -1) {
cf3 = borderFormats.get(index);
} else {
borderFormats.add(cf3);
}
this.sheet.addCell((WritableCell)new Blank(topLeft.getColumn(), i, (CellFormat)cf3));
}
}
if (bottomRight.getColumn() > topLeft.getColumn()) {
if (bottomRight.getRow() != topLeft.getRow()) {
CellXFRecord cf6 = new CellXFRecord(tlformat);
cf6.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf6.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT));
cf6.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));
index = borderFormats.indexOf(cf6);
if (index != -1) {
cf6 = borderFormats.get(index);
} else {
borderFormats.add(cf6);
}
this.sheet.addCell((WritableCell)new Blank(bottomRight.getColumn(), topLeft.getRow(), (CellFormat)cf6));
}
int i = topLeft.getRow() + 1;
for (; i < bottomRight.getRow(); i++) {
CellXFRecord cf7 = new CellXFRecord(tlformat);
cf7.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf7.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT));
index = borderFormats.indexOf(cf7);
if (index != -1) {
cf7 = borderFormats.get(index);
} else {
borderFormats.add(cf7);
}
this.sheet.addCell((WritableCell)new Blank(bottomRight.getColumn(), i, (CellFormat)cf7));
}
i = topLeft.getColumn() + 1;
for (; i < bottomRight.getColumn(); i++) {
CellXFRecord cf8 = new CellXFRecord(tlformat);
cf8.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf8.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));
if (topLeft.getRow() == bottomRight.getRow())
cf8.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM));
index = borderFormats.indexOf(cf8);
if (index != -1) {
cf8 = borderFormats.get(index);
} else {
borderFormats.add(cf8);
}
this.sheet.addCell((WritableCell)new Blank(i, topLeft.getRow(), (CellFormat)cf8));
}
}
if (bottomRight.getColumn() > topLeft.getColumn() || bottomRight.getRow() > topLeft.getRow()) {
CellXFRecord cf4 = new CellXFRecord(tlformat);
cf4.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf4.setBorder(Border.RIGHT, tlformat.getBorderLine(Border.RIGHT), tlformat.getBorderColour(Border.RIGHT));
cf4.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM));
if (bottomRight.getRow() == topLeft.getRow())
cf4.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));
if (bottomRight.getColumn() == topLeft.getColumn())
cf4.setBorder(Border.LEFT, tlformat.getBorderLine(Border.LEFT), tlformat.getBorderColour(Border.LEFT));
index = borderFormats.indexOf(cf4);
if (index != -1) {
cf4 = borderFormats.get(index);
} else {
borderFormats.add(cf4);
}
this.sheet.addCell((WritableCell)new Blank(bottomRight.getColumn(), bottomRight.getRow(), (CellFormat)cf4));
int i = topLeft.getColumn() + 1;
for (; i < bottomRight.getColumn(); i++) {
CellXFRecord cf5 = new CellXFRecord(tlformat);
cf5.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
cf5.setBorder(Border.BOTTOM, tlformat.getBorderLine(Border.BOTTOM), tlformat.getBorderColour(Border.BOTTOM));
if (topLeft.getRow() == bottomRight.getRow())
cf5.setBorder(Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));
index = borderFormats.indexOf(cf5);
if (index != -1) {
cf5 = borderFormats.get(index);
} else {
borderFormats.add(cf5);
}
this.sheet.addCell((WritableCell)new Blank(i, bottomRight.getRow(), (CellFormat)cf5));
}
}
} catch (WriteException e) {
logger.warn(e.toString());
}
}
}
private Cell[] getColumn(int col) {
boolean found = false;
int row = this.numRows - 1;
while (row >= 0 && !found) {
if (this.rows[row] != null && this.rows[row].getCell(col) != null) {
found = true;
continue;
}
row--;
}
Cell[] cells = new Cell[row + 1];
for (int i = 0; i <= row; i++)
cells[i] = (this.rows[i] != null) ? (Cell)this.rows[i].getCell(col) : null;
return cells;
}
void setChartOnly() {
this.chartOnly = true;
}
void setPLS(PLSRecord pls) {
this.plsRecord = pls;
}
void setButtonPropertySet(ButtonPropertySetRecord bps) {
this.buttonPropertySet = bps;
}
void setDataValidation(DataValidation dv) {
this.dataValidation = dv;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class StringRecord extends WritableRecordData {
private String value;
public StringRecord(String val) {
super(Type.STRING);
this.value = val;
}
public byte[] getData() {
byte[] data = new byte[this.value.length() * 2 + 3];
IntegerHelper.getTwoBytes(this.value.length(), data, 0);
data[2] = 1;
StringHelper.getUnicodeBytes(this.value, data, 3);
return data;
}
}

View File

@@ -0,0 +1,20 @@
package jxl.write.biff;
import jxl.biff.DisplayFormat;
import jxl.biff.FontRecord;
import jxl.biff.XFRecord;
public class StyleXFRecord extends XFRecord {
public StyleXFRecord(FontRecord fnt, DisplayFormat form) {
super(fnt, form);
setXFDetails(XFRecord.style, 65520);
}
public final void setCellOptions(int opt) {
setXFCellOptions(opt);
}
public void setLocked(boolean l) {
setXFLocked(l);
}
}

View File

@@ -0,0 +1,110 @@
package jxl.write.biff;
import common.Logger;
import jxl.biff.DisplayFormat;
import jxl.biff.FontRecord;
import jxl.biff.XFRecord;
import jxl.format.Font;
import jxl.write.DateFormat;
import jxl.write.DateFormats;
import jxl.write.NumberFormats;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableWorkbook;
class Styles {
private static Logger logger = Logger.getLogger(Styles.class);
private WritableFont arial10pt = null;
private WritableFont hyperlinkFont = null;
private WritableCellFormat normalStyle = null;
private WritableCellFormat hyperlinkStyle = null;
private WritableCellFormat hiddenStyle = null;
private WritableCellFormat defaultDateFormat;
private synchronized void initNormalStyle() {
this.normalStyle = new WritableCellFormat(getArial10Pt(), NumberFormats.DEFAULT);
this.normalStyle.setFont((FontRecord)getArial10Pt());
}
public WritableCellFormat getNormalStyle() {
if (this.normalStyle == null)
initNormalStyle();
return this.normalStyle;
}
private synchronized void initHiddenStyle() {
this.hiddenStyle = new WritableCellFormat(getArial10Pt(), (DisplayFormat)new DateFormat(";;;"));
}
public WritableCellFormat getHiddenStyle() {
if (this.hiddenStyle == null)
initHiddenStyle();
return this.hiddenStyle;
}
private synchronized void initHyperlinkStyle() {
this.hyperlinkStyle = new WritableCellFormat(getHyperlinkFont(), NumberFormats.DEFAULT);
}
public WritableCellFormat getHyperlinkStyle() {
if (this.hyperlinkStyle == null)
initHyperlinkStyle();
return this.hyperlinkStyle;
}
private synchronized void initArial10Pt() {
this.arial10pt = new WritableFont((Font)WritableWorkbook.ARIAL_10_PT);
}
public WritableFont getArial10Pt() {
if (this.arial10pt == null)
initArial10Pt();
return this.arial10pt;
}
private synchronized void initHyperlinkFont() {
this.hyperlinkFont = new WritableFont((Font)WritableWorkbook.HYPERLINK_FONT);
}
public WritableFont getHyperlinkFont() {
if (this.hyperlinkFont == null)
initHyperlinkFont();
return this.hyperlinkFont;
}
private synchronized void initDefaultDateFormat() {
this.defaultDateFormat = new WritableCellFormat(DateFormats.DEFAULT);
}
public WritableCellFormat getDefaultDateFormat() {
if (this.defaultDateFormat == null)
initDefaultDateFormat();
return this.defaultDateFormat;
}
public XFRecord getFormat(XFRecord wf) {
WritableCellFormat writableCellFormat;
XFRecord format = wf;
if (format == WritableWorkbook.NORMAL_STYLE) {
writableCellFormat = getNormalStyle();
} else if (writableCellFormat == WritableWorkbook.HYPERLINK_STYLE) {
writableCellFormat = getHyperlinkStyle();
} else if (writableCellFormat == WritableWorkbook.HIDDEN_STYLE) {
writableCellFormat = getHiddenStyle();
} else if (writableCellFormat == DateRecord.defaultDateFormat) {
writableCellFormat = getDefaultDateFormat();
}
if (writableCellFormat.getFont() == WritableWorkbook.ARIAL_10_PT) {
writableCellFormat.setFont((FontRecord)getArial10Pt());
} else if (writableCellFormat.getFont() == WritableWorkbook.HYPERLINK_FONT) {
writableCellFormat.setFont((FontRecord)getHyperlinkFont());
}
return (XFRecord)writableCellFormat;
}
}

View File

@@ -0,0 +1,158 @@
package jxl.write.biff;
import common.Assert;
import common.Logger;
import jxl.WorkbookSettings;
import jxl.biff.EncodedURLHelper;
import jxl.biff.IntegerHelper;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class SupbookRecord extends WritableRecordData {
private static Logger logger = Logger.getLogger(SupbookRecord.class);
private SupbookType type;
private byte[] data;
private int numSheets;
private String fileName;
private String[] sheetNames;
private WorkbookSettings workbookSettings;
private static class SupbookType {
private SupbookType() {}
}
public static final SupbookType INTERNAL = new SupbookType();
public static final SupbookType EXTERNAL = new SupbookType();
public static final SupbookType ADDIN = new SupbookType();
public static final SupbookType LINK = new SupbookType();
public static final SupbookType UNKNOWN = new SupbookType();
public SupbookRecord(int sheets, WorkbookSettings ws) {
super(Type.SUPBOOK);
this.numSheets = sheets;
this.type = INTERNAL;
this.workbookSettings = ws;
}
public SupbookRecord(String fn, WorkbookSettings ws) {
super(Type.SUPBOOK);
this.fileName = fn;
this.numSheets = 1;
this.sheetNames = new String[0];
this.workbookSettings = ws;
this.type = EXTERNAL;
}
public SupbookRecord(jxl.read.biff.SupbookRecord sr, WorkbookSettings ws) {
super(Type.SUPBOOK);
this.workbookSettings = ws;
if (sr.getType() == jxl.read.biff.SupbookRecord.INTERNAL) {
this.type = INTERNAL;
this.numSheets = sr.getNumberOfSheets();
} else if (sr.getType() == jxl.read.biff.SupbookRecord.EXTERNAL) {
this.type = EXTERNAL;
this.numSheets = sr.getNumberOfSheets();
this.fileName = sr.getFileName();
this.sheetNames = new String[this.numSheets];
for (int i = 0; i < this.numSheets; i++)
this.sheetNames[i] = sr.getSheetName(i);
}
}
private void initInternal(jxl.read.biff.SupbookRecord sr) {
this.numSheets = sr.getNumberOfSheets();
initInternal();
}
private void initInternal() {
this.data = new byte[4];
IntegerHelper.getTwoBytes(this.numSheets, this.data, 0);
this.data[2] = 1;
this.data[3] = 4;
this.type = INTERNAL;
}
void adjustInternal(int sheets) {
Assert.verify((this.type == INTERNAL));
this.numSheets = sheets;
initInternal();
}
private void initExternal() {
int totalSheetNameLength = 0;
for (int i = 0; i < this.numSheets; i++)
totalSheetNameLength += this.sheetNames[i].length();
byte[] fileNameData = EncodedURLHelper.getEncodedURL(this.fileName, this.workbookSettings);
int dataLength = 6 + fileNameData.length + this.numSheets * 3 + totalSheetNameLength * 2;
this.data = new byte[dataLength];
IntegerHelper.getTwoBytes(this.numSheets, this.data, 0);
int pos = 2;
IntegerHelper.getTwoBytes(fileNameData.length + 1, this.data, pos);
this.data[pos + 2] = 0;
this.data[pos + 3] = 1;
System.arraycopy(fileNameData, 0, this.data, pos + 4, fileNameData.length);
pos += 4 + fileNameData.length;
for (int j = 0; j < this.sheetNames.length; j++) {
IntegerHelper.getTwoBytes(this.sheetNames[j].length(), this.data, pos);
this.data[pos + 2] = 1;
StringHelper.getUnicodeBytes(this.sheetNames[j], this.data, pos + 3);
pos += 3 + this.sheetNames[j].length() * 2;
}
}
public byte[] getData() {
if (this.type == INTERNAL) {
initInternal();
} else if (this.type == EXTERNAL) {
initExternal();
} else {
logger.warn("unsupported supbook type - defaulting to internal");
initInternal();
}
return this.data;
}
public SupbookType getType() {
return this.type;
}
public int getNumberOfSheets() {
return this.numSheets;
}
public String getFileName() {
return this.fileName;
}
public int getSheetIndex(String s) {
boolean found = false;
int sheetIndex = 0;
for (int i = 0; i < this.sheetNames.length && !found; i++) {
if (this.sheetNames[i].equals(s)) {
found = true;
sheetIndex = 0;
}
}
if (found)
return sheetIndex;
String[] names = new String[this.sheetNames.length + 1];
names[this.sheetNames.length] = s;
this.sheetNames = names;
return this.sheetNames.length - 1;
}
public String getSheetName(int s) {
return this.sheetNames[s];
}
}

View File

@@ -0,0 +1,20 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class TabIdRecord extends WritableRecordData {
private byte[] data;
public TabIdRecord(int sheets) {
super(Type.TABID);
this.data = new byte[sheets * 2];
for (int i = 0; i < sheets; i++)
IntegerHelper.getTwoBytes(i + 1, this.data, i * 2);
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,9 @@
package jxl.write.biff;
import jxl.biff.Type;
class TopMarginRecord extends MarginRecord {
TopMarginRecord(double v) {
super(Type.TOPMARGIN, v);
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class UsesElfsRecord extends WritableRecordData {
private byte[] data;
private boolean usesElfs;
public UsesElfsRecord() {
super(Type.USESELFS);
this.usesElfs = true;
this.data = new byte[2];
if (this.usesElfs)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,22 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class VerticalCentreRecord extends WritableRecordData {
private byte[] data;
private boolean centre;
public VerticalCentreRecord(boolean ce) {
super(Type.VCENTER);
this.centre = ce;
this.data = new byte[2];
if (this.centre)
this.data[0] = 1;
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,16 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class Weird1Record extends WritableRecordData {
public Weird1Record() {
super(Type.WEIRD1);
}
public byte[] getData() {
byte[] data = new byte[6];
data[2] = 55;
return data;
}
}

View File

@@ -0,0 +1,19 @@
package jxl.write.biff;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class Window1Record extends WritableRecordData {
private byte[] data;
public Window1Record() {
super(Type.WINDOW1);
this.data = new byte[] {
104, 1, 14, 1, 92, 58, -66, 35, 56, 0,
0, 0, 0, 0, 1, 0, 88, 2 };
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,35 @@
package jxl.write.biff;
import jxl.SheetSettings;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class Window2Record extends WritableRecordData {
private byte[] data;
public Window2Record(SheetSettings settings) {
super(Type.WINDOW2);
int selected = settings.isSelected() ? 6 : 0;
int options = 0;
options |= 0x0;
if (settings.getShowGridLines())
options |= 0x2;
options |= 0x4;
options |= 0x0;
if (settings.getDisplayZeroValues())
options |= 0x10;
options |= 0x20;
options |= 0x80;
if (settings.getHorizontalFreeze() != 0 || settings.getVerticalFreeze() != 0) {
options |= 0x8;
selected |= 0x1;
}
this.data = new byte[] {
(byte)options, (byte)selected, 0, 0, 0, 0, 64, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
}
public byte[] getData() {
return this.data;
}
}

View File

@@ -0,0 +1,23 @@
package jxl.write.biff;
import jxl.biff.IntegerHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
class WindowProtectRecord extends WritableRecordData {
private boolean protection;
private byte[] data;
public WindowProtectRecord(boolean prot) {
super(Type.WINDOWPROTECT);
this.protection = prot;
this.data = new byte[2];
if (this.protection)
IntegerHelper.getTwoBytes(1, this.data, 0);
}
public byte[] getData() {
return this.data;
}
}

Some files were not shown because too many files have changed in this diff Show More