diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas
index 2a8d066e4..96f56d102 100755
--- a/components/fpspreadsheet/fpsopendocument.pas
+++ b/components/fpspreadsheet/fpsopendocument.pas
@@ -174,6 +174,8 @@ type
FRowStyleList: TFPList;
FRichTextFontList: TStringList;
FHeaderFooterFontList: TObjectList;
+ FHasColFormats: Boolean;
+ FHasRowFormats: Boolean;
// Routines to write parts of files
procedure WriteAutomaticStyles(AStream: TStream);
@@ -4947,6 +4949,11 @@ procedure TsSpreadOpenDocWriter.WriteWorksheet(AStream: TStream;
begin
FWorksheet := FWorkbook.GetWorksheetByIndex(ASheetIndex);
+ // Buffer the information whether the worksheet contains column or row formats
+ // Needed for writing rows and cells
+ FHasColFormats := FWorksheet.HasColFormats;
+ FHasRowFormats := FWorksheet.HasRowFormats;
+
// Header
AppendToStream(AStream, Format(
'', [
@@ -4974,6 +4981,8 @@ begin
'');
end;
+{ Writes the cell styles ("ce0", "ce1", ...). Directly maps to the CellFormats
+ list of the workbook. "ce0" is the default format }
procedure TsSpreadOpenDocWriter.WriteCellStyles(AStream: TStream);
var
i, j, p: Integer;
@@ -5016,11 +5025,13 @@ begin
'style:parent-style-name="Default" '+ nfs + '>');
// style:text-properties
+ // - font
s := WriteFontStyleXMLAsString(fmt);
if s <> '' then
AppendToStream(AStream,
'');
+ // - border, background, wordwrap, text rotation, vertical alignment
s := WriteBorderStyleXMLAsString(fmt) +
WriteBackgroundColorStyleXMLAsString(fmt) +
WriteWordwrapStyleXMLAsString(fmt) +
@@ -5031,7 +5042,9 @@ begin
'');
// style:paragraph-properties
- s := WriteHorAlignmentStyleXMLAsString(fmt) + WriteBiDiModeStyleXMLAsString(fmt);
+ // - hor alignment, bidi
+ s := WriteHorAlignmentStyleXMLAsString(fmt) +
+ WriteBiDiModeStyleXMLAsString(fmt);
if s <> '' then
AppendToStream(AStream,
'');
@@ -5082,6 +5095,7 @@ var
lastCol: Integer;
c, k: Integer;
w: Double;
+ fmt: Integer;
// w, w_mm: Double;
// widthMultiplier: Double;
styleName: String;
@@ -5118,8 +5132,12 @@ begin
styleName := TColumnStyleData(FColumnStyleList[k]).Name;
break;
end;
+ if stylename = '' then
+ stylename := 'co1';
+ {
if stylename = '' then
raise Exception.Create(rsColumnStyleNotFound);
+ }
// Determine value for "number-columns-repeated"
colsRepeated := 1;
@@ -5142,6 +5160,9 @@ begin
break;
inc(k);
end;
+ if FHasRowFormats and (k = lastcol) then
+ colsRepeated := FLimitations.MaxColCount - c;
+
colsRepeatedStr := IfThen(colsRepeated = 1, '', Format(' table:number-columns-repeated="%d"', [colsRepeated]));
AppendToStream(AStream, Format(
@@ -5487,28 +5508,28 @@ begin
headerRows := true;
end;
- // Look for the row style of the current row (r)
+ // Look for the row style of the current row (r): row style contains only
+ // row height, no row format!
row := ASheet.FindRow(r);
- if row = nil then begin
- styleName := 'ro1';
- h := ASheet.ReadDefaultRowHeight(FWorkbook.Units);
- end else
+ styleName := '';
+ if row <> nil then
begin
- styleName := '';
-
h := row^.Height; // row height in workbook units
for k := 0 to FRowStyleList.Count-1 do begin
rowStyleData := TRowStyleData(FRowStyleList[k]);
// Compare row heights, but be aware of rounding errors
if SameValue(rowStyleData.RowHeight, h, ROWHEIGHT_EPS) and
- (rowstyleData.RowHeightType = row^.RowHeightType)
+ (rowstyleData.RowHeightType = row^.RowHeightType) and
+ (rowstyleData.RowHeightType <> rhtDefault)
then begin
styleName := rowStyleData.Name;
break;
end;
end;
- if styleName = '' then
- raise Exception.Create(rsRowStyleNotFound);
+ end;
+ if styleName = '' then begin
+ styleName := 'ro1'; // "ro1" is default row record - see ListAllRowStyles
+ h := ASheet.ReadDefaultRowHeight(FWorkbook.Units);
end;
// Take care of empty rows above the first row
@@ -5517,7 +5538,9 @@ begin
rowsRepeated := r;
rowsRepeatedStr := IfThen(rowsRepeated = 1, '',
Format('table:number-rows-repeated="%d"', [rowsRepeated]));
- colsRepeated := lastCol + 1;
+ if FHasRowFormats then
+ colsRepeated := FLimitations.MaxColCount else
+ colsRepeated := lastCol + 1;
colsRepeatedStr := IfThen(colsRepeated = 1, '',
Format('table:number-columns-repeated="%d"', [colsRepeated]));
AppendToStream(AStream, Format(
@@ -5544,7 +5567,9 @@ begin
rowsRepeated := rr - r;
rowsRepeatedStr := IfThen(rowsRepeated = 1, '',
Format('table:number-rows-repeated="%d"', [rowsRepeated]));
- colsRepeated := lastCol - firstCol + 1;
+ if FHasRowFormats then
+ colsRepeated := FLimitations.MaxColCount else
+ colsRepeated := lastCol - firstCol + 1;
colsRepeatedStr := IfThen(colsRepeated = 1, '',
Format('table:number-columns-repeated="%d"', [colsRepeated]));
@@ -5600,11 +5625,17 @@ begin
break;
inc(cc)
end;
- colsRepeated := cc - c;
+ if FHasRowFormats and (cc > lastcol) then
+ colsRepeated := FLimitations.MaxColCount - c else
+ colsRepeated := cc - c;
colsRepeatedStr := IfThen(colsRepeated = 1, '',
- Format('table:number-columns-repeated="%d"', [colsRepeated]));
+ Format(' table:number-columns-repeated="%d"', [colsRepeated]));
+ row := ASheet.FindRow(r);
+ if (row <> nil) and (row^.FormatIndex > 0) then
+ stylename := Format(' table:style-name="ce%d"', [row^.FormatIndex]) else
+ stylename := '';
AppendToStream(AStream, Format(
- '', [colsRepeatedStr]));
+ '', [colsRepeatedStr, stylename]));
end else
WriteCellToStream(AStream, cell);
inc(c, colsRepeated);
@@ -5625,6 +5656,8 @@ begin
end;
end;
+{ Write the style nodes for rows ("ro1", "ro2", ...); they contain only
+ row height information. "ro1" is the default row height }
procedure TsSpreadOpenDocWriter.WriteRowStyles(AStream: TStream);
var
i: Integer;
@@ -5632,10 +5665,13 @@ var
begin
if FRowStyleList.Count = 0 then
begin
- AppendToStream(AStream,
+ AppendToStream(AStream, Format(
'' +
- '' +
- '');
+ '' +
+ '',
+ [FWorksheet.ReadDefaultRowHeight(suMillimeters)]
+ ));
exit;
end;
@@ -5654,7 +5690,6 @@ begin
FPointSeparatorSettings));
AppendToStream(AStream, Format(
'style:use-optimal-row-height="%s" ', [FALSE_TRUE[rowstyle.RowHeightType <> rhtCustom]]));
- // row height < 0 means: automatic row height
AppendToStream(AStream,
'fo:break-before="auto"/>');
@@ -7164,16 +7199,16 @@ begin
if FWorksheet.IsMergeBase(ACell) then
begin
FWorksheet.FindMergedRange(ACell, r1, c1, r2, c2);
- rowsSpannedStr := Format('table:number-rows-spanned="%d"', [r2 - r1 + 1]);
- colsSpannedStr := Format('table:number-columns-spanned="%d"', [c2 - c1 + 1]);
- spannedStr := colsSpannedStr + ' ' + rowsSpannedStr;
+ colsSpannedStr := Format(' table:number-columns-spanned="%d"', [c2 - c1 + 1]);
+ rowsSpannedStr := Format(' table:number-rows-spanned="%d"', [r2 - r1 + 1]);
+ spannedStr := colsSpannedStr + rowsSpannedStr;
end else
spannedStr := '';
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
numFmtParams := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
if fmt.UsedFormattingFields <> [] then
- lStyle := ' table:style-name="ce' + IntToStr(ACell^.FormatIndex) + '" '
+ lStyle := Format(' table:style-name="ce%d"', [ACell^.FormatIndex])
else
lStyle := '';
@@ -7194,7 +7229,7 @@ begin
displayStr := FWorksheet.ReadAsText(ACell);
// displayStr := FormatDateTime(fmt.NumberFormatStr, AValue, [fdoInterval]);
AppendToStream(AStream, Format(
- '' +
+ '' +
comment +
'%s' +
'', [
diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas
index 11219ba0d..8a1cdb89b 100755
--- a/components/fpspreadsheet/fpspreadsheet.pas
+++ b/components/fpspreadsheet/fpspreadsheet.pas
@@ -425,6 +425,8 @@ type
function GetColFormatIndex(ACol: Cardinal): Integer;
function GetColWidth(ACol: Cardinal; AUnits: TsSizeUnits): Single; overload;
function GetColWidth(ACol: Cardinal): Single; overload; deprecated 'Use version with parameter AUnits.';
+ function HasColFormats: Boolean;
+ function HasRowFormats: Boolean;
procedure DeleteCol(ACol: Cardinal);
procedure DeleteRow(ARow: Cardinal);
procedure InsertCol(ACol: Cardinal);
@@ -4622,7 +4624,6 @@ begin
Delete(AValue, 1, 1);
WriteNumberFormat(ACell, nfText);
end;
-
fmtIndex := GetEffectiveCellFormatIndex(ACell);
fmt := Workbook.GetCellFormat(fmtIndex);
numFmtParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
@@ -4661,25 +4662,6 @@ begin
exit;
end;
- if TryStrToFloat(AValue, number, FWorkbook.FormatSettings) then
- begin
- if isPercent then
- WriteNumber(ACell, number/100, nfPercentage)
- else
- begin
- if IsDateTimeFormat(numFmtParams) then
- WriteNumber(ACell, number, nfGeneral)
- else
- WriteNumber(ACell, number);
- end;
- if IsTextFormat(numFmtParams) then
- begin
- WriteNumberFormat(ACell, nfText);
- WriteText(ACell, AValue);
- end;
- exit;
- end;
-
if TryStrToDateTime(AValue, number, FWorkbook.FormatSettings) then
begin
if number < 1.0 then // this is a time alone
@@ -4709,6 +4691,25 @@ begin
exit;
end;
+ if TryStrToFloat(AValue, number, FWorkbook.FormatSettings) then
+ begin
+ if isPercent then
+ WriteNumber(ACell, number/100, nfPercentage)
+ else
+ begin
+ if IsDateTimeFormat(numFmtParams) then
+ WriteNumber(ACell, number, nfGeneral)
+ else
+ WriteNumber(ACell, number);
+ end;
+ if IsTextFormat(numFmtParams) then
+ begin
+ WriteNumberFormat(ACell, nfText);
+ WriteText(ACell, AValue);
+ end;
+ exit;
+ end;
+
HTMLToRichText(FWorkbook, ReadcellFont(ACell), AValue, plain, rtParams);
WriteText(ACell, plain, rtParams);
end;
@@ -6629,6 +6630,32 @@ begin
Result := lRow^.RowHeightType;
end;
+function TsWorksheet.HasColFormats: Boolean;
+var
+ c: Integer;
+begin
+ for c := 0 to FCols.Count-1 do
+ if PCol(FCols[c]).FormatIndex > 0 then
+ begin
+ Result := true;
+ exit;
+ end;
+ Result := false;
+end;
+
+function TsWorksheet.HasRowFormats: Boolean;
+var
+ r: Integer;
+begin
+ for r := 0 to FRows.Count-1 do
+ if PRow(FRows[r]).FormatIndex > 0 then
+ begin
+ Result := true;
+ exit;
+ end;
+ Result := false;
+end;
+
{@@ ----------------------------------------------------------------------------
Deletes the column at the index specified. Cells with greader column indexes
are moved one column to the left. Merged cell blocks and cell references in
diff --git a/components/fpspreadsheet/fpspreadsheetctrls.pas b/components/fpspreadsheet/fpspreadsheetctrls.pas
index e1a3c8a85..0e7a86231 100644
--- a/components/fpspreadsheet/fpspreadsheetctrls.pas
+++ b/components/fpspreadsheet/fpspreadsheetctrls.pas
@@ -3247,6 +3247,9 @@ begin
AStrings.Add(Format('RowHeightType=%s', [
RowHeightTypeNames[lRow^.RowHeightType]
]));
+ AStrings.Add(Format('FormatIndex=%d', [
+ lRow^.FormatIndex
+ ]));
end else
begin
AStrings.Add('No row record=');