You've already forked lazarus-ccr
fpspreadsheet: Fix crash of unit test. Still some number format detection issues.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3046 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -42,7 +42,6 @@ begin
|
|||||||
WriteLn('Row: ', CurCell^.Row, ' Col: ', CurCell^.Col, ' Value: ',
|
WriteLn('Row: ', CurCell^.Row, ' Col: ', CurCell^.Col, ' Value: ',
|
||||||
UTF8ToAnsi(MyWorkSheet.ReadAsUTF8Text(CurCell^.Row, CurCell^.Col))
|
UTF8ToAnsi(MyWorkSheet.ReadAsUTF8Text(CurCell^.Row, CurCell^.Col))
|
||||||
);
|
);
|
||||||
WriteLn(MyWorkbook.GetFont(CurCell^.FontIndex).Size-11);
|
|
||||||
CurCell := MyWorkSheet.GetNextCell();
|
CurCell := MyWorkSheet.GetNextCell();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ begin
|
|||||||
MyWorksheet.WriteBorderLineStyle(5, 5, cbNorth, lsThick);
|
MyWorksheet.WriteBorderLineStyle(5, 5, cbNorth, lsThick);
|
||||||
|
|
||||||
// F7, top border only, but different color
|
// F7, top border only, but different color
|
||||||
|
MyWorksheet.WriteBorders(6, 5, [cbNorth]);
|
||||||
MyWorksheet.WriteBorderColor(6, 5, cbNorth, scGreen);
|
MyWorksheet.WriteBorderColor(6, 5, cbNorth, scGreen);
|
||||||
MyWorksheet.WriteUTF8Text(6, 5, 'top border green or red?');
|
MyWorksheet.WriteUTF8Text(6, 5, 'top border green or red?');
|
||||||
// Excel shows it to be red --> the upper border wins
|
// Excel shows it to be red --> the upper border wins
|
||||||
@ -200,6 +201,10 @@ begin
|
|||||||
inc(r);
|
inc(r);
|
||||||
MyWorksheet.WriteUTF8Text(r, 0, 'nfFmtDateTime, mm:ss.zzz');
|
MyWorksheet.WriteUTF8Text(r, 0, 'nfFmtDateTime, mm:ss.zzz');
|
||||||
MyWorksheet.WriteDateTime(r, 1, now, nfFmtDateTime, 'mm:ss.zzz');
|
MyWorksheet.WriteDateTime(r, 1, now, nfFmtDateTime, 'mm:ss.zzz');
|
||||||
|
// NOTE: The upper option "MSZ" = "mm:ss.z" should result only in 1 decimal.
|
||||||
|
// This is true for writing, but in reading always 3 decimals are displayed.
|
||||||
|
// This is due to fpc's SysUtile.FormatDateTime which does not distinguish
|
||||||
|
// both cases.
|
||||||
|
|
||||||
// Write formatted numbers
|
// Write formatted numbers
|
||||||
number := 12345.67890123456789;
|
number := 12345.67890123456789;
|
||||||
|
@ -149,8 +149,8 @@
|
|||||||
<UnitName Value="fpspreadsheetgrid"/>
|
<UnitName Value="fpspreadsheetgrid"/>
|
||||||
<EditorIndex Value="2"/>
|
<EditorIndex Value="2"/>
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="83"/>
|
<TopLine Value="525"/>
|
||||||
<CursorPos X="15" Y="96"/>
|
<CursorPos X="30" Y="533"/>
|
||||||
<UsageCount Value="100"/>
|
<UsageCount Value="100"/>
|
||||||
<Loaded Value="True"/>
|
<Loaded Value="True"/>
|
||||||
</Unit3>
|
</Unit3>
|
||||||
@ -220,15 +220,18 @@
|
|||||||
<Unit12>
|
<Unit12>
|
||||||
<Filename Value="d:\lazarus-svn\lcl\grids.pas"/>
|
<Filename Value="d:\lazarus-svn\lcl\grids.pas"/>
|
||||||
<UnitName Value="Grids"/>
|
<UnitName Value="Grids"/>
|
||||||
|
<IsVisibleTab Value="True"/>
|
||||||
|
<EditorIndex Value="6"/>
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="2464"/>
|
<TopLine Value="4852"/>
|
||||||
<CursorPos X="1" Y="2495"/>
|
<CursorPos X="16" Y="4884"/>
|
||||||
<UsageCount Value="48"/>
|
<UsageCount Value="48"/>
|
||||||
|
<Loaded Value="True"/>
|
||||||
</Unit12>
|
</Unit12>
|
||||||
<Unit13>
|
<Unit13>
|
||||||
<Filename Value="..\..\fpsutils.pas"/>
|
<Filename Value="..\..\fpsutils.pas"/>
|
||||||
<UnitName Value="fpsutils"/>
|
<UnitName Value="fpsutils"/>
|
||||||
<EditorIndex Value="8"/>
|
<EditorIndex Value="9"/>
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="614"/>
|
<TopLine Value="614"/>
|
||||||
<CursorPos X="23" Y="621"/>
|
<CursorPos X="23" Y="621"/>
|
||||||
@ -263,7 +266,7 @@
|
|||||||
<EditorIndex Value="5"/>
|
<EditorIndex Value="5"/>
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="1747"/>
|
<TopLine Value="1747"/>
|
||||||
<CursorPos X="1" Y="1764"/>
|
<CursorPos X="25" Y="1779"/>
|
||||||
<UsageCount Value="78"/>
|
<UsageCount Value="78"/>
|
||||||
<Bookmarks Count="1">
|
<Bookmarks Count="1">
|
||||||
<Item0 X="1" Y="1761" ID="1"/>
|
<Item0 X="1" Y="1761" ID="1"/>
|
||||||
@ -298,7 +301,7 @@
|
|||||||
<Unit21>
|
<Unit21>
|
||||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||||
<UnitName Value="xlsbiff5"/>
|
<UnitName Value="xlsbiff5"/>
|
||||||
<EditorIndex Value="6"/>
|
<EditorIndex Value="7"/>
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="1363"/>
|
<TopLine Value="1363"/>
|
||||||
<CursorPos X="1" Y="1364"/>
|
<CursorPos X="1" Y="1364"/>
|
||||||
@ -308,11 +311,10 @@
|
|||||||
<Unit22>
|
<Unit22>
|
||||||
<Filename Value="..\..\xlsbiff2.pas"/>
|
<Filename Value="..\..\xlsbiff2.pas"/>
|
||||||
<UnitName Value="xlsbiff2"/>
|
<UnitName Value="xlsbiff2"/>
|
||||||
<IsVisibleTab Value="True"/>
|
<EditorIndex Value="8"/>
|
||||||
<EditorIndex Value="7"/>
|
|
||||||
<WindowIndex Value="0"/>
|
<WindowIndex Value="0"/>
|
||||||
<TopLine Value="664"/>
|
<TopLine Value="664"/>
|
||||||
<CursorPos X="30" Y="687"/>
|
<CursorPos X="21" Y="677"/>
|
||||||
<UsageCount Value="62"/>
|
<UsageCount Value="62"/>
|
||||||
<Loaded Value="True"/>
|
<Loaded Value="True"/>
|
||||||
</Unit22>
|
</Unit22>
|
||||||
@ -577,47 +579,47 @@
|
|||||||
<JumpHistory Count="30" HistoryIndex="29">
|
<JumpHistory Count="30" HistoryIndex="29">
|
||||||
<Position1>
|
<Position1>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1755" Column="19" TopLine="1715"/>
|
<Caret Line="1753" Column="1" TopLine="1738"/>
|
||||||
</Position1>
|
</Position1>
|
||||||
<Position2>
|
<Position2>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1964" Column="1" TopLine="1924"/>
|
<Caret Line="1968" Column="1" TopLine="1928"/>
|
||||||
</Position2>
|
</Position2>
|
||||||
<Position3>
|
<Position3>
|
||||||
<Filename Value="..\..\xlscommon.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1210" Column="81" TopLine="1176"/>
|
<Caret Line="1" Column="1" TopLine="1"/>
|
||||||
</Position3>
|
</Position3>
|
||||||
<Position4>
|
<Position4>
|
||||||
<Filename Value="..\..\xlscommon.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1959" Column="1" TopLine="1919"/>
|
<Caret Line="80" Column="21" TopLine="47"/>
|
||||||
</Position4>
|
</Position4>
|
||||||
<Position5>
|
<Position5>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="41" Column="1" TopLine="41"/>
|
<Caret Line="1760" Column="1" TopLine="1744"/>
|
||||||
</Position5>
|
</Position5>
|
||||||
<Position6>
|
<Position6>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1753" Column="1" TopLine="1738"/>
|
<Caret Line="95" Column="22" TopLine="75"/>
|
||||||
</Position6>
|
</Position6>
|
||||||
<Position7>
|
<Position7>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1968" Column="1" TopLine="1928"/>
|
<Caret Line="1" Column="1" TopLine="1"/>
|
||||||
</Position7>
|
</Position7>
|
||||||
<Position8>
|
<Position8>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1" Column="1" TopLine="1"/>
|
<Caret Line="1524" Column="37" TopLine="1516"/>
|
||||||
</Position8>
|
</Position8>
|
||||||
<Position9>
|
<Position9>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="80" Column="21" TopLine="47"/>
|
<Caret Line="1649" Column="21" TopLine="1622"/>
|
||||||
</Position9>
|
</Position9>
|
||||||
<Position10>
|
<Position10>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1760" Column="1" TopLine="1744"/>
|
<Caret Line="1527" Column="3" TopLine="1524"/>
|
||||||
</Position10>
|
</Position10>
|
||||||
<Position11>
|
<Position11>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="95" Column="22" TopLine="75"/>
|
<Caret Line="1758" Column="3" TopLine="1733"/>
|
||||||
</Position11>
|
</Position11>
|
||||||
<Position12>
|
<Position12>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
@ -625,75 +627,75 @@
|
|||||||
</Position12>
|
</Position12>
|
||||||
<Position13>
|
<Position13>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1524" Column="37" TopLine="1516"/>
|
<Caret Line="51" Column="19" TopLine="18"/>
|
||||||
</Position13>
|
</Position13>
|
||||||
<Position14>
|
<Position14>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1649" Column="21" TopLine="1622"/>
|
<Caret Line="57" Column="11" TopLine="24"/>
|
||||||
</Position14>
|
</Position14>
|
||||||
<Position15>
|
<Position15>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1527" Column="3" TopLine="1524"/>
|
<Caret Line="67" Column="13" TopLine="34"/>
|
||||||
</Position15>
|
</Position15>
|
||||||
<Position16>
|
<Position16>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1758" Column="3" TopLine="1733"/>
|
<Caret Line="1394" Column="3" TopLine="1388"/>
|
||||||
</Position16>
|
</Position16>
|
||||||
<Position17>
|
<Position17>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1" Column="1" TopLine="1"/>
|
<Caret Line="1761" Column="3" TopLine="1738"/>
|
||||||
</Position17>
|
</Position17>
|
||||||
<Position18>
|
<Position18>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="51" Column="19" TopLine="18"/>
|
<Caret Line="95" Column="75" TopLine="76"/>
|
||||||
</Position18>
|
</Position18>
|
||||||
<Position19>
|
<Position19>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="57" Column="11" TopLine="24"/>
|
<Caret Line="1749" Column="8" TopLine="1747"/>
|
||||||
</Position19>
|
</Position19>
|
||||||
<Position20>
|
<Position20>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="67" Column="13" TopLine="34"/>
|
<Caret Line="95" Column="55" TopLine="95"/>
|
||||||
</Position20>
|
</Position20>
|
||||||
<Position21>
|
<Position21>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1394" Column="3" TopLine="1388"/>
|
<Caret Line="1748" Column="49" TopLine="1733"/>
|
||||||
</Position21>
|
</Position21>
|
||||||
<Position22>
|
<Position22>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="1761" Column="3" TopLine="1738"/>
|
<Caret Line="95" Column="55" TopLine="95"/>
|
||||||
</Position22>
|
</Position22>
|
||||||
<Position23>
|
<Position23>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
<Caret Line="95" Column="75" TopLine="76"/>
|
<Caret Line="1749" Column="8" TopLine="1747"/>
|
||||||
</Position23>
|
</Position23>
|
||||||
<Position24>
|
<Position24>
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
|
||||||
<Caret Line="1749" Column="8" TopLine="1747"/>
|
|
||||||
</Position24>
|
|
||||||
<Position25>
|
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
|
||||||
<Caret Line="95" Column="55" TopLine="95"/>
|
|
||||||
</Position25>
|
|
||||||
<Position26>
|
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
|
||||||
<Caret Line="1748" Column="49" TopLine="1733"/>
|
|
||||||
</Position26>
|
|
||||||
<Position27>
|
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
|
||||||
<Caret Line="95" Column="55" TopLine="95"/>
|
|
||||||
</Position27>
|
|
||||||
<Position28>
|
|
||||||
<Filename Value="..\..\xlsbiff8.pas"/>
|
|
||||||
<Caret Line="1749" Column="8" TopLine="1747"/>
|
|
||||||
</Position28>
|
|
||||||
<Position29>
|
|
||||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||||
<Caret Line="1370" Column="1" TopLine="1358"/>
|
<Caret Line="1370" Column="1" TopLine="1358"/>
|
||||||
</Position29>
|
</Position24>
|
||||||
<Position30>
|
<Position25>
|
||||||
<Filename Value="..\..\xlscommon.pas"/>
|
<Filename Value="..\..\xlscommon.pas"/>
|
||||||
<Caret Line="39" Column="3" TopLine="10"/>
|
<Caret Line="39" Column="3" TopLine="10"/>
|
||||||
|
</Position25>
|
||||||
|
<Position26>
|
||||||
|
<Filename Value="..\..\xlsbiff2.pas"/>
|
||||||
|
<Caret Line="677" Column="21" TopLine="664"/>
|
||||||
|
</Position26>
|
||||||
|
<Position27>
|
||||||
|
<Filename Value="..\..\fpspreadsheetgrid.pas"/>
|
||||||
|
<Caret Line="524" Column="27" TopLine="524"/>
|
||||||
|
</Position27>
|
||||||
|
<Position28>
|
||||||
|
<Filename Value="..\..\fpspreadsheetgrid.pas"/>
|
||||||
|
<Caret Line="1" Column="1" TopLine="1"/>
|
||||||
|
</Position28>
|
||||||
|
<Position29>
|
||||||
|
<Filename Value="..\..\fpspreadsheetgrid.pas"/>
|
||||||
|
<Caret Line="1787" Column="3" TopLine="1779"/>
|
||||||
|
</Position29>
|
||||||
|
<Position30>
|
||||||
|
<Filename Value="..\..\xlsbiff8.pas"/>
|
||||||
|
<Caret Line="1779" Column="25" TopLine="1747"/>
|
||||||
</Position30>
|
</Position30>
|
||||||
</JumpHistory>
|
</JumpHistory>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
@ -723,6 +725,15 @@
|
|||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
|
<BreakPoints Count="1">
|
||||||
|
<Item1>
|
||||||
|
<Kind Value="bpkSource"/>
|
||||||
|
<WatchScope Value="wpsLocal"/>
|
||||||
|
<WatchKind Value="wpkWrite"/>
|
||||||
|
<Source Value="..\..\fpspreadsheetgrid.pas"/>
|
||||||
|
<Line Value="1790"/>
|
||||||
|
</Item1>
|
||||||
|
</BreakPoints>
|
||||||
<Watches Count="2">
|
<Watches Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Expression Value="acol"/>
|
<Expression Value="acol"/>
|
||||||
|
@ -46,6 +46,14 @@ type
|
|||||||
dm1904 {e.g. Quattro Pro,Mac Excel compatibility}
|
dm1904 {e.g. Quattro Pro,Mac Excel compatibility}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{ TsSpreadOpenDocNumFormatList }
|
||||||
|
TsSpreadOpenDocNumFormatList = class(TsCustomNumFormatList)
|
||||||
|
protected
|
||||||
|
procedure AddBuiltinFormats; override;
|
||||||
|
public
|
||||||
|
// function FormatStringForWriting(AIndex: Integer): String; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TsSpreadOpenDocReader }
|
{ TsSpreadOpenDocReader }
|
||||||
|
|
||||||
TsSpreadOpenDocReader = class(TsCustomSpreadReader)
|
TsSpreadOpenDocReader = class(TsCustomSpreadReader)
|
||||||
@ -58,6 +66,7 @@ type
|
|||||||
// Figures out what the base year for times in this file (dates are unambiguous)
|
// Figures out what the base year for times in this file (dates are unambiguous)
|
||||||
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
||||||
protected
|
protected
|
||||||
|
procedure CreateNumFormatList; override;
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
procedure ReadFormula(ARow : Word; ACol : Word; ACellNode: TDOMNode);
|
procedure ReadFormula(ARow : Word; ACol : Word; ACellNode: TDOMNode);
|
||||||
procedure ReadLabel(ARow : Word; ACol : Word; ACellNode: TDOMNode);
|
procedure ReadLabel(ARow : Word; ACol : Word; ACellNode: TDOMNode);
|
||||||
@ -79,6 +88,8 @@ type
|
|||||||
// Streams with the contents of files
|
// Streams with the contents of files
|
||||||
FSMeta, FSSettings, FSStyles, FSContent, FSMimetype: TStringStream;
|
FSMeta, FSSettings, FSStyles, FSContent, FSMimetype: TStringStream;
|
||||||
FSMetaInfManifest: TStringStream;
|
FSMetaInfManifest: TStringStream;
|
||||||
|
// Helpers
|
||||||
|
procedure CreateNumFormatList; override;
|
||||||
// Routines to write those files
|
// Routines to write those files
|
||||||
procedure WriteMimetype;
|
procedure WriteMimetype;
|
||||||
procedure WriteMetaInfManifest;
|
procedure WriteMetaInfManifest;
|
||||||
@ -159,8 +170,23 @@ const
|
|||||||
DATEMODE_1904_BASE=1462; //1/1/1904 in FPC TDateTime
|
DATEMODE_1904_BASE=1462; //1/1/1904 in FPC TDateTime
|
||||||
|
|
||||||
|
|
||||||
|
{ TsSpreadOpenDocNumFormatList }
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocNumFormatList.AddBuiltinFormats;
|
||||||
|
begin
|
||||||
|
// to be filled later...
|
||||||
|
end;
|
||||||
|
|
||||||
{ TsSpreadOpenDocReader }
|
{ TsSpreadOpenDocReader }
|
||||||
|
|
||||||
|
{ Creates the correct version of the number format list.
|
||||||
|
It is for ods file formats. }
|
||||||
|
procedure TsSpreadOpenDocReader.CreateNumFormatList;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FNumFormatList);
|
||||||
|
FNumFormatList := TsSpreadOpenDocNumFormatList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
function TsSpreadOpenDocReader.GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
|
function TsSpreadOpenDocReader.GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
|
||||||
var
|
var
|
||||||
i : integer;
|
i : integer;
|
||||||
@ -442,6 +468,12 @@ end;
|
|||||||
|
|
||||||
{ TsSpreadOpenDocWriter }
|
{ TsSpreadOpenDocWriter }
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocWriter.CreateNumFormatList;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FNumFormatList);
|
||||||
|
FNumFormatList := TsSpreadOpenDocNumFormatList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocWriter.WriteMimetype;
|
procedure TsSpreadOpenDocWriter.WriteMimetype;
|
||||||
begin
|
begin
|
||||||
FMimetype := 'application/vnd.oasis.opendocument.spreadsheet';
|
FMimetype := 'application/vnd.oasis.opendocument.spreadsheet';
|
||||||
|
@ -125,7 +125,18 @@ type
|
|||||||
|
|
||||||
{@@ Describes the type of content of a cell on a TsWorksheet }
|
{@@ Describes the type of content of a cell on a TsWorksheet }
|
||||||
TCellContentType = (cctEmpty, cctFormula, cctRPNFormula, cctNumber,
|
TCellContentType = (cctEmpty, cctFormula, cctRPNFormula, cctNumber,
|
||||||
cctUTF8String, cctDateTime);
|
cctUTF8String, cctDateTime, cctBool, cctError);
|
||||||
|
|
||||||
|
{@@ Error code values }
|
||||||
|
TErrorValue = (
|
||||||
|
errEmptyIntersection, // #NULL!
|
||||||
|
errDivideByZero, // #DIV/0!
|
||||||
|
errWrongType, // #VALUE!
|
||||||
|
errIllegalRef, // #REF!
|
||||||
|
errWrongName, // #NAME?
|
||||||
|
errOverflow, // #NUM!
|
||||||
|
errArgNotAvail // #N/A
|
||||||
|
);
|
||||||
|
|
||||||
{@@ List of possible formatting fields }
|
{@@ List of possible formatting fields }
|
||||||
TsUsedFormattingField = (uffTextRotation, uffFont, uffBold, uffBorder,
|
TsUsedFormattingField = (uffTextRotation, uffFont, uffBold, uffBorder,
|
||||||
@ -278,6 +289,8 @@ type
|
|||||||
NumberValue: double;
|
NumberValue: double;
|
||||||
UTF8StringValue: ansistring;
|
UTF8StringValue: ansistring;
|
||||||
DateTimeValue: TDateTime;
|
DateTimeValue: TDateTime;
|
||||||
|
BoolValue: Boolean;
|
||||||
|
StatusValue: Byte;
|
||||||
{ Formatting fields }
|
{ Formatting fields }
|
||||||
UsedFormattingFields: TsUsedFormattingFields;
|
UsedFormattingFields: TsUsedFormattingFields;
|
||||||
FontIndex: Integer;
|
FontIndex: Integer;
|
||||||
@ -369,8 +382,10 @@ type
|
|||||||
procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double;
|
procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double;
|
||||||
AFormatString: String); overload;
|
AFormatString: String); overload;
|
||||||
procedure WriteBlank(ARow, ACol: Cardinal);
|
procedure WriteBlank(ARow, ACol: Cardinal);
|
||||||
|
procedure WriteBoolValue(ARow, ACol: Cardinal; AValue: Boolean);
|
||||||
procedure WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
|
procedure WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
|
||||||
AFormat: TsNumberFormat = nfShortDateTime; AFormatStr: String = '');
|
AFormat: TsNumberFormat = nfShortDateTime; AFormatStr: String = '');
|
||||||
|
procedure WriteErrorValue(ARow, ACol: Cardinal; AValue: TErrorValue);
|
||||||
procedure WriteFormula(ARow, ACol: Cardinal; AFormula: TsFormula);
|
procedure WriteFormula(ARow, ACol: Cardinal; AFormula: TsFormula);
|
||||||
procedure WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TsRPNFormula);
|
procedure WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TsRPNFormula);
|
||||||
{ Writing of cell attributes }
|
{ Writing of cell attributes }
|
||||||
@ -688,6 +703,15 @@ resourcestring
|
|||||||
lpNoValidSpreadsheetFile = '"%s" is not a valid spreadsheet file';
|
lpNoValidSpreadsheetFile = '"%s" is not a valid spreadsheet file';
|
||||||
lpUnknownSpreadsheetFormat = 'unknown format';
|
lpUnknownSpreadsheetFormat = 'unknown format';
|
||||||
lpInvalidFontIndex = 'Invalid font index';
|
lpInvalidFontIndex = 'Invalid font index';
|
||||||
|
lpTRUE = 'TRUE';
|
||||||
|
lpFALSE = 'FALSE';
|
||||||
|
lpErrEmptyIntersection = '#NULL!';
|
||||||
|
lpErrDivideByZero = '#DIV/0!';
|
||||||
|
lpErrWrongType = '#VALUE!';
|
||||||
|
lpErrIllegalRef = '#REF!';
|
||||||
|
lpErrWrongName = '#NAME?';
|
||||||
|
lpErrOverflow = '#NUM!';
|
||||||
|
lpErrArgNotAvail = '#N/A';
|
||||||
|
|
||||||
var
|
var
|
||||||
{@@
|
{@@
|
||||||
@ -1173,6 +1197,18 @@ begin
|
|||||||
Result := UTF8StringValue;
|
Result := UTF8StringValue;
|
||||||
cctDateTime:
|
cctDateTime:
|
||||||
Result := DateTimeToStrNoNaN(DateTimeValue, NumberFormat, NumberFormatStr, NumberDecimals);
|
Result := DateTimeToStrNoNaN(DateTimeValue, NumberFormat, NumberFormatStr, NumberDecimals);
|
||||||
|
cctBool:
|
||||||
|
Result := IfThen(BoolValue, lpTRUE, lpFALSE);
|
||||||
|
cctError:
|
||||||
|
case TErrorValue(StatusValue and $0F) of
|
||||||
|
errEmptyIntersection: Result := lpErrEmptyIntersection;
|
||||||
|
errDivideByZero : Result := lpErrDivideByZero;
|
||||||
|
errWrongType : Result := lpErrWrongType;
|
||||||
|
errIllegalRef : Result := lpErrIllegalRef;
|
||||||
|
errWrongName : Result := lpErrWrongName;
|
||||||
|
errOverflow : Result := lpErrOverflow;
|
||||||
|
errArgNotAvail : Result := lpErrArgNotAvail;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
@ -1382,6 +1418,23 @@ begin
|
|||||||
ChangedCell(ARow, ACol);
|
ChangedCell(ARow, ACol);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Writes as boolean cell
|
||||||
|
|
||||||
|
@param ARow The row of the cell
|
||||||
|
@param ACol The column of the cell
|
||||||
|
@param AValue The boolean value
|
||||||
|
}
|
||||||
|
procedure TsWorksheet.WriteBoolValue(ARow, ACol: Cardinal; AValue: Boolean);
|
||||||
|
var
|
||||||
|
ACell: PCell;
|
||||||
|
begin
|
||||||
|
ACell := GetCell(ARow, ACol);
|
||||||
|
ACell^.ContentType := cctBool;
|
||||||
|
ACell^.BoolValue := AValue;
|
||||||
|
ChangedCell(ARow, ACol);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Writes a date/time value to a determined cell
|
Writes a date/time value to a determined cell
|
||||||
|
|
||||||
@ -1446,6 +1499,23 @@ begin
|
|||||||
ChangedCell(ARow, ACol);
|
ChangedCell(ARow, ACol);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Writes a cell with an error.
|
||||||
|
|
||||||
|
@param ARow The row of the cell
|
||||||
|
@param ACol The column of the cell
|
||||||
|
@param AValue The error code value
|
||||||
|
}
|
||||||
|
procedure TsWorksheet.WriteErrorValue(ARow, ACol: Cardinal; AValue: TErrorValue);
|
||||||
|
var
|
||||||
|
ACell: PCell;
|
||||||
|
begin
|
||||||
|
ACell := GetCell(ARow, ACol);
|
||||||
|
ACell^.ContentType := cctError;
|
||||||
|
ACell^.StatusValue := (ACell^.StatusValue and $F0) or ord(AValue);
|
||||||
|
ChangedCell(ARow, ACol);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Writes a formula to a determined cell
|
Writes a formula to a determined cell
|
||||||
|
|
||||||
@ -2553,8 +2623,12 @@ begin
|
|||||||
ANumFormat := nfShortDateTime
|
ANumFormat := nfShortDateTime
|
||||||
else if isDate then
|
else if isDate then
|
||||||
ANumFormat := SHORT_LONG_DATE[isLongDate]
|
ANumFormat := SHORT_LONG_DATE[isLongDate]
|
||||||
else if isTime then
|
else if isTime then begin
|
||||||
ANumFormat := AMPM_SHORT_LONG_TIME[isAMPM, isLongTime]
|
if (ADecimals > 0) and (not isAMPM) then
|
||||||
|
ANumFormat := nfFmtDateTime
|
||||||
|
else
|
||||||
|
ANumFormat := AMPM_SHORT_LONG_TIME[isAMPM, isLongTime]
|
||||||
|
end
|
||||||
else if AFormatString <> '' then
|
else if AFormatString <> '' then
|
||||||
ANumFormat := nfCustom;
|
ANumFormat := nfCustom;
|
||||||
end;
|
end;
|
||||||
|
@ -189,7 +189,7 @@ begin
|
|||||||
SollDateTimeStrings[i, 6] := FormatDateTime('dd/mmm', SollDateTimes[i]);
|
SollDateTimeStrings[i, 6] := FormatDateTime('dd/mmm', SollDateTimes[i]);
|
||||||
SollDateTimeStrings[i, 7] := FormatDateTime('mmm/yy', SollDateTimes[i]);
|
SollDateTimeStrings[i, 7] := FormatDateTime('mmm/yy', SollDateTimes[i]);
|
||||||
SollDateTimeStrings[i, 8] := FormatDateTime('nn:ss', SollDateTimes[i]);
|
SollDateTimeStrings[i, 8] := FormatDateTime('nn:ss', SollDateTimes[i]);
|
||||||
SollDateTimeStrings[i, 9] := TimeIntervalToString(SollDateTimes[i]);
|
SollDateTimeStrings[i, 9] := FormatDateTime('[h]:mm:ss', SollDateTimes[i]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Column width
|
// Column width
|
||||||
|
@ -25,7 +25,7 @@ uses
|
|||||||
// Not using lazarus package as the user may be working with multiple versions
|
// Not using lazarus package as the user may be working with multiple versions
|
||||||
// Instead, add .. to unit search path
|
// Instead, add .. to unit search path
|
||||||
Classes, SysUtils, fpcunit, testutils, testregistry,
|
Classes, SysUtils, fpcunit, testutils, testregistry,
|
||||||
fpsallformats, fpspreadsheet, xlsbiff8 {and a project requirement for lclbase for utf8 handling},
|
fpsallformats, fpsutils, fpspreadsheet, xlsbiff8 {and a project requirement for lclbase for utf8 handling},
|
||||||
testsutility;
|
testsutility;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
Binary file not shown.
@ -130,37 +130,6 @@ var
|
|||||||
$00FFFF // $07: cyan
|
$00FFFF // $07: cyan
|
||||||
);
|
);
|
||||||
|
|
||||||
(*
|
|
||||||
{ These are the built-in number formats of BIFF2. They are not stored in
|
|
||||||
the file. Note that, compared to the BUFF5+ built-in formats, two formats
|
|
||||||
are missing and the indexes are offset by 2 after #11.
|
|
||||||
It seems that BIFF2 can handle only these 21 formats. The other formats
|
|
||||||
available in fpspreadsheet are mapped to these 21 formats such that least
|
|
||||||
destruction is made. }
|
|
||||||
NUMFORMAT_BIFF2: array[0..20] of string = (
|
|
||||||
'General', // 0
|
|
||||||
'0',
|
|
||||||
'0.00',
|
|
||||||
'#,##0',
|
|
||||||
'#,##0.00',
|
|
||||||
'"$"#,##0_);("$"#,##0)', // 5
|
|
||||||
'"$"#,##0_);[Red]("$"#,##0)',
|
|
||||||
'"$"#,##0.00_);("$"#,##0.00)',
|
|
||||||
'"$"#,##0.00_);[Red]("$"#,##0.00)',
|
|
||||||
'0%',
|
|
||||||
'0.00%', // 10
|
|
||||||
'0.00E+00',
|
|
||||||
'M/D/YY',
|
|
||||||
'D-MMM-YY',
|
|
||||||
'D-MMM',
|
|
||||||
'MMM-YY', // 15
|
|
||||||
'h:mm AM/PM',
|
|
||||||
'h:mm:ss AM/PM',
|
|
||||||
'h:mm',
|
|
||||||
'h:mm:ss',
|
|
||||||
'M/D/YY h:mm' // 20
|
|
||||||
);
|
|
||||||
*)
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -193,36 +162,7 @@ const
|
|||||||
INT_EXCEL_SHEET = $0010;
|
INT_EXCEL_SHEET = $0010;
|
||||||
INT_EXCEL_CHART = $0020;
|
INT_EXCEL_CHART = $0020;
|
||||||
INT_EXCEL_MACRO_SHEET = $0040;
|
INT_EXCEL_MACRO_SHEET = $0040;
|
||||||
(*
|
|
||||||
{ FORMAT record constants for BIFF2 }
|
|
||||||
// Subset of the built-in formats for US Excel,
|
|
||||||
// including those needed for date/time output
|
|
||||||
FORMAT_GENERAL = 0; //general/default format
|
|
||||||
FORMAT_FIXED_0_DECIMALS = 1; //fixed, 0 decimals
|
|
||||||
FORMAT_FIXED_2_DECIMALS = 2; //fixed, 2 decimals
|
|
||||||
FORMAT_FIXED_THOUSANDS_0_DECIMALS = 3; //fixed, w/ thousand separator, 0 decs
|
|
||||||
FORMAT_FIXED_THOUSANDS_2_DECIMALS = 4; //fixed, w/ thousand separator, 2 decs
|
|
||||||
FORMAT_CURRENCY_0_DECIMALS = 5; //currency (with currency symbol), 0 decs
|
|
||||||
FORMAT_CURRENCY_2_DECIMALS = 7; //currency (with currency symbol), 2 decs
|
|
||||||
FORMAT_PERCENT_0_DECIMALS = 9; //percent, 0 decimals
|
|
||||||
FORMAT_PERCENT_2_DECIMALS = 10; //percent, 2 decimals
|
|
||||||
FORMAT_EXP_2_DECIMALS = 11; //exponent, 2 decimals
|
|
||||||
FORMAT_SCI_1_DECIMAL = 11; //scientific, 1 decimal -- not present in BIFF2 -- mapped to EXP_2_DECIMALS
|
|
||||||
FORMAT_SHORT_DATE = 12; //short date
|
|
||||||
FORMAT_DATE_DM = 14; //date D-MMM
|
|
||||||
FORMAT_DATE_MY = 15; //date MMM-YYYY
|
|
||||||
FORMAT_SHORT_TIME_AM = 16; //short time H:MM with AM
|
|
||||||
FORMAT_LONG_TIME_AM = 17; //long time H:MM:SS with AM
|
|
||||||
FORMAT_SHORT_TIME = 18; //short time H:MM
|
|
||||||
FORMAT_LONG_TIME = 19; //long time H:MM:SS
|
|
||||||
FORMAT_SHORT_DATETIME = 20; //short date+time
|
|
||||||
{ The next three formats are not available in BIFF2. They should not be used
|
|
||||||
when a file is to be saved in BIFF2. If it IS saved as BIFF2 the formats
|
|
||||||
are mapped to FORMAT_LONG_TIME}
|
|
||||||
FORMAT_TIME_MS = 19; //time MM:SS
|
|
||||||
FORMAT_TIME_MSZ = 19; //time MM:SS.0
|
|
||||||
FORMAT_TIME_INTERVAL = 19; //time [hh]:mm:ss, hh can be >24
|
|
||||||
*)
|
|
||||||
|
|
||||||
{ TsBIFF2NumFormatList }
|
{ TsBIFF2NumFormatList }
|
||||||
|
|
||||||
@ -351,74 +291,19 @@ end;
|
|||||||
procedure TsSpreadBIFF2Reader.ExtractNumberFormat(AXFIndex: WORD;
|
procedure TsSpreadBIFF2Reader.ExtractNumberFormat(AXFIndex: WORD;
|
||||||
out ANumberFormat: TsNumberFormat; out ADecimals: Word;
|
out ANumberFormat: TsNumberFormat; out ADecimals: Word;
|
||||||
out ANumberFormatStr: String);
|
out ANumberFormatStr: String);
|
||||||
const
|
|
||||||
NOT_USED = nfGeneral;
|
|
||||||
fmts: array[1..20] of TsNumberFormat = (
|
|
||||||
nfFixed, nfFixed, nfFixedTh, nfFixedTh, nfFixedTh, // 1..5
|
|
||||||
nfFixedTh, nfFixedTh, nfFixedTh, nfPercentage, nfPercentage, // 6..10
|
|
||||||
nfExp, nfShortDate, nfShortDate, nfFmtDateTime, nfFmtDateTime, // 11..15
|
|
||||||
nfShortTimeAM, nfLongTimeAM, nfShortTime, nfLongTime, nfShortDateTime// 16..20
|
|
||||||
);
|
|
||||||
decs: array[1..20] of word = (
|
|
||||||
0, 2, 0, 2, 0, 0, 2, 2, 0, 2, // 1..10
|
|
||||||
2, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 11..20
|
|
||||||
);
|
|
||||||
var
|
var
|
||||||
lNumFormatData: TsNumFormatData;
|
lNumFormatData: TsNumFormatData;
|
||||||
lXFData: TXFListData;
|
|
||||||
isAMPM: Boolean;
|
|
||||||
isLongTime: Boolean;
|
|
||||||
isMilliSec: Boolean;
|
|
||||||
t,d: Boolean;
|
|
||||||
begin
|
begin
|
||||||
ANumberFormat := nfGeneral;
|
|
||||||
ANumberFormatStr := '';
|
|
||||||
ADecimals := 0;
|
|
||||||
(*
|
|
||||||
lNumFormatData := FindNumFormatDataForCell(AXFIndex);
|
lNumFormatData := FindNumFormatDataForCell(AXFIndex);
|
||||||
if lNumFormatData = nil then begin
|
if lNumFormatData <> nil then begin
|
||||||
// no custom format, so first test for default formats
|
ANumberFormat := lNumFormatData.NumFormat;
|
||||||
lXFData := TXFListData (FXFList.Items[AXFIndex]);
|
ANumberFormatStr := lNumFormatData.FormatString;
|
||||||
if (lXFData.FormatIndex > 0) and (lXFData.FormatIndex <= 20) then begin
|
ADecimals := lNumFormatData.Decimals;
|
||||||
ANumberFormat := fmts[lXFData.FormatIndex];
|
end else begin
|
||||||
ADecimals := decs[lXFData.FormatIndex];
|
ANumberFormat := nfGeneral;
|
||||||
end;
|
ANumberFormatStr := '';
|
||||||
end else
|
ADecimals := 0;
|
||||||
// The next is copied from xlscommon - I think it's not necessary here
|
end;
|
||||||
if IsPercentNumberFormat(lNumFormatData.FormatString, ADecimals) then
|
|
||||||
ANumberFormat := nfPercentage
|
|
||||||
else
|
|
||||||
if IsExpNumberFormat(lNumFormatData.Formatstring, ADecimals) then
|
|
||||||
ANumberFormat := nfExp
|
|
||||||
else
|
|
||||||
if IsThousandSepNumberFormat(lNumFormatData.FormatString, ADecimals) then
|
|
||||||
ANumberFormat := nfFixedTh
|
|
||||||
else
|
|
||||||
if IsFixedNumberFormat(lNumFormatData.FormatString, ADecimals) then
|
|
||||||
ANumberFormat := nfFixed
|
|
||||||
else begin
|
|
||||||
t := IsTimeFormat(lNumFormatData.FormatString, isLongTime, isAMPM, isMilliSec);
|
|
||||||
d := IsDateFormat(lNumFormatData.FormatString, isLongDate);
|
|
||||||
if d and t then
|
|
||||||
ANumberFormat := nfShortDateTime
|
|
||||||
else
|
|
||||||
if d then
|
|
||||||
ANumberFormat := nfShortDate
|
|
||||||
else
|
|
||||||
if t then begin
|
|
||||||
if isAMPM then begin
|
|
||||||
if isLongTime then
|
|
||||||
ANumberFormat := nfLongTimeAM
|
|
||||||
else
|
|
||||||
ANumberFormat := nfShortTimeAM;
|
|
||||||
end else begin
|
|
||||||
if isLongTime then
|
|
||||||
ANumberFormat := nfLongTime
|
|
||||||
else
|
|
||||||
ANumberFormat := nfShortTime;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end; *)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream);
|
||||||
@ -513,22 +398,20 @@ begin
|
|||||||
CurStreamPos := AStream.Position;
|
CurStreamPos := AStream.Position;
|
||||||
|
|
||||||
case RecordType of
|
case RecordType of
|
||||||
|
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
||||||
INT_EXCEL_ID_FONT : ReadFont(AStream);
|
INT_EXCEL_ID_FONTCOLOR : ReadFontColor(AStream);
|
||||||
INT_EXCEL_ID_FONTCOLOR : ReadFontColor(AStream);
|
INT_EXCEL_ID_INTEGER : ReadInteger(AStream);
|
||||||
INT_EXCEL_ID_INTEGER : ReadInteger(AStream);
|
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
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_ROW : 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);
|
INT_EXCEL_ID_BOF : ;
|
||||||
INT_EXCEL_ID_BOF : ;
|
INT_EXCEL_ID_EOF : BIFF2EOF := True;
|
||||||
INT_EXCEL_ID_EOF : BIFF2EOF := True;
|
|
||||||
|
|
||||||
else
|
else
|
||||||
// nothing
|
// nothing
|
||||||
end;
|
end;
|
||||||
|
@ -78,21 +78,16 @@ type
|
|||||||
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
||||||
procedure ReadBoundsheet(AStream: TStream);
|
procedure ReadBoundsheet(AStream: TStream);
|
||||||
function ReadString(const AStream: TStream; const ALength: WORD): UTF8String;
|
function ReadString(const AStream: TStream; const ALength: WORD): UTF8String;
|
||||||
procedure ReadSST(const AStream: TStream);
|
protected
|
||||||
procedure ReadLabelSST(const AStream: TStream);
|
procedure ReadBlank(AStream: TStream); override;
|
||||||
// Read XF record
|
|
||||||
procedure ReadXF(const AStream: TStream);
|
|
||||||
// Workbook Globals records
|
|
||||||
// procedure ReadCodepage in xlscommon
|
|
||||||
// procedure ReadDateMode in xlscommon
|
|
||||||
procedure ReadFont(const AStream: TStream);
|
procedure ReadFont(const AStream: TStream);
|
||||||
procedure ReadFormat(AStream: TStream); override;
|
procedure ReadFormat(AStream: TStream); override;
|
||||||
{ Record reading methods }
|
|
||||||
procedure ReadBlank(AStream: TStream); override;
|
|
||||||
procedure ReadLabel(AStream: TStream); override;
|
procedure ReadLabel(AStream: TStream); override;
|
||||||
|
procedure ReadLabelSST(const AStream: TStream);
|
||||||
procedure ReadRichString(const AStream: TStream);
|
procedure ReadRichString(const AStream: TStream);
|
||||||
protected
|
procedure ReadSST(const AStream: TStream);
|
||||||
procedure ReadStringRecord(AStream: TStream; var AStringResult: String); override;
|
procedure ReadStringRecord(AStream: TStream; var AStringResult: String); override;
|
||||||
|
procedure ReadXF(const AStream: TStream);
|
||||||
public
|
public
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
{ General reading methods }
|
{ General reading methods }
|
||||||
@ -1750,16 +1745,13 @@ procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream;
|
|||||||
var
|
var
|
||||||
record_id: Word;
|
record_id: Word;
|
||||||
record_size: word;
|
record_size: word;
|
||||||
p: Cardinal;
|
|
||||||
begin
|
begin
|
||||||
record_id := WordLEToN(AStream.ReadWord);
|
record_id := WordLEToN(AStream.ReadWord);
|
||||||
if record_id <> INT_EXCEL_ID_STRING then
|
if record_id <> INT_EXCEL_ID_STRING then
|
||||||
raise Exception.Create('ReadStringRecord: wrong record found.');
|
raise Exception.Create('ReadStringRecord: wrong record found.');
|
||||||
record_size := WordLEToN(AStream.ReadWord);
|
record_size := WordLEToN(AStream.ReadWord);
|
||||||
p := AStream.Position;
|
|
||||||
|
|
||||||
AStringResult := ReadWideString(AStream, false);
|
AStringResult := ReadWideString(AStream, false);
|
||||||
AStream.Position := p + record_size;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream);
|
||||||
|
@ -237,33 +237,6 @@ const
|
|||||||
{ DATEMODE record, 5.28 }
|
{ DATEMODE record, 5.28 }
|
||||||
DATEMODE_1900_BASE=1; //1/1/1900 minus 1 day in FPC TDateTime
|
DATEMODE_1900_BASE=1; //1/1/1900 minus 1 day in FPC TDateTime
|
||||||
DATEMODE_1904_BASE=1462; //1/1/1904 in FPC TDateTime
|
DATEMODE_1904_BASE=1462; //1/1/1904 in FPC TDateTime
|
||||||
(*
|
|
||||||
{ FORMAT record constants for BIFF5-BIFF8}
|
|
||||||
// Subset of the built-in formats for US Excel,
|
|
||||||
// including those needed for date/time output
|
|
||||||
FORMAT_GENERAL = 0; //general/default format
|
|
||||||
FORMAT_FIXED_0_DECIMALS = 1; //fixed, 0 decimals
|
|
||||||
FORMAT_FIXED_2_DECIMALS = 2; //fixed, 2 decimals
|
|
||||||
FORMAT_FIXED_THOUSANDS_0_DECIMALS = 3; //fixed, w/ thousand separator, 0 decs
|
|
||||||
FORMAT_FIXED_THOUSANDS_2_DECIMALS = 4; //fixed, w/ thousand separator, 2 decs
|
|
||||||
FORMAT_CURRENCY_0_DECIMALS = 5; //currency (with currency symbol), 0 decs
|
|
||||||
FORMAT_CURRENCY_2_DECIMALS = 7; //currency (with currency symbol), 2 decs
|
|
||||||
FORMAT_PERCENT_0_DECIMALS = 9; //percent, 0 decimals
|
|
||||||
FORMAT_PERCENT_2_DECIMALS = 10; //percent, 2 decimals
|
|
||||||
FORMAT_EXP_2_DECIMALS = 11; //exponent, 2 decimals
|
|
||||||
FORMAT_SHORT_DATE = 14; //short date
|
|
||||||
FORMAT_DATE_DM = 16; //date D-MMM
|
|
||||||
FORMAT_DATE_MY = 17; //date MMM-YYYY
|
|
||||||
FORMAT_SHORT_TIME_AM = 18; //short time H:MM with AM
|
|
||||||
FORMAT_LONG_TIME_AM = 19; //long time H:MM:SS with AM
|
|
||||||
FORMAT_SHORT_TIME = 20; //short time H:MM
|
|
||||||
FORMAT_LONG_TIME = 21; //long time H:MM:SS
|
|
||||||
FORMAT_SHORT_DATETIME = 22; //short date+time
|
|
||||||
FORMAT_TIME_MS = 45; //time MM:SS
|
|
||||||
FORMAT_TIME_INTERVAL = 46; //time [hh]:mm:ss, hh can be >24
|
|
||||||
FORMAT_TIME_MSZ = 47; //time MM:SS.0
|
|
||||||
FORMAT_SCI_1_DECIMAL = 48; //scientific, 1 decimal
|
|
||||||
*)
|
|
||||||
|
|
||||||
{ WINDOW1 record constants - BIFF5-BIFF8 }
|
{ WINDOW1 record constants - BIFF5-BIFF8 }
|
||||||
MASK_WINDOW1_OPTION_WINDOW_HIDDEN = $0001;
|
MASK_WINDOW1_OPTION_WINDOW_HIDDEN = $0001;
|
||||||
@ -336,6 +309,14 @@ const
|
|||||||
MASK_XF_VERT_ALIGN_BOTTOM = $20;
|
MASK_XF_VERT_ALIGN_BOTTOM = $20;
|
||||||
MASK_XF_VERT_ALIGN_JUSTIFIED = $30;
|
MASK_XF_VERT_ALIGN_JUSTIFIED = $30;
|
||||||
|
|
||||||
|
{ Error codes }
|
||||||
|
ERR_INTERSECTION_EMPTY = $00; // #NULL!
|
||||||
|
ERR_DIVIDE_BY_ZERO = $07; // #DIV/0!
|
||||||
|
ERR_WRONG_TYPE_OF_OPERAND = $0F; // #VALUE!
|
||||||
|
ERR_ILLEGAL_REFERENCE = $17; // #REF!
|
||||||
|
ERR_WRONG_NAME = $1D; // #NAME?
|
||||||
|
ERR_OVERFLOW = $24; // #NUM!
|
||||||
|
ERR_NOT_AVAILABLE = $2A; // #N/A
|
||||||
|
|
||||||
type
|
type
|
||||||
TDateMode=(dm1900,dm1904); //DATEMODE values, 5.28
|
TDateMode=(dm1900,dm1904); //DATEMODE values, 5.28
|
||||||
@ -943,6 +924,7 @@ var
|
|||||||
nd: Word;
|
nd: Word;
|
||||||
nfs: String;
|
nfs: String;
|
||||||
resultStr: String;
|
resultStr: String;
|
||||||
|
err: TErrorValue;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
@ -970,18 +952,33 @@ begin
|
|||||||
|
|
||||||
//RPN data not used by now
|
//RPN data not used by now
|
||||||
AStream.Position := AStream.Position + FormulaSize;
|
AStream.Position := AStream.Position + FormulaSize;
|
||||||
|
(*
|
||||||
|
// Now determine the type of the formula result
|
||||||
if (Data[6] = $FF) and (Data[7] = $FF) then
|
if (Data[6] = $FF) and (Data[7] = $FF) then
|
||||||
case Data[0] of
|
case Data[0] of
|
||||||
0: begin
|
0: begin
|
||||||
ReadStringRecord(AStream, resultStr);
|
ReadStringRecord(AStream, resultStr);
|
||||||
FWorksheet.WriteUTF8Text(ARow, ACol, resultStr);
|
if resultStr = '' then
|
||||||
end;
|
FWorksheet.WriteBlank(ARow, ACol)
|
||||||
1: FWorksheet.WriteUTF8Text(ARow, ACol, '(Bool)');
|
else
|
||||||
2: FWorksheet.WriteUTF8Text(ARow, ACol, '(ERROR)');
|
FWorksheet.WriteUTF8Text(ARow, ACol, resultStr);
|
||||||
3: FWorksheet.WriteUTF8Text(ARow, ACol, '(empty)');
|
end;
|
||||||
|
1: FWorksheet.WriteBoolValue(ARow, ACol, Data[2] = 1);
|
||||||
|
2: begin
|
||||||
|
case Data[2] of
|
||||||
|
ERR_INTERSECTION_EMPTY : err := errEmptyIntersection;
|
||||||
|
ERR_DIVIDE_BY_ZERO : err := errDivideByZero;
|
||||||
|
ERR_WRONG_TYPE_OF_OPERAND: err := errWrongType;
|
||||||
|
ERR_ILLEGAL_REFERENCE : err := errIllegalRef;
|
||||||
|
ERR_WRONG_NAME : err := errWrongName;
|
||||||
|
ERR_OVERFLOW : err := errOverflow;
|
||||||
|
ERR_NOT_AVAILABLE : err := errArgNotAvail;
|
||||||
|
end;
|
||||||
|
FWorksheet.WriteErrorValue(ARow, ACol, err);
|
||||||
|
end;
|
||||||
|
3: FWorksheet.WriteBlank(ARow, ACol);
|
||||||
end
|
end
|
||||||
else begin
|
else begin *)
|
||||||
if SizeOf(Double) <> 8 then
|
if SizeOf(Double) <> 8 then
|
||||||
raise Exception.Create('Double is not 8 bytes');
|
raise Exception.Create('Double is not 8 bytes');
|
||||||
|
|
||||||
@ -994,7 +991,7 @@ begin
|
|||||||
FWorksheet.WriteDateTime(ARow, ACol, dt, nf, nfs)
|
FWorksheet.WriteDateTime(ARow, ACol, dt, nf, nfs)
|
||||||
else
|
else
|
||||||
FWorksheet.WriteNumber(ARow, ACol, ResultFormula, nf, nd);
|
FWorksheet.WriteNumber(ARow, ACol, ResultFormula, nf, nd);
|
||||||
end;
|
// end;
|
||||||
|
|
||||||
{Add attributes}
|
{Add attributes}
|
||||||
ApplyCellFormatting(ARow, ACol, XF);
|
ApplyCellFormatting(ARow, ACol, XF);
|
||||||
@ -1076,7 +1073,7 @@ var
|
|||||||
nd: word;
|
nd: word;
|
||||||
nfs: String;
|
nfs: String;
|
||||||
begin
|
begin
|
||||||
ReadRowColXF(AStream,ARow,ACol,XF);
|
ReadRowColXF(AStream, ARow, ACol, XF);
|
||||||
|
|
||||||
{ IEE 754 floating-point value }
|
{ IEE 754 floating-point value }
|
||||||
AStream.ReadBuffer(value, 8);
|
AStream.ReadBuffer(value, 8);
|
||||||
@ -1609,14 +1606,21 @@ end;
|
|||||||
procedure TsSpreadBIFFWriter.WriteFormats(AStream: TStream);
|
procedure TsSpreadBIFFWriter.WriteFormats(AStream: TStream);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
|
||||||
|
item: TsNumFormatData;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ListAllNumFormats;
|
ListAllNumFormats;
|
||||||
|
|
||||||
|
item := NumFormatList[20];
|
||||||
|
|
||||||
i := NumFormatList.Find(NumFormatList.FirstFormatIndexInFile);
|
i := NumFormatList.Find(NumFormatList.FirstFormatIndexInFile);
|
||||||
while i < NumFormatList.Count do begin
|
if i > -1 then
|
||||||
if NumFormatList[i] <> nil then
|
while i < NumFormatList.Count do begin
|
||||||
WriteFormat(AStream, NumFormatList[i], i);
|
if NumFormatList[i] <> nil then
|
||||||
inc(i);
|
WriteFormat(AStream, NumFormatList[i], i);
|
||||||
end;
|
inc(i);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Writes a 64-bit floating point NUMBER record.
|
{ Writes a 64-bit floating point NUMBER record.
|
||||||
|
Reference in New Issue
Block a user