fpspreadsheet: Fix colwidth issue causing the reader's FixCols to delete all col records.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7091 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2019-07-31 20:46:07 +00:00
parent ac4d69639b
commit 535ad46df3
3 changed files with 78 additions and 19 deletions

View File

@ -2001,6 +2001,7 @@ var
colWidth: double; colWidth: double;
colPageBreak: Boolean; colPageBreak: Boolean;
s: String; s: String;
nodeName: String;
begin begin
styleName := GetAttrValue(AStyleNode, 'style:name'); styleName := GetAttrValue(AStyleNode, 'style:name');
styleChildNode := AStyleNode.FirstChild; styleChildNode := AStyleNode.FirstChild;
@ -2009,7 +2010,8 @@ begin
while Assigned(styleChildNode) do while Assigned(styleChildNode) do
begin begin
if styleChildNode.NodeName = 'style:table-column-properties' then nodeName := styleChildNode.NodeName;
if nodeName = 'style:table-column-properties' then
begin begin
s := GetAttrValue(styleChildNode, 'style:column-width'); s := GetAttrValue(styleChildNode, 'style:column-width');
if s <> '' then if s <> '' then
@ -4862,28 +4864,31 @@ begin
{ At first, add the default column width } { At first, add the default column width }
colStyle := TColumnStyleData.Create; colStyle := TColumnStyleData.Create;
colStyle.Name := 'co1'; colStyle.Name := 'co1'; // 1 = "one"
colStyle.ColWidth := wDef; colStyle.ColWidth := wDef;
FColumnStyleList.Add(colStyle); FColumnStyleList.Add(colStyle);
{ Then iterate through all sheets and all columns and store the unique { Then iterate through all sheets and all columns and store the records with
column widths in the FColumnStyleList. } unique properties in the FColumnStyleList. }
for i:=0 to book.GetWorksheetCount-1 do for i:=0 to book.GetWorksheetCount-1 do
begin begin
sheet := book.GetWorksheetByIndex(i); sheet := book.GetWorksheetByIndex(i);
wDef := sheet.ReadDefaultColWidth(book.Units);
for c := 0 to sheet.Cols.Count-1 do for c := 0 to sheet.Cols.Count-1 do
begin begin
col := PCol(sheet.Cols[c]); col := PCol(sheet.Cols[c]);
if (col^.ColWidthType = cwtCustom) or (croPageBreak in col^.Options) then if not sheet.IsDefaultCol(col) then
begin begin
colPageBreak := (croPageBreak in col^.Options); // has page break? colPageBreak := (croPageBreak in col^.Options); // has page break?
w := col^.Width; // is in workbook units if col^.ColWidthType = cwtDefault then
w := wDef
else
w := col^.Width; // is in workbook units
// Look for this width in the current ColumnStyleList // Look for this width in the current ColumnStyleList
found := false; found := false;
for j := 0 to FColumnStyleList.Count - 1 do begin for j := 0 to FColumnStyleList.Count - 1 do begin
item := TColumnStyleData(FColumnStyleList[j]); item := TColumnStyleData(FColumnStyleList[j]);
if SameValue(item.ColWidth, w, COLWIDTH_EPS) and (item.PageBreak = colPageBreak) then if SameValue(item.ColWidth, w, COLWIDTH_EPS) and
(item.PageBreak = colPageBreak) then
begin begin
found := true; found := true;
break; break;
@ -4894,10 +4899,7 @@ begin
begin begin
colStyle := TColumnStyleData.Create; colStyle := TColumnStyleData.Create;
colStyle.Name := Format('co%d', [FColumnStyleList.Count + 1]); colStyle.Name := Format('co%d', [FColumnStyleList.Count + 1]);
if col^.ColWidthType = cwtDefault then colStyle.ColWidth := w;
colStyle.ColWidth := wDef
else
colStyle.ColWidth := w;
colStyle.PageBreak := colPageBreak; colStyle.PageBreak := colPageBreak;
FColumnStyleList.Add(colStyle); FColumnStyleList.Add(colStyle);
end; end;
@ -4974,7 +4976,7 @@ begin
{ At first, add the default row height } { At first, add the default row height }
{ Initially, row height units will be the same as in the workbook } { Initially, row height units will be the same as in the workbook }
rowStyle := TRowStyleData.Create; rowStyle := TRowStyleData.Create;
rowStyle.Name := 'ro1'; rowStyle.Name := 'ro1'; // 1 = "one"
rowStyle.RowHeight := book.ConvertUnits(15, suPoints, FWorkbook.Units); rowStyle.RowHeight := book.ConvertUnits(15, suPoints, FWorkbook.Units);
rowStyle.RowHeightType := rhtAuto; rowStyle.RowHeightType := rhtAuto;
FRowStyleList.Add(rowStyle); FRowStyleList.Add(rowStyle);
@ -4985,7 +4987,7 @@ begin
for r:=0 to sheet.GetLastRowIndex do for r:=0 to sheet.GetLastRowIndex do
begin begin
row := sheet.FindRow(r); row := sheet.FindRow(r);
if row <> nil then if not sheet.IsDefaultRow(row) then
begin begin
rowPageBreak := (croPageBreak in row^.Options); rowPageBreak := (croPageBreak in row^.Options);
h := sheet.GetRowHeight(r, FWorkbook.Units); h := sheet.GetRowHeight(r, FWorkbook.Units);
@ -5005,7 +5007,7 @@ begin
if not found then if not found then
begin begin
rowStyle := TRowStyleData.Create; rowStyle := TRowStyleData.Create;
rowStyle.Name := Format('ro%d', [FRowStyleList.Count+1]); rowStyle.Name := Format('ro%d', [FRowStyleList.Count + 1]);
rowStyle.RowHeight := h; rowStyle.RowHeight := h;
rowStyle.RowHeightType := row^.RowHeightType; rowStyle.RowHeightType := row^.RowHeightType;
rowStyle.PageBreak := rowPageBreak; rowStyle.PageBreak := rowPageBreak;

View File

@ -453,6 +453,8 @@ type
function GetColWidthType(ACol: Cardinal): TsColWidthType; function GetColWidthType(ACol: Cardinal): TsColWidthType;
function HasColFormats: Boolean; function HasColFormats: Boolean;
function HasRowFormats: Boolean; function HasRowFormats: Boolean;
function IsDefaultCol(ACol: PCol): Boolean;
function IsDefaultRow(ARow: PRow): Boolean;
function ColHidden(ACol: Cardinal): Boolean; function ColHidden(ACol: Cardinal): Boolean;
function RowHidden(ARow: Cardinal): Boolean; function RowHidden(ARow: Cardinal): Boolean;
procedure HideCol(ACol: Cardinal); procedure HideCol(ACol: Cardinal);
@ -7601,6 +7603,15 @@ function TsWorksheet.GetColWidth(ACol: Cardinal; AUnits: TsSizeUnits): Single;
var var
col: PCol; col: PCol;
begin begin
Result := FDefaultColWidth;
if ACol <> UNASSIGNED_ROW_COL_INDEX then begin
col := FindCol(ACol);
if (col <> nil) and (col^.ColWidthType <> cwtDefault) then
Result := col^.Width;
end;
Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits);
{
if ACol = UNASSIGNED_ROW_COL_INDEX then if ACol = UNASSIGNED_ROW_COL_INDEX then
Result := 0 Result := 0
else else
@ -7612,6 +7623,7 @@ begin
Result := col^.Width; Result := col^.Width;
Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits); Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits);
end; end;
}
end; end;
function TsWorksheet.GetColWidth(ACol: Cardinal): Single; function TsWorksheet.GetColWidth(ACol: Cardinal): Single;
@ -7675,6 +7687,16 @@ function TsWorksheet.GetRowHeight(ARow: Cardinal; AUnits: TsSizeUnits): Single;
var var
lRow: PRow; lRow: PRow;
begin begin
Result := FDefaultRowHeight;
if ARow <> UNASSIGNED_ROW_COL_INDEX then
begin
lRow := FindRow(ARow);
if (lRow <> nil) and (lRow^.RowHeightType <> rhtDefault) then
Result := lRow^.Height;
end;
Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits);
{
if ARow = UNASSIGNED_ROW_COL_INDEX then if ARow = UNASSIGNED_ROW_COL_INDEX then
Result := 0 Result := 0
else else
@ -7688,6 +7710,7 @@ begin
Result := FDefaultRowHeight; Result := FDefaultRowHeight;
Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits); Result := FWorkbook.ConvertUnits(Result, FWorkbook.Units, AUnits);
end; end;
}
end; end;
function TsWorksheet.GetRowHeight(ARow: Cardinal): Single; function TsWorksheet.GetRowHeight(ARow: Cardinal): Single;
@ -7741,6 +7764,30 @@ begin
Result := false; Result := false;
end; end;
{@@ ----------------------------------------------------------------------------
Determines whether the properties stored in a TCol record are default values
only. Such a record usually can be removed.
-------------------------------------------------------------------------------}
function TsWorksheet.IsDefaultCol(ACol: PCol): Boolean;
begin
Result :=
(ACol = nil) or (
(ACol^.ColWidthType = cwtDefault) and (ACol^.FormatIndex = 0) and (ACol^.Options = [])
);
end;
{@@ ----------------------------------------------------------------------------
Determines whether the properties stored in a TRow record are default values
only. Such a record normally can be removed.
-------------------------------------------------------------------------------}
function TsWorksheet.IsDefaultRow(ARow: PRow): Boolean;
begin
Result :=
(ARow = nil) or (
(ARow^.RowHeightType = rhtDefault) and (ARow^.FormatIndex = 0) and (ARow^.Options = [])
);
end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Returns whether the specified column is hidden Returns whether the specified column is hidden
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
@ -8273,7 +8320,7 @@ begin
if ARow = UNASSIGNED_ROW_COL_INDEX then if ARow = UNASSIGNED_ROW_COL_INDEX then
exit; exit;
lRow := GetRow(ARow); lRow := GetRow(ARow);
if (croHidden in lRow^.Options) then if not (croHidden in lRow^.Options) then
begin begin
lRow^.Height := FWorkbook.ConvertUnits(AHeight, AUnits, FWorkbook.FUnits); lRow^.Height := FWorkbook.ConvertUnits(AHeight, AUnits, FWorkbook.FUnits);
lRow^.RowHeightType := ARowHeightType; lRow^.RowHeightType := ARowHeightType;

View File

@ -386,7 +386,7 @@ const
var var
sheet: TsWorksheet absolute AWorksheet; sheet: TsWorksheet absolute AWorksheet;
c: LongInt; c: LongInt;
w: Single; w0, w: Single;
lCol: PCol; lCol: PCol;
sameWidth: Boolean; sameWidth: Boolean;
begin begin
@ -416,10 +416,20 @@ begin
// Check whether all columns have the same column width // Check whether all columns have the same column width
sameWidth := true; sameWidth := true;
w := PCol(sheet.Cols[0])^.Width; lCol := PCol(sheet.Cols[0]);
if lCol^.ColWidthType = cwtCustom then
w0 := lCol^.Width
else
w0 := sheet.DefaultColWidth;
// w := PCol(sheet.Cols[0])^.Width;
for c := 1 to sheet.Cols.Count-1 do begin for c := 1 to sheet.Cols.Count-1 do begin
lCol := PCol(sheet.Cols[c]); lCol := PCol(sheet.Cols[c]);
if not SameValue(lCol^.Width, w, EPS) then if lCol^.ColWidthType = cwtCustom then
w := lCol^.Width
else
w := sheet.DefaultColWidth;
if not SameValue(w, w0) then
// if not SameValue(lCol^.Width, w, EPS) then
begin begin
sameWidth := false; sameWidth := false;
break; break;