fpspreadsheet: Cleaning up

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3167 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-06-13 20:32:58 +00:00
parent 9f69ce203a
commit f4f860abc2
7 changed files with 152 additions and 489 deletions

View File

@ -141,18 +141,7 @@ type
public public
constructor Create(AWorkbook: TsWorkbook; const AFormatString: String); constructor Create(AWorkbook: TsWorkbook; const AFormatString: String);
(*
constructor Create(AWorkbook: TsWorkbook; const AFormatString: String;
ANumFormat: TsNumberFormat); overload;
constructor Create(AWorkbook: TsWorkbook; const AFormatSections: TsNumFormatSections;
AConversionDirection: TsConversionDirection = cdFromFPSpreadsheet); overload;
*)
destructor Destroy; override; destructor Destroy; override;
(*
procedure CopySections(const FromSections: TsNumFormatSections;
var ToSections: TsNumFormatSections);
procedure CopySectionsTo(var ADestination: TsNumFormatSections);
*)
function GetDateTimeCode(ASection: Integer): String; function GetDateTimeCode(ASection: Integer): String;
function IsDateTimeFormat: Boolean; function IsDateTimeFormat: Boolean;
procedure LimitDecimals; procedure LimitDecimals;
@ -190,38 +179,7 @@ begin
FWorkbook := AWorkbook; FWorkbook := AWorkbook;
Parse(AFormatString); Parse(AFormatString);
end; end;
(*
constructor TsNumFormatParser.Create(AWorkbook: TsWorkbook;
const AFormatString: String; ANumFormat: TsNumberFormat;
AConversionDirection: TsConversionDirection = cdToFPSpreadsheet);
begin
inherited Create;
FCreateMethod := 0;
FConversionDirection := AConversionDirection;
FWorkbook := AWorkbook;
FNumFormat := ANumFormat;
FFormatSettings := DefaultFormatSettings;
FFormatSettings.DecimalSeparator := '.';
FFormatSettings.ThousandSeparator := ',';
FIsAccounting := (ANumFormat in [nfAccounting, nfAccountingRed]);
Parse(AFormatString);
end;
{ Creates a number format parser to create a format string from the individual
format sections given in "AFormatSections". It is assumed by default that the
format string will be written to file. Therefore, it can contain features of
the destination file format and, in general, will not work if called by
fpspreadsheet. }
constructor TsNumFormatParser.Create(AWorkbook: TsWorkbook;
const AFormatSections: TsNumFormatSections);
begin
inherited Create;
FCreateMethod := 1;
FConversionDirection := AConversionDirection;
FWorkbook := AWorkbook;
CopySections(AFormatSections, FSections);
end;
*)
destructor TsNumFormatParser.Destroy; destructor TsNumFormatParser.Destroy;
begin begin
FSections := nil; FSections := nil;
@ -421,111 +379,9 @@ end;
procedure TsNumFormatParser.CheckSections; procedure TsNumFormatParser.CheckSections;
var var
i: Integer; i: Integer;
{
ns: Integer;
s: String;
isCurr: Boolean;
}
begin begin
for i:=0 to Length(FSections)-1 do for i:=0 to Length(FSections)-1 do
CheckSection(i); CheckSection(i);
(*
ns := Length(FSections);
if (ns > 1) and (FNumFormat in [nfCurrencyRed, nfAccountingRed]) then
FSections[1].Color := scRed;
for i:=0 to ns-1 do begin
if FSections[i].FormatString = '' then
FSections[i].NumFormat := nfGeneral;
if (FSections[i].CurrencySymbol <> '') or FIsAccounting then
FSections[i].NumFormat := nfCurrency;
if FSections[i].CompareOperation <> coNotUsed then begin
FStatus := psErrConditionalFormattingNotSupported;
exit;
end;
// Check format strings
case FSections[i].NumFormat of
nfGeneral, nfFixed, nfFixedTh, nfPercentage, nfExp, nfSci, nfCurrency, nfAccounting:
try
s := FormatFloat(FSections[i].FormatString, 1.0, FWorkBook.FormatSettings);
except
FStatus := psErrNoValidNumberFormat;
exit;
end;
nfShortDateTime, nfShortDate, nfShortTime, nfShortTimeAM,
nfLongDate, nfLongTime, nfLongTimeAM, nfTimeInterval, nfFmtDateTime:
try
s := FormatDateTime(FSections[i].FormatString, now(), FWorkbook.FormatSettings, [fdoInterval]);
except
FStatus := psErrNoValidDateTimeFormat;
exit;
end;
end;
end;
// Extract built-in NumFormat identifier for currency (needs several entries in
// three sections).
isCurr := ((ns = 2) and (FSections[0].NumFormat = nfCurrency) and (FSections[1].NumFormat = nfCurrency))
or ((ns = 3) and (FSections[0].NumFormat = nfCurrency) and (FSections[1].NumFormat = nfCurrency) and
((FSections[2].NumFormat = nfCurrency) or (FSections[2].FormatString = '-')) );
if isCurr then begin
if FIsAccounting then
FNumFormat := IfThen(FSections[1].Color = scRed, nfAccountingRed, nfAccounting)
else
FNumFormat := IfThen(FSections[1].Color = scRed, nfCurrency, nfCurrencyRed);
end;
// If there are other multi-section formatstrings they must be a custom format
if not isCurr then begin
if (ns > 1) then begin
for i:=1 to ns-1 do
if FSections[i].FormatString <> '' then begin
FNumFormat := nfCustom;
break;
end;
if fNumFormat <> nfCustom then
FNumFormat := FSections[0].NumFormat;
end
else
FNumFormat := FSections[0].NumFormat;
end;
// Add colors to section format strings
if (FConversionDirection = cdFromFPSpreadsheet) then
for i := 0 to High(FSections) do
if FSections[i].Color < 8 then
FSections[i].FormatString := Format('[%s]%s', [
FWorkbook.GetColorName(FSections[i].Color),
FSections[i].FormatString
])
else
if FSections[i].Color <> scNotDefined then
FSections[i].FormatString := Format('[Color%d]%s', [
FSections[i].Color,
FSections[i].FormatString
]);
// Construct total format string
if ns = 2 then
FFormatString := Format('%s;%s;%s', [
FSections[0].FormatString,
FSections[1].FormatString,
FSections[0].FormatString // make sure that fpc understands the "zero"
])
else
if ns > 0 then begin
FFormatString := FSections[0].FormatString;
for i:=1 to ns-1 do
FFormatString := Format('%s;%s', [FFormatString, FSections[i].FormatString]);
end else
FStatus := psErrNoUsableFormat;
*)
end; end;
procedure TsNumFormatParser.CheckSection(ASection: Integer); procedure TsNumFormatParser.CheckSection(ASection: Integer);
@ -608,28 +464,6 @@ begin
FSections[ASection].Color FSections[ASection].Color
); );
end; end;
(*
procedure TsNumFormatParser.CopySections(
const FromSections: TsNumFormatSections; var ToSections: TsNumformatSections);
var
i, j: Integer;
begin
SetLength(ToSections, Length(FromSections));
for i:= 0 to High(FromSections) do begin
ToSections[i].NumFormat := FromSections[i].NumFormat;
ToSections[i].Decimals := FromSections[i].Decimals;
ToSections[i].CurrencySymbol := FromSections[i].CurrencySymbol;
SetLength(ToSections[i].Elements, Length(FromSections[i].Elements));
for j:=0 to High(ToSections[i].Elements) do
ToSections[i].Elements[j] := FromSections[i].Elements[j];
end;
end;
procedure TsNumFormatParser.CopySectionsTo(var ADestination: TsNumFormatSections);
begin
CopySections(FSections, ADestination);
end;
*)
procedure TsNumFormatParser.DeleteElement(ASection, AIndex: Integer); procedure TsNumFormatParser.DeleteElement(ASection, AIndex: Integer);
var var
@ -690,14 +524,7 @@ begin
for i:=1 to High(FSections) do for i:=1 to High(FSections) do
Result := Result + ';' + BuildFormatStringFromSection(i, ADialect); Result := Result + ';' + BuildFormatStringFromSection(i, ADialect);
end; end;
{
case FCreateMethod of
0: Result := FFormatString;
1: Result := CreateFormatStringFromSections;
end; end;
}
end;
procedure TsNumFormatParser.EvalNumFormatOfSection(ASection: Integer; procedure TsNumFormatParser.EvalNumFormatOfSection(ASection: Integer;
out ANumFormat: TsNumberFormat; out ADecimals: byte; out ACurrencySymbol: String; out ANumFormat: TsNumberFormat; out ADecimals: byte; out ACurrencySymbol: String;
@ -869,16 +696,10 @@ begin
Result := nfCustom; Result := nfCustom;
exit; exit;
end; end;
if Length(FSections) > 1 then begin if Length(FSections) > 1 then
{
if IsDateTimeFormat then
Result := nfFmtDateTime
else
}
Result := nfCustom; Result := nfCustom;
end; end;
end; end;
end;
function TsNumFormatParser.GetParsedSectionCount: Integer; function TsNumFormatParser.GetParsedSectionCount: Integer;
begin begin
@ -1024,18 +845,6 @@ begin
if CheckFormat(FWorkbook.FormatSettings.LongDateFormat, ANextIndex) then begin if CheckFormat(FWorkbook.FormatSettings.LongDateFormat, ANextIndex) then begin
Result := true; Result := true;
ANumberFormat := nfLongDate; ANumberFormat := nfLongDate;
{
end else begin
// If it is neither nfShortDate nor nfLongDate we look for any year, month
// or day tokens. If we find one it must be at least nfFmtDateTime.
for i:=0 to High(FSections[ASection].Elements) do
if FSections[ASection].Elements[i].Token in [nftYear, nftMonth, nftDay] then begin
Result := true;
ANumberFormat := nfFmtDateTime;
exit;
end;
Result := false;
}
end else end else
Result := false; Result := false;
end; end;
@ -1386,7 +1195,6 @@ begin
until (FToken <> ATestChar) or (FCurrent >= FEnd); until (FToken <> ATestChar) or (FCurrent >= FEnd);
end; end;
{ Extracts the text between square brackets. This can be { Extracts the text between square brackets. This can be
- a time duration like [hh] - a time duration like [hh]
- a condition, like [>= 2.0] - a condition, like [>= 2.0]
@ -1527,7 +1335,6 @@ begin
end; end;
end; end;
{ Scans a date/time format. Procedure is left with the cursor at the last char { Scans a date/time format. Procedure is left with the cursor at the last char
of the date/time format. } of the date/time format. }
procedure TsNumFormatParser.ScanDateTime; procedure TsNumFormatParser.ScanDateTime;

View File

@ -53,7 +53,6 @@ type
protected protected
procedure AddBuiltinFormats; override; procedure AddBuiltinFormats; override;
public public
// function FormatStringForWriting(AIndex: Integer): String; override;
end; end;
{ TsSpreadOpenDocReader } { TsSpreadOpenDocReader }
@ -1082,7 +1081,6 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
if negfmt <> '' then AFormatStr := AFormatStr + ';' + negfmt; if negfmt <> '' then AFormatStr := AFormatStr + ';' + negfmt;
if zerofmt <> '' then AFormatStr := AFormatStr + ';' + zerofmt; if zerofmt <> '' then AFormatStr := AFormatStr + ';' + zerofmt;
// if ANumFormat <> nfFmtDateTime then
ANumFormat := nfCustom; ANumFormat := nfCustom;
end; end;
@ -1241,7 +1239,6 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
node := node.NextSibling; node := node.NextSibling;
end; end;
// nf := IfThen(isInterval, nfTimeInterval, nfFmtDateTime);
nf := IfThen(isInterval, nfTimeInterval, nfCustom); nf := IfThen(isInterval, nfTimeInterval, nfCustom);
node := ANumFormatNode.FindNode('style:map'); node := ANumFormatNode.FindNode('style:map');
if node <> nil then if node <> nil then
@ -1280,11 +1277,6 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
node := ANumFormatNode.FindNode('style:map'); node := ANumFormatNode.FindNode('style:map');
if node <> nil then if node <> nil then
ReadStyleMap(node, nf, fmt); ReadStyleMap(node, nf, fmt);
{
if IsDateTimeFormat(fmt) then
nf := nfCustom
else
}
nf := nfCustom; nf := nfCustom;
NumFormatList.AddFormat(ANumFormatName, fmt, nf); NumFormatList.AddFormat(ANumFormatName, fmt, nf);

View File

@ -4333,19 +4333,18 @@ Number format handling in fpspreadsheet is implemented with the following
concept in mind: concept in mind:
- Formats written into TsWorksheet cells always follow the fpspreadsheet syntax. - Formats written into TsWorksheet cells always follow the fpspreadsheet syntax.
The exception is for the format nfCustom for which the format strings are
left untouched.
- For writing, the writer creates a TsNumFormatList which stores all formats - For writing, the writer creates a TsNumFormatList which stores all formats
in file syntax. in file syntax.
- The built-in formats of the file types are coded in the file syntax. - The built-in formats of the file types are coded in the fpc syntax.
- The method "ConvertBeforeWriting" converts the cell formats from the - The method "ConvertBeforeWriting" converts the cell formats from the
fpspreadsheet to the file syntax. fpspreadsheet to the file syntax.
- For reading, the reader creates another TsNumFormatList. - For reading, the reader creates another TsNumFormatList.
- The built-in formats of the file types are coded again in file syntax. - The built-in formats of the file types are coded again in fpc syntax.
- The formats read from the file are added in file syntax. - After reading, the formats are converted to fpc syntax by means of
- After reading, the formats are converted to fpspreadsheet syntax "ConvertAfterReading".
("ConvertAfterReading").
- Format conversion is done internally by means of the TsNumFormatParser.
} }

View File

@ -96,7 +96,6 @@ procedure SplitFormatString(const AFormatString: String; out APositivePart,
function SciFloat(AValue: Double; ADecimals: Byte): String; overload; function SciFloat(AValue: Double; ADecimals: Byte): String; overload;
function SciFloat(AValue: Double; ADecimals: Byte; AFormatSettings: TFormatSettings): String; overload; function SciFloat(AValue: Double; ADecimals: Byte; AFormatSettings: TFormatSettings): String; overload;
//function TimeIntervalToString(AValue: TDateTime; AFormatStr: String): String;
procedure MakeTimeIntervalMask(Src: String; var Dest: String); procedure MakeTimeIntervalMask(Src: String; var Dest: String);
// These two functions are copies of fpc trunk until they are available in stable fpc. // These two functions are copies of fpc trunk until they are available in stable fpc.
@ -115,7 +114,6 @@ function PtsToMM(AValue: Double): Double;
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double; function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer; function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
function HTMLLengthStrToPts(AValue: String): Double; function HTMLLengthStrToPts(AValue: String): Double;
//function HMTLLengthStrToPts(AValue: String): Double;
function HTMLColorStrToColor(AValue: String): TsColorValue; function HTMLColorStrToColor(AValue: String): TsColorValue;
function ColorToHTMLColorStr(AValue: TsColorValue): String; function ColorToHTMLColorStr(AValue: TsColorValue): String;
@ -591,10 +589,6 @@ var
fmt: String; fmt: String;
begin begin
case ANumberFormat of case ANumberFormat of
{
nfFmtDateTime:
Result := SpecialDateTimeFormat(lowercase(AFormatString), AFormatSettings, false);
}
nfShortDateTime: nfShortDateTime:
Result := AFormatSettings.ShortDateFormat + ' ' + AFormatSettings.ShortTimeFormat; Result := AFormatSettings.ShortDateFormat + ' ' + AFormatSettings.ShortTimeFormat;
// In the DefaultFormatSettings this is: d/m/y hh:nn // In the DefaultFormatSettings this is: d/m/y hh:nn
@ -1078,6 +1072,147 @@ begin
end; end;
end; end;
{ Excel's unit of row heights is "twips", i.e. 1/20 point.
Converts Twips to points. }
function TwipsToPts(AValue: Integer): Single;
begin
Result := AValue / 20;
end;
{ Converts points to twips (1 twip = 1/20 point) }
function PtsToTwips(AValue: Single): Integer;
begin
Result := round(AValue * 20);
end;
{ Converts centimeters to points (72 pts = 1 inch) }
function cmToPts(AValue: Double): Double;
begin
Result := AValue * 72 / 2.54;
end;
{ Converts points to centimeters }
function PtsToCm(AValue: Double): Double;
begin
Result := AValue / 72 * 2.54;
end;
{ Converts inches to points (72 pts = 1 inch) }
function InToPts(AValue: Double): Double;
begin
Result := AValue * 72;
end;
{ Converts millimeters to points (72 pts = 1 inch) }
function mmToPts(AValue: Double): Double;
begin
Result := AValue * 72 / 25.4;
end;
{ Converts points to millimeters }
function PtsToMM(AValue: Double): Double;
begin
Result := AValue / 72 * 25.4;
end;
{ Converts pixels to points. }
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
begin
Result := (AValue / AScreenPixelsPerInch) * 72;
end;
{ Converts points to pixels }
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
begin
Result := Round(AValue / 72 * AScreenPixelsPerInch);
end;
{ converts a HTML length string to points. The units are assumed to be the last
two digits of the string }
function HTMLLengthStrToPts(AValue: String): Double;
var
units: String;
x: Double;
res: Word;
begin
if (Length(AValue) > 1) and (AValue[Length(AValue)] in ['a'..'z', 'A'..'Z']) then begin
units := lowercase(Copy(AValue, Length(AValue)-1, 2));
val(copy(AValue, 1, Length(AValue)-2), x, res);
// No hasseling with the decimal point...
end else begin
units := '';
val(AValue, x, res);
end;
if res <> 0 then
raise Exception.CreateFmt('No valid number or units (%s)', [AValue]);
if (units = 'pt') or (units = '') then
Result := x
else
if units = 'in' then
Result := InToPts(x)
else if units = 'cm' then
Result := cmToPts(x)
else if units = 'mm' then
Result := mmToPts(x)
else if units = 'px' then
Result := pxToPts(Round(x), ScreenPixelsPerInch)
else
raise Exception.Create('Unknown length units');
end;
{ converts a HTML color string to a TsColorValue. For ods }
function HTMLColorStrToColor(AValue: String): TsColorValue;
begin
if AValue = '' then
Result := scNotDefined
else
if AValue[1] = '#' then begin
AValue[1] := '$';
Result := LongRGBToExcelPhysical(StrToInt(AValue));
end else begin
AValue := lowercase(AValue);
if AValue = 'red' then
Result := $0000FF
else if AValue = 'cyan' then
Result := $FFFF00
else if AValue = 'blue' then
Result := $FF0000
else if AValue = 'purple' then
Result := $800080
else if AValue = 'yellow' then
Result := $00FFFF
else if AValue = 'lime' then
Result := $00FF00
else if AValue = 'white' then
Result := $FFFFFF
else if AValue = 'black' then
Result := $000000
else if (AValue = 'gray') or (AValue = 'grey') then
Result := $808080
else if AValue = 'silver' then
Result := $C0C0C0
else if AValue = 'maroon' then
Result := $000080
else if AValue = 'green' then
Result := $008000
else if AValue = 'olive' then
Result := $008080;
end;
end;
{ converts an rgb color value to a string as used in HTML code (for ods) }
function ColorToHTMLColorStr(AValue: TsColorValue): String;
type
TRGB = record r,g,b,a: Byte end;
var
rgb: TRGB;
begin
rgb := TRGB(AValue);
Result := Format('#%.2x%.2x%.2x', [rgb.r, rgb.g, rgb.b]);
end;
{******************************************************************************} {******************************************************************************}
{******************************************************************************} {******************************************************************************}
@ -1442,145 +1577,5 @@ begin
DateTimeToString(Result, FormatStr, DateTime, FormatSettings,Options); DateTimeToString(Result, FormatStr, DateTime, FormatSettings,Options);
end; end;
{ Excel's unit of row heights is "twips", i.e. 1/20 point.
Converts Twips to points. }
function TwipsToPts(AValue: Integer): Single;
begin
Result := AValue / 20;
end;
{ Converts points to twips (1 twip = 1/20 point) }
function PtsToTwips(AValue: Single): Integer;
begin
Result := round(AValue * 20);
end;
{ Converts centimeters to points (72 pts = 1 inch) }
function cmToPts(AValue: Double): Double;
begin
Result := AValue * 72 / 2.54;
end;
{ Converts points to centimeters }
function PtsToCm(AValue: Double): Double;
begin
Result := AValue / 72 * 2.54;
end;
{ Converts inches to points (72 pts = 1 inch) }
function InToPts(AValue: Double): Double;
begin
Result := AValue * 72;
end;
{ Converts millimeters to points (72 pts = 1 inch) }
function mmToPts(AValue: Double): Double;
begin
Result := AValue * 72 / 25.4;
end;
{ Converts points to millimeters }
function PtsToMM(AValue: Double): Double;
begin
Result := AValue / 72 * 25.4;
end;
{ Converts pixels to points. }
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
begin
Result := (AValue / AScreenPixelsPerInch) * 72;
end;
{ Converts points to pixels }
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
begin
Result := Round(AValue / 72 * AScreenPixelsPerInch);
end;
{ converts a HTML length string to points. The units are assumed to be the last
two digits of the string }
function HTMLLengthStrToPts(AValue: String): Double;
var
units: String;
x: Double;
res: Word;
begin
if (Length(AValue) > 1) and (AValue[Length(AValue)] in ['a'..'z', 'A'..'Z']) then begin
units := lowercase(Copy(AValue, Length(AValue)-1, 2));
val(copy(AValue, 1, Length(AValue)-2), x, res);
// No hasseling with the decimal point...
end else begin
units := '';
val(AValue, x, res);
end;
if res <> 0 then
raise Exception.CreateFmt('No valid number or units (%s)', [AValue]);
if (units = 'pt') or (units = '') then
Result := x
else
if units = 'in' then
Result := InToPts(x)
else if units = 'cm' then
Result := cmToPts(x)
else if units = 'mm' then
Result := mmToPts(x)
else if units = 'px' then
Result := pxToPts(Round(x), ScreenPixelsPerInch)
else
raise Exception.Create('Unknown length units');
end;
{ converts a HTML color string to a TsColorValue. For ods }
function HTMLColorStrToColor(AValue: String): TsColorValue;
begin
if AValue = '' then
Result := scNotDefined
else
if AValue[1] = '#' then begin
AValue[1] := '$';
Result := LongRGBToExcelPhysical(StrToInt(AValue));
end else begin
AValue := lowercase(AValue);
if AValue = 'red' then
Result := $0000FF
else if AValue = 'cyan' then
Result := $FFFF00
else if AValue = 'blue' then
Result := $FF0000
else if AValue = 'purple' then
Result := $800080
else if AValue = 'yellow' then
Result := $00FFFF
else if AValue = 'lime' then
Result := $00FF00
else if AValue = 'white' then
Result := $FFFFFF
else if AValue = 'black' then
Result := $000000
else if (AValue = 'gray') or (AValue = 'grey') then
Result := $808080
else if AValue = 'silver' then
Result := $C0C0C0
else if AValue = 'maroon' then
Result := $000080
else if AValue = 'green' then
Result := $008000
else if AValue = 'olive' then
Result := $008080;
end;
end;
{ converts an rgb color value to a string as used in HTML code (for ods) }
function ColorToHTMLColorStr(AValue: TsColorValue): String;
type
TRGB = record r,g,b,a: Byte end;
var
rgb: TRGB;
begin
rgb := TRGB(AValue);
Result := Format('#%.2x%.2x%.2x', [rgb.r, rgb.g, rgb.b]);
end;
end. end.

View File

@ -47,7 +47,6 @@ type
function FindFormatOf(AFormatCell: PCell): Integer; override; function FindFormatOf(AFormatCell: PCell): Integer; override;
public public
constructor Create(AWorkbook: TsWorkbook); constructor Create(AWorkbook: TsWorkbook);
function FormatStringForWriting(AIndex: Integer): String; override;
end; end;
{ TsSpreadBIFF2Reader } { TsSpreadBIFF2Reader }
@ -106,7 +105,6 @@ type
procedure WriteXFRecords(AStream: TStream); procedure WriteXFRecords(AStream: TStream);
protected protected
procedure CreateNumFormatList; override; procedure CreateNumFormatList; override;
procedure ListAllFormattingStyles; override;
procedure ListAllNumFormats; override; procedure ListAllNumFormats; override;
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; ACell: PCell); override; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; ACell: PCell); override;
procedure WriteFormat(AStream: TStream; AFormatData: TsNumFormatData; procedure WriteFormat(AStream: TStream; AFormatData: TsNumFormatData;
@ -198,43 +196,12 @@ begin
AddFormat(13, fs.LongDateFormat, nfLongDate); AddFormat(13, fs.LongDateFormat, nfLongDate);
AddFormat(14, 'd/mmm', nfCustom); AddFormat(14, 'd/mmm', nfCustom);
AddFormat(15, 'mmm/yy', nfCustom); AddFormat(15, 'mmm/yy', nfCustom);
//AddFormat(14, SpecialDateTimeFormat('dm', fs, true), nfFmtDateTime);
//AddFormat(15, SpecialDateTimeFormat('my', fs, true), nfFmtDateTime);
AddFormat(16, AddAMPM(fs.ShortTimeFormat, fs), nfShortTimeAM); AddFormat(16, AddAMPM(fs.ShortTimeFormat, fs), nfShortTimeAM);
AddFormat(17, AddAMPM(fs.LongTimeFormat, fs), nfLongTimeAM); AddFormat(17, AddAMPM(fs.LongTimeFormat, fs), nfLongTimeAM);
AddFormat(18, fs.ShortTimeFormat, nfShortTime); AddFormat(18, fs.ShortTimeFormat, nfShortTime);
AddFormat(19, fs.LongTimeFormat, nfLongTime); AddFormat(19, fs.LongTimeFormat, nfLongTime);
AddFormat(20, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat, nfShortDateTime); AddFormat(20, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat, nfShortDateTime);
(*
fs := Workbook.FormatSettings;
ds := fs.DecimalSeparator;
ts := fs.ThousandSeparator;
cs := fs.CurrencyString;
AddFormat( 0, '', nfGeneral);
AddFormat( 1, '0', nfFixed);
AddFormat( 2, '0'+ds+'00', nfFixed); // 0.00
AddFormat( 3, '#'+ts+'##0', nfFixedTh); // #,##0
AddFormat( 4, '#'+ts+'##0'+ds+'00', nfFixedTh); // #,##0.00
AddFormat( 5, UTF8ToAnsi('"'+cs+'"#'+ts+'##0_);("'+cs+'"#'+ts+'##0)'), nfCurrency);
AddFormat( 6, UTF8ToAnsi('"'+cs+'"#'+ts+'##0_);[Red]("'+cs+'"#'+ts+'##0)'), nfCurrencyRed);
AddFormat( 7, UTF8ToAnsi('"'+cs+'"#'+ts+'##0'+ds+'00_);("'+cs+'"#'+ts+'##0'+ds+'00)'), nfCurrency);
AddFormat( 8, UTF8ToAnsi('"'+cs+'"#'+ts+'##0'+ds+'00_);[Red]("'+cs+'"#'+ts+'##0'+ds+'00)'), nfCurrency);
AddFormat( 9, '0%', nfPercentage);
AddFormat(10, '0'+ds+'00%', nfPercentage);
AddFormat(11, '0'+ds+'00E+00', nfExp);
AddFormat(12, fs.ShortDateFormat, nfShortDate);
AddFormat(13, fs.LongDateFormat, nfLongDate);
AddFormat(14, 'd/mmm', nfCustom);
AddFormat(15, 'mmm/yy', nfCustom);
//AddFormat(14, SpecialDateTimeFormat('dm', fs, true), nfFmtDateTime);
//AddFormat(15, SpecialDateTimeFormat('my', fs, true), nfFmtDateTime);
AddFormat(16, AddAMPM(fs.ShortTimeFormat, fs), nfShortTimeAM);
AddFormat(17, AddAMPM(fs.LongTimeFormat, fs), nfLongTimeAM);
AddFormat(18, fs.ShortTimeFormat, nfShortTime);
AddFormat(19, fs.LongTimeFormat, nfLongTime);
AddFormat(20, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat, nfShortDateTime);
*)
FFirstFormatIndexInFile := 0; // BIFF2 stores built-in formats to file. FFirstFormatIndexInFile := 0; // BIFF2 stores built-in formats to file.
FNextFormatIndex := 21; // not needed - there are not user-defined formats FNextFormatIndex := 21; // not needed - there are not user-defined formats
end; end;
@ -298,26 +265,6 @@ begin
end; end;
end; end;
{ Creates formatting strings that are written into the file. These are the
strings in the format list. The only exception is the nfGeneral entry which
is written as "General". }
function TsBIFF2NumFormatList.FormatStringForWriting(AIndex: Integer): String;
begin
Result := inherited FormatStringForWriting(AIndex);
{
if Result = '' then
Result := 'General'
else begin
parser := TsNumFormatParser.Create(Workbook, Result);
try
parser.Localize;
Result := Parser.FormatString[nfdExcel];
finally
end;
end;
}
end;
{ TsSpreadBIFF2Reader } { TsSpreadBIFF2Reader }
@ -893,21 +840,7 @@ begin
Result := 15 Result := 15
else begin else begin
// If not, then we need to search in the list of dynamic formats // If not, then we need to search in the list of dynamic formats
// But we have to consider that the number formats of the cell is in fpc syntax,
// but the number format list of the writer is in Excel syntax.
// And for BIFF2, there is only a limited number of formats.
lCell := ACell^; lCell := ACell^;
{
with lCell do begin
if IsDateTimeFormat(NumberFormat) then
NumberFormatStr := BuildDateTimeFormatString(NumberFormat,
Workbook.FormatSettings, NumberFormatStr)
else
NumberFormatStr := BuildNumberFormatString(NumberFormat,
Workbook.FormatSettings, Decimals, CurrencySymbol);
NumFormatList.ConvertBeforeWriting(NumberFormatStr, NumberFormat, Decimals, CurrencyString);
end;
}
lIndex := FindFormattingInList(@lCell); lIndex := FindFormattingInList(@lCell);
// Carefully check the index // Carefully check the index
@ -917,27 +850,12 @@ begin
end; end;
end; end;
procedure TsSpreadBIFF2Writer.ListAllFormattingStyles;
var
i: Integer;
begin
inherited ListAllFormattingStyles;
{
for i:=0 to High(FFormattingStyles) do
FNumFormatList.ConvertBeforeWriting(
FFormattingStyles[i].NumberFormatStr,
FFormattingStyles[i].NumberFormat
);
}
end;
{ Builds up the list of number formats to be written to the biff2 file. { Builds up the list of number formats to be written to the biff2 file.
Unlike biff5+ no formats are added here because biff2 supports only 21 Unlike biff5+ no formats are added here because biff2 supports only 21
standard formats; these formats have been added by the NumFormatList's standard formats; these formats have been added by the NumFormatList's
AddBuiltInFormats. AddBuiltInFormats.
NOT CLEAR IF THIS IS TRUE ???? NOT CLEAR IF THIS IS TRUE ????
} }
// ToDo: check if the BIFF2 format is really restricted to 21 formats. // ToDo: check if the BIFF2 format is really restricted to 21 formats.
procedure TsSpreadBIFF2Writer.ListAllNumFormats; procedure TsSpreadBIFF2Writer.ListAllNumFormats;

View File

@ -1221,14 +1221,6 @@ begin
XFBorderDWord1 := XFBorderDWord1 or ((ord(ABorderStyles[cbNorth].LineStyle)+1) shl 8); XFBorderDWord1 := XFBorderDWord1 or ((ord(ABorderStyles[cbNorth].LineStyle)+1) shl 8);
if cbSouth in ABorders then if cbSouth in ABorders then
XFBorderDWord1 := XFBorderDWord1 or ((ord(ABorderStyles[cbSouth].LineStyle)+1) shl 12); XFBorderDWord1 := XFBorderDWord1 or ((ord(ABorderStyles[cbSouth].LineStyle)+1) shl 12);
(*
XFBorderDWord1 := 8 * $10000 {left line - black} + 8 * $800000 {right line - black};
if cbNorth in ABorders then XFBorderDWord1 := XFBorderDWord1 or $100;
if cbWest in ABorders then XFBorderDWord1 := XFBorderDWord1 or $1;
if cbEast in ABorders then XFBorderDWord1 := XFBorderDWord1 or $10;
if cbSouth in ABorders then XFBorderDWord1 := XFBorderDWord1 or $1000;
*)
AStream.WriteDWord(DWordToLE(XFBorderDWord1)); AStream.WriteDWord(DWordToLE(XFBorderDWord1));
// Top and Bottom line colors // Top and Bottom line colors

View File

@ -450,12 +450,6 @@ type
// Write out BLANK cell record // Write out BLANK cell record
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
ACell: PCell); override; ACell: PCell); override;
{
procedure WriteCellBlock(AStream: TStream; ASheet: TsWorksheet;
AFirstRow, ALastRow: Cardinal);
}
// Write out used codepage for character encoding // Write out used codepage for character encoding
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding); procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
// Writes out column info(s) // Writes out column info(s)
@ -766,7 +760,6 @@ end;
procedure TsBIFFNumFormatList.ConvertBeforeWriting(var AFormatString: String; procedure TsBIFFNumFormatList.ConvertBeforeWriting(var AFormatString: String;
var ANumFormat: TsNumberFormat); var ANumFormat: TsNumberFormat);
{var ADecimals: Byte; var ACurrencySymbol: String); }
var var
parser: TsNumFormatParser; parser: TsNumFormatParser;
fmt: String; fmt: String;
@ -774,13 +767,9 @@ begin
parser := TsNumFormatParser.Create(Workbook, AFormatString); parser := TsNumFormatParser.Create(Workbook, AFormatString);
try try
if parser.Status = psOK then begin if parser.Status = psOK then begin
// We convert the fpc format string to Excel dialect // For writing, we have to convert the fpc format string to Excel dialect
AFormatString := parser.FormatString[nfdExcel]; AFormatString := parser.FormatString[nfdExcel];
ANumFormat := parser.NumFormat; ANumFormat := parser.NumFormat;
{
ADecimals := parser.Decimals;
ACurrencySymbol := parser.CurrencySymbol;
}
end; end;
finally finally
parser.Free; parser.Free;
@ -869,14 +858,6 @@ var
begin begin
FreeAndNil(FNumFormatList); FreeAndNil(FNumFormatList);
FNumFormatList := TsBIFFNumFormatList.Create(Workbook); FNumFormatList := TsBIFFNumFormatList.Create(Workbook);
(*
// Convert builtin formats to fps syntax
for i:=0 to FNumFormatList.Count-1 do begin
item := FNumFormatList[i];
FNumFormatList.ConvertAfterReading(item.Index, item.FormatString,
item.NumFormat, item.Decimals, item.CurrencySymbol);
end;
*)
end; end;
{ Extracts a number out of an RK value. { Extracts a number out of an RK value.
@ -910,7 +891,6 @@ begin
Result := Number; Result := Number;
end; end;
{ Extracts number format data from an XF record index by AXFIndex. { Extracts number format data from an XF record index by AXFIndex.
Valid for BIFF5-BIFF8. Needs to be overridden for BIFF2 } Valid for BIFF5-BIFF8. Needs to be overridden for BIFF2 }
procedure TsSpreadBIFFReader.ExtractNumberFormat(AXFIndex: WORD; procedure TsSpreadBIFFReader.ExtractNumberFormat(AXFIndex: WORD;
@ -924,13 +904,9 @@ begin
if lNumFormatData <> nil then begin if lNumFormatData <> nil then begin
ANumberFormat := lNumFormatData.NumFormat; ANumberFormat := lNumFormatData.NumFormat;
ANumberFormatStr := lNumFormatData.FormatString; ANumberFormatStr := lNumFormatData.FormatString;
// ADecimals := lNumFormatData.Decimals;
// ACurrencySymbol := lNumFormatData.CurrencySymbol;
end else begin end else begin
ANumberFormat := nfGeneral; ANumberFormat := nfGeneral;
ANumberFormatStr := ''; ANumberFormatStr := '';
// ADecimals := 0;
// ACurrencySymbol := '';
end; end;
end; end;
@ -1321,8 +1297,6 @@ var
lDateTime: TDateTime; lDateTime: TDateTime;
Number: Double; Number: Double;
nf: TsNumberFormat; // Number format nf: TsNumberFormat; // Number format
nd: Byte; // decimals
ncs: String; // Currency symbol
nfs: String; // Number format string nfs: String; // Number format string
begin begin
{Retrieve XF record, row and column} {Retrieve XF record, row and column}
@ -2084,7 +2058,6 @@ begin
AStream.WriteWord(WordToLE(1)); // only 1 item AStream.WriteWord(WordToLE(1)); // only 1 item
{ Index to first and last row - are the same here } { Index to first and last row - are the same here }
AStream.WriteWord(WordTOLE(activeCellRow)); AStream.WriteWord(WordTOLE(activeCellRow));
AStream.WriteWord(WordTOLE(activeCellRow)); AStream.WriteWord(WordTOLE(activeCellRow));
@ -2172,19 +2145,6 @@ begin
// But we have to consider that the number formats of the cell is in fpc syntax, // But we have to consider that the number formats of the cell is in fpc syntax,
// but the number format list of the writer is in Excel syntax. // but the number format list of the writer is in Excel syntax.
lCell := ACell^; lCell := ACell^;
(*
with lCell do begin
if NumberFormat <> nfCustom then begin
if IsDateTimeFormat(NumberFormat) then
NumberFormatStr := BuildDateTimeFormatString(NumberFormat,
Workbook.FormatSettings, NumberFormatStr)
else
NumberFormatStr := BuildNumberFormatString(NumberFormat,
Workbook.FormatSettings, Decimals, CurrencySymbol);
//NumFormatList.ConvertBeforeWriting(NumberFormatStr, NumberFormat, Decimals, CurrencyString);
end;
end;
*)
lIndex := FindFormattingInList(@lCell); lIndex := FindFormattingInList(@lCell);
// Carefully check the index // Carefully check the index