You've already forked lazarus-ccr
fpspreadsheet: Finishes the basic support for date reading
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2263 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -602,7 +602,8 @@ begin
|
|||||||
|
|
||||||
//cctFormula
|
//cctFormula
|
||||||
cctNumber: Result := FloatToStr(ACell^.NumberValue);
|
cctNumber: Result := FloatToStr(ACell^.NumberValue);
|
||||||
cctUTF8String: Result := ACell^.UTF8StringValue;
|
cctUTF8String: Result := ACell^.UTF8StringValue;
|
||||||
|
cctDateTime: Result := SysUtils.DateToStr(ACell^.DateTimeValue);
|
||||||
else
|
else
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
@ -52,7 +52,7 @@ unit xlsbiff8;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpcanvas,
|
Classes, SysUtils, fpcanvas, DateUtils,
|
||||||
fpspreadsheet, xlscommon,
|
fpspreadsheet, xlscommon,
|
||||||
{$ifdef USE_NEW_OLE}
|
{$ifdef USE_NEW_OLE}
|
||||||
fpolebasic,
|
fpolebasic,
|
||||||
@ -104,7 +104,7 @@ type
|
|||||||
procedure ReadXF(const AStream: TStream);
|
procedure ReadXF(const AStream: TStream);
|
||||||
procedure ReadFormat(const AStream: TStream);
|
procedure ReadFormat(const AStream: TStream);
|
||||||
function FindFormatRecordForCell(const AFXIndex: Integer): TFormatRecordData;
|
function FindFormatRecordForCell(const AFXIndex: Integer): TFormatRecordData;
|
||||||
class function ConvertExcelDateToTDateTime(const AExcelDateNum: Integer): TDateTime;
|
class function ConvertExcelDateToTDateTime(const AExcelDateNum: Double; ABaseDate: TDateTime): TDateTime;
|
||||||
|
|
||||||
// Workbook Globals records
|
// Workbook Globals records
|
||||||
// procedure ReadCodepage in xlscommon
|
// procedure ReadCodepage in xlscommon
|
||||||
@ -1472,6 +1472,7 @@ begin
|
|||||||
INT_EXCEL_ID_FONT: ReadFont(AStream);
|
INT_EXCEL_ID_FONT: ReadFont(AStream);
|
||||||
INT_EXCEL_ID_XF: ReadXF(AStream);
|
INT_EXCEL_ID_XF: ReadXF(AStream);
|
||||||
INT_EXCEL_ID_FORMAT: ReadFormat(AStream);
|
INT_EXCEL_ID_FORMAT: ReadFormat(AStream);
|
||||||
|
INT_EXCEL_ID_DATEMODE: ReadDateMode(AStream);
|
||||||
else
|
else
|
||||||
// nothing
|
// nothing
|
||||||
end;
|
end;
|
||||||
@ -1557,6 +1558,7 @@ var
|
|||||||
ARow, ACol, XF: WORD;
|
ARow, ACol, XF: WORD;
|
||||||
Number: Double;
|
Number: Double;
|
||||||
lFormatData: TFormatRecordData;
|
lFormatData: TFormatRecordData;
|
||||||
|
lDateTime: TDateTime;
|
||||||
begin
|
begin
|
||||||
ReadRowColXF(AStream,ARow,ACol,XF);
|
ReadRowColXF(AStream,ARow,ACol,XF);
|
||||||
|
|
||||||
@ -1570,14 +1572,17 @@ begin
|
|||||||
// See: http://www.gaia-gis.it/FreeXL/freexl-1.0.0a-doxy-doc/Format.html
|
// See: http://www.gaia-gis.it/FreeXL/freexl-1.0.0a-doxy-doc/Format.html
|
||||||
// Unfornately Excel doesnt give us a direct way to find this,
|
// Unfornately Excel doesnt give us a direct way to find this,
|
||||||
// we need to guess by the FORMAT field
|
// we need to guess by the FORMAT field
|
||||||
{ lFormatData := FindFormatRecordForCell(XF);
|
lFormatData := FindFormatRecordForCell(XF);
|
||||||
if lFormatData <> nil then
|
if lFormatData <> nil then
|
||||||
begin
|
begin
|
||||||
// Dates have /
|
// Dates have /
|
||||||
if Pos('/', lFormatData.FormatString) > 0 then
|
if Pos('/', lFormatData.FormatString) > 0 then
|
||||||
begin
|
begin
|
||||||
|
lDateTime := ConvertExcelDateToTDateTime(Number, FBaseDate);
|
||||||
|
FWorksheet.WriteDateTime(ARow,ACol,lDateTime);
|
||||||
|
Exit;
|
||||||
end;
|
end;
|
||||||
end;}
|
end;
|
||||||
|
|
||||||
FWorksheet.WriteNumber(ARow,ACol,Number);
|
FWorksheet.WriteNumber(ARow,ACol,Number);
|
||||||
end;
|
end;
|
||||||
@ -1963,9 +1968,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
class function TsSpreadBIFF8Reader.ConvertExcelDateToTDateTime(
|
class function TsSpreadBIFF8Reader.ConvertExcelDateToTDateTime(
|
||||||
const AExcelDateNum: Integer): TDateTime;
|
const AExcelDateNum: Double; ABaseDate: TDateTime): TDateTime;
|
||||||
begin
|
begin
|
||||||
|
Result := IncDay(ABaseDate, Round(AExcelDateNum));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadFont(const AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadFont(const AStream: TStream);
|
||||||
|
@ -7,13 +7,14 @@ unit xlscommon;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils, DateUtils,
|
||||||
fpspreadsheet,
|
fpspreadsheet,
|
||||||
fpsutils, lconvencoding;
|
fpsutils, lconvencoding;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ RECORD IDs which didn't change across versions 2-8 }
|
{ RECORD IDs which didn't change across versions 2-8 }
|
||||||
INT_EXCEL_ID_CODEPAGE = $0042;
|
INT_EXCEL_ID_CODEPAGE = $0042;
|
||||||
|
INT_EXCEL_ID_DATEMODE = $0022;
|
||||||
|
|
||||||
{ Formula constants TokenID values }
|
{ Formula constants TokenID values }
|
||||||
|
|
||||||
@ -104,9 +105,12 @@ type
|
|||||||
TsSpreadBIFFReader = class(TsCustomSpreadReader)
|
TsSpreadBIFFReader = class(TsCustomSpreadReader)
|
||||||
protected
|
protected
|
||||||
FCodepage: string;
|
FCodepage: string;
|
||||||
|
FBaseDate: TDateTime;
|
||||||
|
constructor Create; override;
|
||||||
// Here we can add reading of records which didn't change across BIFF2-8 versions
|
// Here we can add reading of records which didn't change across BIFF2-8 versions
|
||||||
// Workbook Globals records
|
// Workbook Globals records
|
||||||
procedure ReadCodePage(AStream: TStream);
|
procedure ReadCodePage(AStream: TStream);
|
||||||
|
procedure ReadDateMode(AStream: TStream);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsSpreadBIFFWriter }
|
{ TsSpreadBIFFWriter }
|
||||||
@ -130,6 +134,14 @@ implementation
|
|||||||
|
|
||||||
{ TsSpreadBIFFReader }
|
{ TsSpreadBIFFReader }
|
||||||
|
|
||||||
|
constructor TsSpreadBIFFReader.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
// Initial base date in case it wont be informed
|
||||||
|
FBaseDate := DateUtils.EncodeDateDay(1900, 1);
|
||||||
|
FBaseDate := DateUtils.IncDay(FBaseDate, -1);
|
||||||
|
end;
|
||||||
|
|
||||||
// In BIFF 8 it seams to always use the UTF-16 codepage
|
// In BIFF 8 it seams to always use the UTF-16 codepage
|
||||||
procedure TsSpreadBIFFReader.ReadCodePage(AStream: TStream);
|
procedure TsSpreadBIFFReader.ReadCodePage(AStream: TStream);
|
||||||
var
|
var
|
||||||
@ -181,6 +193,30 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadBIFFReader.ReadDateMode(AStream: TStream);
|
||||||
|
var
|
||||||
|
lBaseMode: Word;
|
||||||
|
begin
|
||||||
|
//5.28 DATEMODE
|
||||||
|
//BIFF2 BIFF3 BIFF4 BIFF5 BIFF8
|
||||||
|
//0022H 0022H 0022H 0022H 0022H
|
||||||
|
//This record specifies the base date for displaying date values. All dates are stored as count of days past this base date. In
|
||||||
|
//BIFF2-BIFF4 this record is part of the Calculation Settings Block (➜4.3). In BIFF5-BIFF8 it is stored in the Workbook
|
||||||
|
//Globals Substream.
|
||||||
|
//Record DATEMODE, BIFF2-BIFF8:
|
||||||
|
//Offset Size Contents
|
||||||
|
//0 2 0 = Base date is 1899-Dec-31 (the cell value 1 represents 1900-Jan-01)
|
||||||
|
// 1 = Base date is 1904-Jan-01 (the cell value 1 represents 1904-Jan-02)
|
||||||
|
lBaseMode := WordLEtoN(AStream.ReadWord);
|
||||||
|
if lBaseMode = 0 then
|
||||||
|
begin
|
||||||
|
FBaseDate := DateUtils.EncodeDateDay(1900, 1);
|
||||||
|
FBaseDate := DateUtils.IncDay(FBaseDate, -1);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FBaseDate := DateUtils.EncodeDateDay(1904, 1);
|
||||||
|
end;
|
||||||
|
|
||||||
function TsSpreadBIFFWriter.FPSColorToEXCELPallete(AColor: TsColor): Word;
|
function TsSpreadBIFFWriter.FPSColorToEXCELPallete(AColor: TsColor): Word;
|
||||||
begin
|
begin
|
||||||
case AColor of
|
case AColor of
|
||||||
|
Reference in New Issue
Block a user