fpspreadsheet: Split shared code for ooxml and ods readers off into new unit fpsxmlcommon.pas

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3378 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-07-25 16:31:34 +00:00
parent e3ce3e1d71
commit 005434006f
5 changed files with 102 additions and 157 deletions

View File

@ -66,11 +66,16 @@
<PackageName Value="LazUtils"/>
</Item1>
</RequiredPackages>
<Units Count="1">
<Units Count="2">
<Unit0>
<Filename Value="ooxmlread.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="..\..\fpsxmlcommon.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="fpsxmlcommon"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -10,7 +10,7 @@ program ooxmlread;
{$mode delphi}{$H+}
uses
Classes, SysUtils, fpspreadsheet, xlsxooxml; //fpsallformats;
Classes, SysUtils, fpspreadsheet, xlsxooxml, fpsxmlcommon; //fpsallformats;
var
MyWorkbook: TsWorkbook;

View File

@ -39,7 +39,7 @@ uses
fpspreadsheet,
laz2_xmlread, laz2_DOM,
AVL_Tree, math, dateutils,
fpsutils, fpsNumFormatParser;
fpsutils, fpsNumFormatParser, fpsxmlcommon;
type
TDateMode=(
@ -71,7 +71,7 @@ type
{ TsSpreadOpenDocReader }
TsSpreadOpenDocReader = class(TsCustomSpreadReader)
TsSpreadOpenDocReader = class(TsSpreadXMLReader)
private
FCellStyleList: TFPList;
FColumnStyleList: TFPList;
@ -94,10 +94,6 @@ type
function FindColumnByCol(AColIndex: Integer): Integer;
function FindColStyleByName(AStyleName: String): integer;
function FindRowStyleByName(AStyleName: String): Integer;
// Gets value for the specified attribute. Returns empty string if attribute
// not found.
function GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
function GetNodeValue(ANode: TDOMNode): String;
procedure ReadColumns(ATableNode: TDOMNode);
procedure ReadColumnStyle(AStyleNode: TDOMNode);
// Figures out the base year for times in this file (dates are unambiguous)
@ -968,36 +964,6 @@ begin
Result := -1;
end;
function TsSpreadOpenDocReader.GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
var
i : integer;
Found : Boolean;
begin
Found:=false;
i:=0;
Result:='';
while not Found and (i<ANode.Attributes.Length) do begin
if ANode.Attributes.Item[i].NodeName=AAttrName then begin
Found:=true;
Result:=ANode.Attributes.Item[i].NodeValue;
end;
inc(i);
end;
end;
{ Returns the text value of a node. Normally it would be sufficient to call
"ANode.NodeValue", but since the DOMParser needs to preserve white space
(for the spaces in date/time formats), we have to go more into detail. }
function TsSpreadOpenDocReader.GetNodeValue(ANode: TDOMNode): String;
var
child: TDOMNode;
begin
Result := '';
child := ANode.FirstChild;
if Assigned(child) and (child.NodeName = '#text') then
Result := child.NodeValue;
end;
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Word; ACellNode: TDOMNode);
var
styleName: String;
@ -1188,50 +1154,6 @@ var
BodyNode, SpreadSheetNode, TableNode: TDOMNode;
StylesNode: TDOMNode;
OfficeSettingsNode: TDOMNode;
{ We have to use our own ReadXMLFile procedure (there is one in xmlread)
because we have to preserve spaces in element text for date/time separator.
As a side-effect we have to skip leading spaces by ourselves. }
procedure ReadXMLFile(out ADoc: TXMLDocument; AFileName: String);
var
parser: TDOMParser;
src: TXMLInputSource;
stream: TStream;
// fstream: TStream;
begin
{
if (boBufStream in Workbook.Options) then begin
fstream := TFileStream.Create(AFilename, fmOpenRead + fmShareDenyWrite);
stream := TMemorystream.Create;
stream.CopyFrom(fstream, fstream.Size);
stream.Position := 0;
fstream.free;
end
}
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyWrite)
else
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyWrite);
try
parser := TDOMParser.Create;
try
parser.Options.PreserveWhiteSpace := true; // This preserves spaces!
src := TXMLInputSource.Create(stream);
try
parser.Parse(src, ADoc);
finally
src.Free;
end;
finally
parser.Free;
end;
finally
stream.Free;
end;
end;
begin
//unzip files into AFileName path
FilePath := GetTempDir(false);

View File

@ -0,0 +1,91 @@
unit fpsxmlcommon;
{$mode objfpc}
interface
uses
Classes, SysUtils,
laz2_xmlread, laz2_DOM,
fpspreadsheet;
type
TsSpreadXMLReader = class(TsCustomSpreadReader)
protected
function GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
function GetNodeValue(ANode: TDOMNode): String;
procedure ReadXMLFile(out ADoc: TXMLDocument; AFileName: String);
end;
implementation
uses
fpsStreams;
{ Gets value for the specified attribute. Returns empty string if attribute
not found. }
function TsSpreadXMLReader.GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
var
i: integer;
Found: Boolean;
begin
Found := false;
i := 0;
Result := '';
while not Found and (i < ANode.Attributes.Length) do begin
if ANode.Attributes.Item[i].NodeName = AAttrName then begin
Found := true;
Result := ANode.Attributes.Item[i].NodeValue;
end;
inc(i);
end;
end;
{ Returns the text value of a node. Normally it would be sufficient to call
"ANode.NodeValue", but since the DOMParser needs to preserve white space
(for the spaces in date/time formats), we have to go more into detail. }
function TsSpreadXMLReader.GetNodeValue(ANode: TDOMNode): String;
var
child: TDOMNode;
begin
Result := '';
child := ANode.FirstChild;
if Assigned(child) and (child.NodeName = '#text') then
Result := child.NodeValue;
end;
{ We have to use our own ReadXMLFile procedure (there is one in xmlread)
because we have to preserve spaces in element text for date/time separator.
As a side-effect we have to skip leading spaces by ourselves. }
procedure TsSpreadXMLReader.ReadXMLFile(out ADoc: TXMLDocument; AFileName: String);
var
parser: TDOMParser;
src: TXMLInputSource;
stream: TStream;
begin
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyWrite)
else
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyWrite);
try
parser := TDOMParser.Create;
try
parser.Options.PreserveWhiteSpace := true; // This preserves spaces!
src := TXMLInputSource.Create(stream);
try
parser.Parse(src, ADoc);
finally
src.Free;
end;
finally
parser.Free;
end;
finally
stream.Free;
end;
end;
end.

View File

@ -41,7 +41,7 @@ uses
{$ENDIF}
laz2_xmlread, laz2_DOM,
AVL_Tree,
fpspreadsheet, fpsutils;
fpspreadsheet, fpsutils, fpsxmlcommon;
type
@ -56,12 +56,10 @@ type
{ TsSpreadOOXMLReader }
TsSpreadOOXMLReader = class(TsCustomSpreadReader)
TsSpreadOOXMLReader = class(TsSpreadXMLReader)
private
FPointSeparatorSettings: TFormatSettings;
FSharedStrings: TStringList;
function GetAttrValue(ANode: TDOMNode; AAttrName: string): string;
function GetNodeValue(ANode: TDOMNode): String;
procedure ReadFont(ANode: TDOMNode);
procedure ReadFonts(ANode: TDOMNode);
procedure ReadSharedStrings(ANode: TDOMNode);
@ -271,33 +269,6 @@ begin
inherited Destroy;
end;
function TsSpreadOOXMLReader.GetAttrValue(ANode : TDOMNode; AAttrName : string) : string;
var
i : integer;
Found : Boolean;
begin
Found := false;
i := 0;
Result := '';
while not Found and (i < ANode.Attributes.Length) do begin
if ANode.Attributes.Item[i].NodeName = AAttrName then begin
Found := true;
Result := ANode.Attributes.Item[i].NodeValue;
end;
inc(i);
end;
end;
function TsSpreadOOXMLReader.GetNodeValue(ANode: TDOMNode): String;
var
child: TDOMNode;
begin
Result := '';
child := ANode.FirstChild;
if Assigned(child) and (child.NodeName = '#text') then
Result := child.NodeValue;
end;
procedure TsSpreadOOXMLReader.ReadFont(ANode: TDOMNode);
var
node: TDOMNode;
@ -482,50 +453,6 @@ var
StylesNode: TDOMNode;
OfficeSettingsNode: TDOMNode;
{ We have to use our own ReadXMLFile procedure (there is one in xmlread)
because we have to preserve spaces in element text for date/time separator.
As a side-effect we have to skip leading spaces by ourselves. }
procedure ReadXMLFile(out ADoc: TXMLDocument; AFileName: String);
var
parser: TDOMParser;
src: TXMLInputSource;
stream: TStream;
// fstream: TStream;
begin
{
if (boBufStream in Workbook.Options) then begin
fstream := TFileStream.Create(AFilename, fmOpenRead + fmShareDenyWrite);
stream := TMemorystream.Create;
stream.CopyFrom(fstream, fstream.Size);
stream.Position := 0;
fstream.free;
end
}
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create(AFileName, fmOpenRead + fmShareDenyWrite)
else
stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyWrite);
try
parser := TDOMParser.Create;
try
parser.Options.PreserveWhiteSpace := true; // This preserves spaces!
src := TXMLInputSource.Create(stream);
try
parser.Parse(src, ADoc);
finally
src.Free;
end;
finally
parser.Free;
end;
finally
stream.Free;
end;
end;
var
s: String;
node: TDOMNode;