fpspreadsheet: Write some more conditional formatting conditions to ODS.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7507 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-07-01 10:40:36 +00:00
parent 1845d0fd8d
commit 54fc098d03
4 changed files with 85 additions and 27 deletions

View File

@ -38,7 +38,7 @@ begin
sh.WriteNumber(i, 8, 7.0);
sh.WriteNumber(i, 9, 8.0);
sh.WriteNumber(i, 10, 9.0);
sh.WriteNumber(i, 11, 10.0);
//sh.WriteNumber(i, 11, 10.0);
sh.WriteText(i, 12, 'abc');
sh.WriteText(i, 13, 'abc');
sh.WriteBlank(i, 14);
@ -60,7 +60,7 @@ begin
fmtIdx := wb.AddCellFormat(fmt);
// Write conditional format
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcEqual, 5, fmtIdx);
(*
// conditional format #2: equal to text constant
inc(row);
sh.WriteText(row, 0, 'equal to text "abc"');
@ -123,7 +123,7 @@ begin
InitFormatRecord(fmt);
fmt.SetBackground(fsThinStripeDiagUp, scRed, scYellow);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcAboveAverage, fmtIdx);
sh.WriteConditionalCellFormat(Range(row, 2, row, 10), cfcAboveAverage, fmtIdx); // only 1..9 -> ave = 5
// conditional format #6: below average
inc(row);
@ -132,7 +132,7 @@ begin
InitFormatRecord(fmt);
fmt.SetBackground(fsGray25, scRed, scYellow);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcBelowAverage, fmtIdx);
sh.WriteConditionalCellFormat(Range(row, 2, row, 10), cfcBelowAverage, fmtIdx); // only 1..9 -> ave = 5
// conditional format #6: above or equal to average
inc(row);
@ -141,7 +141,7 @@ begin
InitFormatRecord(fmt);
fmt.SetBackground(fsThinStripeHor, scRed, scYellow);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcAboveEqualAverage, fmtIdx);
sh.WriteConditionalCellFormat(Range(row, 2, row, 10), cfcAboveEqualAverage, fmtIdx); // only 1..9 -> ave = 5
// conditional format #6: below or equal to average
inc(row);
@ -150,7 +150,7 @@ begin
InitFormatRecord(fmt);
fmt.SetBackground(fsThinStripeVert, scRed, scYellow);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcBelowEqualAverage, fmtIdx);
sh.WriteConditionalCellFormat(Range(row, 2, row, 10), cfcBelowEqualAverage, fmtIdx); // only 1..9 -> ave = 5
// conditional format #6: top 3 values
inc(row);
@ -183,7 +183,7 @@ begin
fmt.SetBackgroundColor($FFC0C0);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcBottomPercent, 10, fmtIdx);
(*
// conditional format #6: duplicates
inc(row);
sh.WriteText(row, 0, 'duplicate values');
@ -199,7 +199,7 @@ begin
fmt.SetBackgroundColor($D0D0FF);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcUnique, fmtIdx);
*)
// conditional format #6: contains any text
inc(row);
sh.WriteText(row, 0, 'contains any text');
@ -247,7 +247,7 @@ begin
fmt.SetBackgroundColor(scRed);
fmtIdx := wb.AddCellFormat(fmt);
sh.WriteConditionalCellFormat(Range(row, 2, row, lastCol), cfcNotContainsText, 'ef', fmtIdx);
(*
// conditional format #6: contains error
inc(row);
sh.WriteText(row, 0, 'contains error');

View File

@ -46,8 +46,8 @@ It provides graphical components like a grid and chart."/>
<RequiredPkgs Count="4">
<Item1>
<PackageName Value="laz_fpspreadsheet"/>
<MaxVersion Major="1" Minor="11"/>
<MinVersion Major="1" Minor="12" Valid="True"/>
<MaxVersion Major="1" Minor="12"/>
<MinVersion Major="1" Minor="13" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="tachartlazaruspkg"/>

View File

@ -383,9 +383,11 @@ const
COLWIDTH_EPS = 1e-3;
ROWHEIGHT_EPS = 1e-3;
CF_OPERATORS: array[TsCFCondition] of string = (
'=', '!=', '&gt;', '&lt;', '&gt;=', '&lt;=',
'', '', // cfcBetween, cfcNotBetween,
CF_STYLE_OP: array[TsCFCondition] of string = (
'cell-content()=%s', 'cell-content()!=%s', // cfcEqual, cfcNotEqual
'cell-content()&gt;%s', 'cell-content()&lt;%s', //cfcGreaterThan, cfcLessThan
'cell-content()&gt;=%s', 'cell-content&lt;=%s', // cfcGreaterEqual, cfdLessEqual
'cell-is-between(%s,%s)', 'cell-is-not-between(%s,%s)', // cfcBetween, cfcNotBetween,
'', '', '', '', // cfcAboveAverage, cfcBelowAverage, cfcAboveEqualAverage, cfcBelowEqualAverage
'', '', '', '', // cfcTop, cfcBottom, cfcTopPercent, cfcBottomPercent,
'', '', // cfcDuplicate, cfcUnique,
@ -393,6 +395,22 @@ const
'', '' // cfcContainsErrors, cfcNotContainsErrors
);
CF_CALCEXT_OP: array[TsCFCondition] of string = (
'=%s', '!=%s', // cfcEqual, cfcNotEqual
'&gt;%s', '&lt;%s', //cfcGreaterThan, cfcLessThan
'&gt;=%s', '&lt;=%s', // cfcGreaterEqual, cfdLessEqual
'between(%s,%s)', 'not-between(%s,%s)', // cfcBetween, cfcNotBetween,
'above-average', 'below-average', // cfcAboveAverage, cfcBelowAverage,
'above-equal-average', 'below-equal-average', // cfcAboveEqualAverage, cfcBelowEqualAverage
'top-elements(%s)', 'bottom-elements(%s)', // cfcTop, cfcBottom,
'top-percent(%s)', 'bottom-percent(%s)', // cfcTopPercent, cfcBottomPercent,
'', '', // cfcDuplicate, cfcUnique,
'begins-with(%s)', 'ends-with(%s)', // cfcBeginsWith, cfcEndsWith,
'contains-text(%s)', 'not-contains-text(%s)', // cfcContainsText, cfcNotContainsText,
'', '' // cfcContainsErrors, cfcNotContainsErrors
);
type
{ Table style items stored in TableStyleList of the reader }
@ -5899,6 +5917,12 @@ begin
begin
cf_cellRule := TsCFCellRule(cf.Rules[k]);
cf_styleName := Format('conditional_%d', [cf_CellRule.FormatIndex]);
value1Str := VarToStr(cf_cellRule.Operand1);
if VarIsStr(cf_cellRule.Operand1) then value1Str := UTF8TextToXMLText(SafeQuoteStr(value1Str));
value2Str := VarToStr(cf_cellRule.Operand2);
if VarIsStr(cf_cellRule.Operand1) then value2Str := UTF8TextToXMLText(SafeQuoteStr(value2Str));
opStr := Format(CF_CALCEXT_OP[cf_cellRule.Condition], [value1Str, value2str]);
(*
case cf_cellRule.Condition of
cfcEqual..cfcLessEqual:
begin
@ -5926,6 +5950,8 @@ begin
else
Continue;
end;
*)
if opStr <> '' then
AppendToStream(AStream, Format(
'<calcext:condition calcext:apply-style-name="%s" calcext:value="%s" calcext:base-cell-address="%s" />',
[cf_stylename, opStr, firstCellStr]
@ -7365,12 +7391,18 @@ begin
cf_sheet := cf.Worksheet as TsWorksheet;
firstCellOfRange := cf_sheet.Name + '.' + GetCellString(cf.CellRange.Row1, cf.CellRange.Col1);
// Every rule has a style:map node
// Some rules have a style:map node
for k := 0 to cf.RulesCount-1 do begin
if cf.Rules[k] is TsCFCellRule then
begin
cf_cellRule := TsCFCellRule(cf.Rules[k]);
cf_styleName := Format('conditional_%d', [cf_cellRule.FormatIndex]);
operand1Str := VarToStr(cf_cellrule.Operand1);
if VarIsStr(cf_cellRule.Operand1) then operand1Str := UTF8TextToXMLText(SafeQuoteStr(operand1Str));
operand2Str := VarToStr(cf_cellrule.Operand2);
if VarIsStr(cf_cellRule.Operand2) then operand2Str := UTF8TextToXMLText(SafeQuoteStr(operand2Str));
cf_condition := Format(CF_STYLE_OP[cf_cellRule.Condition], [operand1Str, operand2Str]);
(*
case cf_cellRule.Condition of
cfcEqual..cfcLessEqual:
begin
@ -7399,6 +7431,7 @@ begin
else
cf_Condition := '';
end;
*)
if cf_Condition <> '' then
Result := Result +

View File

@ -640,8 +640,9 @@ type
imRow, imCol);
{@@ Inspector expanded nodes }
TsInspectorExpandedNode = (ienFormatSettings, ienPageLayout, ienFonts, ienFormats,
ienEmbeddedObj, ienImages, ienCryptoInfo);
TsInspectorExpandedNode = (ienFormatSettings, ienConditionalFormats,
ienPageLayout, ienFonts, ienFormats, ienEmbeddedObj, ienImages,
ienCryptoInfo);
TsInspectorExpandedNodes = set of TsInspectorExpandedNode;
{@@ TsSpreadsheetInspector displays all properties of a workbook, worksheet,
@ -691,8 +692,8 @@ type
{@@ Displays subproperties }
property ExpandedNodes: TsInspectorExpandedNodes
read FExpanded write SetExpanded
default [ienFormatSettings, ienPageLayout, ienFonts, ienFormats,
ienEmbeddedObj, ienImages, ienCryptoInfo];
default [ienFormatSettings, ienConditionalFormats, ienPageLayout,
ienFonts, ienFormats, ienEmbeddedObj, ienImages, ienCryptoInfo];
{@@ inherited from TValueListEditor. Turns of the fixed column by default}
property FixedCols default 0;
{@@ inherited from TStringGrid, but not published in TValueListEditor. }
@ -708,7 +709,7 @@ uses
Types, Math, StrUtils, TypInfo, LCLType, LCLIntf, LCLProc,
Dialogs, Forms, Clipbrd,
fpsStrings, fpsCrypto, fpsReaderWriter, fpsUtils, fpsNumFormat, fpsImages,
fpsHTMLUtils, fpsCSV, fpsExprParser;
fpsHTMLUtils, fpsCSV, fpsExprParser, fpsConditionalFormat;
var
cfBiff8Format: Integer = 0;
@ -3529,8 +3530,8 @@ begin
inherited Create(AOwner);
DisplayOptions := DisplayOptions - [doKeyColFixed];
FixedCols := 0;
FExpanded := [ienFormatSettings, ienPageLayout, ienFonts, ienFormats,
ienEmbeddedObj, ienImages, ienCryptoInfo];
FExpanded := [ienFormatSettings, ienConditionalFormats, ienPageLayout,
ienFonts, ienFormats, ienEmbeddedObj, ienImages, ienCryptoInfo];
with (TitleCaptions as TStringList) do begin
OnChange := nil; // This fixes an issue with Laz 1.0
Clear;
@ -3566,6 +3567,12 @@ begin
then Exclude(expNodes, ienFormatSettings)
else Include(expNodes, ienFormatSettings);
end else
if (pos('Conditional formats', s) > 0) or (pos('ConditionalFormats', s) > 0) then
begin
if (ienConditionalFormats in expNodes)
then Exclude(expNodes, ienConditionalFormats)
else Include(expNodes, ienConditionalFormats);
end else
if (pos('Page layout', s) > 0) or (pos('PageLayout', s) > 0) then
begin
if (ienPageLayout in expNodes)
@ -4252,6 +4259,7 @@ var
embObj: TsEmbeddedObj;
so: TsSheetOption;
sp: TsWorksheetProtection;
cf: TsConditionalFormat;
begin
if ASheet = nil then
begin
@ -4270,6 +4278,7 @@ begin
AStrings.Add('Options=');
AStrings.Add('Protection=');
AStrings.Add('TabColor=');
AStrings.Add('Conditional formats=');
end else
begin
AStrings.Add(Format('Name=%s', [ASheet.Name]));
@ -4292,7 +4301,23 @@ begin
AStrings.Add(Format('Hyperlinks=%d items', [ASheet.Hyperlinks.Count]));
AStrings.Add(Format('MergedCells=%d items', [ASheet.MergedCells.Count]));
AStrings.Add(Format('TabColor=$%.8x (%s)', [ASheet.TabColor, GetColorName(ASheet.TabColor)]));
(*
if ienConditionalFormats in FExpanded then
begin
AStrings.Add('(-) Conditional formats=');
AStrings.Add(Format(' Count=%d', [ASheet.ConditionalFormatCount]));
for i := 0 to ASheet.ConditionalFormatCount-1 do
begin
cf := ASheet.ReadConditionalFormat(i);
AStrings.Add(' Item #' + IntToStr(i) + ':');
with cf.CellRange do
AStrings.Add(Format(' CellRange=%s', [GetCellRangeString(Row1, Col1, Row2, Col2)]));
end;
end else
begin
AStrings.Add('(+) Conditional formats=(dblclick for more...)');
end;
*)
if ienPageLayout in FExpanded then
begin
AStrings.Add('(-) Page layout=');