fpspreadsheet: Add redundant information on selected worksheet to xls files (like Excel does). Add code to read/write selected cell in xls, xlsx and ods.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4243 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
31090f663a
commit
71fa9ae693
@ -2961,6 +2961,7 @@ var
|
||||
sheet: TsWorksheet;
|
||||
vsm, hsm, hsp, vsp: Integer;
|
||||
showGrid, showHeaders: Boolean;
|
||||
actCol, actRow: Cardinal;
|
||||
i: Integer;
|
||||
begin
|
||||
showGrid := true;
|
||||
@ -3027,14 +3028,14 @@ begin
|
||||
begin
|
||||
cfgName := GetAttrValue(node, 'config:name');
|
||||
cfgValue := GetNodeValue(node);
|
||||
if cfgName = 'VerticalSplitMode' then
|
||||
vsm := StrToInt(cfgValue)
|
||||
else if cfgName = 'HorizontalSplitMode' then
|
||||
hsm := StrToInt(cfgValue)
|
||||
else if cfgName = 'VerticalSplitPosition' then
|
||||
vsp := StrToInt(cfgValue)
|
||||
else if cfgName = 'HorizontalSplitPosition' then
|
||||
hsp := StrToInt(cfgValue);
|
||||
case cfgName of
|
||||
'CursorPositionX': actCol := StrToInt(cfgValue);
|
||||
'CursorPositionY': actRow := StrToInt(cfgValue);
|
||||
'VerticalSplitMode': vsm := StrToInt(cfgValue);
|
||||
'HorizontalSplitMode': hsm := StrToInt(cfgValue);
|
||||
'VerticalSplitPosition': vsp := StrToInt(cfgValue);
|
||||
'HorizontalSplitPosition': hsp := StrToInt(cfgValue);
|
||||
end;
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
@ -3046,6 +3047,8 @@ begin
|
||||
end else
|
||||
sheet.Options := sheet.Options - [soHasFrozenPanes];
|
||||
end;
|
||||
// Active cell
|
||||
sheet.SelectCell(actRow, actCol);
|
||||
end;
|
||||
end;
|
||||
cfgTableItemNode := cfgTableItemNode.NextSibling;
|
||||
@ -5023,9 +5026,10 @@ procedure TsSpreadOpenDocWriter.WriteTableSettings(AStream: TStream);
|
||||
var
|
||||
i: Integer;
|
||||
sheet: TsWorkSheet;
|
||||
hsm: Integer; // HorizontalSplitMode
|
||||
vsm: Integer; // VerticalSplitMode
|
||||
asr: Integer; // ActiveSplitRange
|
||||
hsm: Integer; // HorizontalSplitMode
|
||||
vsm: Integer; // VerticalSplitMode
|
||||
asr: Integer; // ActiveSplitRange
|
||||
actX, actY: Integer; // Active cell col/row index
|
||||
begin
|
||||
for i:=0 to Workbook.GetWorksheetCount-1 do
|
||||
begin
|
||||
@ -5051,10 +5055,20 @@ begin
|
||||
end;
|
||||
{showGrid := (soShowGridLines in sheet.Options);}
|
||||
|
||||
if (sheet.ActiveCellRow <> cardinal(-1)) and (sheet.ActiveCellCol <> cardinal(-1)) then
|
||||
begin
|
||||
actX := sheet.ActiveCellCol;
|
||||
actY := sheet.ActiveCellRow;
|
||||
end else
|
||||
begin
|
||||
actX := sheet.LeftPaneWidth;
|
||||
actY := sheet.TopPaneHeight;
|
||||
end;
|
||||
|
||||
AppendToStream(AStream,
|
||||
'<config:config-item config:name="CursorPositionX" config:type="int">'+IntToStr(sheet.LeftPaneWidth)+'</config:config-item>');
|
||||
'<config:config-item config:name="CursorPositionX" config:type="int">'+IntToStr(actX)+'</config:config-item>');
|
||||
AppendToStream(AStream,
|
||||
'<config:config-item config:name="CursorPositionY" config:type="int">'+IntToStr(sheet.TopPaneHeight)+'</config:config-item>');
|
||||
'<config:config-item config:name="CursorPositionY" config:type="int">'+IntToStr(actY)+'</config:config-item>');
|
||||
AppendToStream(AStream,
|
||||
'<config:config-item config:name="HorizontalSplitMode" config:type="short">'+IntToStr(hsm)+'</config:config-item>');
|
||||
AppendToStream(AStream,
|
||||
|
@ -504,6 +504,7 @@ begin
|
||||
INT_EXCEL_ID_PRINTHEADERS: ReadPrintHeaders(AStream);
|
||||
INT_EXCEL_ID_RIGHTMARGIN : ReadMargin(AStream, 1);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_TOPMARGIN : ReadMargin(AStream, 2);
|
||||
INT_EXCEL_ID_DEFROWHEIGHT: ReadDefRowHeight(AStream);
|
||||
|
@ -431,6 +431,7 @@ begin
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_SHEETPR : ReadSHEETPR(AStream);
|
||||
INT_EXCEL_ID_STANDARDWIDTH : ReadStandardWidth(AStream, FWorksheet);
|
||||
|
@ -819,6 +819,7 @@ begin
|
||||
// This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream);
|
||||
|
||||
INT_EXCEL_ID_SELECTION : ReadSELECTION(AStream);
|
||||
INT_EXCEL_ID_SHAREDFMLA : ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_SHEETPR : ReadSHEETPR(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
|
@ -431,6 +431,7 @@ type
|
||||
function ReadRPNTokenArray(AStream: TStream; ACell: PCell;
|
||||
ASharedFormulaBase: PCell = nil): Boolean;
|
||||
function ReadRPNTokenArraySize(AStream: TStream): word; virtual;
|
||||
procedure ReadSELECTION(AStream: TStream);
|
||||
procedure ReadSharedFormula(AStream: TStream);
|
||||
procedure ReadSHEETPR(AStream: TStream);
|
||||
|
||||
@ -543,7 +544,7 @@ type
|
||||
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); virtual;
|
||||
|
||||
// Writes out a SELECTION record
|
||||
procedure WriteSelection(AStream: TStream; ASheet: TsWorksheet; APane: Byte);
|
||||
procedure WriteSELECTION(AStream: TStream; ASheet: TsWorksheet; APane: Byte);
|
||||
procedure WriteSelections(AStream: TStream; ASheet: TsWorksheet);
|
||||
(*
|
||||
// Writes out a shared formula
|
||||
@ -2163,6 +2164,35 @@ begin
|
||||
Result := WordLEToN(AStream.ReadWord);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads a SELECTION record containing the currently selected cell
|
||||
Valid for BIFF2-BIFF8.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFReader.ReadSELECTION(AStream: TStream);
|
||||
var
|
||||
actPane: byte;
|
||||
actRow, actCol: Word;
|
||||
rngIndex: Word;
|
||||
i, numRanges: Word;
|
||||
begin
|
||||
// Active pane
|
||||
actPane := AStream.ReadByte;
|
||||
|
||||
// Row index of the active cell
|
||||
actRow := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Column index of the active cell
|
||||
actCol := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Index into the following range list which contains the active cell
|
||||
rngIndex := WordLEToN(AStream.ReadWord);
|
||||
|
||||
// Count of selected ranges
|
||||
// Selected ranges --> ignore
|
||||
|
||||
FWorksheet.SelectCell(actRow, actCol);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads a SHAREDFMLA record, i.e. reads cell range coordinates and a rpn
|
||||
formula. The formula is applied to all cells in the range. The formula is
|
||||
@ -3695,29 +3725,34 @@ end;
|
||||
APane is 0..3 (see below)
|
||||
Valid for BIFF2-BIFF8
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteSelection(AStream: TStream;
|
||||
procedure TsSpreadBIFFWriter.WriteSELECTION(AStream: TStream;
|
||||
ASheet: TsWorksheet; APane: Byte);
|
||||
var
|
||||
activeCellRow, activeCellCol: Word;
|
||||
begin
|
||||
case APane of
|
||||
0: begin // right-bottom
|
||||
activeCellRow := ASheet.TopPaneHeight;
|
||||
activeCellCol := ASheet.LeftPaneWidth;
|
||||
end;
|
||||
1: begin // right-top
|
||||
activeCellRow := 0;
|
||||
activeCellCol := ASheet.LeftPaneWidth;
|
||||
end;
|
||||
2: begin // left-bottom
|
||||
activeCellRow := ASheet.TopPaneHeight;
|
||||
activeCellCol := 0;
|
||||
end;
|
||||
3: begin // left-top
|
||||
activeCellRow := 0;
|
||||
activeCellCol := 0;
|
||||
end;
|
||||
end;
|
||||
if FWorkbook.ActiveWorksheet <> nil then
|
||||
begin
|
||||
activeCellRow := FWorksheet.ActiveCellRow;
|
||||
activeCellCol := FWorksheet.ActiveCellCol;
|
||||
end else
|
||||
case APane of
|
||||
0: begin // right-bottom
|
||||
activeCellRow := ASheet.TopPaneHeight;
|
||||
activeCellCol := ASheet.LeftPaneWidth;
|
||||
end;
|
||||
1: begin // right-top
|
||||
activeCellRow := 0;
|
||||
activeCellCol := ASheet.LeftPaneWidth;
|
||||
end;
|
||||
2: begin // left-bottom
|
||||
activeCellRow := ASheet.TopPaneHeight;
|
||||
activeCellCol := 0;
|
||||
end;
|
||||
3: begin // left-top
|
||||
activeCellRow := 0;
|
||||
activeCellCol := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ BIFF record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_SELECTION, 15);
|
||||
@ -3963,6 +3998,8 @@ end;
|
||||
Valid for BIFF5-BIFF8.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteWindow1(AStream: TStream);
|
||||
var
|
||||
actSheet: Integer;
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
WriteBIFFHeader(AStream, INT_EXCEL_ID_WINDOW1, 18);
|
||||
@ -3986,7 +4023,10 @@ begin
|
||||
MASK_WINDOW1_OPTION_WORKSHEET_TAB_VISIBLE));
|
||||
|
||||
{ Index to active (displayed) worksheet }
|
||||
AStream.WriteWord(WordToLE($00));
|
||||
if FWorkbook.ActiveWorksheet = nil then
|
||||
actSheet := 0 else
|
||||
actSheet := FWorkbook.GetWorksheetIndex(FWorkbook.ActiveWorksheet);
|
||||
AStream.WriteWord(WordToLE(actSheet));
|
||||
|
||||
{ Index of first visible tab in the worksheet tab bar }
|
||||
AStream.WriteWord(WordToLE($00));
|
||||
|
@ -1751,6 +1751,7 @@ var
|
||||
childNode: TDOMNode;
|
||||
nodeName: String;
|
||||
s: String;
|
||||
actRow, actCol: Cardinal;
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit;
|
||||
@ -1778,6 +1779,14 @@ begin
|
||||
s := GetAttrValue(childNode, 'ySplit');
|
||||
if s <> '' then AWorksheet.TopPaneHeight := StrToInt(s);
|
||||
end;
|
||||
end else
|
||||
if nodeName = 'selection' then begin
|
||||
s := GetAttrValue(childnode, 'activeCell');
|
||||
if s <> '' then
|
||||
begin
|
||||
ParseCellString(s, actRow, actCol);
|
||||
AWorksheet.SelectCell(actRow, actCol);
|
||||
end;
|
||||
end;
|
||||
childNode := childNode.NextSibling;
|
||||
end;
|
||||
@ -3025,6 +3034,8 @@ var
|
||||
topRightCell: String;
|
||||
bottomLeftCell: String;
|
||||
bottomRightCell: String;
|
||||
actCell: String;
|
||||
tabSel: String;
|
||||
begin
|
||||
// Show gridlines ?
|
||||
showGridLines := StrUtils.IfThen(soShowGridLines in AWorksheet.Options, ' ', 'showGridLines="0" ');
|
||||
@ -3032,63 +3043,86 @@ begin
|
||||
// Show headers?
|
||||
showHeaders := StrUtils.IfThen(soShowHeaders in AWorksheet.Options, ' ', 'showRowColHeaders="0" ');
|
||||
|
||||
// Active cell
|
||||
if (AWorksheet.ActiveCellRow <> cardinal(-1)) and (AWorksheet.ActiveCellCol <> cardinal(-1)) then
|
||||
actCell := GetCellString(AWorksheet.ActiveCellRow, AWorksheet.ActiveCellCol) else
|
||||
actCell := '';
|
||||
|
||||
// Selected tab?
|
||||
tabSel := StrUtils.IfThen(AWorksheet = FWorkbook.ActiveWorksheet, 'tabSelected="1" ', '');
|
||||
|
||||
// No frozen panes
|
||||
if not (soHasFrozenPanes in AWorksheet.Options) or
|
||||
((AWorksheet.LeftPaneWidth = 0) and (AWorksheet.TopPaneHeight = 0))
|
||||
then
|
||||
begin
|
||||
if actCell = '' then actCell := 'A1';
|
||||
AppendToStream(AStream, Format(
|
||||
'<sheetViews>' +
|
||||
'<sheetView workbookViewId="0" %s%s/>' +
|
||||
'<sheetView workbookViewId="0" %s%s%s>' +
|
||||
'<selection activeCell="%s" sqref="%s" />' +
|
||||
'</sheetView>' +
|
||||
'</sheetViews>', [
|
||||
showGridLines, showHeaders
|
||||
showGridLines, showHeaders, tabSel,
|
||||
actCell, actCell
|
||||
]))
|
||||
else
|
||||
end else
|
||||
begin // Frozen panes
|
||||
topRightCell := GetCellString(0, AWorksheet.LeftPaneWidth, [rfRelRow, rfRelCol]);
|
||||
bottomLeftCell := GetCellString(AWorksheet.TopPaneHeight, 0, [rfRelRow, rfRelCol]);
|
||||
bottomRightCell := GetCellString(AWorksheet.TopPaneHeight, AWorksheet.LeftPaneWidth, [rfRelRow, rfRelCol]);
|
||||
if (AWorksheet.LeftPaneWidth > 0) and (AWorksheet.TopPaneHeight > 0) then
|
||||
begin
|
||||
if actCell = '' then
|
||||
actCell := bottomRightcell;
|
||||
AppendToStream(AStream, Format(
|
||||
'<sheetViews>' +
|
||||
'<sheetView workbookViewId="0" %s%s>'+
|
||||
'<sheetView workbookViewId="0" %s%s%s>'+
|
||||
'<pane xSplit="%d" ySplit="%d" topLeftCell="%s" activePane="bottomRight" state="frozen" />' +
|
||||
'<selection pane="topRight" activeCell="%s" sqref="%s" />' +
|
||||
'<selection pane="bottomLeft" activeCell="%s" sqref="%s" />' +
|
||||
'<selection pane="bottomRight" activeCell="%s" sqref="%s" />' +
|
||||
'</sheetView>' +
|
||||
'</sheetViews>', [
|
||||
showGridLines, showHeaders,
|
||||
showGridLines, showHeaders, tabSel,
|
||||
AWorksheet.LeftPaneWidth, AWorksheet.TopPaneHeight, bottomRightCell,
|
||||
topRightCell, topRightCell,
|
||||
bottomLeftCell, bottomLeftCell,
|
||||
bottomRightCell, bottomrightCell
|
||||
actCell, actCell
|
||||
]))
|
||||
else
|
||||
end else
|
||||
if (AWorksheet.LeftPaneWidth > 0) then
|
||||
begin
|
||||
if actCell = '' then
|
||||
actCell := topRightCell;
|
||||
AppendToStream(AStream, Format(
|
||||
'<sheetViews>' +
|
||||
'<sheetView workbookViewId="0" %s%s>'+
|
||||
'<sheetView workbookViewId="0" %s%s%s>'+
|
||||
'<pane xSplit="%d" topLeftCell="%s" activePane="topRight" state="frozen" />' +
|
||||
'<selection pane="topRight" activeCell="%s" sqref="%s" />' +
|
||||
'</sheetView>' +
|
||||
'</sheetViews>', [
|
||||
showGridLines, showHeaders,
|
||||
showGridLines, showHeaders, tabSel,
|
||||
AWorksheet.LeftPaneWidth, topRightCell,
|
||||
topRightCell, topRightCell
|
||||
actCell, actCell
|
||||
]))
|
||||
else
|
||||
end else
|
||||
if (AWorksheet.TopPaneHeight > 0) then
|
||||
begin
|
||||
if actCell = '' then
|
||||
actCell := bottomLeftCell;
|
||||
AppendToStream(AStream, Format(
|
||||
'<sheetViews>'+
|
||||
'<sheetView workbookViewId="0" %s%s>'+
|
||||
'<sheetView workbookViewId="0" %s%s%s>'+
|
||||
'<pane ySplit="%d" topLeftCell="%s" activePane="bottomLeft" state="frozen" />'+
|
||||
'<selection pane="bottomLeft" activeCell="%s" sqref="%s" />' +
|
||||
'</sheetView>'+
|
||||
'</sheetViews>', [
|
||||
showGridLines, showHeaders,
|
||||
showGridLines, showHeaders, tabSel,
|
||||
AWorksheet.TopPaneHeight, bottomLeftCell,
|
||||
bottomLeftCell, bottomLeftCell
|
||||
actCell, actCell
|
||||
]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user