You've already forked lazarus-ccr
fpspreadsheet: Add stream version of TsWorkbook.GetFormatFromFileHeader (patch by Craig Peterson, issue #28465)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4241 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -637,7 +637,9 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
class function GetFormatFromFileHeader(const AFileName: TFileName;
|
class function GetFormatFromFileHeader(const AFileName: TFileName;
|
||||||
out SheetType: TsSpreadsheetFormat): Boolean;
|
out SheetType: TsSpreadsheetFormat): Boolean; overload;
|
||||||
|
class function GetFormatFromFileHeader(AStream: TStream;
|
||||||
|
out SheetType: TsSpreadsheetFormat): Boolean; overload;
|
||||||
function CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsBasicSpreadReader;
|
function CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsBasicSpreadReader;
|
||||||
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsBasicSpreadWriter;
|
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsBasicSpreadWriter;
|
||||||
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); overload;
|
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); overload;
|
||||||
@@ -6504,6 +6506,25 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
class function TsWorkbook.GetFormatFromFileHeader(const AFileName: TFileName;
|
class function TsWorkbook.GetFormatFromFileHeader(const AFileName: TFileName;
|
||||||
out SheetType: TsSpreadsheetFormat): Boolean;
|
out SheetType: TsSpreadsheetFormat): Boolean;
|
||||||
|
var
|
||||||
|
stream: TStream;
|
||||||
|
begin
|
||||||
|
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
|
||||||
|
try
|
||||||
|
Result := GetFormatFromFileHeader(stream, SheetType)
|
||||||
|
finally
|
||||||
|
stream.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Helper method for determining the spreadsheet type. Read the first few bytes
|
||||||
|
of a stream and determines the spreadsheet type from the characteristic
|
||||||
|
signature. Only implemented for xls where several file types have the same
|
||||||
|
extension.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
class function TsWorkbook.GetFormatFromFileHeader(AStream: TStream;
|
||||||
|
out SheetType: TsSpreadsheetFormat): Boolean; overload;
|
||||||
const
|
const
|
||||||
BIFF2_HEADER: array[0..3] of byte = (
|
BIFF2_HEADER: array[0..3] of byte = (
|
||||||
$09,$00, $04,$00); // they are common to all BIFF2 files that I've seen
|
$09,$00, $04,$00); // they are common to all BIFF2 files that I've seen
|
||||||
@@ -6526,51 +6547,47 @@ const
|
|||||||
|
|
||||||
var
|
var
|
||||||
buf: packed array[0..7] of byte = (0,0,0,0,0,0,0,0);
|
buf: packed array[0..7] of byte = (0,0,0,0,0,0,0,0);
|
||||||
stream: TStream;
|
|
||||||
i: Integer;
|
i: Integer;
|
||||||
ok: Boolean;
|
ok: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone);
|
if AStream = nil then
|
||||||
try
|
exit;
|
||||||
// Read first 8 bytes
|
|
||||||
stream.ReadBuffer(buf, 8);
|
|
||||||
|
|
||||||
// Check for Excel 2
|
// Read first 8 bytes
|
||||||
ok := true;
|
AStream.ReadBuffer(buf, 8);
|
||||||
for i:=0 to High(BIFF2_HEADER) do
|
|
||||||
if buf[i] <> BIFF2_HEADER[i] then
|
// Check for Excel 2
|
||||||
begin
|
ok := true;
|
||||||
ok := false;
|
for i:=0 to High(BIFF2_HEADER) do
|
||||||
break;
|
if buf[i] <> BIFF2_HEADER[i] then
|
||||||
end;
|
|
||||||
if ok then
|
|
||||||
begin
|
begin
|
||||||
SheetType := sfExcel2;
|
ok := false;
|
||||||
Exit(True);
|
break;
|
||||||
end;
|
end;
|
||||||
|
if ok then
|
||||||
|
begin
|
||||||
|
SheetType := sfExcel2;
|
||||||
|
Exit(True);
|
||||||
|
end;
|
||||||
|
|
||||||
// Check for Excel 5 or 8
|
// Check for Excel 5 or 8
|
||||||
for i:=0 to High(BIFF58_HEADER) do
|
for i:=0 to High(BIFF58_HEADER) do
|
||||||
if buf[i] <> BIFF58_HEADER[i] then
|
if buf[i] <> BIFF58_HEADER[i] then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Now we know that the file is a Microsoft compound document.
|
// Now we know that the file is a Microsoft compound document.
|
||||||
|
|
||||||
// We check for Excel 5 in which the stream is named "Book"
|
// We check for Excel 5 in which the stream is named "Book"
|
||||||
if ValidOLEStream(stream, 'Book') then begin
|
if ValidOLEStream(AStream, 'Book') then begin
|
||||||
SheetType := sfExcel5;
|
SheetType := sfExcel5;
|
||||||
exit(True);
|
exit(True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Now we check for Excel 8 which names the stream "Workbook"
|
// Now we check for Excel 8 which names the stream "Workbook"
|
||||||
if ValidOLEStream(stream, 'Workbook') then begin
|
if ValidOLEStream(AStream, 'Workbook') then begin
|
||||||
SheetType := sfExcel8;
|
SheetType := sfExcel8;
|
||||||
exit(True);
|
exit(True);
|
||||||
end;
|
|
||||||
|
|
||||||
finally
|
|
||||||
stream.Free;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user