Adds a initial implementation of border support in FPSpreadsheet

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1641 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat 2011-05-25 13:40:53 +00:00
parent 1d5b1799c9
commit 038d224034
4 changed files with 316 additions and 31 deletions

View File

@ -0,0 +1,178 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<UseDefaultCompilerOptions Value="True"/>
</Flags>
<MainUnit Value="0"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1" Active="Default">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="laz_fpspreadsheet"/>
</Item1>
</RequiredPackages>
<Units Count="4">
<Unit0>
<Filename Value="excel8write_format.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="excel8write_format"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="31"/>
<CursorPos X="12" Y="44"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
<Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="93"/>
<CursorPos X="1" Y="105"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\..\..\..\..\lazarus29\fpc\2.4.3\source\packages\fcl-image\src\fpimage.pp"/>
<UnitName Value="FPimage"/>
<EditorIndex Value="3"/>
<WindowIndex Value="0"/>
<TopLine Value="10"/>
<CursorPos X="3" Y="30"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\..\xlsbiff8.pas"/>
<UnitName Value="xlsbiff8"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="758"/>
<CursorPos X="61" Y="766"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit3>
</Units>
<JumpHistory Count="18" HistoryIndex="17">
<Position1>
<Filename Value="excel8write_format.pas"/>
<Caret Line="29" Column="1" TopLine="9"/>
</Position1>
<Position2>
<Filename Value="excel8write_format.pas"/>
<Caret Line="35" Column="23" TopLine="20"/>
</Position2>
<Position3>
<Filename Value="excel8write_format.pas"/>
<Caret Line="15" Column="25" TopLine="2"/>
</Position3>
<Position4>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="160" Column="78" TopLine="146"/>
</Position4>
<Position5>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="122" Column="25" TopLine="116"/>
</Position5>
<Position6>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="132" Column="25" TopLine="114"/>
</Position6>
<Position7>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="131" Column="10" TopLine="106"/>
</Position7>
<Position8>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="132" Column="24" TopLine="112"/>
</Position8>
<Position9>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="17" Column="35" TopLine="3"/>
</Position9>
<Position10>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="132" Column="25" TopLine="111"/>
</Position10>
<Position11>
<Filename Value="excel8write_format.pas"/>
<Caret Line="15" Column="25" TopLine="5"/>
</Position11>
<Position12>
<Filename Value="excel8write_format.pas"/>
<Caret Line="47" Column="25" TopLine="33"/>
</Position12>
<Position13>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="941" Column="11" TopLine="926"/>
</Position13>
<Position14>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="125" Column="17" TopLine="116"/>
</Position14>
<Position15>
<Filename Value="..\..\xlsbiff8.pas"/>
<Caret Line="933" Column="61" TopLine="924"/>
</Position15>
<Position16>
<Filename Value="excel8write_format.pas"/>
<Caret Line="57" Column="29" TopLine="36"/>
</Position16>
<Position17>
<Filename Value="excel8write_format.pas"/>
<Caret Line="28" Column="54" TopLine="14"/>
</Position17>
<Position18>
<Filename Value="excel8write_format.pas"/>
<Caret Line="41" Column="14" TopLine="28"/>
</Position18>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
<Version Value="10"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="excel8write_format"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Other>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,64 @@
{
excel8write.dpr
Demonstrates how to write an Excel 8+ file using the fpspreadsheet library
Adds formatting to the file
AUTHORS: Felipe Monteiro de Carvalho
}
program excel8write_format;
{$mode delphi}{$H+}
uses
Classes, SysUtils, fpspreadsheet, xlsbiff8,
laz_fpspreadsheet, fpsconvencoding;
var
MyWorkbook: TsWorkbook;
MyWorksheet: TsWorksheet;
MyDir: string;
MyCell: PCell;
begin
MyDir := ExtractFilePath(ParamStr(0));
// Create the spreadsheet
MyWorkbook := TsWorkbook.Create;
MyWorksheet := MyWorkbook.AddWorksheet('Worksheet1');
// Write some cells
MyWorksheet.WriteUTF8Text(1, 0, 'Border');// A2
MyWorksheet.WriteUTF8Text(1, 1, '[]'); // B2
MyWorksheet.WriteUTF8Text(1, 2, '[North]');// C2
MyWorksheet.WriteUTF8Text(1, 3, '[West]');// D2
MyWorksheet.WriteUTF8Text(1, 4, '[East]');// E2
MyWorksheet.WriteUTF8Text(1, 5, '[South]');// F2
// Format them
MyCell := MyWorksheet.GetCell(1, 1);
MyCell^.Border := [];
MyCell^.UsedFormattingFields := [uffBorder];
MyCell := MyWorksheet.GetCell(1, 2);
MyCell^.Border := [cbNorth];
MyCell^.UsedFormattingFields := [uffBorder];
MyCell := MyWorksheet.GetCell(1, 3);
MyCell^.Border := [cbWest];
MyCell^.UsedFormattingFields := [uffBorder];
MyCell := MyWorksheet.GetCell(1, 4);
MyCell^.Border := [cbEast];
MyCell^.UsedFormattingFields := [uffBorder];
MyCell := MyWorksheet.GetCell(1, 5);
MyCell^.Border := [cbSouth];
MyCell^.UsedFormattingFields := [uffBorder];
// Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test3.xls', sfExcel8, False);
MyWorkbook.Free;
end.

View File

@ -88,17 +88,29 @@ type
{@@ List of possible formatting fields } {@@ List of possible formatting fields }
TsUsedFormattingField = (uffTextRotation, uffBold); TsUsedFormattingField = (uffTextRotation, uffBold, uffBorder{, uffBackgroundColor});
{@@ Describes which formatting fields are active } {@@ Describes which formatting fields are active }
TsUsedFormattingFields = set of TsUsedFormattingField; TsUsedFormattingFields = set of TsUsedFormattingField;
{@@ Text rotation formatting} {@@ Text rotation formatting }
TsTextRotation = (trHorizontal, rt90DegreeClockwiseRotation, TsTextRotation = (trHorizontal, rt90DegreeClockwiseRotation,
rt90DegreeCounterClockwiseRotation); rt90DegreeCounterClockwiseRotation);
{@@ Indicates the border for a cell }
TsCellBorder = (cbNorth, cbWest, cbEast, cbSouth);
{@@ Indicates the border for a cell }
TsCellBorders = set of TsCellBorder;
{.@@ Colors in FPSpreadsheet as given by a list of possible default values }
//TsColor = ();
{@@ Cell structure for TsWorksheet {@@ Cell structure for TsWorksheet
Never suppose that all *Value fields are valid, Never suppose that all *Value fields are valid,
@ -120,6 +132,8 @@ type
{ Formatting fields } { Formatting fields }
UsedFormattingFields: TsUsedFormattingFields; UsedFormattingFields: TsUsedFormattingFields;
TextRotation: TsTextRotation; TextRotation: TsTextRotation;
Border: TsCellBorders;
//BackgroundColor: TsColor;
end; end;
PCell = ^TCell; PCell = ^TCell;

View File

@ -123,7 +123,7 @@ type
procedure WriteWindow1(AStream: TStream); procedure WriteWindow1(AStream: TStream);
procedure WriteWindow2(AStream: TStream; ASheetSelected: Boolean); procedure WriteWindow2(AStream: TStream; ASheetSelected: Boolean);
procedure WriteXF(AStream: TStream; AFontIndex: Word; procedure WriteXF(AStream: TStream; AFontIndex: Word;
AXF_TYPE_PROT, ATextRotation: Byte); AXF_TYPE_PROT, ATextRotation: Byte; ABorders: TsCellBorders);
end; end;
implementation implementation
@ -324,43 +324,51 @@ begin
end; end;
// XF0 // XF0
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF1 // XF1
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF2 // XF2
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF3 // XF3
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF4 // XF4
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF5 // XF5
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF6 // XF6
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF7 // XF7
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF8 // XF8
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF9 // XF9
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF10 // XF10
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF11 // XF11
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF12 // XF12
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF13 // XF13
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF14 // XF14
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF, XF_ROTATION_HORIZONTAL, []);
// XF15 // XF15 - Default, no formatting
WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL, []);
// XF16 // XF16 - Rotated
WriteXF(AStream, 0, 0, XF_ROTATION_90_DEGREE_COUNTERCLOCKWISE); WriteXF(AStream, 0, 0, XF_ROTATION_90_DEGREE_COUNTERCLOCKWISE, []);
// XF17 // XF17 - Rotated
WriteXF(AStream, 0, 0, XF_ROTATION_90_DEGREE_CLOCKWISE); WriteXF(AStream, 0, 0, XF_ROTATION_90_DEGREE_CLOCKWISE, []);
// XF18 // XF18 - Bold
WriteXF(AStream, 1, 0, XF_ROTATION_HORIZONTAL); WriteXF(AStream, 1, 0, XF_ROTATION_HORIZONTAL, []);
// XF19 - Border
WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL, [cbNorth]);
// XF20 - Border
WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL, [cbWest]);
// XF21 - Border
WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL, [cbEast]);
// XF22 - Border
WriteXF(AStream, 0, 0, XF_ROTATION_HORIZONTAL, [cbSouth]);
WriteStyle(AStream); WriteStyle(AStream);
@ -753,6 +761,14 @@ begin
begin begin
AStream.WriteWord(WordToLE(18)); AStream.WriteWord(WordToLE(18));
end end
else if ACell^.UsedFormattingFields = [uffBorder] then
begin
if ACell^.Border = [] then AStream.WriteWord(WordToLE(15))
else if ACell^.Border = [cbNorth] then AStream.WriteWord(WordToLE(19))
else if ACell^.Border = [cbWest] then AStream.WriteWord(WordToLE(20))
else if ACell^.Border = [cbEast] then AStream.WriteWord(WordToLE(21))
else if ACell^.Border = [cbSouth] then AStream.WriteWord(WordToLE(22));
end
else else
AStream.WriteWord(WordToLE(15)); AStream.WriteWord(WordToLE(15));
@ -930,10 +946,11 @@ end;
* *
*******************************************************************} *******************************************************************}
procedure TsSpreadBIFF8Writer.WriteXF(AStream: TStream; AFontIndex: Word; procedure TsSpreadBIFF8Writer.WriteXF(AStream: TStream; AFontIndex: Word;
AXF_TYPE_PROT, ATextRotation: Byte); AXF_TYPE_PROT, ATextRotation: Byte; ABorders: TsCellBorders);
var var
XFOptions: Word; XFOptions: Word;
XFAlignment, XFOrientationAttrib: Byte; XFAlignment, XFOrientationAttrib: Byte;
XFBorderDWord1, XFBorderDWord2: DWord;
begin begin
{ BIFF Record header } { BIFF Record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_XF)); AStream.WriteWord(WordToLE(INT_EXCEL_ID_XF));
@ -976,10 +993,22 @@ begin
AStream.WriteByte(XFOrientationAttrib); AStream.WriteByte(XFOrientationAttrib);
{ Cell border lines and background area } { Cell border lines and background area }
AStream.WriteDWord(DWordToLE($00000000));
AStream.WriteDWord(DWordToLE($00000000)); // Left and Right line colors, use black
AStream.WriteByte(0); XFBorderDWord1 := 8 * $10000 {left line - black} + 8 * $800000 {right line - black};
AStream.WriteByte(0);
if cbNorth in ABorders then XFBorderDWord1 := XFBorderDWord1 or $100;
if cbWest in ABorders then XFBorderDWord1 := XFBorderDWord1 or $1;
if cbEast in ABorders then XFBorderDWord1 := XFBorderDWord1 or $10;
if cbSouth in ABorders then XFBorderDWord1 := XFBorderDWord1 or $1000;
AStream.WriteDWord(DWordToLE(XFBorderDWord1));
// Top and Bottom line colors, use black
XFBorderDWord2 := 8 {top line - black} + 8 * $80 {bottom line - black};
AStream.WriteDWord(DWordToLE(XFBorderDWord2));
// Background Pattern Color, always zeroed
AStream.WriteWord(0);
end; end;
{ TsSpreadBIFF8Reader } { TsSpreadBIFF8Reader }