fpspreadsheet: Fix bug 0026386 (in Excel, all sheets must be "active" and "selected"). New chm help file. Fix some issues with spready and fpsgrid due to range check errors. BiffExplorer shows detail info on SHEETPR record.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3236 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-06-24 22:47:15 +00:00
parent 92ed17a049
commit 9eefbdaa06
9 changed files with 266 additions and 53 deletions

View File

@ -15,8 +15,71 @@
<VersionInfo> <VersionInfo>
<StringTable ProductVersion=""/> <StringTable ProductVersion=""/>
</VersionInfo> </VersionInfo>
<BuildModes Count="1"> <BuildModes Count="3">
<Item1 Name="default" Default="True"/> <Item1 Name="default" Default="True"/>
<Item2 Name="Debug">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<OtherUnitFiles Value=".."/>
<SrcPath Value=".."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
</Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item2>
<Item3 Name="Release">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<OtherUnitFiles Value=".."/>
<SrcPath Value=".."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
</Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</Item3>
</BuildModes> </BuildModes>
<PublishOptions> <PublishOptions>
<Version Value="2"/> <Version Value="2"/>
@ -59,5 +122,8 @@
<DebugInfoType Value="dsStabs"/> <DebugInfoType Value="dsStabs"/>
</Debugging> </Debugging>
</Linking> </Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions> </CompilerOptions>
</CONFIG> </CONFIG>

View File

@ -437,9 +437,8 @@ type
@param soShowHeaders Show or hide the column or row headers of the spreadsheet @param soShowHeaders Show or hide the column or row headers of the spreadsheet
@param soHasFrozenPanes If set a number of rows and columns of the spreadsheet @param soHasFrozenPanes If set a number of rows and columns of the spreadsheet
is fixed and does not scroll. The number is defined by is fixed and does not scroll. The number is defined by
LeftPaneWidth and TopPaneHeight. LeftPaneWidth and TopPaneHeight. }
@param soSelected (currently not used) } TsSheetOption = (soShowGridLines, soShowHeaders, soHasFrozenPanes);
TsSheetOption = (soShowGridLines, soShowHeaders, soHasFrozenPanes, soSelected);
{@@ Set of user interface options {@@ Set of user interface options
@ see TsSheetOption } @ see TsSheetOption }
@ -1083,15 +1082,15 @@ type
const const
FEProps: array[TFEKind] of TFEProp = ( FEProps: array[TFEKind] of TFEProp = (
{ Operands } { Operands }
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCell (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCell
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellRef (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellRef
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellRange (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellRange
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellNum (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellNum
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellInteger (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellInteger
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellString (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellString
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellBool (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellBool
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellErr (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellErr
(Symbol:''; MinParams:-1; MaxParams:Byte(-1)), // fekCellMissingArg (Symbol:''; MinParams:Byte(-1); MaxParams:Byte(-1)), // fekCellMissingArg
{ Basic operations } { Basic operations }
(Symbol:'+'; MinParams:2; MaxParams:2), // fekAdd (Symbol:'+'; MinParams:2; MaxParams:2), // fekAdd
(Symbol:'-'; MinParams:2; MaxParams:2), // fekSub (Symbol:'-'; MinParams:2; MaxParams:2), // fekSub
@ -1278,14 +1277,10 @@ procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
var var
i: Integer; i: Integer;
begin begin
{$PUSH}{$R-}
for i := 0 to APaletteSize-1 do for i := 0 to APaletteSize-1 do
{$IFDEF RNGCHECK}
{$R-}
{$ENDIF}
APalette^[i] := LongRGBToExcelPhysical(APalette^[i]) APalette^[i] := LongRGBToExcelPhysical(APalette^[i])
{$IFDEF RNGCHECK} {$POP}
{$R+}
{$ENDIF}
end; end;
{@@ {@@
@ -3754,8 +3749,8 @@ end;
It is added to the end of the list of worksheets It is added to the end of the list of worksheets
@param AName The name of the new worksheet @param AName The name of the new worksheet
@return The instace of the newly created worksheet @return The instance of the newly created worksheet
@see TsWorkbook @see TsWorksheet
} }
function TsWorkbook.AddWorksheet(AName: string): TsWorksheet; function TsWorkbook.AddWorksheet(AName: string): TsWorksheet;
begin begin
@ -3849,7 +3844,29 @@ procedure TsWorkbook.RemoveAllWorksheets;
begin begin
FWorksheets.ForEachCall(RemoveWorksheetsCallback, nil); FWorksheets.ForEachCall(RemoveWorksheetsCallback, nil);
end; end;
(*
{@@
Sets the selected flag for the sheet with the given index.
Excel requires one sheet to be selected, otherwise strange things happen when
the file is loaded into Excel (cannot print, hanging instance of Excel - see
bug 0026386).
@param AIndex Index of the worksheet to be selected
}
procedure TsWorkbook.SelectWorksheet(AIndex: Integer);
var
i: Integer;
sheet: TsWorksheet;
begin
for i:=0 to FWorksheets.Count-1 do begin
sheet := TsWorksheet(FWorksheets.Items[i]);
if i = AIndex then
sheet.Options := sheet.Options + [soSelected]
else
sheet.Options := sheet.Options - [soSelected];
end;
end;
*)
{ Font handling } { Font handling }

View File

@ -28,9 +28,8 @@ type
{ TsCustomWorksheetGrid } { TsCustomWorksheetGrid }
{@@ {@@
TsCustomWorksheetGrid is a grid which displays spreadsheet data along with TsCustomWorksheetGrid is the ancestor of TsWorkseetGrid and is able to
their formatting. Being linked to an instance of TsWorkbook it provides display spreadsheet data along with their formatting.
methods for reading data from or writing to spreadsheet files.
} }
TsCustomWorksheetGrid = class(TCustomDrawGrid) TsCustomWorksheetGrid = class(TCustomDrawGrid)
private private
@ -288,8 +287,8 @@ type
{@@ {@@
TsWorksheetGrid is a grid which displays spreadsheet data along with TsWorksheetGrid is a grid which displays spreadsheet data along with
formatting. As it is linked to an instance of TsWorkbook, it provides formatting. As it is linked to an instance of TsWorkbook, it provides
methods for reading data from or writing to spreadsheet files. In contrast methods for reading data from or writing to spreadsheet files. It has the
to TsCustomWorksheetGrid it has all properties published. same funtionality as TsCustomWorksheetGrid, but publishes has all properties.
} }
TsWorksheetGrid = class(TsCustomWorksheetGrid) TsWorksheetGrid = class(TsCustomWorksheetGrid)
published published
@ -853,7 +852,8 @@ begin
if ShowHeaders and ((ACol = 0) or (ARow = 0)) then if ShowHeaders and ((ACol = 0) or (ARow = 0)) then
Canvas.Brush.Color := FixedColor Canvas.Brush.Color := FixedColor
end; end;
if FWorksheet <> nil then begin if (FWorksheet <> nil) and (ARow >= FHeaderCount) and (ACol >= FHeaderCount)
then begin
r := ARow - FHeaderCount; r := ARow - FHeaderCount;
c := ACol - FHeaderCount; c := ACol - FHeaderCount;
lCell := FWorksheet.FindCell(r, c); lCell := FWorksheet.FindCell(r, c);
@ -1150,12 +1150,15 @@ var
txtLeft, txtRight: String; txtLeft, txtRight: String;
justif: Byte; justif: Byte;
begin begin
if FWorksheet = nil then if (FWorksheet = nil) then
exit; exit;
c := ACol - FHeaderCount; c := ACol - FHeaderCount;
r := ARow - FHeaderCount; r := ARow - FHeaderCount;
lCell := FWorksheet.FindCell(r, c); if (r >= 0) and (c >= 0) then
lCell := FWorksheet.FindCell(r, c)
else
lCell := nil;
// Header // Header
if lCell = nil then begin if lCell = nil then begin
@ -2887,7 +2890,7 @@ end;
If the file format is not known is is written as BIFF8/XLS. If the file format is not known is is written as BIFF8/XLS.
@param AOverwriteExisting If this file already exists it is overwritten if @param AOverwriteExisting If this file already exists it is overwritten if
AOverwriteExisting = true, or an exception is raised AOverwriteExisting = true, or an exception is raised
if AOverwriteExisting = false: if AOverwriteExisting = false.
} }
procedure TsCustomWorksheetGrid.SaveToSpreadsheetFile(AFileName: String; procedure TsCustomWorksheetGrid.SaveToSpreadsheetFile(AFileName: String;
AOverwriteExisting: Boolean = true); AOverwriteExisting: Boolean = true);

View File

@ -86,6 +86,7 @@ type
procedure ShowRow; procedure ShowRow;
procedure ShowSelection; procedure ShowSelection;
procedure ShowSheet; procedure ShowSheet;
procedure ShowSheetPR;
procedure ShowSST; procedure ShowSST;
procedure ShowString; procedure ShowString;
procedure ShowStyle; procedure ShowStyle;
@ -326,6 +327,8 @@ begin
ShowRecalc; ShowRecalc;
$007D: $007D:
ShowColInfo; ShowColInfo;
$0081:
ShowSheetPR;
$0085: $0085:
ShowSheet; ShowSheet;
$0086: $0086:
@ -3233,6 +3236,62 @@ begin
end; end;
procedure TBIFFGrid.ShowSheetPR;
var
numBytes: Integer;
w: Word;
begin
RowCount := FixedRows + 1;
numBytes := 2;
Move(FBuffer[FBufferIndex], w, numBytes);
w := WordLEToN(w);
if Row = FCurrRow then begin
FDetails.Add('Option flags:'#13);
if w and $0001 = 0
then FDetails.Add('Bit $0001 = 0: Do not show automatic page breaks')
else FDetails.Add('Bit $0001 = 1: Show automatic page breaks');
if w and $0010 = 0
then FDetails.Add('Bit $0010 = 0: Standard sheet')
else FDetails.Add('Bit $0010 = 1: Dialog sheet (BIFF5-BIFF8)');
if w and $0020 = 0
then FDetails.Add('Bit $0020 = 0: No automatic styles in outlines')
else FDetails.Add('Bit $0020 = 1: Apply automatic styles to outlines');
if w and $0040 = 0
then FDetails.Add('Bit $0040 = 0: Outline buttons above outline group')
else FDetails.Add('Bit $0040 = 1: Outline buttons below outline group');
if w and $0080 = 0
then FDetails.Add('Bit $0080 = 0: Outline buttons left of outline group')
else FDetails.Add('Bit $0080 = 1: Outline buttons right of outline group');
if w and $0100 = 0
then FDetails.Add('Bit $0100 = 0: Scale printout in percent')
else FDetails.Add('Bit $0100 = 1: Fit printout to number of pages');
if w and $0200 = 0
then FDetails.Add('Bit $0200 = 0: Save external linked values (BIFF3-BIFF4 only)')
else FDetails.Add('Bit $0200 = 1: Do NOT save external linked values (BIFF3-BIFF4 only)');
if w and $0400 = 0
then FDetails.Add('Bit $0400 = 0: Do not show row outline symbols')
else FDetails.Add('Bit $0400 = 1: Show row outline symbols');
if w and $0800 = 0
then FDetails.Add('Bit $0800 = 0: Do not show column outline symbols')
else FDetails.Add('Bit $0800 = 1: Show column outline symbols');
case (w and $3000) shr 12 of
0: FDetails.Add('Bits $3000 = $0000: Arrange windows tiled');
1: FDetails.Add('Bits $3000 = $1000: Arrange windows horizontal');
2: FDetails.Add('Bits $3000 = $2000: Arrange windows vertical');
3: FDetails.Add('Bits $3000 = $3000: Arrange windows cascaded');
end;
if w and $4000 = 0
then FDetails.Add('Bits $4000 = 0: Excel like expression evaluation (BIFF4-BIFF8 only)')
else FDetails.Add('Bits $4000 = 1: Lotus like expression evaluation (BIFF4-BIFF8 only)');
if w and $8000 = 0
then FDetails.Add('Bits $8000 = 0: Excel like formula editing (BIFF4-BIFF8 only)')
else FDetails.Add('Bits $8000 = 1: Lotus like formula editing (BIFF4-BIFF8 only)');
end;
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x (%d)', [w, w]),
'Option flags');
end;
procedure TBIFFGrid.ShowSST; procedure TBIFFGrid.ShowSST;
var var
numBytes: Integer; numBytes: Integer;

View File

@ -961,6 +961,7 @@ end;
procedure TsSpreadBIFF2Writer.WriteToStream(AStream: TStream); procedure TsSpreadBIFF2Writer.WriteToStream(AStream: TStream);
var var
sheet: TsWorksheet; sheet: TsWorksheet;
pane: Byte;
begin begin
sheet := Workbook.GetFirstWorksheet; sheet := Workbook.GetFirstWorksheet;
@ -976,7 +977,7 @@ begin
WriteWindow1(AStream); WriteWindow1(AStream);
// { -- currently not working // { -- currently not working
WriteWindow2(AStream, sheet); WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, false); // false for "is not BIFF5 or BIFF8" WritePane(AStream, sheet, false, pane); // false for "is not BIFF5 or BIFF8"
WriteSelections(AStream, sheet); WriteSelections(AStream, sheet);
//} //}
WriteEOF(AStream); WriteEOF(AStream);

View File

@ -361,6 +361,7 @@ var
Boundsheets: array of Int64; Boundsheets: array of Int64;
i, len: Integer; i, len: Integer;
sheet : TsWorksheet; sheet : TsWorksheet;
pane: Byte;
begin begin
{ Store some data about the workbook that other routines need } { Store some data about the workbook that other routines need }
WorkBookEncoding := Workbook.Encoding; WorkBookEncoding := Workbook.Encoding;
@ -383,7 +384,7 @@ begin
begin begin
len := Length(Boundsheets); len := Length(Boundsheets);
SetLength(Boundsheets, len + 1); SetLength(Boundsheets, len + 1);
Boundsheets[len] := WriteBoundsheet(AStream, UTF8ToAnsi(Workbook.GetWorksheetByIndex(i).Name)); Boundsheets[len] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i).Name);
// BIFF8 does not support unicode --> Need UTF8ToAnsi ! // BIFF8 does not support unicode --> Need UTF8ToAnsi !
end; end;
@ -404,10 +405,12 @@ begin
WriteBOF(AStream, INT_BOF_SHEET); WriteBOF(AStream, INT_BOF_SHEET);
WriteIndex(AStream); WriteIndex(AStream);
// WritePageSetup(AStream);
WriteColInfos(AStream, sheet); WriteColInfos(AStream, sheet);
WriteDimensions(AStream, sheet); WriteDimensions(AStream, sheet);
WriteWindow2(AStream, sheet); WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, true); // true for "is BIFF5 or BIFF8" WritePane(AStream, sheet, true, pane); // true for "is BIFF5 or BIFF8"
WriteSelection(AStream, sheet, pane);
WriteRows(AStream, sheet); WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells); WriteCellsToStream(AStream, sheet.Cells);
WriteEOF(AStream); WriteEOF(AStream);
@ -985,7 +988,9 @@ begin
MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES or MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES or
MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR or MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR or
MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS or MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS or
MASK_WINDOW2_OPTION_SHEET_SELECTED or
MASK_WINDOW2_OPTION_SHEET_ACTIVE; MASK_WINDOW2_OPTION_SHEET_ACTIVE;
{ Bug 0026386 -> every sheet must be selected/active, otherwise Excel cannot print }
if (soShowGridLines in ASheet.Options) then if (soShowGridLines in ASheet.Options) then
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES; Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
@ -993,8 +998,6 @@ begin
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS; Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN; Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
if (soSelected in ASheet.Options) then
Options := Options or MASK_WINDOW2_OPTION_SHEET_SELECTED;
AStream.WriteWord(WordToLE(Options)); AStream.WriteWord(WordToLE(Options));

View File

@ -395,6 +395,7 @@ var
Boundsheets: array of Int64; Boundsheets: array of Int64;
sheet: TsWorksheet; sheet: TsWorksheet;
i, len: Integer; i, len: Integer;
pane: Byte;
begin begin
{ Write workbook globals } { Write workbook globals }
@ -433,6 +434,8 @@ begin
WriteBOF(AStream, INT_BOF_SHEET); WriteBOF(AStream, INT_BOF_SHEET);
WriteIndex(AStream); WriteIndex(AStream);
//WriteSheetPR(AStream);
// WritePageSetup(AStream);
WriteColInfos(AStream, sheet); WriteColInfos(AStream, sheet);
WriteDimensions(AStream, sheet); WriteDimensions(AStream, sheet);
//WriteRowAndCellBlock(AStream, sheet); //WriteRowAndCellBlock(AStream, sheet);
@ -441,7 +444,8 @@ begin
WriteCellsToStream(AStream, sheet.Cells); WriteCellsToStream(AStream, sheet.Cells);
WriteWindow2(AStream, sheet); WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, isBIFF8); WritePane(AStream, sheet, isBIFF8, pane);
WriteSelection(AStream, sheet, pane);
WriteEOF(AStream); WriteEOF(AStream);
end; end;
@ -1101,7 +1105,9 @@ begin
MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES or MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES or
MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR or MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR or
MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS or MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS or
MASK_WINDOW2_OPTION_SHEET_SELECTED or
MASK_WINDOW2_OPTION_SHEET_ACTIVE; MASK_WINDOW2_OPTION_SHEET_ACTIVE;
{ Bug 0026386 -> every sheet must be selected/active, otherwise Excel cannot print }
if (soShowGridLines in ASheet.Options) then if (soShowGridLines in ASheet.Options) then
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES; Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
@ -1109,9 +1115,6 @@ begin
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS; Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN; Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
if (soSelected in ASheet.Options) then
Options := Options or MASK_WINDOW2_OPTION_SHEET_SELECTED;
AStream.WriteWord(WordToLE(Options)); AStream.WriteWord(WordToLE(Options));
{ Index to first visible row } { Index to first visible row }

View File

@ -30,6 +30,7 @@ const
{ RECORD IDs which did not change across version 3-8} { RECORD IDs which did not change across version 3-8}
INT_EXCEL_ID_COLINFO = $007D; // does not exist in BIFF2 INT_EXCEL_ID_COLINFO = $007D; // does not exist in BIFF2
INT_EXCEL_ID_SHEETPR = $0081; // does not exist in BIFF2
INT_EXCEL_ID_COUNTRY = $008C; // does not exist in BIFF2 INT_EXCEL_ID_COUNTRY = $008C; // does not exist in BIFF2
INT_EXCEL_ID_PALETTE = $0092; // does not exist in BIFF2 INT_EXCEL_ID_PALETTE = $0092; // does not exist in BIFF2
INT_EXCEL_ID_DIMENSIONS = $0200; // BIFF2: $0000 INT_EXCEL_ID_DIMENSIONS = $0200; // BIFF2: $0000
@ -44,6 +45,7 @@ const
INT_EXCEL_ID_STYLE = $0293; // does not exist in BIFF2 INT_EXCEL_ID_STYLE = $0293; // does not exist in BIFF2
{ RECORD IDs which did not change across version 4-8 } { RECORD IDs which did not change across version 4-8 }
INT_EXCEL_ID_PAGESETUP = $00A1; // does not exist before BIFF4
INT_EXCEL_ID_FORMAT = $041E; // BIFF2-3: $001E INT_EXCEL_ID_FORMAT = $041E; // BIFF2-3: $001E
{ RECORD IDs which did not change across versions 5-8 } { RECORD IDs which did not change across versions 5-8 }
@ -468,10 +470,12 @@ type
// Writes out a floating point NUMBER record // Writes out a floating point NUMBER record
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
const AValue: Double; ACell: PCell); override; const AValue: Double; ACell: PCell); override;
procedure WritePageSetup(AStream: TStream);
// Writes out a PALETTE record containing all colors defined in the workbook // Writes out a PALETTE record containing all colors defined in the workbook
procedure WritePalette(AStream: TStream); procedure WritePalette(AStream: TStream);
// Writes out a PANE record // Writes out a PANE record
procedure WritePane(AStream: TStream; ASheet: TsWorksheet; IsBiff58: Boolean); procedure WritePane(AStream: TStream; ASheet: TsWorksheet; IsBiff58: Boolean;
out ActivePane: Byte);
// Writes out a ROW record // Writes out a ROW record
procedure WriteRow(AStream: TStream; ASheet: TsWorksheet; procedure WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); virtual; ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); virtual;
@ -480,6 +484,7 @@ type
// Writes out a SELECTION record // 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); procedure WriteSelections(AStream: TStream; ASheet: TsWorksheet);
procedure WriteSheetPR(AStream: TStream);
// Writes out a WINDOW1 record // Writes out a WINDOW1 record
procedure WriteWindow1(AStream: TStream); virtual; procedure WriteWindow1(AStream: TStream); virtual;
// Writes the index of the XF record used in the given cell // Writes the index of the XF record used in the given cell
@ -1573,11 +1578,6 @@ begin
else else
FWorksheet.Options := FWorksheet.Options - [soShowHeaders]; FWorksheet.Options := FWorksheet.Options - [soShowHeaders];
if (flags and MASK_WINDOW2_OPTION_SHEET_SELECTED <> 0) then
FWorksheet.Options := FWorksheet.Options + [soSelected]
else
FWorksheet.Options := FWorksheet.Options - [soSelected];
if (flags and MASK_WINDOW2_OPTION_PANES_ARE_FROZEN <> 0) then if (flags and MASK_WINDOW2_OPTION_PANES_ARE_FROZEN <> 0) then
FWorksheet.Options := FWorksheet.Options + [soHasFrozenPanes] FWorksheet.Options := FWorksheet.Options + [soHasFrozenPanes]
else else
@ -1848,15 +1848,62 @@ begin
AStream.WriteDWord(DWordToLE($FFFFFF)); AStream.WriteDWord(DWordToLE($FFFFFF));
end; end;
{@@
Writes a PAGESETUP record containing information on printing
}
procedure TsSpreadBIFFWriter.WritePageSetup(AStream: TStream);
var
flags: Word;
dbl: Double;
begin
{ BIFF record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_PAGESETUP));
AStream.WriteWord(WordToLE(9*2 + 2*8));
{ Paper size }
AStream.WriteWord(WordToLE(0)); // 1 = Letter, 9 = A4
{ Scaling factor in percent }
AStream.WriteWord(WordToLE(100)); // 100 %
{ Start page number }
AStream.WriteWord(WordToLE(1)); // starting at page 1
{ Fit worksheet width to this number of pages, 0 = use as many as needed }
AStream.WriteWord(WordToLE(0));
{ Fit worksheet height to this number of pages, 0 = use as many as needed }
AStream.WriteWord(WordToLE(0));
flags := 0;
AStream.WriteWord(WordToLE(0));
{ Print resolution in dpi }
AStream.WriteWord(WordToLE(600));
{ Vertical print resolution in dpi }
AStream.WriteWord(WordToLE(600));
{ Header margin }
dbl := 0.5;
AStream.WriteBuffer(dbl, SizeOf(dbl));
{ Footer margin }
AStream.WriteBuffer(dbl, SizeOf(dbl));
{ Number of copies to print }
AStream.WriteWord(WordToLE(1)); // 1 copy
end;
{ Writes a PANE record to the stream. { Writes a PANE record to the stream.
Valid for all BIFF versions. The difference for BIFF5-BIFF8 is a non-used Valid for all BIFF versions. The difference for BIFF5-BIFF8 is a non-used
byte at the end. Activate IsBiff58 in these cases. } byte at the end. Activate IsBiff58 in these cases. }
procedure TsSpreadBIFFWriter.WritePane(AStream: TStream; ASheet: TsWorksheet; procedure TsSpreadBIFFWriter.WritePane(AStream: TStream; ASheet: TsWorksheet;
IsBiff58: Boolean); IsBiff58: Boolean; out ActivePane: Byte);
var var
n: Word; n: Word;
active_pane: Byte;
begin begin
ActivePane := 3;
if not (soHasFrozenPanes in ASheet.Options) then if not (soHasFrozenPanes in ASheet.Options) then
exit; exit;
if (ASheet.LeftPaneWidth = 0) and (ASheet.TopPaneHeight = 0) then if (ASheet.LeftPaneWidth = 0) and (ASheet.TopPaneHeight = 0) then
@ -1901,18 +1948,18 @@ begin
3 = left-top } 3 = left-top }
if (soHasFrozenPanes in ASheet.Options) then begin if (soHasFrozenPanes in ASheet.Options) then begin
if (ASheet.LeftPaneWidth = 0) and (ASheet.TopPaneHeight = 0) then if (ASheet.LeftPaneWidth = 0) and (ASheet.TopPaneHeight = 0) then
active_pane := 3 ActivePane := 3
else else
if (ASheet.LeftPaneWidth = 0) then if (ASheet.LeftPaneWidth = 0) then
active_pane := 2 ActivePane := 2
else else
if (ASheet.TopPaneHeight =0) then if (ASheet.TopPaneHeight =0) then
active_pane := 1 ActivePane := 1
else else
active_pane := 0; ActivePane := 0;
end else end else
active_pane := 0; ActivePane := 0;
AStream.WriteByte(active_pane); AStream.WriteByte(ActivePane);
if IsBIFF58 then if IsBIFF58 then
AStream.WriteByte(0); AStream.WriteByte(0);
@ -2080,6 +2127,20 @@ begin
end; end;
end; end;
{ Writes a SHEETPR Record.
Valid for BIFF3-BIFF8. }
procedure TsSpreadBIFFWriter.WriteSheetPR(AStream: TStream);
var
flags: Word;
begin
{ BIFF Record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_SHEETPR));
AStream.WriteWord(WordToLE(2));
flags := $04C1;
AStream.WriteWord(WordToLE(flags));
end;
{ Writes an Excel 5/8 WINDOW1 record { Writes an Excel 5/8 WINDOW1 record
This record contains general settings for the document window and This record contains general settings for the document window and
global workbook settings. global workbook settings.