You've already forked lazarus-ccr
fpspreadsheet: xlsx reads images in header/footer
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8333 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -64,6 +64,7 @@
|
||||
</Parsing>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
<UseExternalDbgSyms Value="True"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
|
@ -20,6 +20,24 @@ const
|
||||
|
||||
begin
|
||||
Writeln('Starting program "demo_write_headerfooter_images"...');
|
||||
if not FileExists(image1) then
|
||||
begin
|
||||
WriteLn(ExpandFilename(image1) + ' not found.');
|
||||
Halt;
|
||||
end;
|
||||
|
||||
if not FileExists(image2) then
|
||||
begin
|
||||
WriteLn(ExpandFilename(image2) + ' not found.');
|
||||
Halt;
|
||||
end;
|
||||
|
||||
if not FileExists(image3) then
|
||||
begin
|
||||
WriteLn(ExpandFilename(image3) + ' not found.');
|
||||
Halt;
|
||||
end;
|
||||
|
||||
// Create the spreadsheet
|
||||
MyWorkbook := TsWorkbook.Create;
|
||||
try
|
||||
|
@ -7,6 +7,9 @@ program demo_read_images;
|
||||
uses
|
||||
SysUtils, fpspreadsheet, fpstypes, fpsutils, fpsimages, xlsxooxml, fpsopendocument;
|
||||
|
||||
const
|
||||
FILE_NAME = 'img';
|
||||
|
||||
var
|
||||
workbook: TsWorkbook;
|
||||
worksheet: TsWorksheet;
|
||||
@ -24,10 +27,10 @@ begin
|
||||
// Read spreadsheet file
|
||||
myDir := ExtractFilePath(ParamStr(0));
|
||||
{$IFDEF USE_XLSX}
|
||||
workbook.ReadFromFile(myDir + 'img.xlsx', sfOOXML);
|
||||
workbook.ReadFromFile(myDir + FILE_NAME + '.xlsx', sfOOXML);
|
||||
{$ENDIF}
|
||||
{$IFDEF USE_OPENDOCUMENT}
|
||||
workbook.ReadFromFile(myDir + 'img.ods', sfOpenDocument);
|
||||
workbook.ReadFromFile(myDir + FILE_NAME + '.ods', sfOpenDocument);
|
||||
{$ENDIF}
|
||||
|
||||
// Get worksheets
|
||||
@ -48,6 +51,7 @@ begin
|
||||
', ScaleX=', img^.ScaleX:0:2,
|
||||
', ScaleY=', img^.ScaleY:0:2
|
||||
);
|
||||
if embObj.FileName <> '' then
|
||||
embobj.Stream.SaveToFile(ExtractFileName(embobj.FileName));
|
||||
end;
|
||||
end;
|
||||
|
@ -105,10 +105,10 @@ type
|
||||
procedure ReadDifferentialFormat(ANode: TDOMNode);
|
||||
procedure ReadDifferentialFormats(ANode: TDOMNode);
|
||||
procedure ReadDimension(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadDrawing(ANode: TDOMNode; ASheet: TsBasicWorksheet);
|
||||
function ReadDrawingFileName(AStream: TStream; ASheetRel: String): String;
|
||||
procedure ReadDrawing(AStream: TStream; ARelsFile: String; ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadDrawingRels(ANode: TDOMNode; ASheet: TsBasicWorksheet);
|
||||
procedure ReadEmbeddedObjs(AStream: TStream);
|
||||
function ReadFileNameFromRels(AStream: TStream; ARelsFile, ARelType, ARelID: String): String;
|
||||
procedure ReadFileVersion(ANode: TDOMNode);
|
||||
procedure ReadFills(ANode: TDOMNode);
|
||||
function ReadFont(ANode: TDOMNode): Integer;
|
||||
@ -129,9 +129,12 @@ type
|
||||
procedure ReadSheetList(ANode: TDOMNode);
|
||||
procedure ReadSheetPr(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadSheetProtection(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadSheetRelFileNames(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadSheetRels(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadSheetViews(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadThemeElements(ANode: TDOMNode);
|
||||
procedure ReadThemeColors(ANode: TDOMNode);
|
||||
procedure ReadThemeElements(ANode: TDOMNode);
|
||||
procedure ReadVmlDrawing(AStream: TStream; ARelsFile: String; ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadWorkbookProtection(ANode: TDOMNode);
|
||||
procedure ReadWorksheet(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
protected
|
||||
@ -392,10 +395,14 @@ type
|
||||
RelID: String;
|
||||
MediaName: String;
|
||||
FileName: String;
|
||||
Worksheet: TsBasicWorksheet;
|
||||
ImgIndex: Integer;
|
||||
IsHeaderFooter: Boolean;
|
||||
Worksheet: TsBasicWorksheet;
|
||||
// This part is for images embedded in to worksheet
|
||||
FromRow, FromCol, ToRow, ToCol: Cardinal;
|
||||
FromRowOffs, FromColOffs, ToRowOffs, ToColOffs: Double;
|
||||
// This part is for header/footer images.
|
||||
// ... to be completed ...
|
||||
end;
|
||||
|
||||
THyperlinkListData = class
|
||||
@ -419,7 +426,10 @@ type
|
||||
Name: String;
|
||||
ID: String;
|
||||
Hidden: Boolean;
|
||||
DrawingFile: String;
|
||||
Drawing_relID: String;
|
||||
Drawing_File: String;
|
||||
VmlDrawing_relID: String;
|
||||
VmlDrawing_File: String;
|
||||
end;
|
||||
|
||||
TSharedObjData = class
|
||||
@ -526,6 +536,18 @@ begin
|
||||
Result[2] := 'F'; // --> "FFrrggbb"
|
||||
end;
|
||||
|
||||
function RelsFileFor(AFileName: String): String;
|
||||
var
|
||||
path: String;
|
||||
fn: String;
|
||||
p: Integer;
|
||||
begin
|
||||
p := RPos('/', AFileName);
|
||||
path := Copy(AFileName, 1, p);
|
||||
fn := copy(AFileName, p+1, MaxInt);
|
||||
Result := path + '_rels/' + fn + '.rels';
|
||||
end;
|
||||
|
||||
function StrToFillStyle(s: String): TsFillStyle;
|
||||
var
|
||||
fs: TsFillStyle;
|
||||
@ -2471,7 +2493,12 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadDrawing(ANode: TDOMNode; ASheet: TsBasicWorksheet);
|
||||
{ Reads the parameters of the embedded images defined as children of the
|
||||
specified node which is in a drawingX.xml file.
|
||||
ARelsFile is the associated rels file, drawingX.xml.rels in the _rels folder,
|
||||
and contains the media file names of the images. }
|
||||
procedure TsSpreadOOXMLReader.ReadDrawing(AStream: TStream; ARelsFile: String;
|
||||
ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
node, child, child2: TDOMNode;
|
||||
nodeName: String = '';
|
||||
@ -2482,6 +2509,7 @@ var
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit;
|
||||
|
||||
ANode := ANode.FirstChild;
|
||||
while Assigned(ANode) do
|
||||
begin
|
||||
@ -2572,8 +2600,10 @@ begin
|
||||
data.ToRowOffs := toRowOffs;
|
||||
data.RelId := rId;
|
||||
data.FileName := fileName;
|
||||
data.MediaName := ReadFileNameFromRels(AStream, ARelsFile, SCHEMAS_IMAGE, rID);
|
||||
data.ImgIndex := -1;
|
||||
data.Worksheet := ASheet;
|
||||
data.Worksheet := AWorksheet;
|
||||
data.IsHeaderFooter := false;
|
||||
FEmbeddedObjList.Add(data);
|
||||
end;
|
||||
|
||||
@ -2581,39 +2611,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsSpreadOOXMLReader.ReadDrawingFileName(AStream: TStream; ASheetRel: String): String;
|
||||
var
|
||||
XMLStream: TStream;
|
||||
doc: TXMLDocument;
|
||||
node: TDOMNode;
|
||||
relType: String;
|
||||
relTarget: String;
|
||||
begin
|
||||
Result := '';
|
||||
doc := nil;
|
||||
XMLStream := CreateXMLStream;
|
||||
try
|
||||
if not UnzipToStream(AStream, ASheetRel, XMLStream) then
|
||||
raise EFPSpreadsheetReader.CreateFmt(rsDefectiveInternalFileStructure, ['xlsx']);
|
||||
ReadXMLStream(doc, XMLStream);
|
||||
node := doc.DocumentElement.FindNode('Relationship');
|
||||
while Assigned(node) do begin
|
||||
relType := GetAttrValue(node, 'Type');
|
||||
if relType = SCHEMAS_DRAWING then
|
||||
begin
|
||||
relTarget := GetAttrValue(node, 'Target'); // --> '../drawings/drawing1.xml'
|
||||
// Replace '..' by 'xl' (needed by the unzipper to extract the file)
|
||||
Result := MakeXLPath(relTarget); // --> 'xl/drawings/drawing1.xml'
|
||||
exit;
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
finally
|
||||
XMLStream.Free;
|
||||
doc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadDrawingRels(ANode: TDOMNode; ASheet: TsBasicWorksheet);
|
||||
var
|
||||
nodeName: String;
|
||||
@ -2656,78 +2653,58 @@ end;
|
||||
procedure TsSpreadOOXMLReader.ReadEmbeddedObjs(AStream: TStream);
|
||||
var
|
||||
i, j: Integer;
|
||||
fn, s: String;
|
||||
fn, relsFn, s: String;
|
||||
XMLStream: TStream;
|
||||
doc: TXMLDocument;
|
||||
sheet: TsWorksheet;
|
||||
data: TEmbeddedObjData;
|
||||
SheetRels: TStrings;
|
||||
sheetData: TSheetData;
|
||||
w, h: Double;
|
||||
img: TsEmbeddedObj;
|
||||
scaleX, scaleY: Double;
|
||||
begin
|
||||
SheetRels := TStringList.Create;
|
||||
try
|
||||
// Get the name of the files in xl/worksheet/_rels.
|
||||
// This should be "sheet1.xml.rels", "sheet2.xml.rels", etc.
|
||||
// They belong to the 1st, 2nd etc. worksheet and contain the name of
|
||||
// the drawing.xml files describing the embedded images.
|
||||
ListFileNamesInDir(sheetRels, OOXML_PATH_XL_WORKSHEETS_RELS);
|
||||
// Get the name of the drawing files and store them in the SheetData
|
||||
for i := 0 to sheetRels.Count-1 do
|
||||
begin
|
||||
// Get index in sheet-rel file. Decremented by 1 this is the index of the
|
||||
// worksheet.
|
||||
fn := SheetRels[i];
|
||||
Delete(fn, 1, Length(OOXML_PATH_XL_WORKSHEETS_RELS + 'sheet'));
|
||||
s := Copy(fn, 1, pos('.', fn)-1);
|
||||
j := StrToInt(s) - 1;
|
||||
sheetData := TSheetData(FSheetList[j]) ;
|
||||
// Store the name of the drawing.xml file in the SheetData
|
||||
sheetData.DrawingFile := ReadDrawingFileName(AStream, SheetRels[i]);
|
||||
end;
|
||||
finally
|
||||
SheetRels.Free;
|
||||
end;
|
||||
|
||||
doc := nil;
|
||||
j := 1;
|
||||
try
|
||||
for i := 0 to FSheetList.Count-1 do
|
||||
begin
|
||||
fn := TSheetData(FSheetList[i]).DrawingFile;
|
||||
if fn = '' then
|
||||
Continue;
|
||||
sheetData := TSheetData(FSheetList[i]);
|
||||
sheet := (FWorkbook as TsWorkbook).GetWorksheetByIndex(i);
|
||||
|
||||
// Read the drawings.xml file
|
||||
fn := sheetData.Drawing_File;
|
||||
if fn <> '' then
|
||||
begin
|
||||
XMLStream := CreateXMLStream;
|
||||
try
|
||||
// Read drawings parameters and store them in the FEmbeddedObjList.
|
||||
if not UnzipToStream(AStream, fn, XMLStream) then
|
||||
raise EFPSpreadsheetReader.CreateFmt(rsDefectiveInternalFileStructure, ['xlsx']);
|
||||
ReadXMLStream(doc, XMLStream);
|
||||
// Read drawings parameters and store them in the FEmbeddedObjList.
|
||||
ReadDrawing(doc.DocumentElement, sheet);
|
||||
relsFn := RelsFileFor(fn);
|
||||
ReadDrawing(AStream, relsFn, doc.DocumentElement, sheet);
|
||||
finally
|
||||
XMLStream.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Now repeat the same with the vmlDrawings file
|
||||
fn := sheetData.VmlDrawing_File;
|
||||
if fn <> '' then
|
||||
begin
|
||||
XMLStream := CreateXMLStream;
|
||||
try
|
||||
// construct filename of drawing.xml.rels file
|
||||
Delete(fn, 1, Length(OOXML_PATH_XL_DRAWINGS));
|
||||
fn := OOXML_PATH_XL_DRAWINGS_RELS + fn + '.rels';
|
||||
// Read vmDrawings parameters and store them in the FEmbeddedObjList, too.
|
||||
if not UnzipToStream(AStream, fn, XMLStream) then
|
||||
raise EFPSpreadsheetReader.CreateFmt(rsDefectiveInternalFileStructure, ['xlsx']);
|
||||
ReadXMLStream(doc, XMLStream);
|
||||
// Read rId value for this sheet and look up the media file name.
|
||||
// Store it in the FEmbeddedObjList.
|
||||
ReadDrawingRels(Doc.DocumentElement.FindNode('Relationship'), sheet);
|
||||
relsFn := RelsFileFor(fn);
|
||||
ReadVmlDrawing(AStream, relsFn, doc.DocumentElement, sheet);
|
||||
finally
|
||||
XMLStream.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Read the embedded streams, add them to the workbook...
|
||||
ReadMedia(AStream);
|
||||
@ -2740,6 +2717,11 @@ begin
|
||||
if (sheet <> nil) and (data.ImgIndex > -1) then
|
||||
begin
|
||||
img := TsWorkbook(FWorkbook).GetEmbeddedObj(data.ImgIndex);
|
||||
if data.IsHeaderFooter then
|
||||
begin
|
||||
// to do: add header/footer processing here.
|
||||
end else
|
||||
begin
|
||||
w := -data.FromColOffs + data.ToColOffs;
|
||||
h := -data.FromRowOffs + data.ToRowOffs;
|
||||
for j := data.FromCol to data.ToCol-1 do
|
||||
@ -2760,11 +2742,50 @@ begin
|
||||
);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
doc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsSpreadOOXMLReader.ReadFileNameFromRels(AStream: TStream;
|
||||
ARelsFile, ARelType, ARelID: String): String;
|
||||
var
|
||||
XMLStream: TStream;
|
||||
doc: TXMLDocument;
|
||||
node: TDOMNode;
|
||||
relID: String;
|
||||
relType: String;
|
||||
relTarget: String;
|
||||
begin
|
||||
Result := '';
|
||||
if ARelID = '' then
|
||||
exit;
|
||||
|
||||
doc := nil;
|
||||
XMLStream := CreateXMLStream;
|
||||
try
|
||||
if not UnzipToStream(AStream, ARelsFile, XMLStream) then
|
||||
raise EFPSpreadsheetReader.CreateFmt(rsDefectiveInternalFileStructure, ['xlsx']);
|
||||
ReadXMLStream(doc, XMLStream);
|
||||
node := doc.DocumentElement.FindNode('Relationship');
|
||||
while Assigned(node) do begin
|
||||
relType := GetAttrValue(node, 'Type');
|
||||
relID := GetAttrValue(node, 'Id');
|
||||
if (relType = ARelType) and (relID = ARelID) then
|
||||
begin
|
||||
relTarget := GetAttrValue(node, 'Target');
|
||||
Result := MakeXLPath(relTarget);
|
||||
exit;
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
finally
|
||||
XMLStream.Free;
|
||||
doc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadFileVersion(ANode: TDOMNode);
|
||||
begin
|
||||
FWrittenByFPS := GetAttrValue(ANode, 'appName') = 'fpspreadsheet';
|
||||
@ -3129,6 +3150,7 @@ var
|
||||
unzip: TStreamUnzipper;
|
||||
i: Integer;
|
||||
data: TEmbeddedObjData;
|
||||
ext: String;
|
||||
begin
|
||||
unzip := TStreamUnzipper.Create(AStream);
|
||||
try
|
||||
@ -3142,7 +3164,15 @@ begin
|
||||
unzip.UnzipFile(data.MediaName, memStream);
|
||||
memStream.Position := 0;
|
||||
if memStream.Size > 0 then
|
||||
begin
|
||||
data.ImgIndex := (FWorkbook as TsWorkbook).AddEmbeddedObj(memStream, ExtractFileName(data.Filename));
|
||||
ext := ExtractFileExt(data.MediaName);
|
||||
if data.FileName = '' then
|
||||
data.FileName := ExtractFileName(data.MediaName)
|
||||
else
|
||||
if ExtractFileExt(data.FileName) = '' then
|
||||
data.FileName := data.FileName + ext;
|
||||
end;
|
||||
memStream.Free;
|
||||
end;
|
||||
end;
|
||||
@ -3800,6 +3830,45 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// Get the names of the files associated with the specified worksheet by means
|
||||
// of Relationship IDs.
|
||||
procedure TsSpreadOOXMLReader.ReadSheetRelFileNames(AStream: TStream;
|
||||
AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
sheetData: TSheetData;
|
||||
sheetIndex: Integer;
|
||||
relsFile: String;
|
||||
begin
|
||||
sheetIndex := TsWorksheet(AWorksheet).Index;
|
||||
sheetData := TSheetData(FSheetList[sheetIndex]);
|
||||
relsFile := OOXML_PATH_XL_WORKSHEETS_RELS + 'sheet' + IntToStr(sheetIndex+1) + '.xml.rels';
|
||||
sheetData.Drawing_File := ReadFileNameFromRels(AStream, relsFile, SCHEMAS_DRAWING, sheetData.Drawing_relID);
|
||||
sheetData.VMLDrawing_File := ReadFileNameFromRels(AStream, relsFile, SCHEMAS_VMLDRAWING, sheetData.VMLDrawing_relID);
|
||||
end;
|
||||
|
||||
{ Extract the Relationship-IDs of the files related to the specified worksheet }
|
||||
procedure TsSpreadOOXMLReader.ReadSheetRels(ANode: TDOMNode;
|
||||
AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
nodeName: string;
|
||||
sheetData: TSheetData;
|
||||
sheetIndex: Integer;
|
||||
begin
|
||||
sheetIndex := TsWorksheet(AWorksheet).Index;
|
||||
sheetData := TSheetData(FSheetList[sheetIndex]);
|
||||
|
||||
ANode := ANode.FirstChild;
|
||||
while Assigned(ANode) do
|
||||
begin
|
||||
nodeName := ANode.NodeName;
|
||||
if nodeName = 'drawing' then
|
||||
sheetData.Drawing_relID := GetAttrValue(ANode, 'r:id')
|
||||
else if nodeName = 'legacyDrawingHF' then
|
||||
sheetData.VMLDrawing_relID := GetAttrValue(ANode, 'r:id');
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadSheetViews(ANode: TDOMNode;
|
||||
AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
@ -3949,6 +4018,60 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Reads the parameters of the header/footer images defined as children of the
|
||||
specified node which is in a vmlDrawingX.xml file.
|
||||
ARelsFile is the associated rels file, vmlDrawingX.xml.rels in the _rels folder,
|
||||
and contains the media file names of the images. }
|
||||
procedure TsSpreadOOXMLReader.ReadVmlDrawing(AStream: TStream; ARelsFile: String;
|
||||
ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
nodeName: String;
|
||||
node: TDOMNode;
|
||||
relID: String;
|
||||
title: String;
|
||||
data: TEmbeddedObjData;
|
||||
begin
|
||||
ANode := ANode.FirstChild;
|
||||
while Assigned(ANode) do
|
||||
begin
|
||||
nodeName := ANode.NodeName;
|
||||
if nodeName = 'v:shape' then
|
||||
begin
|
||||
node := ANode.FirstChild;
|
||||
while Assigned(node) do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
if nodeName = 'v:imagedata' then
|
||||
begin
|
||||
relID := GetAttrValue(node, 'o:relid');
|
||||
title := GetAttrValue(node, 'o:title');
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
if relID <> '' then
|
||||
begin
|
||||
data := TEmbeddedObjData.Create;
|
||||
data.FromCol := UNASSIGNED_ROW_COL_INDEX;
|
||||
data.FromColOffs := 0.0;
|
||||
data.ToCol := UNASSIGNED_ROW_COL_INDEX;
|
||||
data.ToColOffs := 0.0;
|
||||
data.FromRow := UNASSIGNED_ROW_COL_INDEX;
|
||||
data.FromRowOffs := 0.0;
|
||||
data.ToRow := UNASSIGNED_ROW_COL_INDEX;
|
||||
data.ToRowOffs := 0.0;
|
||||
data.RelId := relId;
|
||||
data.FileName := title;
|
||||
data.MediaName := ReadFileNameFromRels(AStream, ARelsFile, SCHEMAS_IMAGE, relID);
|
||||
data.ImgIndex := -1;
|
||||
data.Worksheet := AWorksheet;
|
||||
data.IsHeaderFooter := true;
|
||||
FEmbeddedObjList.Add(data);
|
||||
end;
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadWorkbookProtection(ANode: TDOMNode);
|
||||
var
|
||||
s : string;
|
||||
@ -4179,6 +4302,8 @@ begin
|
||||
ReadColRowBreaks(Doc_FindNode('rowBreaks'), FWorksheet);
|
||||
ReadColRowBreaks(Doc_FindNode('colBreaks'), FWorksheet);
|
||||
ReadHeaderFooter(Doc_FindNode('headerFooter'), FWorksheet);
|
||||
ReadSheetRels(Doc.DocumentElement, FWorksheet);
|
||||
ReadSheetRelFileNames(AStream, FWorksheet);
|
||||
|
||||
FreeAndNil(Doc);
|
||||
|
||||
|
Reference in New Issue
Block a user