fpspreadsheet: Write column and row formats to biff5/biff8

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5252 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-10-08 17:57:29 +00:00
parent 33f7d1b3af
commit 547331def4
6 changed files with 63 additions and 34 deletions

View File

@ -2044,9 +2044,16 @@ end;
(e.g., during reading into empty worksheets).
-------------------------------------------------------------------------------}
function TsWorksheet.AddCell(ARow, ACol: Cardinal): PCell;
var
fmtIndex: Integer;
begin
Result := Cells.AddCell(ARow, ACol);
fmtIndex := GetRowFormatIndex(ARow);
if fmtIndex = 0 then
fmtIndex := GetColFormatIndex(ACol);
Result^.FormatIndex := fmtIndex;
if FFirstColIndex = UNASSIGNED_ROW_COL_INDEX then
FFirstColIndex := GetFirstColIndex(true) else
FFirstColIndex := Min(FFirstColIndex, ACol);
@ -6366,8 +6373,8 @@ end;
pointer to the TCol record, or nil if not found
@param ACol Index of the column looked for
@return Pointer to the column record with this column index, or
nil if not found
@return Pointer to the column record with this column index, or nil
if not found
-------------------------------------------------------------------------------}
function TsWorksheet.FindCol(ACol: Cardinal): PCol;
var
@ -6490,14 +6497,14 @@ end;
-------------------------------------------------------------------------------}
function TsWorksheet.GetColFormatIndex(ACol: Cardinal): Integer;
var
col: PCol;
lCol: PCol;
begin
Result := 0; // Default format has index 0
if ACol <> UNASSIGNED_ROW_COL_INDEX then
begin
col := FindCol(ACol);
if col <> nil then
Result := col^.FormatIndex
lCol := FindCol(ACol);
if lCol <> nil then
Result := lCol^.FormatIndex
end;
end;
@ -6959,7 +6966,7 @@ end;
{@@ ----------------------------------------------------------------------------
Removes a specified column record from the worksheet and frees the occupied
memory. This resets its column width to default.
memory. This resets its column width and format to default.
Note: Cells in that column are retained.
-------------------------------------------------------------------------------}
@ -7125,6 +7132,7 @@ begin
exit;
lCol := GetCol(ACol);
lCol^.Width := FWorkbook.ConvertUnits(AWidth, AUnits, FWorkbook.FUnits);
lCol^.ColWidthType := cwtCustom;
end;
{@@ ----------------------------------------------------------------------------

View File

@ -325,20 +325,28 @@ const
var
c: Cardinal;
w: Single;
lCol: PCol;
begin
if AWorksheet.Cols.Count < 2 then
exit;
// Check whether all columns have the same column width
w := PCol(AWorksheet.Cols[0])^.Width;
for c := 1 to AWorksheet.Cols.Count-1 do
if not SameValue(PCol(AWorksheet.Cols[c])^.Width, w, EPS) then
for c := 1 to AWorksheet.Cols.Count-1 do begin
lCol := PCol(AWorksheet.Cols[c]);
if not SameValue(lCol^.Width, w, EPS) then
exit;
end;
// At this point we know that all columns have the same width. We pass this
// to the DefaultColWidth and delete all column records.
// to the DefaultColWidth ...
AWorksheet.WriteDefaultColWidth(w, FWorkbook.Units);
AWorksheet.RemoveAllCols;
// ...and delete all column records with non-default format
for c := AWorksheet.Cols.Count-1 downto 0 do begin
lCol := PCol(AWorksheet.Cols[c]);
if lCol^.FormatIndex = 0 then AWorksheet.RemoveCol(c);
end;
end;
{@@ ----------------------------------------------------------------------------
@ -352,20 +360,28 @@ const
var
r: Cardinal;
h: Single;
lRow: PRow;
begin
if AWorksheet.Rows.Count <= 1 then
exit;
// Check whether all rows have the same height
h := PRow(AWorksheet.Rows[0])^.Height;
for r := 1 to AWorksheet.Rows.Count-1 do
if not SameValue(PRow(AWorksheet.Rows[r])^.Height, h, EPS) then
for r := 1 to AWorksheet.Rows.Count-1 do begin
lRow := PRow(AWorksheet.Rows[r]);
if not SameValue(lRow^.Height, h, EPS) then
exit;
end;
// At this point we know that all rows have the same height. We pass this
// to the DefaultRowHeight and delete all row records.
// to the DefaultRowHeight ...
AWorksheet.WriteDefaultRowHeight(h, FWorkbook.Units);
AWorksheet.RemoveAllRows;
// ... and delete all row records with non-default format.
for r := AWorksheet.Rows.Count-1 downto 0 do begin
lRow := PRow(AWorksheet.Rows[r]);
if lRow^.FormatIndex = 0 then AWorksheet.RemoveRow(r);
end;
end;
{@@ ----------------------------------------------------------------------------

View File

@ -1659,7 +1659,7 @@ begin
RPNLength := 0;
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);
@ -1751,7 +1751,7 @@ begin
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit;
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);
@ -1807,7 +1807,7 @@ begin
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit;
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);
@ -1851,7 +1851,7 @@ begin
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit;
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);
@ -1906,7 +1906,7 @@ begin
end;
L := Length(AnsiText);
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);
@ -1946,7 +1946,7 @@ begin
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit;
xf := FindXFIndex(ACell);
xf := FindXFIndex(ACell^.FormatIndex);
if xf >= 63 then
WriteIXFE(AStream, xf);

View File

@ -1706,7 +1706,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record }
rec.XFIndex := WordToLE(FindXFIndex(ACell));
rec.XFIndex := WordToLE(FindXFIndex(ACell^.FormatIndex));
{ String length, 16 bit }
rec.TextLen := WordToLE(L);

View File

@ -3037,7 +3037,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record, according to formatting }
rec.XFIndex := WordToLE(FindXFIndex(ACell));
rec.XFIndex := WordToLE(FindXFIndex(ACell^.FormatIndex));
{ Byte String with 16-bit length }
rec.TextLen := WordToLE(L);

View File

@ -503,7 +503,7 @@ type
FPalette: TsPalette;
procedure AddBuiltinNumFormats; override;
function FindXFIndex(ACell: PCell): Integer; virtual;
function FindXFIndex(AFormatIndex: Integer): Integer; virtual;
function FixLineEnding(const AText: String): String;
function FormulaSupported(ARPNFormula: TsRPNFormula; out AUnsupported: String): Boolean;
function FunctionSupported(AExcelCode: Integer; const AFuncName: String): Boolean; virtual;
@ -2980,11 +2980,12 @@ end;
{@@ ----------------------------------------------------------------------------
Determines the index of the XF record, according to formatting of the
given cell
given format index; this format index is taken from a cell, row, or column
record.
-------------------------------------------------------------------------------}
function TsSpreadBIFFWriter.FindXFIndex(ACell: PCell): Integer;
function TsSpreadBIFFWriter.FindXFIndex(AFormatIndex: Integer): Integer;
begin
Result := LAST_BUILTIN_XF + ACell^.FormatIndex;
Result := LAST_BUILTIN_XF + AFormatIndex;
end;
{@@ ----------------------------------------------------------------------------
@ -3144,7 +3145,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record, according to formatting }
rec.XFIndex := WordToLE(FindXFIndex(ACell));
rec.XFIndex := WordToLE(FindXFIndex(ACell^.FormatIndex));
{ Write out }
AStream.WriteBuffer(rec, SizeOf(rec));
@ -3171,7 +3172,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record, according to formatting }
rec.XFIndex := WordToLE(FindXFIndex(ACell));
rec.XFIndex := WordToLE(FindXFIndex(ACell^.FormatIndex));
{ Cell value }
rec.BoolErrValue := ord(AValue);
@ -3258,8 +3259,8 @@ begin
w := round(FWorkbook.ConvertUnits(ACol^.Width, FWorkbook.Units, suChars)*256);
rec.ColWidth := WordToLE(w);
rec.XFIndex := WordToLE(15); // Index of XF record, not used
rec.OptionFlags := 0; // not used
rec.XFIndex := WordToLE(FindXFIndex(ACol^.FormatIndex));// Index of XF record
rec.OptionFlags := 0; // hidden, outline, collapsed flags are not used
rec.NotUsed := 0;
{ Write out }
@ -3470,7 +3471,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record, according to formatting }
rec.XFIndex := WordToLE(FindXFIndex(ACell));
rec.XFIndex := WordToLE(FindXFIndex(ACell^.FormatIndex));
{ Cell value }
rec.BoolErrValue := ConvertToExcelError(AValue);
@ -3692,7 +3693,7 @@ begin
rec.Col := WordToLE(ACol);
{ Index to XF record }
rec.XFIndex := FindXFIndex(ACell);
rec.XFIndex := FindXFIndex(ACell^.FormatIndex);
{ IEE 754 floating-point value }
rec.Value := AValue;
@ -4023,7 +4024,7 @@ begin
AStream.WriteWord(WordToLE(ACol));
{ Index to XF record, according to formatting }
AStream.WriteWord(FindXFIndex(ACell));
AStream.WriteWord(FindXFIndex(ACell^.FormatIndex));
{ Encoded result of RPN formula }
WriteRPNResult(AStream, ACell);
@ -4388,6 +4389,10 @@ begin
if spacebelow then dw := dw or $20000000;
if (ARow <> nil) and (ARow^.RowHeightType = rhtCustom) then // Custom row height
dw := dw or $00000040; // Row height and font height do not match
if ARow^.FormatIndex > 0 then begin
dw := dw or $00000080; // Row has custom format
dw := dw or (FindXFIndex(ARow^.FormatIndex) shl 16); // xf index
end;
{ Write out }
AStream.WriteDWord(DWordToLE(dw));