fpspreadsheet: Row heights now can be saved to all biff versions. Add unit test case for row heights, ok. Bug fixed in BIFFExplorer with format detection.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3019 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-05-07 18:31:27 +00:00
parent 56c90a2f05
commit f0928db9f5
17 changed files with 499 additions and 231 deletions

View File

@ -31,6 +31,8 @@ begin
//MyWorksheet.WriteColWidth(0, 5); //MyWorksheet.WriteColWidth(0, 5);
//MyWorksheet.WriteColWidth(1, 30); //MyWorksheet.WriteColWidth(1, 30);
MyWorksheet.WriteRowHeight(0, 30); // 30 mm
// Turn off grid lines and hide headers // Turn off grid lines and hide headers
MyWorksheet.Options := MyWorksheet.Options - [soShowGridLines, soShowHeaders]; MyWorksheet.Options := MyWorksheet.Options - [soShowGridLines, soShowHeaders];

View File

@ -43,6 +43,14 @@ begin
MyWorkbook.AddFont('Calibri', 20, [], scRed); MyWorkbook.AddFont('Calibri', 20, [], scRed);
// Change row height
MyWorksheet.WriteRowHeight(0, 20); // modify height of row 0 to 20 mm
// Change colum widths
MyWorksheet.WriteColWidth(0, 40);
MyWorksheet.WriteColWidth(1, 20);
MyWorksheet.WriteColWidth(2, 20);
// Write some cells // Write some cells
MyWorksheet.WriteNumber(0, 0, 1.0);// A1 MyWorksheet.WriteNumber(0, 0, 1.0);// A1
MyWorksheet.WriteVertAlignment(0, 0, vaCenter); MyWorksheet.WriteVertAlignment(0, 0, vaCenter);

View File

@ -46,7 +46,7 @@ begin
myWorksheet.LeftPaneWidth := 1; myWorksheet.LeftPaneWidth := 1;
MyWorksheet.TopPaneHeight := 2; MyWorksheet.TopPaneHeight := 2;
{ non-frozen panes not working, at the moment. Require SELECTION records? { non-frozen panes not working, at the moment. Requires SELECTION records?
MyWorksheet.LeftPaneWidth := 20*72*2; // 72 pt = inch --> 2 inches = 5 cm MyWorksheet.LeftPaneWidth := 20*72*2; // 72 pt = inch --> 2 inches = 5 cm
} }
@ -122,15 +122,16 @@ begin
MyWorksheet.WriteFont(8, 3, 'Courier New', 12, [fssUnderline], scBlue); MyWorksheet.WriteFont(8, 3, 'Courier New', 12, [fssUnderline], scBlue);
MyWorksheet.WriteBackgroundColor(8, 3, scYellow); MyWorksheet.WriteBackgroundColor(8, 3, scYellow);
{ Uncomment this to test large XLS files
for i := 2 to 20 do // Uncomment this to test large XLS files
for i := 40 to 1000 do
begin begin
MyWorksheet.WriteAnsiText(i, 0, ParamStr(0)); // MyWorksheet.WriteUTF8Text(i, 0, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 1, ParamStr(0)); // MyWorksheet.WriteUTF8Text(i, 1, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 2, ParamStr(0)); // MyWorksheet.WriteUTF8Text(i, 2, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 3, ParamStr(0)); MyWorksheet.WriteUTF8Text(i, 3, ParamStr(0));
end; end;
}
// Write the formula E1 = A1 + B1 // Write the formula E1 = A1 + B1
SetLength(MyRPNFormula, 3); SetLength(MyRPNFormula, 3);
@ -209,17 +210,15 @@ begin
MyWorksheet.WriteUTF8Text(37, 0, 'nfTimeInterval'); MyWorksheet.WriteUTF8Text(37, 0, 'nfTimeInterval');
MyWorksheet.WriteDateTime(37, 1, number, nfTimeInterval); MyWorksheet.WriteDateTime(37, 1, number, nfTimeInterval);
// Set width of columns 1 and 5 // Set width of columns 0, 1 and 5
lCol.Width := 30; MyWorksheet.WriteColWidth(0, 25);
lCol.Width := 20;
MyWorksheet.WriteColInfo(1, lCol); MyWorksheet.WriteColInfo(1, lCol);
lCol.Width := 5; lCol.Width := 5;
MyWorksheet.WriteColInfo(5, lCol); MyWorksheet.WriteColInfo(5, lCol);
// Set height of rows 5 and 6 // Set height of rows 0
lRow.Height := 10; MyWorksheet.WriteRowHeight(0, 30); // 30 mm
MyWorksheet.WriteRowInfo(5, lRow);
lRow.Height := 5;
MyWorksheet.WriteRowInfo(6, lRow);
// Creates a new worksheet // Creates a new worksheet
MyWorksheet := MyWorkbook.AddWorksheet(Str_Worksheet2); MyWorksheet := MyWorkbook.AddWorksheet(Str_Worksheet2);

View File

@ -127,11 +127,10 @@
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="mainform"/> <UnitName Value="mainform"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="140"/> <TopLine Value="140"/>
<CursorPos X="41" Y="152"/> <CursorPos X="62" Y="157"/>
<UsageCount Value="139"/> <UsageCount Value="139"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
@ -139,7 +138,7 @@
<Unit2> <Unit2>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/> <UnitName Value="fpspreadsheet"/>
<EditorIndex Value="8"/> <EditorIndex Value="4"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="297"/> <TopLine Value="297"/>
<CursorPos X="57" Y="305"/> <CursorPos X="57" Y="305"/>
@ -149,10 +148,11 @@
<Unit3> <Unit3>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<UnitName Value="fpspreadsheetgrid"/> <UnitName Value="fpspreadsheetgrid"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="3"/> <EditorIndex Value="3"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="877"/> <TopLine Value="857"/>
<CursorPos X="25" Y="893"/> <CursorPos X="27" Y="879"/>
<UsageCount Value="67"/> <UsageCount Value="67"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit3> </Unit3>
@ -222,7 +222,6 @@
<Unit12> <Unit12>
<Filename Value="d:\lazarus-svn\lcl\grids.pas"/> <Filename Value="d:\lazarus-svn\lcl\grids.pas"/>
<UnitName Value="Grids"/> <UnitName Value="Grids"/>
<EditorIndex Value="4"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="3915"/> <TopLine Value="3915"/>
<CursorPos X="1" Y="3924"/> <CursorPos X="1" Y="3924"/>
@ -230,7 +229,6 @@
<Bookmarks Count="1"> <Bookmarks Count="1">
<Item0 X="7" Y="3905" ID="1"/> <Item0 X="7" Y="3905" ID="1"/>
</Bookmarks> </Bookmarks>
<Loaded Value="True"/>
</Unit12> </Unit12>
<Unit13> <Unit13>
<Filename Value="..\..\fpsutils.pas"/> <Filename Value="..\..\fpsutils.pas"/>
@ -252,12 +250,10 @@
<Unit15> <Unit15>
<Filename Value="d:\lazarus-svn\lcl\graphics.pp"/> <Filename Value="d:\lazarus-svn\lcl\graphics.pp"/>
<UnitName Value="Graphics"/> <UnitName Value="Graphics"/>
<EditorIndex Value="5"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="649"/> <TopLine Value="649"/>
<CursorPos X="28" Y="675"/> <CursorPos X="28" Y="675"/>
<UsageCount Value="33"/> <UsageCount Value="33"/>
<Loaded Value="True"/>
</Unit15> </Unit15>
<Unit16> <Unit16>
<Filename Value="d:\lazarus-svn\fpc\2.6.2\source\rtl\objpas\classes\classesh.inc"/> <Filename Value="d:\lazarus-svn\fpc\2.6.2\source\rtl\objpas\classes\classesh.inc"/>
@ -269,7 +265,7 @@
<Unit17> <Unit17>
<Filename Value="..\..\xlsbiff8.pas"/> <Filename Value="..\..\xlsbiff8.pas"/>
<UnitName Value="xlsbiff8"/> <UnitName Value="xlsbiff8"/>
<EditorIndex Value="10"/> <EditorIndex Value="6"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1174"/> <TopLine Value="1174"/>
<CursorPos X="1" Y="1198"/> <CursorPos X="1" Y="1198"/>
@ -294,17 +290,17 @@
<Unit20> <Unit20>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<UnitName Value="xlscommon"/> <UnitName Value="xlscommon"/>
<EditorIndex Value="9"/> <EditorIndex Value="5"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="914"/> <TopLine Value="1530"/>
<CursorPos X="1" Y="942"/> <CursorPos X="47" Y="1554"/>
<UsageCount Value="37"/> <UsageCount Value="37"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit20> </Unit20>
<Unit21> <Unit21>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<UnitName Value="xlsbiff5"/> <UnitName Value="xlsbiff5"/>
<EditorIndex Value="11"/> <EditorIndex Value="7"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1319"/> <TopLine Value="1319"/>
<CursorPos X="3" Y="1325"/> <CursorPos X="3" Y="1325"/>
@ -314,7 +310,7 @@
<Unit22> <Unit22>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<UnitName Value="xlsbiff2"/> <UnitName Value="xlsbiff2"/>
<EditorIndex Value="12"/> <EditorIndex Value="8"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="399"/> <TopLine Value="399"/>
<CursorPos X="16" Y="406"/> <CursorPos X="16" Y="406"/>
@ -332,12 +328,10 @@
<Unit24> <Unit24>
<Filename Value="d:\lazarus-svn\fpc\2.6.2\source\packages\fcl-image\src\fpcanvas.pp"/> <Filename Value="d:\lazarus-svn\fpc\2.6.2\source\packages\fcl-image\src\fpcanvas.pp"/>
<UnitName Value="FPCanvas"/> <UnitName Value="FPCanvas"/>
<EditorIndex Value="7"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="111"/> <TopLine Value="111"/>
<CursorPos X="3" Y="112"/> <CursorPos X="3" Y="112"/>
<UsageCount Value="20"/> <UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit24> </Unit24>
<Unit25> <Unit25>
<Filename Value="d:\lazarus-svn\fpc\2.6.2\source\packages\fcl-image\src\fpimage.pp"/> <Filename Value="d:\lazarus-svn\fpc\2.6.2\source\packages\fcl-image\src\fpimage.pp"/>
@ -357,143 +351,139 @@
<Unit27> <Unit27>
<Filename Value="d:\Prog_Delphi\common\units\XLS.pas"/> <Filename Value="d:\Prog_Delphi\common\units\XLS.pas"/>
<UnitName Value="Xls"/> <UnitName Value="Xls"/>
<EditorIndex Value="13"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="114"/> <TopLine Value="114"/>
<CursorPos X="42" Y="152"/> <CursorPos X="42" Y="152"/>
<UsageCount Value="16"/> <UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit27> </Unit27>
<Unit28> <Unit28>
<Filename Value="d:\lazarus-svn\lcl\include\pen.inc"/> <Filename Value="d:\lazarus-svn\lcl\include\pen.inc"/>
<EditorIndex Value="6"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="272"/> <TopLine Value="272"/>
<CursorPos X="3" Y="286"/> <CursorPos X="3" Y="286"/>
<UsageCount Value="16"/> <UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit28> </Unit28>
</Units> </Units>
<JumpHistory Count="30" HistoryIndex="29"> <JumpHistory Count="30" HistoryIndex="29">
<Position1> <Position1>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1347" Column="26" TopLine="1332"/>
</Position1>
<Position2>
<Filename Value="..\..\xlsbiff8.pas"/> <Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="1578" Column="26" TopLine="1568"/> <Caret Line="1578" Column="26" TopLine="1568"/>
</Position1>
<Position2>
<Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="438" Column="33" TopLine="419"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="438" Column="33" TopLine="419"/> <Caret Line="892" Column="57" TopLine="876"/>
</Position3> </Position3>
<Position4> <Position4>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="892" Column="57" TopLine="876"/> <Caret Line="898" Column="23" TopLine="886"/>
</Position4> </Position4>
<Position5> <Position5>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="898" Column="23" TopLine="886"/> <Caret Line="161" Column="1" TopLine="145"/>
</Position5> </Position5>
<Position6> <Position6>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="161" Column="1" TopLine="145"/> <Caret Line="158" Column="46" TopLine="140"/>
</Position6> </Position6>
<Position7> <Position7>
<Filename Value="mainform.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="158" Column="46" TopLine="140"/> <Caret Line="272" Column="15" TopLine="256"/>
</Position7> </Position7>
<Position8> <Position8>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="272" Column="15" TopLine="256"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position8> </Position8>
<Position9> <Position9>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="31" Column="8" TopLine="4"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="31" Column="8" TopLine="4"/>
</Position10>
<Position11>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="400" Column="48" TopLine="400"/> <Caret Line="400" Column="48" TopLine="400"/>
</Position10>
<Position11>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="997" Column="54" TopLine="997"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="997" Column="54" TopLine="997"/> <Caret Line="1004" Column="43" TopLine="997"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1004" Column="43" TopLine="997"/> <Caret Line="1010" Column="50" TopLine="997"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1010" Column="50" TopLine="997"/> <Caret Line="1015" Column="17" TopLine="997"/>
</Position14> </Position14>
<Position15> <Position15>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1015" Column="17" TopLine="997"/> <Caret Line="1016" Column="17" TopLine="997"/>
</Position15> </Position15>
<Position16> <Position16>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1016" Column="17" TopLine="997"/> <Caret Line="1017" Column="17" TopLine="997"/>
</Position16> </Position16>
<Position17> <Position17>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1017" Column="17" TopLine="997"/> <Caret Line="1018" Column="17" TopLine="997"/>
</Position17> </Position17>
<Position18> <Position18>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1018" Column="17" TopLine="997"/> <Caret Line="1021" Column="39" TopLine="997"/>
</Position18> </Position18>
<Position19> <Position19>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1021" Column="39" TopLine="997"/> <Caret Line="1023" Column="39" TopLine="997"/>
</Position19> </Position19>
<Position20> <Position20>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1023" Column="39" TopLine="997"/> <Caret Line="1025" Column="39" TopLine="998"/>
</Position20> </Position20>
<Position21> <Position21>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1025" Column="39" TopLine="998"/> <Caret Line="1027" Column="39" TopLine="1000"/>
</Position21> </Position21>
<Position22> <Position22>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1027" Column="39" TopLine="1000"/> <Caret Line="1346" Column="25" TopLine="1319"/>
</Position22> </Position22>
<Position23> <Position23>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1346" Column="25" TopLine="1319"/>
</Position23>
<Position24>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="66" Column="15" TopLine="50"/> <Caret Line="66" Column="15" TopLine="50"/>
</Position23>
<Position24>
<Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1346" Column="33" TopLine="1319"/>
</Position24> </Position24>
<Position25> <Position25>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff5.pas"/>
<Caret Line="1346" Column="33" TopLine="1319"/> <Caret Line="1325" Column="3" TopLine="1319"/>
</Position25> </Position25>
<Position26> <Position26>
<Filename Value="..\..\xlsbiff5.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="1325" Column="3" TopLine="1319"/> <Caret Line="588" Column="1" TopLine="562"/>
</Position26> </Position26>
<Position27> <Position27>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="588" Column="1" TopLine="562"/> <Caret Line="1435" Column="5" TopLine="1435"/>
</Position27> </Position27>
<Position28> <Position28>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="1435" Column="5" TopLine="1435"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position28> </Position28>
<Position29> <Position29>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="63" Column="22" TopLine="36"/>
</Position29> </Position29>
<Position30> <Position30>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="63" Column="22" TopLine="36"/> <Caret Line="893" Column="25" TopLine="877"/>
</Position30> </Position30>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>

View File

@ -4,7 +4,7 @@ object Form1: TForm1
Top = 258 Top = 258
Width = 518 Width = 518
Caption = 'fpsGrid' Caption = 'fpsGrid'
ClientHeight = 366 ClientHeight = 361
ClientWidth = 518 ClientWidth = 518
Menu = MainMenu1 Menu = MainMenu1
OnActivate = FormActivate OnActivate = FormActivate
@ -12,19 +12,19 @@ object Form1: TForm1
LCLVersion = '1.3' LCLVersion = '1.3'
object Panel1: TPanel object Panel1: TPanel
Left = 0 Left = 0
Height = 70 Height = 73
Top = 296 Top = 288
Width = 518 Width = 518
Align = alBottom Align = alBottom
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 70 ClientHeight = 73
ClientWidth = 518 ClientWidth = 518
TabOrder = 0 TabOrder = 0
object btnPopulateGrid: TButton object btnPopulateGrid: TButton
Left = 400 Left = 392
Height = 25 Height = 31
Top = 13 Top = 24
Width = 112 Width = 120
Caption = 'Populate Grid' Caption = 'Populate Grid'
OnClick = btnPopulateGridClick OnClick = btnPopulateGridClick
TabOrder = 0 TabOrder = 0
@ -32,9 +32,9 @@ object Form1: TForm1
end end
object CbShowHeaders: TCheckBox object CbShowHeaders: TCheckBox
Left = 8 Left = 8
Height = 19 Height = 24
Top = 8 Top = 11
Width = 93 Width = 116
Caption = 'Show headers' Caption = 'Show headers'
Checked = True Checked = True
OnClick = CbShowHeadersClick OnClick = CbShowHeadersClick
@ -43,9 +43,9 @@ object Form1: TForm1
end end
object CbShowGridLines: TCheckBox object CbShowGridLines: TCheckBox
Left = 8 Left = 8
Height = 19 Height = 24
Top = 29 Top = 36
Width = 100 Width = 125
Caption = 'Show grid lines' Caption = 'Show grid lines'
Checked = True Checked = True
OnClick = CbShowGridLinesClick OnClick = CbShowGridLinesClick
@ -53,35 +53,35 @@ object Form1: TForm1
TabOrder = 2 TabOrder = 2
end end
object EdFrozenCols: TSpinEdit object EdFrozenCols: TSpinEdit
Left = 208 Left = 238
Height = 23 Height = 28
Top = 8 Top = 8
Width = 52 Width = 52
OnChange = EdFrozenColsChange OnChange = EdFrozenColsChange
TabOrder = 3 TabOrder = 3
end end
object EdFrozenRows: TSpinEdit object EdFrozenRows: TSpinEdit
Left = 208 Left = 238
Height = 23 Height = 28
Top = 36 Top = 39
Width = 52 Width = 52
OnChange = EdFrozenRowsChange OnChange = EdFrozenRowsChange
TabOrder = 4 TabOrder = 4
end end
object Label1: TLabel object Label1: TLabel
Left = 135 Left = 152
Height = 15 Height = 20
Top = 13 Top = 13
Width = 62 Width = 77
Caption = 'Frozen cols:' Caption = 'Frozen cols:'
FocusControl = EdFrozenCols FocusControl = EdFrozenCols
ParentColor = False ParentColor = False
end end
object Label2: TLabel object Label2: TLabel
Left = 136 Left = 153
Height = 15 Height = 20
Top = 39 Top = 40
Width = 66 Width = 82
Caption = 'Frozen rows:' Caption = 'Frozen rows:'
FocusControl = EdFrozenRows FocusControl = EdFrozenRows
ParentColor = False ParentColor = False
@ -89,7 +89,7 @@ object Form1: TForm1
end end
object PageControl1: TPageControl object PageControl1: TPageControl
Left = 0 Left = 0
Height = 270 Height = 262
Top = 26 Top = 26
Width = 518 Width = 518
ActivePage = TabSheet1 ActivePage = TabSheet1
@ -99,17 +99,24 @@ object Form1: TForm1
OnChange = PageControl1Change OnChange = PageControl1Change
object TabSheet1: TTabSheet object TabSheet1: TTabSheet
Caption = 'Sheet1' Caption = 'Sheet1'
ClientHeight = 242 ClientHeight = 229
ClientWidth = 510 ClientWidth = 510
object sWorksheetGrid1: TsWorksheetGrid object sWorksheetGrid1: TsWorksheetGrid
Left = 0 Left = 0
Height = 242 Height = 229
Top = 0 Top = 0
Width = 510 Width = 510
Align = alClient Align = alClient
ColCount = 2
ExtendedSelect = False
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goThumbTracking, goSmoothScroll, goFixedColSizing] Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goThumbTracking, goSmoothScroll, goFixedColSizing]
RowCount = 2
TabOrder = 0 TabOrder = 0
TitleStyle = tsNative TitleStyle = tsNative
ColWidths = (
56
64
)
end end
end end
end end

View File

@ -2,37 +2,38 @@
LazarusResources.Add('TForm1','FORMDATA',[ LazarusResources.Add('TForm1','FORMDATA',[
'TPF0'#6'TForm1'#5'Form1'#4'Left'#3'r'#1#6'Height'#3#130#1#3'Top'#3#2#1#5'Wid' 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3'r'#1#6'Height'#3#130#1#3'Top'#3#2#1#5'Wid'
+'th'#3#6#2#7'Caption'#6#7'fpsGrid'#12'ClientHeight'#3'n'#1#11'ClientWidth'#3 +'th'#3#6#2#7'Caption'#6#7'fpsGrid'#12'ClientHeight'#3'i'#1#11'ClientWidth'#3
+#6#2#4'Menu'#7#9'MainMenu1'#10'OnActivate'#7#12'FormActivate'#8'ShowHint'#9 +#6#2#4'Menu'#7#9'MainMenu1'#10'OnActivate'#7#12'FormActivate'#8'ShowHint'#9
+#10'LCLVersion'#6#3'1.3'#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'F'#3 +#10'LCLVersion'#6#3'1.3'#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'I'#3
+'Top'#3'('#1#5'Width'#3#6#2#5'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone' +'Top'#3' '#1#5'Width'#3#6#2#5'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'
+#12'ClientHeight'#2'F'#11'ClientWidth'#3#6#2#8'TabOrder'#2#0#0#7'TButton'#15 +#12'ClientHeight'#2'I'#11'ClientWidth'#3#6#2#8'TabOrder'#2#0#0#7'TButton'#15
+'btnPopulateGrid'#4'Left'#3#144#1#6'Height'#2#25#3'Top'#2#13#5'Width'#2'p'#7 +'btnPopulateGrid'#4'Left'#3#136#1#6'Height'#2#31#3'Top'#2#24#5'Width'#2'x'#7
+'Caption'#6#13'Populate Grid'#7'OnClick'#7#20'btnPopulateGridClick'#8'TabOrd' +'Caption'#6#13'Populate Grid'#7'OnClick'#7#20'btnPopulateGridClick'#8'TabOrd'
+'er'#2#0#7'Visible'#8#0#0#9'TCheckBox'#13'CbShowHeaders'#4'Left'#2#8#6'Heigh' +'er'#2#0#7'Visible'#8#0#0#9'TCheckBox'#13'CbShowHeaders'#4'Left'#2#8#6'Heigh'
+'t'#2#19#3'Top'#2#8#5'Width'#2']'#7'Caption'#6#12'Show headers'#7'Checked'#9 +'t'#2#24#3'Top'#2#11#5'Width'#2't'#7'Caption'#6#12'Show headers'#7'Checked'#9
+#7'OnClick'#7#18'CbShowHeadersClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#1 +#7'OnClick'#7#18'CbShowHeadersClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#1
+#0#0#9'TCheckBox'#15'CbShowGridLines'#4'Left'#2#8#6'Height'#2#19#3'Top'#2#29 +#0#0#9'TCheckBox'#15'CbShowGridLines'#4'Left'#2#8#6'Height'#2#24#3'Top'#2'$'
+#5'Width'#2'd'#7'Caption'#6#15'Show grid lines'#7'Checked'#9#7'OnClick'#7#20 +#5'Width'#2'}'#7'Caption'#6#15'Show grid lines'#7'Checked'#9#7'OnClick'#7#20
+'CbShowGridLinesClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#2#0#0#9'TSpinEd' +'CbShowGridLinesClick'#5'State'#7#9'cbChecked'#8'TabOrder'#2#2#0#0#9'TSpinEd'
+'it'#12'EdFrozenCols'#4'Left'#3#208#0#6'Height'#2#23#3'Top'#2#8#5'Width'#2'4' +'it'#12'EdFrozenCols'#4'Left'#3#238#0#6'Height'#2#28#3'Top'#2#8#5'Width'#2'4'
+#8'OnChange'#7#18'EdFrozenColsChange'#8'TabOrder'#2#3#0#0#9'TSpinEdit'#12'Ed' +#8'OnChange'#7#18'EdFrozenColsChange'#8'TabOrder'#2#3#0#0#9'TSpinEdit'#12'Ed'
+'FrozenRows'#4'Left'#3#208#0#6'Height'#2#23#3'Top'#2'$'#5'Width'#2'4'#8'OnCh' +'FrozenRows'#4'Left'#3#238#0#6'Height'#2#28#3'Top'#2''''#5'Width'#2'4'#8'OnC'
+'ange'#7#18'EdFrozenRowsChange'#8'TabOrder'#2#4#0#0#6'TLabel'#6'Label1'#4'Le' +'hange'#7#18'EdFrozenRowsChange'#8'TabOrder'#2#4#0#0#6'TLabel'#6'Label1'#4'L'
+'ft'#3#135#0#6'Height'#2#15#3'Top'#2#13#5'Width'#2'>'#7'Caption'#6#12'Frozen' +'eft'#3#152#0#6'Height'#2#20#3'Top'#2#13#5'Width'#2'M'#7'Caption'#6#12'Froze'
+' cols:'#12'FocusControl'#7#12'EdFrozenCols'#11'ParentColor'#8#0#0#6'TLabel' +'n cols:'#12'FocusControl'#7#12'EdFrozenCols'#11'ParentColor'#8#0#0#6'TLabel'
+#6'Label2'#4'Left'#3#136#0#6'Height'#2#15#3'Top'#2''''#5'Width'#2'B'#7'Capti' +#6'Label2'#4'Left'#3#153#0#6'Height'#2#20#3'Top'#2'('#5'Width'#2'R'#7'Captio'
+'on'#6#12'Frozen rows:'#12'FocusControl'#7#12'EdFrozenRows'#11'ParentColor'#8 +'n'#6#12'Frozen rows:'#12'FocusControl'#7#12'EdFrozenRows'#11'ParentColor'#8
+#0#0#0#12'TPageControl'#12'PageControl1'#4'Left'#2#0#6'Height'#3#14#1#3'Top' +#0#0#0#12'TPageControl'#12'PageControl1'#4'Left'#2#0#6'Height'#3#6#1#3'Top'#2
+#2#26#5'Width'#3#6#2#10'ActivePage'#7#9'TabSheet1'#5'Align'#7#8'alClient'#8 +#26#5'Width'#3#6#2#10'ActivePage'#7#9'TabSheet1'#5'Align'#7#8'alClient'#8'Ta'
+'TabIndex'#2#0#8'TabOrder'#2#1#8'OnChange'#7#18'PageControl1Change'#0#9'TTab' +'bIndex'#2#0#8'TabOrder'#2#1#8'OnChange'#7#18'PageControl1Change'#0#9'TTabSh'
+'Sheet'#9'TabSheet1'#7'Caption'#6#6'Sheet1'#12'ClientHeight'#3#242#0#11'Clie' +'eet'#9'TabSheet1'#7'Caption'#6#6'Sheet1'#12'ClientHeight'#3#229#0#11'Client'
+'ntWidth'#3#254#1#0#15'TsWorksheetGrid'#15'sWorksheetGrid1'#4'Left'#2#0#6'He' +'Width'#3#254#1#0#15'TsWorksheetGrid'#15'sWorksheetGrid1'#4'Left'#2#0#6'Heig'
+'ight'#3#242#0#3'Top'#2#0#5'Width'#3#254#1#5'Align'#7#8'alClient'#7'Options' +'ht'#3#229#0#3'Top'#2#0#5'Width'#3#254#1#5'Align'#7#8'alClient'#8'ColCount'#2
+#11#15'goFixedVertLine'#15'goFixedHorzLine'#10'goVertLine'#10'goHorzLine'#13 +#2#14'ExtendedSelect'#8#7'Options'#11#15'goFixedVertLine'#15'goFixedHorzLine'
+'goRangeSelect'#11'goRowSizing'#11'goColSizing'#15'goThumbTracking'#14'goSmo' +#10'goVertLine'#10'goHorzLine'#13'goRangeSelect'#11'goRowSizing'#11'goColSiz'
+'othScroll'#16'goFixedColSizing'#0#8'TabOrder'#2#0#10'TitleStyle'#7#8'tsNati' +'ing'#15'goThumbTracking'#14'goSmoothScroll'#16'goFixedColSizing'#0#8'RowCou'
+'ve'#0#0#0#0#8'TToolBar'#8'ToolBar1'#4'Left'#2#0#6'Height'#2#26#3'Top'#2#0#5 +'nt'#2#2#8'TabOrder'#2#0#10'TitleStyle'#7#8'tsNative'#9'ColWidths'#1#2'8'#2
+'@'#0#0#0#0#0#8'TToolBar'#8'ToolBar1'#4'Left'#2#0#6'Height'#2#26#3'Top'#2#0#5
+'Width'#3#6#2#12'ButtonHeight'#2#24#7'Caption'#6#8'ToolBar1'#11'EdgeBorders' +'Width'#3#6#2#12'ButtonHeight'#2#24#7'Caption'#6#8'ToolBar1'#11'EdgeBorders'
+#11#0#6'Images'#7#10'ImageList1'#8'TabOrder'#2#2#0#11'TToolButton'#11'ToolBu' +#11#0#6'Images'#7#10'ImageList1'#8'TabOrder'#2#2#0#11'TToolButton'#11'ToolBu'
+'tton1'#4'Left'#2#1#3'Top'#2#0#6'Action'#7#6'AcOpen'#0#0#11'TToolButton'#11 +'tton1'#4'Left'#2#1#3'Top'#2#0#6'Action'#7#6'AcOpen'#0#0#11'TToolButton'#11
@ -64,8 +65,8 @@ LazarusResources.Add('TForm1','FORMDATA',[
+#248#255#137#227#248#255#130#225#247#255'z'#223#247#255'q'#222#246#255'g'#219 +#248#255#137#227#248#255#130#225#247#255'z'#223#247#255'q'#222#246#255'g'#219
+#245#255'['#216#244#255'M'#212#243#255'@'#209#242#255#202#242#251#255'5'#148 +#245#255'['#216#244#255'M'#212#243#255'@'#209#242#255#202#242#251#255'5'#148
+#218#255#255#255#255#0#255#255#255#0'6'#154#218#248#242#250#253#255#148#230 +#218#255#255#255#255#0#255#255#255#0'6'#154#218#248#242#250#253#255#148#230
+#248#255#146#229#248#255#144#229#248#255#139#227#248#255#134#226#247#255#127 ,#248#255#146#229#248#255#144#229#248#255#139#227#248#255#134#226#247#255#127
,#225#247#255'w'#222#246#255'l'#220#246#255'^'#217#244#255'O'#213#243#255#204 +#225#247#255'w'#222#246#255'l'#220#246#255'^'#217#244#255'O'#213#243#255#204
+#242#251#255'5'#148#218#255#255#255#255#0#255#255#255#0'6'#161#218#249#246 +#242#251#255'5'#148#218#255#255#255#255#0#255#255#255#0'6'#161#218#249#246
+#252#254#255#148#229#248#255#147#229#248#255#147#229#248#255#145#229#248#255 +#252#254#255#148#229#248#255#147#229#248#255#147#229#248#255#145#229#248#255
+#147#219#233#255#147#215#227#255#147#210#220#255#144#206#215#255#140#200#207 +#147#219#233#255#147#215#227#255#147#210#220#255#144#206#215#255#140#200#207
@ -128,8 +129,8 @@ LazarusResources.Add('TForm1','FORMDATA',[
+#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248 +#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248#255#254#251#248
+#255#254#251#248#255#254#251#248#255#254#251#248#255#211#150'm'#255#210#167 +#255#254#251#248#255#254#251#248#255#254#251#248#255#211#150'm'#255#210#167
+#138#255#171'b2'#255#187'j6'#255#240#210#190#255#226#163'z'#255#226#163'z' +#138#255#171'b2'#255#187'j6'#255#240#210#190#255#226#163'z'#255#226#163'z'
+#255#225#163'z'#255#226#163'{'#255#225#163'{'#255#224#161'x'#255#222#159'w' ,#255#225#163'z'#255#226#163'{'#255#225#163'{'#255#224#161'x'#255#222#159'w'
,#255#221#159'v'#255#220#157't'#255#217#155'r'#255#216#153'q'#255#214#153'p' +#255#221#159'v'#255#220#157't'#255#217#155'r'#255#216#153'q'#255#214#153'p'
+#255#213#171#142#255#173'c3'#255#187'j6'#255#242#213#194#255#227#163'z'#255 +#255#213#171#142#255#173'c3'#255#187'j6'#255#242#213#194#255#227#163'z'#255
+#227#163'z'#255#226#163'{'#255#226#163'{'#255#226#164'{'#255#225#162'y'#255 +#227#163'z'#255#226#163'{'#255#226#163'{'#255#226#164'{'#255#225#162'y'#255
+#224#161'x'#255#222#160'w'#255#222#158'u'#255#220#157't'#255#218#155's'#255 +#224#161'x'#255#222#160'w'#255#222#158'u'#255#220#157't'#255#218#155's'#255
@ -192,8 +193,8 @@ LazarusResources.Add('TForm1','FORMDATA',[
+#145'K'#255'?'#141'H'#255'='#137'E'#255']'#164'e'#255'Z'#160'a'#255'E'#131'K' +#145'K'#255'?'#141'H'#255'='#137'E'#255']'#164'e'#255'Z'#160'a'#255'E'#131'K'
+#255#158#158#158#255#158#158#158#255'`'#146#201#255#158#199#226#255#131#184 +#255#158#158#158#255#158#158#158#255'`'#146#201#255#158#199#226#255#131#184
+#218#255'}'#180#215#255'~'#179#215#255'O'#137#180#255';y'#177#234#255#255#255 +#218#255'}'#180#215#255'~'#179#215#255'O'#137#180#255';y'#177#234#255#255#255
+#0#255#255#255#0'www'#255#154#154#154#255'='#138'E'#255'I'#138'O'#255#156#156 ,#0#255#255#255#0'www'#255#154#154#154#255'='#138'E'#255'I'#138'O'#255#156#156
,#156#255#157#157#157#255#157#157#157#255'f'#150#204#255#162#203#227#255#137 +#156#255#157#157#157#255#157#157#157#255'f'#150#204#255#162#203#227#255#137
+#189#220#255#131#185#218#255#132#185#218#255'Q'#139#181#255'C~'#182#234#255 +#189#220#255#131#185#218#255#132#185#218#255'Q'#139#181#255'C~'#182#234#255
+#255#255#0#255#255#255#0'zzz'#255#153#153#153#255'R'#145'Y'#255#153#154#153 +#255#255#0#255#255#255#0'zzz'#255#153#153#153#255'R'#145'Y'#255#153#154#153
+#255#155#155#155#255#156#156#156#255#156#156#156#255'l'#154#208#255#167#206 +#255#155#155#155#255#156#156#156#255#156#156#156#255'l'#154#208#255#167#206
@ -256,8 +257,8 @@ LazarusResources.Add('TForm1','FORMDATA',[
+#255'l'#220#246#255'^'#217#244#255'O'#213#243#255#204#242#251#255'5'#148#218 +#255'l'#220#246#255'^'#217#244#255'O'#213#243#255#204#242#251#255'5'#148#218
+#255#255#255#255#0#255#255#255#0'5'#148#218#247#239#250#254#255#147#229#248 +#255#255#255#255#0#255#255#255#0'5'#148#218#247#239#250#254#255#147#229#248
+#255#143#228#248#255#137#227#248#255#130#225#247#255'z'#223#247#255'q'#222 +#255#143#228#248#255#137#227#248#255#130#225#247#255'z'#223#247#255'q'#222
+#246#255'g'#219#245#255'['#216#244#255'M'#212#243#255'@'#209#242#255#202#242 ,#246#255'g'#219#245#255'['#216#244#255'M'#212#243#255'@'#209#242#255#202#242
,#251#255'5'#148#218#255#255#255#255#0#255#255#255#0'3'#142#217#251#220#240 +#251#255'5'#148#218#255#255#255#255#0#255#255#255#0'3'#142#217#251#220#240
+#250#255#152#225#246#255#149#224#246#255#146#223#246#255#142#222#245#255#137 +#250#255#152#225#246#255#149#224#246#255#146#223#246#255#142#222#245#255#137
+#220#245#255#133#218#244#255#128#217#244#255'z'#215#243#255't'#213#243#255'p' +#220#245#255#133#218#244#255#128#217#244#255'z'#215#243#255't'#213#243#255'p'
+#211#242#255#194#234#248#255'5'#148#218#255#255#255#255#0#255#255#255#0',' +#211#242#255#194#234#248#255'5'#148#218#255#255#255#255#0#255#255#255#0','
@ -320,8 +321,8 @@ LazarusResources.Add('TForm1','FORMDATA',[
+#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255 +#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255
+#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0'p'#158#214#219 +#255#0#255#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0'p'#158#214#219
+'m'#156#212#255#133#177#218#255'Z'#145#185#255'`'#147#203#234#255#255#255#0 +'m'#156#212#255#133#177#218#255'Z'#145#185#255'`'#147#203#234#255#255#255#0
+#255#255#255#0#128#128#128#255'~~~'#255'|||'#255'zzz'#255'www'#255'uuu'#255 ,#255#255#255#0#128#128#128#255'~~~'#255'|||'#255'zzz'#255'www'#255'uuu'#255
,'rrr'#255'q'#158#212#255'o'#158#214#255#135#178#220#255#171#211#232#255#169 +'rrr'#255'q'#158#212#255'o'#158#214#255#135#178#220#255#171#211#232#255#169
+#208#230#255'X'#144#184#255'Y'#142#198#234#255#255#255#0#255#255#255#0'}}}' +#208#230#255'X'#144#184#255'Y'#142#198#234#255#255#255#0#255#255#255#0'}}}'
+#255#153#153#153#255#153#153#153#255#154#154#154#255#154#154#154#255#155#155 +#255#153#153#153#255#153#153#153#255#154#154#154#255#154#154#154#255#155#155
+#155#255#155#155#155#255'o'#157#211#255#170#209#231#255#171#209#231#255#152 +#155#255#155#155#155#255'o'#157#211#255#170#209#231#255#171#209#231#255#152

View File

@ -290,7 +290,6 @@ type
TRow = record TRow = record
Row: Cardinal; Row: Cardinal;
Height: Single; // in millimeters Height: Single; // in millimeters
AutoHeight: Boolean; // true: height corresponds to font; false: use Height
end; end;
PRow = ^TRow; PRow = ^TRow;
@ -337,6 +336,8 @@ type
function GetCellCount: Cardinal; function GetCellCount: Cardinal;
function GetFirstCell(): PCell; function GetFirstCell(): PCell;
function GetNextCell(): PCell; function GetNextCell(): PCell;
function GetFirstCellOfRow(ARow: Cardinal): PCell;
function GetLastCellOfRow(ARow: Cardinal): PCell;
function GetLastColNumber: Cardinal; function GetLastColNumber: Cardinal;
function GetLastRowNumber: Cardinal; function GetLastRowNumber: Cardinal;
function ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring; function ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring;
@ -385,6 +386,7 @@ type
procedure RemoveAllRows; procedure RemoveAllRows;
procedure RemoveAllCols; procedure RemoveAllCols;
procedure WriteRowInfo(ARow: Cardinal; AData: TRow); procedure WriteRowInfo(ARow: Cardinal; AData: TRow);
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single);
procedure WriteColInfo(ACol: Cardinal; AData: TCol); procedure WriteColInfo(ACol: Cardinal; AData: TCol);
procedure WriteColWidth(ACol: Cardinal; AWidth: Single); procedure WriteColWidth(ACol: Cardinal; AWidth: Single);
{ Properties } { Properties }
@ -1014,6 +1016,32 @@ begin
end; end;
end; end;
function TsWorksheet.GetFirstCellOfRow(ARow: Cardinal): PCell;
var
c, n: Cardinal;
begin
n := GetLastColNumber;
c := 0;
Result := FindCell(ARow, c);
while (result = nil) and (c < n) do begin
inc(c);
result := FindCell(ARow, c);
end;
end;
function TsWorksheet.GetLastCellOfRow(ARow: Cardinal): PCell;
var
c, n: Cardinal;
begin
n := GetLastColNumber;
c := n;
Result := FindCell(ARow, c);
while (Result = nil) and (c > 0) do begin
dec(c);
Result := FindCell(ARow, c);
end;
end;
{@@ {@@
Returns the 0-based number of the last row with a cell with contents. Returns the 0-based number of the last row with a cell with contents.
@ -1624,14 +1652,10 @@ end;
function TsWorksheet.GetRow(ARow: Cardinal): PRow; function TsWorksheet.GetRow(ARow: Cardinal): PRow;
begin begin
Result := FindRow(ARow); Result := FindRow(ARow);
if (Result = nil) then begin
if (Result = nil) then
begin
Result := GetMem(SizeOf(TRow)); Result := GetMem(SizeOf(TRow));
FillChar(Result^, SizeOf(TRow), #0); FillChar(Result^, SizeOf(TRow), #0);
Result^.Row := ARow; Result^.Row := ARow;
FRows.Add(Result); FRows.Add(Result);
end; end;
end; end;
@ -1639,14 +1663,10 @@ end;
function TsWorksheet.GetCol(ACol: Cardinal): PCol; function TsWorksheet.GetCol(ACol: Cardinal): PCol;
begin begin
Result := FindCol(ACol); Result := FindCol(ACol);
if (Result = nil) then begin
if (Result = nil) then
begin
Result := GetMem(SizeOf(TCol)); Result := GetMem(SizeOf(TCol));
FillChar(Result^, SizeOf(TCol), #0); FillChar(Result^, SizeOf(TCol), #0);
Result^.Col := ACol; Result^.Col := ACol;
FCols.Add(Result); FCols.Add(Result);
end; end;
end; end;
@ -1656,8 +1676,7 @@ var
Node: Pointer; Node: Pointer;
i: Integer; i: Integer;
begin begin
for i := FRows.Count-1 downto 0 do for i := FRows.Count-1 downto 0 do begin
begin
Node := FRows.Items[i]; Node := FRows.Items[i];
FreeMem(Node, SizeOf(TRow)); FreeMem(Node, SizeOf(TRow));
end; end;
@ -1669,8 +1688,7 @@ var
Node: Pointer; Node: Pointer;
i: Integer; i: Integer;
begin begin
for i := FCols.Count-1 downto 0 do for i := FCols.Count-1 downto 0 do begin
begin
Node := FCols.Items[i]; Node := FCols.Items[i];
FreeMem(Node, SizeOf(TCol)); FreeMem(Node, SizeOf(TCol));
end; end;
@ -1685,6 +1703,14 @@ begin
AElement^.Height := AData.Height; AElement^.Height := AData.Height;
end; end;
procedure TsWorksheet.WriteRowHeight(ARow: Cardinal; AHeight: Single);
var
AElement: PRow;
begin
AElement := GetRow(ARow);
AElement^.Height := AHeight;
end;
procedure TsWorksheet.WriteColInfo(ACol: Cardinal; AData: TCol); procedure TsWorksheet.WriteColInfo(ACol: Cardinal; AData: TCol);
var var
AElement: PCol; AElement: PCol;

View File

@ -876,7 +876,7 @@ begin
end; end;
for i := FHeaderCount to RowCount-1 do begin for i := FHeaderCount to RowCount-1 do begin
lRow := FWorksheet.FindRow(i - FHeaderCount); lRow := FWorksheet.FindRow(i - FHeaderCount);
if (lRow = nil) or lRow^.AutoHeight then if (lRow = nil) then
RowHeights[i] := CalcAutoRowHeight(i) RowHeights[i] := CalcAutoRowHeight(i)
else else
RowHeights[i] := CalcRowHeight(lRow^.Height); RowHeights[i] := CalcRowHeight(lRow^.Height);

View File

@ -535,7 +535,7 @@ begin
s := '$0005=WB globals, $0006=VB module, ' + s + ', $0100=Workspace'; s := '$0005=WB globals, $0006=VB module, ' + s + ', $0100=Workspace';
w := WordLEToN(w); w := WordLEToN(w);
if Row = FCurrRow then begin if Row = FCurrRow then begin
FDetails.Add('Type of data:'); FDetails.Add('Type of data:'#13);
FDetails.Add(Format('$%.4x = %s', [w, BofName(w)])); FDetails.Add(Format('$%.4x = %s', [w, BofName(w)]));
end; end;
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]),
@ -906,7 +906,6 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)), ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)),
'Index to first used row'); 'Index to first used row');
numBytes := 4;
Move(FBuffer[FBufferIndex], dw, numBytes); Move(FBuffer[FBufferIndex], dw, numBytes);
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)), ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)),
'Index to last used row, increased by 1'); 'Index to last used row, increased by 1');
@ -916,7 +915,6 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to first used row'); 'Index to first used row');
numBytes := 2;
Move(FBuffer[FBufferIndex], w, numBytes); Move(FBuffer[FBufferIndex], w, numBytes);
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to last used row, increased by 1'); 'Index to last used row, increased by 1');
@ -932,9 +930,11 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to last used column, increased by 1'); 'Index to last used column, increased by 1');
numBytes := 2; if FFormat <> sfExcel2 then begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, '', numBytes := 2;
'(not used)'); ShowInRow(FCurrRow, FBufferIndex, numBytes, '',
'(not used)');
end;
end; end;
@ -2714,7 +2714,17 @@ begin
numBytes := 2; numBytes := 2;
Move(FBuffer[FBufferIndex], w, numbytes); Move(FBuffer[FBufferIndex], w, numbytes);
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [WordLEToN(w)]), w := WordLEToN(w);
if Row = FCurrRow then begin
FDetails.Add('Row height:'#13);
FDetails.Add(Format('Bits 14-0 = %d: Row height in twips (1/20 pt) --> %.1f-pt',
[w and $7FFF, (w and $7FFF)/20.0])
);
if w and $8000 = 0
then FDetails.Add('Bit 15 = 0: Row has custom height')
else FDetails.Add('Bit 15 = 1: Row has default height');
end;
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]),
'Bits 14-0: Height of row in twips (1/20 pt), Bit 15: Row has default height'); 'Bits 14-0: Height of row in twips (1/20 pt), Bit 15: Row has default height');
numBytes := 2; numBytes := 2;

View File

@ -720,7 +720,6 @@ end;
procedure TMainForm.LoadFile(const AFileName: String); procedure TMainForm.LoadFile(const AFileName: String);
var var
fmt: TsSpreadsheetFormat;
valid: Boolean; valid: Boolean;
excptn: Exception = nil; excptn: Exception = nil;
begin begin
@ -735,19 +734,19 @@ begin
exit; exit;
end; end;
fmt := sfExcel8; FFormat := sfExcel8;
while True do begin while True do begin
try try
LoadFile(AFileName, fmt); LoadFile(AFileName, FFormat);
valid := True; valid := True;
except except
on E: Exception do begin on E: Exception do begin
if fmt = sfExcel8 then excptn := E; if FFormat = sfExcel8 then excptn := E;
valid := False valid := False
end; end;
end; end;
if valid or (fmt = sfExcel2) then Break; if valid or (FFormat = sfExcel2) then Break;
fmt := Pred(fmt); FFormat := Pred(FFormat);
end; end;
// A failed attempt to read a file should bring an exception, so re-raise // A failed attempt to read a file should bring an exception, so re-raise
@ -755,8 +754,6 @@ begin
// since this is the most common format // since this is the most common format
if (not valid) and (excptn <> nil) then if (not valid) and (excptn <> nil) then
raise excptn; raise excptn;
FFormat := fmt;
end; end;
@ -793,7 +790,9 @@ begin
FFileName := ExpandFileName(AFileName); FFileName := ExpandFileName(AFileName);
ReadFromStream(MemStream); ReadFromStream(MemStream);
FFormat := AFormat;
UpdateCaption; UpdateCaption;
FMRUMenuManager.AddToRecent(AFileName); FMRUMenuManager.AddToRecent(AFileName);
end; end;
@ -1062,9 +1061,9 @@ begin
while AStream.Position < AStream.Size do begin while AStream.Position < AStream.Size do begin
p := AStream.Position; p := AStream.Position;
recType := WordLEToN(AStream.ReadWord); recType := WordLEToN(AStream.ReadWord);
if recType = 0 then
break;
recSize := WordLEToN(AStream.ReadWord); recSize := WordLEToN(AStream.ReadWord);
if (recType = 0) and (recSize = 0) then
break;
s := RecTypeName(recType); s := RecTypeName(recType);
i := pos(':', s); i := pos(':', s);
// in case of BOF record: create new parent node for this substream // in case of BOF record: create new parent node for this substream

View File

@ -29,6 +29,7 @@ var
SollDateTimeFormatStrings: array[0..9] of String; SollDateTimeFormatStrings: array[0..9] of String;
SollColWidths: array[0..1] of Single; SollColWidths: array[0..1] of Single;
SollRowHeights: Array[0..2] of Single;
SollBorders: array[0..15] of TsCellBorders; SollBorders: array[0..15] of TsCellBorders;
SollBorderLineStyles: array[0..6] of TsLineStyle; SollBorderLineStyles: array[0..6] of TsLineStyle;
SollBorderColors: array[0..5] of TsColor; SollBorderColors: array[0..5] of TsColor;
@ -53,6 +54,8 @@ type
procedure TestWriteReadBorderStyles(AFormat: TsSpreadsheetFormat); procedure TestWriteReadBorderStyles(AFormat: TsSpreadsheetFormat);
// Test column widths // Test column widths
procedure TestWriteReadColWidths(AFormat: TsSpreadsheetFormat); procedure TestWriteReadColWidths(AFormat: TsSpreadsheetFormat);
// Test row heights
procedure TestWriteReadRowHeights(AFormat: TsSpreadsheetFormat);
// Test text rotation // Test text rotation
procedure TestWriteReadTextRotation(AFormat:TsSpreadsheetFormat); procedure TestWriteReadTextRotation(AFormat:TsSpreadsheetFormat);
// Test word wrapping // Test word wrapping
@ -70,6 +73,7 @@ type
procedure TestWriteReadBIFF2_Alignment; procedure TestWriteReadBIFF2_Alignment;
procedure TestWriteReadBIFF2_Border; procedure TestWriteReadBIFF2_Border;
procedure TestWriteReadBIFF2_ColWidths; procedure TestWriteReadBIFF2_ColWidths;
procedure TestWriteReadBIFF2_RowHeights;
procedure TestWriteReadBIFF2_DateTimeFormats; procedure TestWriteReadBIFF2_DateTimeFormats;
procedure TestWriteReadBIFF2_NumberFormats; procedure TestWriteReadBIFF2_NumberFormats;
// These features are not supported by Excel2 --> no test cases required! // These features are not supported by Excel2 --> no test cases required!
@ -82,6 +86,7 @@ type
procedure TestWriteReadBIFF5_Border; procedure TestWriteReadBIFF5_Border;
procedure TestWriteReadBIFF5_BorderStyles; procedure TestWriteReadBIFF5_BorderStyles;
procedure TestWriteReadBIFF5_ColWidths; procedure TestWriteReadBIFF5_ColWidths;
procedure TestWriteReadBIFF5_RowHeights;
procedure TestWriteReadBIFF5_DateTimeFormats; procedure TestWriteReadBIFF5_DateTimeFormats;
procedure TestWriteReadBIFF5_NumberFormats; procedure TestWriteReadBIFF5_NumberFormats;
procedure TestWriteReadBIFF5_TextRotation; procedure TestWriteReadBIFF5_TextRotation;
@ -92,6 +97,7 @@ type
procedure TestWriteReadBIFF8_Border; procedure TestWriteReadBIFF8_Border;
procedure TestWriteReadBIFF8_BorderStyles; procedure TestWriteReadBIFF8_BorderStyles;
procedure TestWriteReadBIFF8_ColWidths; procedure TestWriteReadBIFF8_ColWidths;
procedure TestWriteReadBIFF8_RowHeights;
procedure TestWriteReadBIFF8_DateTimeFormats; procedure TestWriteReadBIFF8_DateTimeFormats;
procedure TestWriteReadBIFF8_NumberFormats; procedure TestWriteReadBIFF8_NumberFormats;
procedure TestWriteReadBIFF8_TextRotation; procedure TestWriteReadBIFF8_TextRotation;
@ -101,12 +107,13 @@ type
implementation implementation
uses uses
TypInfo; TypInfo, fpsutils;
const const
FmtNumbersSheet = 'NumbersFormat'; //let's distinguish it from the regular numbers sheet FmtNumbersSheet = 'NumbersFormat'; //let's distinguish it from the regular numbers sheet
FmtDateTimesSheet = 'DateTimesFormat'; FmtDateTimesSheet = 'DateTimesFormat';
ColWidthSheet = 'ColWidths'; ColWidthSheet = 'ColWidths';
RowHeightSheet = 'RowHeights';
BordersSheet = 'CellBorders'; BordersSheet = 'CellBorders';
AlignmentSheet = 'TextAlignments'; AlignmentSheet = 'TextAlignments';
TextRotationSheet = 'TextRotation'; TextRotationSheet = 'TextRotation';
@ -189,6 +196,11 @@ begin
SollColWidths[0] := 20; // characters based on width of "0" SollColWidths[0] := 20; // characters based on width of "0"
SollColWidths[1] := 40; SollColWidths[1] := 40;
// Row heights
SollRowHeights[0] := 5;
SollRowHeights[1] := 10;
SollRowHeights[2] := 50;
// Cell borders // Cell borders
SollBorders[0] := []; SollBorders[0] := [];
SollBorders[1] := [cbEast]; SollBorders[1] := [cbEast];
@ -672,7 +684,8 @@ begin
if lpCol = nil then if lpCol = nil then
fail('Error in test code. Failed to return saved column width'); fail('Error in test code. Failed to return saved column width');
ActualColWidth := lpCol^.Width; ActualColWidth := lpCol^.Width;
CheckEquals(SollColWidths[Col], ActualColWidth, 'Test saved colwidth mismatch column '+ColNotation(MyWorkSheet,Col)); CheckEquals(SollColWidths[Col], ActualColWidth,
'Test saved colwidth mismatch, column '+ColNotation(MyWorkSheet,Col));
end; end;
// Finalization // Finalization
MyWorkbook.Free; MyWorkbook.Free;
@ -695,6 +708,68 @@ begin
TestWriteReadColWidths(sfExcel8); TestWriteReadColWidths(sfExcel8);
end; end;
procedure TSpreadWriteReadFormatTests.TestWriteReadRowHeights(AFormat: TsSpreadsheetFormat);
var
MyWorksheet: TsWorksheet;
MyWorkbook: TsWorkbook;
ActualRowHeight: Single;
Row: Integer;
lpRow: PRow;
TempFile: string; //write xls/xml to this file and read back from it
begin
TempFile:=GetTempFileName;
{// Not needed: use workbook.writetofile with overwrite=true
if fileexists(TempFile) then
DeleteFile(TempFile);
}
// Write out all test values
MyWorkbook := TsWorkbook.Create;
MyWorkSheet:= MyWorkBook.AddWorksheet(RowHeightSheet);
for Row := Low(SollRowHeights) to High(SollRowHeights) do
MyWorksheet.WriteRowHeight(Row, SollRowHeights[Row]);
MyWorkBook.WriteToFile(TempFile, AFormat, true);
MyWorkbook.Free;
// Open the spreadsheet, as biff8
MyWorkbook := TsWorkbook.Create;
MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet
else
MyWorksheet := GetWorksheetByName(MyWorkBook, RowHeightSheet);
if MyWorksheet=nil then
fail('Error in test code. Failed to get named worksheet');
for Row := Low(SollRowHeights) to High(SollRowHeights) do begin
lpRow := MyWorksheet.GetRow(Row);
if lpRow = nil then
fail('Error in test code. Failed to return saved row height');
// Rounding to twips in Excel would cause severe rounding error if we'd compare millimeters
// --> go back to twips
ActualRowHeight := MillimetersToTwips(lpRow^.Height);
CheckEquals(MillimetersToTwips(SollRowHeights[Row]), ActualRowHeight,
'Test saved row height mismatch, row '+RowNotation(MyWorkSheet,Row));
end;
// Finalization
MyWorkbook.Free;
DeleteFile(TempFile);
end;
procedure TSpreadWriteReadFormatTests.TestWriteReadBIFF2_RowHeights;
begin
TestWriteReadRowHeights(sfExcel2);
end;
procedure TSpreadWriteReadFormatTests.TestWriteReadBIFF5_RowHeights;
begin
TestWriteReadRowHeights(sfExcel5);
end;
procedure TSpreadWriteReadFormatTests.TestWriteReadBIFF8_RowHeights;
begin
TestWriteReadRowHeights(sfExcel8);
end;
procedure TSpreadWriteReadFormatTests.TestWriteReadTextRotation(AFormat: TsSpreadsheetFormat); procedure TSpreadWriteReadFormatTests.TestWriteReadTextRotation(AFormat: TsSpreadsheetFormat);
const const
col = 0; col = 0;

View File

@ -37,7 +37,6 @@
<CodeGeneration> <CodeGeneration>
<Checks> <Checks>
<IOChecks Value="True"/> <IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/> <OverflowChecks Value="True"/>
<StackChecks Value="True"/> <StackChecks Value="True"/>
</Checks> </Checks>

View File

@ -28,6 +28,9 @@ function CellNotation(WorkSheet: TsWorksheet; Row: integer; Column: integer=0):
// Returns an A notation of column based on sheet and column // Returns an A notation of column based on sheet and column
function ColNotation(WorkSheet: TsWorksheet; Column:Integer): String; function ColNotation(WorkSheet: TsWorksheet; Column:Integer): String;
// Returns a notation for row bassed on sheet and row
function RowNotation(Worksheet: TsWorksheet; Row: Integer): String;
// Note: using this function instead of GetWorkSheetByName for compatibility with // Note: using this function instead of GetWorkSheetByName for compatibility with
// older fpspreadsheet versions that don't have that function // older fpspreadsheet versions that don't have that function
function GetWorksheetByName(AWorkBook: TsWorkBook; AName: String): TsWorksheet; function GetWorksheetByName(AWorkBook: TsWorkBook; AName: String): TsWorksheet;
@ -97,5 +100,13 @@ begin
Result := WorkSheet.Name + '!' + ColumnToLetter(Column); Result := WorkSheet.Name + '!' + ColumnToLetter(Column);
end; end;
function RowNotation(Worksheet: TsWorksheet; Row: Integer): String;
begin
if not Assigned(Worksheet) then
Result := 'RowNotation: error getting worksheet.'
else
Result := Worksheet.Name + '!' + IntToStr(Row+1);
end;
end. end.

View File

@ -89,13 +89,15 @@ type
AddBackground: Boolean = false); AddBackground: Boolean = false);
procedure WriteXFFieldsForFormattingStyles(AStream: TStream); procedure WriteXFFieldsForFormattingStyles(AStream: TStream);
procedure WriteXFRecords(AStream: TStream); procedure WriteXFRecords(AStream: TStream);
procedure WriteWindow1(AStream: TStream); override;
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
protected protected
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; ACell: PCell); override; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; ACell: PCell); override;
procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Cardinal; const AFormula: TsRPNFormula; ACell: PCell); override; procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Cardinal; const AFormula: TsRPNFormula; ACell: PCell); override;
procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; const AValue: string; ACell: PCell); override; procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; const AValue: string; ACell: PCell); override;
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double; ACell: PCell); override; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double; ACell: PCell); override;
procedure WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); override;
procedure WriteWindow1(AStream: TStream); override;
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
public public
{ General writing methods } { General writing methods }
procedure WriteToStream(AStream: TStream); override; procedure WriteToStream(AStream: TStream); override;
@ -155,10 +157,9 @@ const
INT_EXCEL_ID_INTEGER = $0002; INT_EXCEL_ID_INTEGER = $0002;
INT_EXCEL_ID_NUMBER = $0003; INT_EXCEL_ID_NUMBER = $0003;
INT_EXCEL_ID_LABEL = $0004; INT_EXCEL_ID_LABEL = $0004;
INT_EXCEL_ID_FORMULA = $0006; INT_EXCEL_ID_ROW = $0008;
INT_EXCEL_ID_ROWINFO = $0008;
INT_EXCEL_ID_BOF = $0009; INT_EXCEL_ID_BOF = $0009;
INT_EXCEL_ID_EOF = $000A; INT_EXCEL_ID_INDEX = $000B;
INT_EXCEL_ID_FORMAT = $001E; INT_EXCEL_ID_FORMAT = $001E;
INT_EXCEL_ID_FORMATCOUNT= $001F; INT_EXCEL_ID_FORMATCOUNT= $001F;
INT_EXCEL_ID_COLWIDTH = $0024; INT_EXCEL_ID_COLWIDTH = $0024;
@ -427,7 +428,7 @@ begin
INT_EXCEL_ID_LABEL : ReadLabel(AStream); INT_EXCEL_ID_LABEL : ReadLabel(AStream);
INT_EXCEL_ID_FORMULA : ReadFormula(AStream); INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
INT_EXCEL_ID_COLWIDTH : ReadColWidth(AStream); INT_EXCEL_ID_COLWIDTH : ReadColWidth(AStream);
INT_EXCEL_ID_ROWINFO : ReadRowInfo(AStream); INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream); INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
INT_EXCEL_ID_PANE : ReadPane(AStream); INT_EXCEL_ID_PANE : ReadPane(AStream);
INT_EXCEL_ID_XF : ReadXF(AStream); INT_EXCEL_ID_XF : ReadXF(AStream);
@ -565,8 +566,7 @@ begin
lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex)); lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex));
// Row height is encoded into the 15 remaining bits in units "twips" (1/20 pt) // Row height is encoded into the 15 remaining bits in units "twips" (1/20 pt)
lRow^.Height := TwipsToMillimeters(h and $7FFF); lRow^.Height := TwipsToMillimeters(h and $7FFF);
end else end;
lRow^.AutoHeight := true;
end; end;
{ Reads the WINDOW2 record containing information like "show grid lines", { Reads the WINDOW2 record containing information like "show grid lines",
@ -828,6 +828,7 @@ begin
WriteFormats(AStream); WriteFormats(AStream);
WriteXFRecords(AStream); WriteXFRecords(AStream);
WriteColWidths(AStream); WriteColWidths(AStream);
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells); WriteCellsToStream(AStream, sheet.Cells);
WriteWindow1(AStream); WriteWindow1(AStream);
@ -1533,6 +1534,55 @@ begin
AStream.WriteBuffer(AValue, 8); AStream.WriteBuffer(AValue, 8);
end; end;
procedure TsSpreadBIFF2Writer.WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
var
containsXF: Boolean;
rowheight: Word;
w: Word;
begin
containsXF := false;
{ BIFF record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_ROW));
AStream.WriteWord(WordToLE(IfThen(containsXF, 18, 13)));
{ Index of row }
AStream.WriteWord(WordToLE(Word(ARowIndex)));
{ Index to column of the first cell which is described by a cell record }
AStream.WriteWord(WordToLE(Word(AFirstColIndex)));
{ Index to column of the last cell which is described by a cell record, increased by 1 }
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
{ Row height (in twips, 1/20 point) and info on custom row height }
if (ARow = nil) or (ARow^.Height = 0) then
rowheight := round(Workbook.GetFont(0).Size*20)
else
rowheight := MillimetersToTwips(ARow^.Height);
w := rowheight and $7FFF;
AStream.WriteWord(WordToLE(w));
{ not used }
AStream.WriteWord(0);
{ Contains row attribute field and XF index }
AStream.WriteByte(ord(containsXF));
{ Relative offset to calculate stream position of the first cell record for this row }
AStream.WriteWord(0);
if containsXF then begin
{ Default row attributes }
AStream.WriteByte(0);
AStream.WriteByte(0);
AStream.WriteByte(0);
{ Index to XF record }
AStream.WriteWord(WordToLE(15));
end;
end;
{******************************************************************* {*******************************************************************
* Initialization section * Initialization section

View File

@ -219,20 +219,7 @@ implementation
const const
{ Excel record IDs } { Excel record IDs }
INT_EXCEL_ID_BOF = $0809; // see: in xlscommon
INT_EXCEL_ID_BOUNDSHEET = $0085; // Renamed to SHEET in the latest OpenOffice docs
INT_EXCEL_ID_EOF = $000A;
INT_EXCEL_ID_DIMENSIONS = $0200;
INT_EXCEL_ID_FORMAT = $041E;
INT_EXCEL_ID_FORMULA = $0006;
INT_EXCEL_ID_INDEX = $020B;
INT_EXCEL_ID_ROWINFO = $0208;
INT_EXCEL_ID_STYLE = $0293;
INT_EXCEL_ID_WINDOW1 = $003D;
INT_EXCEL_ID_RSTRING = $00D6;
INT_EXCEL_ID_RK = $027E;
INT_EXCEL_ID_MULRK = $00BD;
INT_EXCEL_ID_CODEPAGE = xlscommon.INT_EXCEL_ID_CODEPAGE;
{ Cell Addresses constants } { Cell Addresses constants }
MASK_EXCEL_ROW = $3FFF; MASK_EXCEL_ROW = $3FFF;
@ -412,6 +399,7 @@ begin
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); // true for "is BIFF5 or BIFF8"
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells); WriteCellsToStream(AStream, sheet.Cells);
WriteEOF(AStream); WriteEOF(AStream);
end; end;
@ -1284,7 +1272,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_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_MULRK : ReadMulRKValues(AStream); INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream); INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
INT_EXCEL_ID_ROWINFO : ReadRowInfo(AStream); INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
INT_EXCEL_ID_FORMULA : ReadFormulaExcel(AStream); INT_EXCEL_ID_FORMULA : ReadFormulaExcel(AStream);
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream); INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
INT_EXCEL_ID_PANE : ReadPane(AStream); INT_EXCEL_ID_PANE : ReadPane(AStream);

View File

@ -217,23 +217,8 @@ implementation
const const
{ Excel record IDs } { Excel record IDs }
INT_EXCEL_ID_BOF = $0809;
INT_EXCEL_ID_BOUNDSHEET = $0085; // Renamed to SHEET in the latest OpenOffice docs
INT_EXCEL_ID_COUNTRY = $008C;
INT_EXCEL_ID_EOF = $000A;
INT_EXCEL_ID_DIMENSIONS = $0200;
INT_EXCEL_ID_FORMULA = $0006;
INT_EXCEL_ID_INDEX = $020B;
INT_EXCEL_ID_ROWINFO = $0208;
INT_EXCEL_ID_STYLE = $0293;
INT_EXCEL_ID_WINDOW2 = $023E;
INT_EXCEL_ID_RSTRING = $00D6;
INT_EXCEL_ID_RK = $027E;
INT_EXCEL_ID_MULRK = $00BD;
INT_EXCEL_ID_SST = $00FC; //BIFF8 only INT_EXCEL_ID_SST = $00FC; //BIFF8 only
INT_EXCEL_ID_CONTINUE = $003C;
INT_EXCEL_ID_LABELSST = $00FD; //BIFF8 only INT_EXCEL_ID_LABELSST = $00FD; //BIFF8 only
INT_EXCEL_ID_FORMAT = $041E;
INT_EXCEL_ID_FORCEFULLCALCULATION = $08A3; INT_EXCEL_ID_FORCEFULLCALCULATION = $08A3;
{ Cell Addresses constants } { Cell Addresses constants }
@ -447,6 +432,8 @@ end;
* *
*******************************************************************} *******************************************************************}
procedure TsSpreadBIFF8Writer.WriteToStream(AStream: TStream); procedure TsSpreadBIFF8Writer.WriteToStream(AStream: TStream);
const
isBIFF8 = true;
var var
MyData: TMemoryStream; MyData: TMemoryStream;
CurrentPos: Int64; CurrentPos: Int64;
@ -492,14 +479,17 @@ begin
WriteIndex(AStream); WriteIndex(AStream);
WriteColInfos(AStream, sheet); WriteColInfos(AStream, sheet);
WriteDimensions(AStream, sheet); WriteDimensions(AStream, sheet);
//WriteRowAndCellBlock(AStream, sheet);
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells); WriteCellsToStream(AStream, sheet.Cells);
WriteWindow2(AStream, sheet); WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, true); // true for "is BIFF5 or BIFF8" WritePane(AStream, sheet, isBIFF8);
WriteEOF(AStream); WriteEOF(AStream);
end; end;
{ Cleanup } { Cleanup }
SetLength(Boundsheets, 0); SetLength(Boundsheets, 0);
end; end;
@ -1535,7 +1525,7 @@ begin
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream); INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
INT_EXCEL_ID_LABELSST: ReadLabelSST(AStream); //BIFF8 only INT_EXCEL_ID_LABELSST: ReadLabelSST(AStream); //BIFF8 only
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream); INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
INT_EXCEL_ID_ROWINFO : ReadRowInfo(AStream); INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream); INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
INT_EXCEL_ID_PANE : ReadPane(AStream); INT_EXCEL_ID_PANE : ReadPane(AStream);
INT_EXCEL_ID_BOF : ; INT_EXCEL_ID_BOF : ;

View File

@ -16,21 +16,41 @@ uses
const const
{ RECORD IDs which didn't change across versions 2-8 } { RECORD IDs which didn't change across versions 2-8 }
INT_EXCEL_ID_EOF = $000A;
INT_EXCEL_ID_SELECTION = $001D; INT_EXCEL_ID_SELECTION = $001D;
INT_EXCEL_ID_FONT = $0031; INT_EXCEL_ID_CONTINUE = $003C;
INT_EXCEL_ID_PANE = $0041; INT_EXCEL_ID_PANE = $0041;
INT_EXCEL_ID_CODEPAGE = $0042; INT_EXCEL_ID_CODEPAGE = $0042;
INT_EXCEL_ID_COLINFO = $007D;
INT_EXCEL_ID_DATEMODE = $0022; INT_EXCEL_ID_DATEMODE = $0022;
INT_EXCEL_ID_PALETTE = $0092;
INT_EXCEL_ID_WINDOW1 = $003D; INT_EXCEL_ID_WINDOW1 = $003D;
INT_EXCEL_ID_XF = $00E0;
{ RECORD IDs which did not change across versions 2, 5, 8}
INT_EXCEL_ID_FORMULA = $0006; // BIFF3: $0206, BIFF4: $0406
INT_EXCEL_ID_FONT = $0031; // BIFF3-4: $0231
{ RECORD IDs which did not change across version 3-8}
INT_EXCEL_ID_COLINFO = $007D; // 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_DIMENSIONS = $0200; // BIFF2: $0000
INT_EXCEL_ID_BLANK = $0201; // BIFF2: $0001
INT_EXCEL_ID_NUMBER = $0203; // BIFF2: $0003
INT_EXCEL_ID_LABEL = $0204; // BIFF2: $0004
INT_EXCEL_ID_ROW = $0208; // BIFF2: $0008
INT_EXCEL_ID_INDEX = $020B; // BIFF2: $000B
INT_EXCEL_ID_WINDOW2 = $023E; // BIFF2: $003E
INT_EXCEL_ID_RK = $027E; // 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 }
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 }
INT_EXCEL_ID_BLANK = $0201; INT_EXCEL_ID_BOUNDSHEET = $0085; // Renamed to SHEET in the latest OpenOffice docs, does not exist before 5
INT_EXCEL_ID_NUMBER = $0203; INT_EXCEL_ID_MULRK = $00BD; // does not exist before BIFF5
INT_EXCEL_ID_LABEL = $0204; INT_EXCEL_ID_XF = $00E0; // BIFF2:$0043, BIFF3:$0243, BIFF4:$0443
INT_EXCEL_ID_WINDOW2 = $023E; INT_EXCEL_ID_RSTRING = $00D6; // does not exist before BIFF5
INT_EXCEL_ID_BOF = $0809; // BIFF2:$0009, BIFF3:$0209; BIFF4:$0409
{ FONT record constants } { FONT record constants }
INT_FONT_WEIGHT_NORMAL = $0190; INT_FONT_WEIGHT_NORMAL = $0190;
@ -408,6 +428,12 @@ type
// Write out BLANK cell record // Write out BLANK cell record
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
ACell: PCell); override; ACell: PCell); override;
{
procedure WriteCellBlock(AStream: TStream; ASheet: TsWorksheet;
AFirstRow, ALastRow: Cardinal);
}
// Write out used codepage for character encoding // Write out used codepage for character encoding
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding); procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
// Writes out column info(s) // Writes out column info(s)
@ -425,6 +451,11 @@ type
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);
// Writes out a ROW record
procedure WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); virtual;
// Write all ROW records for a sheet
procedure WriteRows(AStream: TStream; ASheet: TsWorksheet);
// 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);
@ -924,8 +955,8 @@ begin
lRow^.Height := TwipsToMillimeters(h and $7FFF); lRow^.Height := TwipsToMillimeters(h and $7FFF);
end else end else
lRow^.Height := 0; lRow^.Height := 0;
lRow^.AutoHeight := rowrec.Flags and $00000040 = 0; //lRow^.AutoHeight := rowrec.Flags and $00000040 = 0;
// If this bit is set row height does not change font height, i.e. has been // If this bit is set row height does not change with font height, i.e. has been
// changed manually. // changed manually.
end; end;
@ -1410,6 +1441,88 @@ begin
{ Not used (BIFF5-BIFF8 only, not written in BIFF2-BIFF4 } { Not used (BIFF5-BIFF8 only, not written in BIFF2-BIFF4 }
end; end;
{ Writes an Excel 3-8 ROW record
Valid for BIFF3-BIFF8 }
procedure TsSpreadBIFFWriter.WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
var
w: Word;
dw: DWord;
cell: PCell;
spaceabove, spacebelow: Boolean;
colindex: Cardinal;
rowheight: Word;
begin
// Check for additional space above/below row
spaceabove := false;
spacebelow := false;
colindex := AFirstColIndex;
while colindex <= ALastColIndex do begin
cell := ASheet.FindCell(ARowindex, colindex);
if (cell <> nil) and (uffBorder in cell^.UsedFormattingFields) then begin
if (cbNorth in cell^.Border) and (cell^.BorderStyles[cbNorth].LineStyle = lsThick)
then spaceabove := true;
if (cbSouth in cell^.Border) and (cell^.BorderStyles[cbSouth].LineStyle = lsThick)
then spacebelow := true;
end;
if spaceabove and spacebelow then break;
inc(colindex);
end;
{ BIFF record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_ROW));
AStream.WriteWord(WordToLE(16));
{ Index of row }
AStream.WriteWord(WordToLE(Word(ARowIndex)));
{ Index to column of the first cell which is described by a cell record }
AStream.WriteWord(WordToLE(Word(AFirstColIndex)));
{ Index to column of the last cell which is described by a cell record, increased by 1 }
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
{ Row height (in twips, 1/20 point) and info on custom row height }
if (ARow = nil) or (ARow^.Height = 0) then
rowheight := round(Workbook.GetFont(0).Size*20)
else
rowheight := MillimetersToTwips(ARow^.Height);
w := rowheight and $7FFF;
AStream.WriteWord(WordToLE(w));
{ 2 words not used }
AStream.WriteDWord(0);
{ Option flags }
dw := $00000100; // bit 8 is always 1
if spaceabove then dw := dw or $10000000;
if spacebelow then dw := dw or $20000000;
if (ARow <> nil) then
dw := dw or $00000040; // Row height and font height do not match
AStream.WriteDWord(DWordToLE(dw));
end;
{ Writes all ROW records for the given sheet.
Note that the OpenOffice documentation says that rows must be written in
groups of 32, followed by the cells on these rows, etc. THIS IS NOT NECESSARY!
Valid for BIFF2-BIFF8 }
procedure TsSpreadBIFFWriter.WriteRows(AStream: TStream; ASheet: TsWorksheet);
var
row: PRow;
i: Integer;
cell1, cell2: PCell;
begin
for i := 0 to ASheet.Rows.Count-1 do begin
row := ASheet.Rows[i];
cell1 := ASheet.GetFirstCellOfRow(row^.Row);
if cell1 <> nil then begin
cell2 := ASheet.GetLastCellOfRow(row^.Row);
WriteRow(AStream, ASheet, row^.Row, cell1^.Col, cell2^.Col, row);
end else
WriteRow(AStream, ASheet, row^.Row, 0, 0, row);
end;
end;
{ Writes an Excel 2-8 SELECTION record { Writes an Excel 2-8 SELECTION record
Writes just reasonable default values Writes just reasonable default values
APane is 0..3 (see below) APane is 0..3 (see below)
@ -1420,19 +1533,19 @@ var
activeCellRow, activeCellCol: Word; activeCellRow, activeCellCol: Word;
begin begin
case APane of case APane of
0: begin // right-bottom 0: begin // right-bottom
activeCellRow := ASheet.TopPaneHeight; activeCellRow := ASheet.TopPaneHeight;
activeCellCol := ASheet.LeftPaneWidth; activeCellCol := ASheet.LeftPaneWidth;
end; end;
1: begin // right-top 1: begin // right-top
activeCellRow := 0; activeCellRow := 0;
activeCellCol := ASheet.LeftPaneWidth; activeCellCol := ASheet.LeftPaneWidth;
end; end;
2: begin // left-bottom 2: begin // left-bottom
activeCellRow := ASheet.TopPaneHeight; activeCellRow := ASheet.TopPaneHeight;
activeCellCol := 0; activeCellCol := 0;
end; end;
3: begin // left-top 3: begin // left-top
activeCellRow := 0; activeCellRow := 0;
activeCellCol := 0; activeCellCol := 0;
end; end;