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(1, 30);
MyWorksheet.WriteRowHeight(0, 30); // 30 mm
// Turn off grid lines and hide headers
MyWorksheet.Options := MyWorksheet.Options - [soShowGridLines, soShowHeaders];

View File

@ -43,6 +43,14 @@ begin
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
MyWorksheet.WriteNumber(0, 0, 1.0);// A1
MyWorksheet.WriteVertAlignment(0, 0, vaCenter);

View File

@ -46,7 +46,7 @@ begin
myWorksheet.LeftPaneWidth := 1;
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
}
@ -122,15 +122,16 @@ begin
MyWorksheet.WriteFont(8, 3, 'Courier New', 12, [fssUnderline], scBlue);
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
MyWorksheet.WriteAnsiText(i, 0, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 1, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 2, ParamStr(0));
MyWorksheet.WriteAnsiText(i, 3, ParamStr(0));
// MyWorksheet.WriteUTF8Text(i, 0, ParamStr(0));
// MyWorksheet.WriteUTF8Text(i, 1, ParamStr(0));
// MyWorksheet.WriteUTF8Text(i, 2, ParamStr(0));
MyWorksheet.WriteUTF8Text(i, 3, ParamStr(0));
end;
}
// Write the formula E1 = A1 + B1
SetLength(MyRPNFormula, 3);
@ -209,17 +210,15 @@ begin
MyWorksheet.WriteUTF8Text(37, 0, 'nfTimeInterval');
MyWorksheet.WriteDateTime(37, 1, number, nfTimeInterval);
// Set width of columns 1 and 5
lCol.Width := 30;
// Set width of columns 0, 1 and 5
MyWorksheet.WriteColWidth(0, 25);
lCol.Width := 20;
MyWorksheet.WriteColInfo(1, lCol);
lCol.Width := 5;
MyWorksheet.WriteColInfo(5, lCol);
// Set height of rows 5 and 6
lRow.Height := 10;
MyWorksheet.WriteRowInfo(5, lRow);
lRow.Height := 5;
MyWorksheet.WriteRowInfo(6, lRow);
// Set height of rows 0
MyWorksheet.WriteRowHeight(0, 30); // 30 mm
// Creates a new worksheet
MyWorksheet := MyWorkbook.AddWorksheet(Str_Worksheet2);

View File

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

View File

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

View File

@ -2,37 +2,38 @@
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'
+'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
+#10'LCLVersion'#6#3'1.3'#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'F'#3
+'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
+'btnPopulateGrid'#4'Left'#3#144#1#6'Height'#2#25#3'Top'#2#13#5'Width'#2'p'#7
+#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'
+#12'ClientHeight'#2'I'#11'ClientWidth'#3#6#2#8'TabOrder'#2#0#0#7'TButton'#15
+'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'
+'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
+#0#0#9'TCheckBox'#15'CbShowGridLines'#4'Left'#2#8#6'Height'#2#19#3'Top'#2#29
+#5'Width'#2'd'#7'Caption'#6#15'Show grid lines'#7'Checked'#9#7'OnClick'#7#20
+#0#0#9'TCheckBox'#15'CbShowGridLines'#4'Left'#2#8#6'Height'#2#24#3'Top'#2'$'
+#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'
+'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'
+'FrozenRows'#4'Left'#3#208#0#6'Height'#2#23#3'Top'#2'$'#5'Width'#2'4'#8'OnCh'
+'ange'#7#18'EdFrozenRowsChange'#8'TabOrder'#2#4#0#0#6'TLabel'#6'Label1'#4'Le'
+'ft'#3#135#0#6'Height'#2#15#3'Top'#2#13#5'Width'#2'>'#7'Caption'#6#12'Frozen'
+' 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'
+'on'#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'
+#2#26#5'Width'#3#6#2#10'ActivePage'#7#9'TabSheet1'#5'Align'#7#8'alClient'#8
+'TabIndex'#2#0#8'TabOrder'#2#1#8'OnChange'#7#18'PageControl1Change'#0#9'TTab'
+'Sheet'#9'TabSheet1'#7'Caption'#6#6'Sheet1'#12'ClientHeight'#3#242#0#11'Clie'
+'ntWidth'#3#254#1#0#15'TsWorksheetGrid'#15'sWorksheetGrid1'#4'Left'#2#0#6'He'
+'ight'#3#242#0#3'Top'#2#0#5'Width'#3#254#1#5'Align'#7#8'alClient'#7'Options'
+#11#15'goFixedVertLine'#15'goFixedHorzLine'#10'goVertLine'#10'goHorzLine'#13
+'goRangeSelect'#11'goRowSizing'#11'goColSizing'#15'goThumbTracking'#14'goSmo'
+'othScroll'#16'goFixedColSizing'#0#8'TabOrder'#2#0#10'TitleStyle'#7#8'tsNati'
+'ve'#0#0#0#0#8'TToolBar'#8'ToolBar1'#4'Left'#2#0#6'Height'#2#26#3'Top'#2#0#5
+'FrozenRows'#4'Left'#3#238#0#6'Height'#2#28#3'Top'#2''''#5'Width'#2'4'#8'OnC'
+'hange'#7#18'EdFrozenRowsChange'#8'TabOrder'#2#4#0#0#6'TLabel'#6'Label1'#4'L'
+'eft'#3#152#0#6'Height'#2#20#3'Top'#2#13#5'Width'#2'M'#7'Caption'#6#12'Froze'
+'n cols:'#12'FocusControl'#7#12'EdFrozenCols'#11'ParentColor'#8#0#0#6'TLabel'
+#6'Label2'#4'Left'#3#153#0#6'Height'#2#20#3'Top'#2'('#5'Width'#2'R'#7'Captio'
+'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#6#1#3'Top'#2
+#26#5'Width'#3#6#2#10'ActivePage'#7#9'TabSheet1'#5'Align'#7#8'alClient'#8'Ta'
+'bIndex'#2#0#8'TabOrder'#2#1#8'OnChange'#7#18'PageControl1Change'#0#9'TTabSh'
+'eet'#9'TabSheet1'#7'Caption'#6#6'Sheet1'#12'ClientHeight'#3#229#0#11'Client'
+'Width'#3#254#1#0#15'TsWorksheetGrid'#15'sWorksheetGrid1'#4'Left'#2#0#6'Heig'
+'ht'#3#229#0#3'Top'#2#0#5'Width'#3#254#1#5'Align'#7#8'alClient'#8'ColCount'#2
+#2#14'ExtendedSelect'#8#7'Options'#11#15'goFixedVertLine'#15'goFixedHorzLine'
+#10'goVertLine'#10'goHorzLine'#13'goRangeSelect'#11'goRowSizing'#11'goColSiz'
+'ing'#15'goThumbTracking'#14'goSmoothScroll'#16'goFixedColSizing'#0#8'RowCou'
+'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'
+#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
@ -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
+#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
+#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
,#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
+#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
+#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
+#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'
+#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#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#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
+#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'
+#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
+#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
,#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
+#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#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#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
+#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
,#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
+#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'
+#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#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
+#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
,#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
+#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
+#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
Row: Cardinal;
Height: Single; // in millimeters
AutoHeight: Boolean; // true: height corresponds to font; false: use Height
end;
PRow = ^TRow;
@ -337,6 +336,8 @@ type
function GetCellCount: Cardinal;
function GetFirstCell(): PCell;
function GetNextCell(): PCell;
function GetFirstCellOfRow(ARow: Cardinal): PCell;
function GetLastCellOfRow(ARow: Cardinal): PCell;
function GetLastColNumber: Cardinal;
function GetLastRowNumber: Cardinal;
function ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring;
@ -385,6 +386,7 @@ type
procedure RemoveAllRows;
procedure RemoveAllCols;
procedure WriteRowInfo(ARow: Cardinal; AData: TRow);
procedure WriteRowHeight(ARow: Cardinal; AHeight: Single);
procedure WriteColInfo(ACol: Cardinal; AData: TCol);
procedure WriteColWidth(ACol: Cardinal; AWidth: Single);
{ Properties }
@ -1014,6 +1016,32 @@ begin
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.
@ -1624,14 +1652,10 @@ end;
function TsWorksheet.GetRow(ARow: Cardinal): PRow;
begin
Result := FindRow(ARow);
if (Result = nil) then
begin
if (Result = nil) then begin
Result := GetMem(SizeOf(TRow));
FillChar(Result^, SizeOf(TRow), #0);
Result^.Row := ARow;
FRows.Add(Result);
end;
end;
@ -1639,14 +1663,10 @@ end;
function TsWorksheet.GetCol(ACol: Cardinal): PCol;
begin
Result := FindCol(ACol);
if (Result = nil) then
begin
if (Result = nil) then begin
Result := GetMem(SizeOf(TCol));
FillChar(Result^, SizeOf(TCol), #0);
Result^.Col := ACol;
FCols.Add(Result);
end;
end;
@ -1656,8 +1676,7 @@ var
Node: Pointer;
i: Integer;
begin
for i := FRows.Count-1 downto 0 do
begin
for i := FRows.Count-1 downto 0 do begin
Node := FRows.Items[i];
FreeMem(Node, SizeOf(TRow));
end;
@ -1669,8 +1688,7 @@ var
Node: Pointer;
i: Integer;
begin
for i := FCols.Count-1 downto 0 do
begin
for i := FCols.Count-1 downto 0 do begin
Node := FCols.Items[i];
FreeMem(Node, SizeOf(TCol));
end;
@ -1685,6 +1703,14 @@ begin
AElement^.Height := AData.Height;
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);
var
AElement: PCol;

View File

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

View File

@ -535,7 +535,7 @@ begin
s := '$0005=WB globals, $0006=VB module, ' + s + ', $0100=Workspace';
w := WordLEToN(w);
if Row = FCurrRow then begin
FDetails.Add('Type of data:');
FDetails.Add('Type of data:'#13);
FDetails.Add(Format('$%.4x = %s', [w, BofName(w)]));
end;
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]),
@ -906,7 +906,6 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)),
'Index to first used row');
numBytes := 4;
Move(FBuffer[FBufferIndex], dw, numBytes);
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)),
'Index to last used row, increased by 1');
@ -916,7 +915,6 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to first used row');
numBytes := 2;
Move(FBuffer[FBufferIndex], w, numBytes);
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to last used row, increased by 1');
@ -932,10 +930,12 @@ begin
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
'Index to last used column, increased by 1');
if FFormat <> sfExcel2 then begin
numBytes := 2;
ShowInRow(FCurrRow, FBufferIndex, numBytes, '',
'(not used)');
end;
end;
procedure TBIFFGrid.ShowDSF;
@ -2714,7 +2714,17 @@ begin
numBytes := 2;
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');
numBytes := 2;

View File

@ -720,7 +720,6 @@ end;
procedure TMainForm.LoadFile(const AFileName: String);
var
fmt: TsSpreadsheetFormat;
valid: Boolean;
excptn: Exception = nil;
begin
@ -735,19 +734,19 @@ begin
exit;
end;
fmt := sfExcel8;
FFormat := sfExcel8;
while True do begin
try
LoadFile(AFileName, fmt);
LoadFile(AFileName, FFormat);
valid := True;
except
on E: Exception do begin
if fmt = sfExcel8 then excptn := E;
if FFormat = sfExcel8 then excptn := E;
valid := False
end;
end;
if valid or (fmt = sfExcel2) then Break;
fmt := Pred(fmt);
if valid or (FFormat = sfExcel2) then Break;
FFormat := Pred(FFormat);
end;
// 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
if (not valid) and (excptn <> nil) then
raise excptn;
FFormat := fmt;
end;
@ -793,7 +790,9 @@ begin
FFileName := ExpandFileName(AFileName);
ReadFromStream(MemStream);
FFormat := AFormat;
UpdateCaption;
FMRUMenuManager.AddToRecent(AFileName);
end;
@ -1062,9 +1061,9 @@ begin
while AStream.Position < AStream.Size do begin
p := AStream.Position;
recType := WordLEToN(AStream.ReadWord);
if recType = 0 then
break;
recSize := WordLEToN(AStream.ReadWord);
if (recType = 0) and (recSize = 0) then
break;
s := RecTypeName(recType);
i := pos(':', s);
// 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;
SollColWidths: array[0..1] of Single;
SollRowHeights: Array[0..2] of Single;
SollBorders: array[0..15] of TsCellBorders;
SollBorderLineStyles: array[0..6] of TsLineStyle;
SollBorderColors: array[0..5] of TsColor;
@ -53,6 +54,8 @@ type
procedure TestWriteReadBorderStyles(AFormat: TsSpreadsheetFormat);
// Test column widths
procedure TestWriteReadColWidths(AFormat: TsSpreadsheetFormat);
// Test row heights
procedure TestWriteReadRowHeights(AFormat: TsSpreadsheetFormat);
// Test text rotation
procedure TestWriteReadTextRotation(AFormat:TsSpreadsheetFormat);
// Test word wrapping
@ -70,6 +73,7 @@ type
procedure TestWriteReadBIFF2_Alignment;
procedure TestWriteReadBIFF2_Border;
procedure TestWriteReadBIFF2_ColWidths;
procedure TestWriteReadBIFF2_RowHeights;
procedure TestWriteReadBIFF2_DateTimeFormats;
procedure TestWriteReadBIFF2_NumberFormats;
// These features are not supported by Excel2 --> no test cases required!
@ -82,6 +86,7 @@ type
procedure TestWriteReadBIFF5_Border;
procedure TestWriteReadBIFF5_BorderStyles;
procedure TestWriteReadBIFF5_ColWidths;
procedure TestWriteReadBIFF5_RowHeights;
procedure TestWriteReadBIFF5_DateTimeFormats;
procedure TestWriteReadBIFF5_NumberFormats;
procedure TestWriteReadBIFF5_TextRotation;
@ -92,6 +97,7 @@ type
procedure TestWriteReadBIFF8_Border;
procedure TestWriteReadBIFF8_BorderStyles;
procedure TestWriteReadBIFF8_ColWidths;
procedure TestWriteReadBIFF8_RowHeights;
procedure TestWriteReadBIFF8_DateTimeFormats;
procedure TestWriteReadBIFF8_NumberFormats;
procedure TestWriteReadBIFF8_TextRotation;
@ -101,12 +107,13 @@ type
implementation
uses
TypInfo;
TypInfo, fpsutils;
const
FmtNumbersSheet = 'NumbersFormat'; //let's distinguish it from the regular numbers sheet
FmtDateTimesSheet = 'DateTimesFormat';
ColWidthSheet = 'ColWidths';
RowHeightSheet = 'RowHeights';
BordersSheet = 'CellBorders';
AlignmentSheet = 'TextAlignments';
TextRotationSheet = 'TextRotation';
@ -189,6 +196,11 @@ begin
SollColWidths[0] := 20; // characters based on width of "0"
SollColWidths[1] := 40;
// Row heights
SollRowHeights[0] := 5;
SollRowHeights[1] := 10;
SollRowHeights[2] := 50;
// Cell borders
SollBorders[0] := [];
SollBorders[1] := [cbEast];
@ -672,7 +684,8 @@ begin
if lpCol = nil then
fail('Error in test code. Failed to return saved column 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;
// Finalization
MyWorkbook.Free;
@ -695,6 +708,68 @@ begin
TestWriteReadColWidths(sfExcel8);
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);
const
col = 0;

View File

@ -37,7 +37,6 @@
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</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
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
// older fpspreadsheet versions that don't have that function
function GetWorksheetByName(AWorkBook: TsWorkBook; AName: String): TsWorksheet;
@ -97,5 +100,13 @@ begin
Result := WorkSheet.Name + '!' + ColumnToLetter(Column);
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.

View File

@ -89,13 +89,15 @@ type
AddBackground: Boolean = false);
procedure WriteXFFieldsForFormattingStyles(AStream: TStream);
procedure WriteXFRecords(AStream: TStream);
procedure WriteWindow1(AStream: TStream); override;
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
protected
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 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 WriteRow(AStream: TStream; ASheet: TsWorksheet;
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); override;
procedure WriteWindow1(AStream: TStream); override;
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
public
{ General writing methods }
procedure WriteToStream(AStream: TStream); override;
@ -155,10 +157,9 @@ const
INT_EXCEL_ID_INTEGER = $0002;
INT_EXCEL_ID_NUMBER = $0003;
INT_EXCEL_ID_LABEL = $0004;
INT_EXCEL_ID_FORMULA = $0006;
INT_EXCEL_ID_ROWINFO = $0008;
INT_EXCEL_ID_ROW = $0008;
INT_EXCEL_ID_BOF = $0009;
INT_EXCEL_ID_EOF = $000A;
INT_EXCEL_ID_INDEX = $000B;
INT_EXCEL_ID_FORMAT = $001E;
INT_EXCEL_ID_FORMATCOUNT= $001F;
INT_EXCEL_ID_COLWIDTH = $0024;
@ -427,7 +428,7 @@ begin
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
INT_EXCEL_ID_FORMULA : ReadFormula(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_PANE : ReadPane(AStream);
INT_EXCEL_ID_XF : ReadXF(AStream);
@ -565,8 +566,7 @@ begin
lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex));
// Row height is encoded into the 15 remaining bits in units "twips" (1/20 pt)
lRow^.Height := TwipsToMillimeters(h and $7FFF);
end else
lRow^.AutoHeight := true;
end;
end;
{ Reads the WINDOW2 record containing information like "show grid lines",
@ -828,6 +828,7 @@ begin
WriteFormats(AStream);
WriteXFRecords(AStream);
WriteColWidths(AStream);
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells);
WriteWindow1(AStream);
@ -1533,6 +1534,55 @@ begin
AStream.WriteBuffer(AValue, 8);
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

View File

@ -219,20 +219,7 @@ implementation
const
{ Excel record IDs }
INT_EXCEL_ID_BOF = $0809;
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;
// see: in xlscommon
{ Cell Addresses constants }
MASK_EXCEL_ROW = $3FFF;
@ -412,6 +399,7 @@ begin
WriteDimensions(AStream, sheet);
WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, true); // true for "is BIFF5 or BIFF8"
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells);
WriteEOF(AStream);
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_MULRK : ReadMulRKValues(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_WINDOW2 : ReadWindow2(AStream);
INT_EXCEL_ID_PANE : ReadPane(AStream);

View File

@ -217,23 +217,8 @@ implementation
const
{ 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_CONTINUE = $003C;
INT_EXCEL_ID_LABELSST = $00FD; //BIFF8 only
INT_EXCEL_ID_FORMAT = $041E;
INT_EXCEL_ID_FORCEFULLCALCULATION = $08A3;
{ Cell Addresses constants }
@ -447,6 +432,8 @@ end;
*
*******************************************************************}
procedure TsSpreadBIFF8Writer.WriteToStream(AStream: TStream);
const
isBIFF8 = true;
var
MyData: TMemoryStream;
CurrentPos: Int64;
@ -492,14 +479,17 @@ begin
WriteIndex(AStream);
WriteColInfos(AStream, sheet);
WriteDimensions(AStream, sheet);
//WriteRowAndCellBlock(AStream, sheet);
WriteRows(AStream, sheet);
WriteCellsToStream(AStream, sheet.Cells);
WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, true); // true for "is BIFF5 or BIFF8"
WritePane(AStream, sheet, isBIFF8);
WriteEOF(AStream);
end;
{ Cleanup }
SetLength(Boundsheets, 0);
end;
@ -1535,7 +1525,7 @@ begin
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
INT_EXCEL_ID_LABELSST: ReadLabelSST(AStream); //BIFF8 only
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_PANE : ReadPane(AStream);
INT_EXCEL_ID_BOF : ;

View File

@ -16,21 +16,41 @@ uses
const
{ RECORD IDs which didn't change across versions 2-8 }
INT_EXCEL_ID_EOF = $000A;
INT_EXCEL_ID_SELECTION = $001D;
INT_EXCEL_ID_FONT = $0031;
INT_EXCEL_ID_CONTINUE = $003C;
INT_EXCEL_ID_PANE = $0041;
INT_EXCEL_ID_CODEPAGE = $0042;
INT_EXCEL_ID_COLINFO = $007D;
INT_EXCEL_ID_DATEMODE = $0022;
INT_EXCEL_ID_PALETTE = $0092;
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 }
INT_EXCEL_ID_BLANK = $0201;
INT_EXCEL_ID_NUMBER = $0203;
INT_EXCEL_ID_LABEL = $0204;
INT_EXCEL_ID_WINDOW2 = $023E;
INT_EXCEL_ID_BOUNDSHEET = $0085; // Renamed to SHEET in the latest OpenOffice docs, does not exist before 5
INT_EXCEL_ID_MULRK = $00BD; // does not exist before BIFF5
INT_EXCEL_ID_XF = $00E0; // BIFF2:$0043, BIFF3:$0243, BIFF4:$0443
INT_EXCEL_ID_RSTRING = $00D6; // does not exist before BIFF5
INT_EXCEL_ID_BOF = $0809; // BIFF2:$0009, BIFF3:$0209; BIFF4:$0409
{ FONT record constants }
INT_FONT_WEIGHT_NORMAL = $0190;
@ -408,6 +428,12 @@ type
// Write out BLANK cell record
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
ACell: PCell); override;
{
procedure WriteCellBlock(AStream: TStream; ASheet: TsWorksheet;
AFirstRow, ALastRow: Cardinal);
}
// Write out used codepage for character encoding
procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding);
// Writes out column info(s)
@ -425,6 +451,11 @@ type
procedure WritePalette(AStream: TStream);
// Writes out a PANE record
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
procedure WriteSelection(AStream: TStream; ASheet: TsWorksheet; APane: Byte);
procedure WriteSelections(AStream: TStream; ASheet: TsWorksheet);
@ -924,8 +955,8 @@ begin
lRow^.Height := TwipsToMillimeters(h and $7FFF);
end else
lRow^.Height := 0;
lRow^.AutoHeight := rowrec.Flags and $00000040 = 0;
// If this bit is set row height does not change font height, i.e. has been
//lRow^.AutoHeight := rowrec.Flags and $00000040 = 0;
// If this bit is set row height does not change with font height, i.e. has been
// changed manually.
end;
@ -1410,6 +1441,88 @@ begin
{ Not used (BIFF5-BIFF8 only, not written in BIFF2-BIFF4 }
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 just reasonable default values
APane is 0..3 (see below)