You've already forked lazarus-ccr
fpspreadsheet: Heavy refactoring of ods row & cell reading. Intention is to read row and column formats, not 100% correct yet.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5260 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -97,17 +97,21 @@ type
|
|||||||
FRepeatedCols: TsRowColRange;
|
FRepeatedCols: TsRowColRange;
|
||||||
FRepeatedRows: TsRowColRange;
|
FRepeatedRows: TsRowColRange;
|
||||||
procedure ApplyColWidths;
|
procedure ApplyColWidths;
|
||||||
|
procedure ApplyStyleToCell(ACell: PCell; AStyleIndex: Integer);
|
||||||
function ApplyStyleToCell(ACell: PCell; AStyleName: String): Boolean;
|
function ApplyStyleToCell(ACell: PCell; AStyleName: String): Boolean;
|
||||||
function ApplyTableStyle(ASheet: TsWorksheet; AStyleName: String): Boolean;
|
function ApplyTableStyle(ASheet: TsWorksheet; AStyleName: String): Boolean;
|
||||||
function ExtractBoolFromNode(ANode: TDOMNode): Boolean;
|
function ExtractBoolFromNode(ANode: TDOMNode): Boolean;
|
||||||
function ExtractDateTimeFromNode(ANode: TDOMNode;
|
function ExtractDateTimeFromNode(ANode: TDOMNode;
|
||||||
ANumFormat: TsNumberFormat; const AFormatStr: String): TDateTime;
|
ANumFormat: TsNumberFormat; const AFormatStr: String): TDateTime;
|
||||||
function ExtractErrorFromNode(ANode: TDOMNode; out AErrorValue: TsErrorValue): Boolean;
|
function ExtractErrorFromNode(ANode: TDOMNode; out AErrorValue: TsErrorValue): Boolean;
|
||||||
|
function ExtractFormatIndexFromStyle(ACellStyleName: String; ACol: Integer): Integer;
|
||||||
function FindColumnByCol(AColIndex: Integer): Integer;
|
function FindColumnByCol(AColIndex: Integer): Integer;
|
||||||
function FindColStyleByName(AStyleName: String): integer;
|
function FindColStyleByName(AStyleName: String): integer;
|
||||||
function FindNumFormatByName(ANumFmtName: String): Integer;
|
function FindNumFormatByName(ANumFmtName: String): Integer;
|
||||||
function FindRowStyleByName(AStyleName: String): Integer;
|
function FindRowStyleByName(AStyleName: String): Integer;
|
||||||
function FindTableStyleByName(AStyleName: String): Integer;
|
function FindTableStyleByName(AStyleName: String): Integer;
|
||||||
|
procedure ReadCell(ANode: TDOMNode; ARow, ACol: Integer;
|
||||||
|
AFormatIndex: Integer; out AColsRepeated: Integer);
|
||||||
procedure ReadColumns(ATableNode: TDOMNode);
|
procedure ReadColumns(ATableNode: TDOMNode);
|
||||||
procedure ReadColumnStyle(AStyleNode: TDOMNode);
|
procedure ReadColumnStyle(AStyleNode: TDOMNode);
|
||||||
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
||||||
@ -138,14 +142,21 @@ type
|
|||||||
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
||||||
procedure ReadStyles(AStylesNode: TDOMNode);
|
procedure ReadStyles(AStylesNode: TDOMNode);
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
procedure ReadBlank(ARow, ACol: Cardinal; ACellNode: TDOMNode); reintroduce;
|
procedure ReadBlank(ARow, ACol: Cardinal;
|
||||||
procedure ReadBoolean(ARow, ACol: Cardinal; ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode); reintroduce;
|
||||||
|
procedure ReadBoolean(ARow, ACol: Cardinal;
|
||||||
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
procedure ReadComment(ARow, ACol: Cardinal; ACellNode: TDOMNode);
|
procedure ReadComment(ARow, ACol: Cardinal; ACellNode: TDOMNode);
|
||||||
procedure ReadDateTime(ARow, ACol: Cardinal; ACellNode: TDOMNode);
|
procedure ReadDateTime(ARow, ACol: Cardinal;
|
||||||
procedure ReadError(ARow, ACol: Cardinal; ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
procedure ReadFormula(ARow, ACol: Cardinal; ACellNode: TDOMNode); reintroduce;
|
procedure ReadError(ARow, ACol: Cardinal; AStyleIndex: Integer;
|
||||||
procedure ReadLabel(ARow, ACol: Cardinal; ACellNode: TDOMNode); reintroduce;
|
ACellNode: TDOMNode);
|
||||||
procedure ReadNumber(ARow, ACol: Cardinal; ACellNode: TDOMNode); reintroduce;
|
procedure ReadFormula(ARow, ACol: Cardinal; AstyleIndex: Integer;
|
||||||
|
ACellNode: TDOMNode); reintroduce;
|
||||||
|
procedure ReadLabel(ARow, ACol: Cardinal; AStyleIndex: Integer;
|
||||||
|
ACellNode: TDOMNode); reintroduce;
|
||||||
|
procedure ReadNumber(ARow, ACol: Cardinal; AStyleIndex: Integer;
|
||||||
|
ACellNode: TDOMNode); reintroduce;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsWorkbook); override;
|
||||||
@ -958,6 +969,10 @@ constructor TsSpreadOpenDocReader.Create(AWorkbook: TsWorkbook);
|
|||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
|
|
||||||
|
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications
|
||||||
|
FLimitations.MaxColCount := 1024;
|
||||||
|
FLimitations.MaxRowCount := 1048576;
|
||||||
|
|
||||||
FPointSeparatorSettings := DefaultFormatSettings;
|
FPointSeparatorSettings := DefaultFormatSettings;
|
||||||
FPointSeparatorSettings.DecimalSeparator := '.';
|
FPointSeparatorSettings.DecimalSeparator := '.';
|
||||||
FPointSeparatorSettings.ListSeparator := ';'; // for formulas
|
FPointSeparatorSettings.ListSeparator := ';'; // for formulas
|
||||||
@ -1030,46 +1045,103 @@ end;
|
|||||||
procedure TsSpreadOpenDocReader.ApplyColWidths;
|
procedure TsSpreadOpenDocReader.ApplyColWidths;
|
||||||
var
|
var
|
||||||
colIndex: Integer;
|
colIndex: Integer;
|
||||||
|
colData: TColumnData;
|
||||||
colStyleIndex: Integer;
|
colStyleIndex: Integer;
|
||||||
colStyle: TColumnStyleData;
|
colStyle: TColumnStyleData;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
u: TsSizeUnits;
|
|
||||||
defColWidth: Single;
|
defColWidth: Single;
|
||||||
|
colWidth: Single;
|
||||||
|
colWidthType: TsColWidthType;
|
||||||
lastOccCol: Integer;
|
lastOccCol: Integer;
|
||||||
begin
|
begin
|
||||||
u := FWorkbook.Units;
|
defColWidth := FWorksheet.ReadDefaultColWidth(FWorkbook.Units);
|
||||||
defColWidth := FWorksheet.ReadDefaultColWidth(u);
|
|
||||||
lastOccCol := FWorksheet.GetLastOccupiedColIndex;
|
lastOccCol := FWorksheet.GetLastOccupiedColIndex;
|
||||||
for i:=0 to FColumnList.Count-1 do
|
for i:=0 to FColumnList.Count-1 do
|
||||||
begin
|
begin
|
||||||
colIndex := TColumnData(FColumnList[i]).Col;
|
colData := TColumnData(FColumnList[i]);
|
||||||
|
colIndex := colData.Col;
|
||||||
|
|
||||||
// Skip column records beyond the last data column - there's a bug in OO/LO
|
// Skip column records beyond the last data column - there's a bug in OO/LO
|
||||||
// which adds column records up to the max column limit.
|
// which adds column records up to the max column limit.
|
||||||
if colIndex > lastOccCol then
|
if colIndex > lastOccCol then
|
||||||
Continue;
|
Continue;
|
||||||
colStyleIndex := TColumnData(FColumnList[i]).ColStyleIndex;
|
|
||||||
|
colStyleIndex := colData.ColStyleIndex;
|
||||||
colStyle := TColumnStyleData(FColumnStyleList[colStyleIndex]);
|
colStyle := TColumnStyleData(FColumnStyleList[colStyleIndex]);
|
||||||
// Add only column records to the worksheet if their width is different from
|
//defCellStyleIndex := colData.DefaultCellStyleIndex;
|
||||||
// the default column width. The column width stored in colStyle is already
|
{
|
||||||
// in workbook units (see ReadColumnStyles).
|
// Get column format
|
||||||
if not SameValue(colStyle.ColWidth, defColWidth, COLWIDTH_EPS) then
|
fmt := FCellFormatList.Items[defCellStyleIndex];
|
||||||
FWorksheet.WriteColWidth(colIndex, colStyle.ColWidth, u);
|
if fmt <> nil then
|
||||||
|
fmtIndex := FWorkbook.AddCellFormat(fmt^)
|
||||||
|
else
|
||||||
|
fmtIndex := 0;
|
||||||
|
}
|
||||||
|
// Prepare column record for the worksheet
|
||||||
|
colWidth := colStyle.ColWidth; // is already in workbook units
|
||||||
|
if SameValue(colWidth, defColWidth, COLWIDTH_EPS) then
|
||||||
|
colWidthType := cwtDefault
|
||||||
|
else
|
||||||
|
colWidthType := cwtCustom;
|
||||||
|
|
||||||
|
// Write non-default column width to the worksheet
|
||||||
|
if (colWidthType = cwtCustom) then
|
||||||
|
FWorksheet.WriteColWidth(colIndex, colWidth, FWorkbook.Units);
|
||||||
|
|
||||||
|
// Note: we don't store the column format index here; this is done in the
|
||||||
|
// row/cell reading method (ReadRowsAndCells).
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocReader.ExtractFormatIndexFromStyle(ACellStyleName: String;
|
||||||
|
ACol: Integer): Integer;
|
||||||
|
var
|
||||||
|
idx: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
if ACellStyleName <> '' then
|
||||||
|
Result := FCellFormatList.FindIndexOfName(ACellStyleName);
|
||||||
|
if Result = -1 then begin
|
||||||
|
idx := FindColumnByCol(ACol);
|
||||||
|
if idx > -1 then
|
||||||
|
Result := TColumnData(FColumnList[idx]).DefaultCellStyleIndex;
|
||||||
|
end;
|
||||||
|
if Result = -1 then
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocReader.ApplyStyleToCell(ACell: PCell; AStyleIndex: Integer);
|
||||||
|
var
|
||||||
|
fmt: TsCellFormat;
|
||||||
|
begin
|
||||||
|
if FWorksheet.HasHyperlink(ACell) then
|
||||||
|
FWorksheet.WriteFont(ACell, HYPERLINK_FONTINDEX);
|
||||||
|
|
||||||
|
fmt := FCellFormatList.Items[AStyleIndex]^;
|
||||||
|
if (AStyleIndex = 0) and FWorksheet.HasHyperlink(ACell) then begin
|
||||||
|
// Make sure to use hyperlink font for hyperlink cells in case of default cell style
|
||||||
|
fmt.FontIndex := HYPERLINK_FONTINDEX;
|
||||||
|
Include(fmt.UsedFormattingFields, uffFont);
|
||||||
|
end;
|
||||||
|
ACell^.FormatIndex := FWorkbook.AddCellFormat(fmt);
|
||||||
|
end;
|
||||||
|
|
||||||
{ Applies the style data referred to by the style name to the specified cell
|
{ Applies the style data referred to by the style name to the specified cell
|
||||||
The function result is false if a style with the given name could not be found }
|
The function result is false if a style with the given name could not be found }
|
||||||
function TsSpreadOpenDocReader.ApplyStyleToCell(ACell: PCell; AStyleName: String): Boolean;
|
function TsSpreadOpenDocReader.ApplyStyleToCell(ACell: PCell; AStyleName: String): Boolean;
|
||||||
var
|
var
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
styleIndex: Integer;
|
styleIndex: Integer;
|
||||||
i: Integer;
|
//i: Integer;
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
|
|
||||||
if FWorksheet.HasHyperlink(ACell) then
|
if FWorksheet.HasHyperlink(ACell) then
|
||||||
FWorksheet.WriteFont(ACell, HYPERLINK_FONTINDEX);
|
FWorksheet.WriteFont(ACell, HYPERLINK_FONTINDEX);
|
||||||
|
|
||||||
|
styleIndex := ExtractFormatIndexFromStyle(AStyleName, ACell^.Col);
|
||||||
|
(*
|
||||||
// Is there a style attached to the cell?
|
// Is there a style attached to the cell?
|
||||||
styleIndex := -1;
|
styleIndex := -1;
|
||||||
if AStyleName <> '' then
|
if AStyleName <> '' then
|
||||||
@ -1083,6 +1155,8 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
styleIndex := TColumnData(FColumnList[i]).DefaultCellStyleIndex;
|
styleIndex := TColumnData(FColumnList[i]).DefaultCellStyleIndex;
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
|
|
||||||
fmt := FCellFormatList.Items[styleIndex]^;
|
fmt := FCellFormatList.Items[styleIndex]^;
|
||||||
if (styleIndex = 0) and FWorksheet.HasHyperlink(ACell) then
|
if (styleIndex = 0) and FWorksheet.HasHyperlink(ACell) then
|
||||||
begin
|
begin
|
||||||
@ -1672,22 +1746,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal;
|
||||||
ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
styleName: String;
|
// styleName: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
lCell: TCell;
|
// lCell: TCell;
|
||||||
begin
|
begin
|
||||||
|
// No need to store a record for an empty, unformatted cell
|
||||||
|
if AStyleIndex = 0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
(*
|
||||||
// a temporary cell record to store the formatting if there is any
|
// a temporary cell record to store the formatting if there is any
|
||||||
lCell.Row := ARow; // to silence a compiler warning...
|
lCell.Row := ARow; // to silence a compiler warning...
|
||||||
InitCell(ARow, ACol, lCell);
|
InitCell(ARow, ACol, lCell);
|
||||||
lCell.ContentType := cctEmpty;
|
lCell.ContentType := cctEmpty;
|
||||||
|
lCell
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
if not ApplyStyleToCell(@lCell, stylename) then
|
if not ApplyStyleToCell(@lCell, stylename) then
|
||||||
exit;
|
exit;
|
||||||
// No need to store a record for an empty, unformatted cell
|
// No need to store a record for an empty, unformatted cell
|
||||||
|
*)
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
begin
|
begin
|
||||||
InitCell(ARow, ACol, FVirtualCell);
|
InitCell(ARow, ACol, FVirtualCell);
|
||||||
@ -1695,16 +1774,17 @@ begin
|
|||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := FWorksheet.AddCell(ARow, ACol);
|
||||||
FWorkSheet.WriteBlank(cell);
|
FWorkSheet.WriteBlank(cell);
|
||||||
FWorksheet.CopyFormat(@lCell, cell);
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
// FWorksheet.CopyFormat(@lCell, cell);
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadBoolean(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadBoolean(ARow, ACol: Cardinal;
|
||||||
ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
styleName: String;
|
// styleName: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
boolValue: Boolean;
|
boolValue: Boolean;
|
||||||
begin
|
begin
|
||||||
@ -1718,9 +1798,11 @@ begin
|
|||||||
boolValue := ExtractBoolFromNode(ACellNode);
|
boolValue := ExtractBoolFromNode(ACellNode);
|
||||||
FWorkSheet.WriteBoolValue(cell, boolValue);
|
FWorkSheet.WriteBoolValue(cell, boolValue);
|
||||||
|
|
||||||
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
{
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
ApplyStyleToCell(cell, stylename);
|
ApplyStyleToCell(cell, stylename);
|
||||||
|
}
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
@ -1758,13 +1840,14 @@ var
|
|||||||
colData.DefaultCellStyleIndex := defCellStyleIndex;
|
colData.DefaultCellStyleIndex := defCellStyleIndex;
|
||||||
FColumnList.Add(colData);
|
FColumnList.Add(colData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
s := GetAttrValue(AColNode, 'table:number-columns-repeated');
|
s := GetAttrValue(AColNode, 'table:number-columns-repeated');
|
||||||
if s = '' then
|
if s = '' then
|
||||||
inc(col)
|
inc(col)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
colsRepeated := StrToInt(s);
|
colsRepeated := StrToInt(s);
|
||||||
if defCellStyleIndex > -1 then
|
if defCellStyleIndex > -1 then begin
|
||||||
for j:=1 to colsRepeated-1 do
|
for j:=1 to colsRepeated-1 do
|
||||||
begin
|
begin
|
||||||
colData := TColumnData.Create;
|
colData := TColumnData.Create;
|
||||||
@ -1773,6 +1856,7 @@ var
|
|||||||
colData.DefaultCellStyleIndex := defCellStyleIndex;
|
colData.DefaultCellStyleIndex := defCellStyleIndex;
|
||||||
FColumnList.Add(colData);
|
FColumnList.Add(colData);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
inc(col, colsRepeated);
|
inc(col, colsRepeated);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1896,10 +1980,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadDateTime(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadDateTime(ARow, ACol: Cardinal;
|
||||||
ACellNode : TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
dt: TDateTime;
|
dt: TDateTime;
|
||||||
styleName: String;
|
// styleName: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
@ -1910,8 +1994,9 @@ begin
|
|||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := FWorksheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
ApplyStyleToCell(cell, stylename);
|
//styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
|
//ApplyStyleToCell(cell, stylename);
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(cell^.FormatIndex);;
|
fmt := FWorkbook.GetPointerToCellFormat(cell^.FormatIndex);;
|
||||||
|
|
||||||
dt := ExtractDateTimeFromNode(ACellNode, fmt^.NumberFormat, fmt^.NumberFormatStr);
|
dt := ExtractDateTimeFromNode(ACellNode, fmt^.NumberFormat, fmt^.NumberFormatStr);
|
||||||
@ -1922,9 +2007,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadError(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadError(ARow, ACol: Cardinal;
|
||||||
ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
styleName: String;
|
//styleName: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
errValue: TsErrorValue;
|
errValue: TsErrorValue;
|
||||||
begin
|
begin
|
||||||
@ -1939,8 +2024,11 @@ begin
|
|||||||
FWorkSheet.WriteErrorValue(cell, errValue) else
|
FWorkSheet.WriteErrorValue(cell, errValue) else
|
||||||
FWorksheet.WriteText(cell, 'ERROR');
|
FWorksheet.WriteText(cell, 'ERROR');
|
||||||
|
|
||||||
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
{
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
ApplyStyleToCell(cell, stylename);
|
ApplyStyleToCell(cell, stylename);
|
||||||
|
}
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
@ -2152,11 +2240,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadFormula(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadFormula(ARow, ACol: Cardinal;
|
||||||
ACellNode : TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
formula: String;
|
formula: String;
|
||||||
stylename: String;
|
// stylename: String;
|
||||||
floatValue: Double;
|
floatValue: Double;
|
||||||
boolValue: Boolean;
|
boolValue: Boolean;
|
||||||
errorValue: TsErrorValue;
|
errorValue: TsErrorValue;
|
||||||
@ -2175,8 +2263,11 @@ begin
|
|||||||
end else
|
end else
|
||||||
cell := FWorksheet.GetCell(ARow, ACol); // Don't use AddCell here
|
cell := FWorksheet.GetCell(ARow, ACol); // Don't use AddCell here
|
||||||
|
|
||||||
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
{
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
ApplyStyleToCell(cell, stylename);
|
ApplyStyleToCell(cell, stylename);
|
||||||
|
}
|
||||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||||
|
|
||||||
formula := '';
|
formula := '';
|
||||||
@ -2464,7 +2555,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadLabel(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadLabel(ARow, ACol: Cardinal;
|
||||||
ACellNode: TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
cellText, spanText: String;
|
cellText, spanText: String;
|
||||||
styleName: String;
|
styleName: String;
|
||||||
@ -2497,8 +2588,11 @@ begin
|
|||||||
|
|
||||||
// Apply style to cell
|
// Apply style to cell
|
||||||
// We do this already here because we need the cell font for rich-text
|
// We do this already here because we need the cell font for rich-text
|
||||||
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
{
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
ApplyStyleToCell(cell, stylename);
|
ApplyStyleToCell(cell, stylename);
|
||||||
|
}
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(cell^.FormatIndex);
|
fmt := FWorkbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||||
fntIndex := fmt^.FontIndex;
|
fntIndex := fmt^.FontIndex;
|
||||||
fnt := FWorkbook.GetFont(fntIndex);
|
fnt := FWorkbook.GetFont(fntIndex);
|
||||||
@ -2590,11 +2684,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadNumber(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadNumber(ARow, ACol: Cardinal;
|
||||||
ACellNode : TDOMNode);
|
AStyleIndex: Integer; ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
Value, Str: String;
|
Value, Str: String;
|
||||||
lNumber: Double;
|
lNumber: Double;
|
||||||
styleName: String;
|
// styleName: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
numFmt: TsNumFormatParams;
|
numFmt: TsNumFormatParams;
|
||||||
@ -2613,13 +2707,16 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// Don't merge, or else we can't debug
|
// Don't merge, or else we can't debug
|
||||||
Str := GetAttrValue(ACellNode,'office:value');
|
Str := GetAttrValue(ACellNode, 'office:value');
|
||||||
lNumber := StrToFloat(Str, FPointSeparatorSettings);
|
lNumber := StrToFloat(Str, FPointSeparatorSettings);
|
||||||
FWorkSheet.WriteNumber(cell, lNumber);
|
FWorkSheet.WriteNumber(cell, lNumber);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ApplyStyleToCell(cell, AStyleIndex);
|
||||||
|
{
|
||||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||||
ApplyStyleToCell(cell, stylename);
|
ApplyStyleToCell(cell, stylename);
|
||||||
|
}
|
||||||
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
fmt := Workbook.GetPointerToCellFormat(cell^.FormatIndex);
|
||||||
numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
numFmt := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||||
|
|
||||||
@ -3233,6 +3330,82 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocReader.ReadCell(ANode: TDOMNode; ARow, ACol: Integer;
|
||||||
|
AFormatIndex: Integer; out AColsRepeated: Integer);
|
||||||
|
var
|
||||||
|
paramValueType, paramFormula: String;
|
||||||
|
s: String;
|
||||||
|
colsSpanned, rowsSpanned: Integer;
|
||||||
|
begin
|
||||||
|
// select this cell value's type
|
||||||
|
paramValueType := GetAttrValue(ANode, 'office:value-type');
|
||||||
|
paramFormula := GetAttrValue(ANode, 'table:formula');
|
||||||
|
|
||||||
|
if paramFormula <> '' then
|
||||||
|
ReadFormula(ARow, ACol, AFormatIndex, ANode)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if paramValueType = 'string' then
|
||||||
|
ReadLabel(ARow, ACol, AFormatIndex, ANode)
|
||||||
|
else
|
||||||
|
if (paramValueType = 'float') or
|
||||||
|
(paramValueType = 'percentage') or
|
||||||
|
(paramValueType = 'currency')
|
||||||
|
then
|
||||||
|
ReadNumber(ARow, ACol, AFormatIndex, ANode)
|
||||||
|
else if (paramValueType = 'date') or (paramValueType = 'time') then
|
||||||
|
ReadDateTime(ARow, ACol, AFormatIndex, ANode)
|
||||||
|
else if (paramValueType = 'boolean') then
|
||||||
|
ReadBoolean(ARow, ACol, AFormatIndex, ANode)
|
||||||
|
else
|
||||||
|
if (paramValueType = '') and (AFormatIndex > 0) and
|
||||||
|
(ARow < FLimitations.MaxRowCount-10) and
|
||||||
|
(ACol < FLimitations.MaxColCount-10)
|
||||||
|
then
|
||||||
|
ReadBlank(ARow, ACol, AFormatIndex, ANode);
|
||||||
|
{ NOTE 1: Empty cells having no cell format, but a column format only,
|
||||||
|
are skipped here. --> Currently the reader does not detect the format
|
||||||
|
of empty cells correctly.
|
||||||
|
It would work if the "(cellStyleName <> '')" would be omitted, but // <--- wp: still up-to-date?
|
||||||
|
then the reader would create a record for all 1E9 cells prepared by
|
||||||
|
the Excel2007 export --> crash!
|
||||||
|
The column format is available in the FColumnList, but since the usage
|
||||||
|
of colsSpanned in the row it is possible to miss the correct column format.
|
||||||
|
Pretty nasty situation!
|
||||||
|
|
||||||
|
NOTE 2: Sometimes, ods files have an additional empty cell at the end
|
||||||
|
of the spreadsheet range. Adding a cell to the worksheet here would
|
||||||
|
extend the sheet range unrealistically, and, if using the WorksheetGrid,
|
||||||
|
would add unnecessary rows/columns to the grid. --> Check against
|
||||||
|
FLimitations.MaxRowCount/MaxColCount; use some spare values because I
|
||||||
|
don't understand this mechanism of ods at all }
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Read cell comment
|
||||||
|
ReadComment(ARow, ACol, ANode);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'table:number-columns-spanned');
|
||||||
|
if s <> '' then
|
||||||
|
colsSpanned := StrToInt(s) - 1
|
||||||
|
else
|
||||||
|
colsSpanned := 0;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'table:number-rows-spanned');
|
||||||
|
if s <> '' then
|
||||||
|
rowsSpanned := StrToInt(s) - 1
|
||||||
|
else
|
||||||
|
rowsSpanned := 0;
|
||||||
|
|
||||||
|
if (colsSpanned <> 0) or (rowsSpanned <> 0) then
|
||||||
|
FWorksheet.MergeCells(ARow, ACol, ARow + rowsSpanned, ACol + colsSpanned);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'table:number-columns-repeated');
|
||||||
|
if s <> '' then
|
||||||
|
AColsRepeated := StrToInt(s)
|
||||||
|
else
|
||||||
|
AColsRepeated := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
{ Reads the cells in the given table. Loops through all rows, and then finds all
|
{ Reads the cells in the given table. Loops through all rows, and then finds all
|
||||||
cells of each row. }
|
cells of each row. }
|
||||||
procedure TsSpreadOpenDocReader.ReadRowsAndCells(ATableNode: TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadRowsAndCells(ATableNode: TDOMNode);
|
||||||
@ -3241,8 +3414,10 @@ var
|
|||||||
rowNode, childnode: TDOMNode;
|
rowNode, childnode: TDOMNode;
|
||||||
nodeName: String;
|
nodeName: String;
|
||||||
rowsRepeated: Integer;
|
rowsRepeated: Integer;
|
||||||
|
colFmt: array of Integer;
|
||||||
|
isFirstRow: Boolean;
|
||||||
|
|
||||||
procedure ProcessRow(ARowNode: TDOMNode);
|
procedure ProcessRow(ARowNode: TDOMNode; GetRowFormat: Boolean);
|
||||||
var
|
var
|
||||||
rowStyleName: String;
|
rowStyleName: String;
|
||||||
rowStyleIndex: Integer;
|
rowStyleIndex: Integer;
|
||||||
@ -3252,13 +3427,16 @@ var
|
|||||||
col: Integer;
|
col: Integer;
|
||||||
cellNode: TDOMNode;
|
cellNode: TDOMNode;
|
||||||
nodeName: String;
|
nodeName: String;
|
||||||
|
lRow: PRow;
|
||||||
|
cellRecord: TCell;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
paramValueType, paramFormula, tableStyleName: String;
|
cellStyleName: String;
|
||||||
paramColsSpanned, paramRowsSpanned: String;
|
s: String;
|
||||||
paramColsRepeated, paramRowsRepeated: String;
|
colsRepeated: Integer;
|
||||||
rowsSpanned: Integer;
|
i: Integer;
|
||||||
colsSpanned: Integer;
|
hasRowFormat: Boolean;
|
||||||
i, n: Integer;
|
styleIndex: Integer;
|
||||||
|
firstStyleIndex: Integer;
|
||||||
begin
|
begin
|
||||||
// Read rowstyle
|
// Read rowstyle
|
||||||
rowStyleName := GetAttrValue(ARowNode, 'table:style-name');
|
rowStyleName := GetAttrValue(ARowNode, 'table:style-name');
|
||||||
@ -3269,11 +3447,13 @@ var
|
|||||||
rowHeight := rowStyle.RowHeight; // in Workbook units (see ReadRowStyles)
|
rowHeight := rowStyle.RowHeight; // in Workbook units (see ReadRowStyles)
|
||||||
rowHeightType := rowStyle.RowHeightType;
|
rowHeightType := rowStyle.RowHeightType;
|
||||||
end else begin
|
end else begin
|
||||||
rowHeight := FWorksheet.DefaultRowHeight;
|
rowHeight := FWorksheet.ReadDefaultRowHeight(FWorkbook.Units);
|
||||||
rowHeightTYpe := rhtDefault;
|
rowHeightTYpe := rhtDefault;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
col := 0;
|
col := 0;
|
||||||
|
firstStyleIndex := -1;
|
||||||
|
hasRowFormat := true;
|
||||||
|
|
||||||
//process each cell of the row
|
//process each cell of the row
|
||||||
cellNode := ARowNode.FirstChild;
|
cellNode := ARowNode.FirstChild;
|
||||||
@ -3283,61 +3463,38 @@ var
|
|||||||
nodeName := cellNode.NodeName;
|
nodeName := cellNode.NodeName;
|
||||||
if nodeName = 'table:table-cell' then
|
if nodeName = 'table:table-cell' then
|
||||||
begin
|
begin
|
||||||
// select this cell value's type
|
cellStyleName := GetAttrValue(CellNode, 'table:style-name');
|
||||||
paramValueType := GetAttrValue(CellNode, 'office:value-type');
|
styleIndex := ExtractFormatIndexFromStyle(cellStyleName, col);
|
||||||
paramFormula := GetAttrValue(CellNode, 'table:formula');
|
ReadCell(cellNode, row, col, styleIndex, colsRepeated);
|
||||||
tableStyleName := GetAttrValue(CellNode, 'table:style-name');
|
|
||||||
|
|
||||||
if paramFormula <> '' then
|
// Check whether the current cell format is still the same as for the
|
||||||
ReadFormula(row, col, cellNode)
|
// first cell. If it is then we might have a row format here.
|
||||||
else
|
if (firstStyleIndex = -1) and hasRowFormat then
|
||||||
|
firstStyleIndex := styleIndex
|
||||||
|
else if (styleIndex <> firstStyleIndex) and (cellStyleName <> 'Default') then
|
||||||
|
hasRowFormat := false;
|
||||||
|
|
||||||
|
// If all cell styles in the row are the same then hasRowFormat is true
|
||||||
|
// and we can store the format of the first cell in the row record.
|
||||||
|
if GetRowFormat and hasRowFormat and
|
||||||
|
(col + colsRepeated >= LongInt(FLimitations.MaxColCount) - 10) then
|
||||||
begin
|
begin
|
||||||
if paramValueType = 'string' then
|
lRow := FWorksheet.GetRow(row);
|
||||||
ReadLabel(row, col, cellNode)
|
// Find first cell in row, all cells have the same format here.
|
||||||
|
cell := FWorksheet.FindNextCellInRow(row, 0);
|
||||||
|
if cell <> nil then
|
||||||
|
// Cell found --> copy its format index to cell record
|
||||||
|
lRow^.FormatIndex := cell^.FormatIndex
|
||||||
else
|
else
|
||||||
if (paramValueType = 'float') or (paramValueType = 'percentage') or
|
begin
|
||||||
(paramValueType = 'currency')
|
// No cell in row --> appy format to dummy cell to get its format index
|
||||||
then
|
InitCell(row, 0, cellRecord);
|
||||||
ReadNumber(row, col, cellNode)
|
ApplyStyleToCell(@cellRecord, styleIndex);
|
||||||
else if (paramValueType = 'date') or (paramValueType = 'time') then
|
lRow^.FormatIndex := cellRecord.FormatIndex;
|
||||||
ReadDateTime(row, col, cellNode)
|
end;
|
||||||
else if (paramValueType = 'boolean') then
|
|
||||||
ReadBoolean(row, col, cellNode)
|
|
||||||
else if (paramValueType = '') and (tableStyleName <> '') then
|
|
||||||
ReadBlank(row, col, cellNode);
|
|
||||||
{ NOTE: Empty cells having no cell format, but a column format only,
|
|
||||||
are skipped here. --> Currently the reader does not detect the format
|
|
||||||
of empty cells correctly.
|
|
||||||
It would work if the "(tableStyleName <> '')" would be omitted, but
|
|
||||||
then the reader would create a record for all 1E9 cells prepared by
|
|
||||||
the Excel2007 export --> crash!
|
|
||||||
The column format is available in the FColumnList, but since the usage
|
|
||||||
of colsSpanned in the row it is possible to miss the correct column format.
|
|
||||||
Pretty nasty situation! }
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Read cell comment
|
if (colsRepeated > 1) and (col + colsRepeated < LongInt(FLimitations.MaxColCount) - 10) then
|
||||||
ReadComment(row, col, cellNode);
|
|
||||||
|
|
||||||
paramColsSpanned := GetAttrValue(cellNode, 'table:number-columns-spanned');
|
|
||||||
if paramColsSpanned <> '' then
|
|
||||||
colsSpanned := StrToInt(paramColsSpanned) - 1
|
|
||||||
else
|
|
||||||
colsSpanned := 0;
|
|
||||||
|
|
||||||
paramRowsSpanned := GetAttrValue(cellNode, 'table:number-rows-spanned');
|
|
||||||
if paramRowsSpanned <> '' then
|
|
||||||
rowsSpanned := StrToInt(paramRowsSpanned) - 1
|
|
||||||
else
|
|
||||||
rowsSpanned := 0;
|
|
||||||
|
|
||||||
if (colsSpanned <> 0) or (rowsSpanned <> 0) then
|
|
||||||
FWorksheet.MergeCells(row, col, row+rowsSpanned, col+colsSpanned);
|
|
||||||
|
|
||||||
paramColsRepeated := GetAttrValue(cellNode, 'table:number-columns-repeated');
|
|
||||||
if paramColsRepeated = '' then paramColsRepeated := '1';
|
|
||||||
n := StrToInt(paramColsRepeated);
|
|
||||||
if (n > 1) and (col + n < LongInt(FLimitations.MaxColCount) - 10) then
|
|
||||||
begin
|
begin
|
||||||
// The 2nd condition belongs to a workaround for a bug of LO/OO whichs
|
// The 2nd condition belongs to a workaround for a bug of LO/OO whichs
|
||||||
// extends imported xlsx files with blank cols up to their
|
// extends imported xlsx files with blank cols up to their
|
||||||
@ -3346,27 +3503,27 @@ var
|
|||||||
// sometimes split into two parts.
|
// sometimes split into two parts.
|
||||||
cell := FWorksheet.FindCell(row, col);
|
cell := FWorksheet.FindCell(row, col);
|
||||||
if cell <> nil then
|
if cell <> nil then
|
||||||
for i:=1 to n-1 do
|
for i:=1 to colsRepeated-1 do
|
||||||
FWorksheet.CopyCell(row, col, row, col+i);
|
FWorksheet.CopyCell(row, col, row, col+i);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if nodeName = 'table:covered-table-cell' then
|
if nodeName = 'table:covered-table-cell' then
|
||||||
begin
|
begin
|
||||||
paramColsRepeated := GetAttrValue(cellNode, 'table:number-columns-repeated');
|
s := GetAttrValue(cellNode, 'table:number-columns-repeated');
|
||||||
if paramColsRepeated = '' then paramColsRepeated := '1';
|
if s = '' then colsRepeated := 1;
|
||||||
end else
|
end else
|
||||||
paramColsRepeated := '0';
|
colsRepeated := 0;
|
||||||
|
|
||||||
col := col + StrToInt(paramColsRepeated);
|
col := col + colsRepeated;
|
||||||
cellNode := cellNode.NextSibling;
|
cellNode := cellNode.NextSibling;
|
||||||
end; //while Assigned(cellNode)
|
end; //while Assigned(cellNode)
|
||||||
|
|
||||||
paramRowsRepeated := GetAttrValue(RowNode, 'table:number-rows-repeated');
|
s := GetAttrValue(RowNode, 'table:number-rows-repeated');
|
||||||
if paramRowsRepeated = '' then
|
if s = '' then
|
||||||
rowsRepeated := 1
|
rowsRepeated := 1
|
||||||
else
|
else
|
||||||
rowsRepeated := StrToInt(paramRowsRepeated);
|
rowsRepeated := StrToInt(s);
|
||||||
|
|
||||||
// Transfer non-default row heights to sheet's rows
|
// Transfer non-default row heights to sheet's rows
|
||||||
// This first "if" is a workaround for a bug of LO/OO whichs extends imported
|
// This first "if" is a workaround for a bug of LO/OO whichs extends imported
|
||||||
@ -3377,12 +3534,47 @@ var
|
|||||||
for i:=1 to rowsRepeated do
|
for i:=1 to rowsRepeated do
|
||||||
FWorksheet.WriteRowHeight(row + i - 1, rowHeight, FWorkbook.Units, rowHeightType);
|
FWorksheet.WriteRowHeight(row + i - 1, rowHeight, FWorkbook.Units, rowHeightType);
|
||||||
|
|
||||||
|
// Prepare checking of column format
|
||||||
|
if GetRowFormat then begin
|
||||||
|
// Store the format indexes of all cells in the first row
|
||||||
|
if isFirstRow then begin
|
||||||
|
SetLength(colFmt, col);
|
||||||
|
for col:=0 to High(colFmt) do begin
|
||||||
|
cell := FWorksheet.FindCell(row, col);
|
||||||
|
if cell <> nil then
|
||||||
|
colFmt[col] := cell^.FormatIndex
|
||||||
|
else begin
|
||||||
|
InitCell(row, col, cellRecord);
|
||||||
|
ApplyStyleToCell(@cellRecord, styleIndex);
|
||||||
|
colFmt[col] := cellRecord.FormatIndex;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
// In the other rows compare the cell format indexes with those stored
|
||||||
|
// from the first row. If an index does not match then this col cannot
|
||||||
|
// have a column format.
|
||||||
|
for col:=0 to High(colFmt) do begin
|
||||||
|
if colFmt[col] > -1 then begin
|
||||||
|
cell := FWorksheet.FindCell(row, col);
|
||||||
|
if ((cell <> nil) and (cell^.FormatIndex <> colFmt[col])) then
|
||||||
|
colFmt[col] := -1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
row := row + rowsRepeated;
|
row := row + rowsRepeated;
|
||||||
|
isFirstRow := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
PrintRowMode: Boolean;
|
||||||
|
c: Cardinal;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
rowsRepeated := 0;
|
rowsRepeated := 0;
|
||||||
row := 0;
|
row := 0;
|
||||||
|
isFirstRow := true;
|
||||||
|
PrintRowMode := false;
|
||||||
|
|
||||||
rownode := ATableNode.FirstChild;
|
rownode := ATableNode.FirstChild;
|
||||||
while Assigned(rowNode) do
|
while Assigned(rowNode) do
|
||||||
@ -3392,6 +3584,7 @@ begin
|
|||||||
// Repeated print rows
|
// Repeated print rows
|
||||||
if nodeName = 'table:table-header-rows' then
|
if nodeName = 'table:table-header-rows' then
|
||||||
begin
|
begin
|
||||||
|
PrintRowMode := true;
|
||||||
if FRepeatedRows.FirstIndex = Cardinal(UNASSIGNED_ROW_COL_INDEX) then
|
if FRepeatedRows.FirstIndex = Cardinal(UNASSIGNED_ROW_COL_INDEX) then
|
||||||
FRepeatedRows.FirstIndex := row;
|
FRepeatedRows.FirstIndex := row;
|
||||||
childnode := rowNode.FirstChild;
|
childnode := rowNode.FirstChild;
|
||||||
@ -3400,19 +3593,26 @@ begin
|
|||||||
nodename := childnode.NodeName;
|
nodename := childnode.NodeName;
|
||||||
if nodename = 'table:table-row' then
|
if nodename = 'table:table-row' then
|
||||||
begin
|
begin
|
||||||
ProcessRow(childnode);
|
ProcessRow(childnode, false);
|
||||||
end;
|
end;
|
||||||
childnode := childnode.NextSibling;
|
childnode := childnode.NextSibling;
|
||||||
end;
|
end;
|
||||||
FRepeatedRows.LastIndex := row-1;
|
FRepeatedRows.LastIndex := row-1;
|
||||||
end else
|
end
|
||||||
|
else
|
||||||
// "normal" rows
|
// "normal" rows
|
||||||
if nodeName = 'table:table-row' then
|
if nodeName = 'table:table-row' then
|
||||||
begin
|
ProcessRow(rowNode, true);
|
||||||
ProcessRow(rowNode);
|
|
||||||
end;
|
|
||||||
rowNode := rowNode.NextSibling;
|
rowNode := rowNode.NextSibling;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Construct column records with column format
|
||||||
|
if not PrintRowMode and (row > FLimitations.MaxRowCount-10) then begin
|
||||||
|
for c := 0 to High(colFmt) do
|
||||||
|
if colFmt[c] > 0 then
|
||||||
|
FWorksheet.WriteColFormatIndex(c, colFmt[c]);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadRowStyle(AStyleNode: TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadRowStyle(AStyleNode: TDOMNode);
|
||||||
@ -3466,6 +3666,8 @@ begin
|
|||||||
showGrid := true;
|
showGrid := true;
|
||||||
showHeaders := true;
|
showHeaders := true;
|
||||||
zoom := 100.0;
|
zoom := 100.0;
|
||||||
|
actRow := 0;
|
||||||
|
actCol := 0;
|
||||||
cfgItemSetNode := AOfficeSettingsNode.FirstChild;
|
cfgItemSetNode := AOfficeSettingsNode.FirstChild;
|
||||||
while Assigned(cfgItemSetNode) do
|
while Assigned(cfgItemSetNode) do
|
||||||
begin
|
begin
|
||||||
@ -3547,11 +3749,11 @@ begin
|
|||||||
sheet.TopPaneHeight := vsp;
|
sheet.TopPaneHeight := vsp;
|
||||||
end else
|
end else
|
||||||
sheet.Options := sheet.Options - [soHasFrozenPanes];
|
sheet.Options := sheet.Options - [soHasFrozenPanes];
|
||||||
|
// Active cell
|
||||||
|
sheet.SelectCell(actRow, actCol);
|
||||||
|
// Zoom factor
|
||||||
|
sheet.ZoomFactor := zoom / 100.0;
|
||||||
end;
|
end;
|
||||||
// Active cell
|
|
||||||
sheet.SelectCell(actRow, actCol);
|
|
||||||
// Zoom factor
|
|
||||||
sheet.ZoomFactor := zoom / 100.0;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
cfgTableItemNode := cfgTableItemNode.NextSibling;
|
cfgTableItemNode := cfgTableItemNode.NextSibling;
|
||||||
|
@ -3291,7 +3291,7 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsCustomWorksheetGrid.GetDefaultHeaderColWidth: Integer;
|
function TsCustomWorksheetGrid.GetDefaultHeaderColWidth: Integer;
|
||||||
begin
|
begin
|
||||||
Result := Canvas.TextWidth(' 999999 ');
|
Result := Canvas.TextWidth(' 9999999 ');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user