264 lines
7.1 KiB
Java
264 lines
7.1 KiB
Java
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;
|
|
}
|
|
}
|