You've already forked lazarus-ccr
fpspreadsheet: Add custom meta data support. Reading/writing for XLSX, Excel XML, ODS.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7591 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -58,6 +58,7 @@ end;
|
||||
var
|
||||
book: TsWorkbook;
|
||||
sheet: TsWorksheet;
|
||||
i: Integer;
|
||||
begin
|
||||
book := TsWorkbook.Create;
|
||||
try
|
||||
@ -72,6 +73,8 @@ begin
|
||||
book.MetaData.Comments.Add('Assign the creation date to the field CreatedAt.');
|
||||
book.MetaData.Keywords.Add('Test');
|
||||
book.MetaData.Keywords.Add('FPSpreadsheet');
|
||||
book.MetaData.AddCustom('Comparny', 'Disney');
|
||||
book.MetaData.AddCustom('Status', 'finished');
|
||||
|
||||
sheet := book.AddWorksheet('Test');
|
||||
sheet.WriteText(2, 3, 'abc');
|
||||
@ -86,9 +89,9 @@ begin
|
||||
book := TsWorkbook.Create;
|
||||
try
|
||||
// Select one of these
|
||||
book.ReadFromFile('test.ods');
|
||||
// book.ReadFromFile('test.ods');
|
||||
// book.ReadFromFile('test.xlsx');
|
||||
// book.ReadFromFile('test.xml');
|
||||
book.ReadFromFile('test.xml');
|
||||
WriteLn('Created by : ', book.MetaData.CreatedBy);
|
||||
WriteLn('Date created : ', DateTimeToStr(book.MetaData.DateCreated));
|
||||
WriteLn('Modified by : ', book.MetaData.LastModifiedBy);
|
||||
@ -96,6 +99,9 @@ begin
|
||||
WriteLn('Title : ', book.MetaData.Title);
|
||||
WriteLn('Subject : ', book.MetaData.Subject);
|
||||
WriteLn('Keywords : ', book.MetaData.Keywords.CommaText);
|
||||
WriteLn('Custom : ', 'Name':20, 'Value':20);
|
||||
for i := 0 to book.MetaData.Custom.Count-1 do
|
||||
WriteLn(' ', book.MetaData.Custom.Names[i]:20, book.MetaData.Custom.ValueFromIndex[i]:20);
|
||||
WriteLn('Comments: ');
|
||||
WriteLn(book.MetaData.Comments.Text);
|
||||
finally
|
||||
|
@ -1966,6 +1966,7 @@ var
|
||||
book: TsWorkbook;
|
||||
nodeName: String;
|
||||
s: String;
|
||||
name: String;
|
||||
begin
|
||||
book := TsWorkbook(FWorkbook);
|
||||
|
||||
@ -1992,6 +1993,12 @@ begin
|
||||
book.MetaData.Title := s;
|
||||
'dc:subject':
|
||||
book.Metadata.Subject := s;
|
||||
'meta:user-defined':
|
||||
begin
|
||||
name := GetAttrValue(ANode, 'meta:name');
|
||||
if name <> '' then
|
||||
book.MetaData.AddCustom(name, s);
|
||||
end;
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
@ -5911,6 +5918,16 @@ begin
|
||||
'<dc:description>%s</dc:description>', [s]));
|
||||
end;
|
||||
|
||||
if book.MetaData.Custom.Count > 0 then
|
||||
begin
|
||||
for i := 0 to book.Metadata.Custom.Count-1 do
|
||||
AppendToStream(FSMeta, Format(
|
||||
'<meta:user-defined meta:name="%s">%s</meta:user-defined>', [
|
||||
book.Metadata.Custom.Names[i],
|
||||
book.Metadata.Custom.ValueFromIndex[i]
|
||||
]));
|
||||
end;
|
||||
|
||||
AppendToStream(FSMeta,
|
||||
'</office:meta>');
|
||||
AppendToStream(FSMeta,
|
||||
|
@ -976,9 +976,12 @@ type
|
||||
FSubject: String;
|
||||
FComments: TStrings;
|
||||
FKeywords: TStrings;
|
||||
FCustom: TStrings;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function AddCustom(AName, AValue: String): Integer;
|
||||
procedure Clear;
|
||||
function IsEmpty: Boolean;
|
||||
property CreatedBy: String read FCreatedBy write FCreatedBy;
|
||||
property LastModifiedBy: String read FLastModifiedBy write FLastModifiedBy;
|
||||
@ -987,6 +990,7 @@ type
|
||||
property Subject: String read FSubject write FSubject;
|
||||
property Title: String read FTitle write FTitle;
|
||||
property Comments: TStrings read FComments write FComments;
|
||||
property Custom: TStrings read FCustom write FCustom;
|
||||
property Keywords: TStrings read FKeywords write FKeywords;
|
||||
end;
|
||||
|
||||
@ -1199,20 +1203,44 @@ begin
|
||||
inherited;
|
||||
FComments := TStringList.Create;
|
||||
FKeywords := TStringList.Create;
|
||||
FCustom := TStringList.Create;
|
||||
end;
|
||||
|
||||
destructor TsMetaData.Destroy;
|
||||
begin
|
||||
FComments.Free;
|
||||
FKeywords.Free;
|
||||
FCustom.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TsMetaData.Clear;
|
||||
begin
|
||||
FTitle := '';
|
||||
FSubject := '';
|
||||
FCreatedBy := '';
|
||||
FLastModifiedBy := '';
|
||||
FDateCreated := 0;
|
||||
FDateLastModified := 0;
|
||||
FComments.Clear;
|
||||
FKeywords.Clear;
|
||||
FCustom.Clear;
|
||||
end;
|
||||
|
||||
function TsMetaData.AddCustom(AName, AValue: String): Integer;
|
||||
begin
|
||||
Result := FCustom.IndexOf(AName);
|
||||
if result > -1 then
|
||||
FCustom.ValueFromIndex[Result] := AValue
|
||||
else
|
||||
Result := FCustom.Add(AName + '=' + AValue);
|
||||
end;
|
||||
|
||||
function TsMetaData.IsEmpty: Boolean;
|
||||
begin
|
||||
Result := (FCreatedBy = '') and (FLastModifiedBy = '') and
|
||||
(FTitle = '') and (FSubject = '') and
|
||||
(FComments.Count = 0) and (FKeywords.Count = 0) and
|
||||
(FComments.Count = 0) and (FKeywords.Count = 0) and (FCustom.Count = 0) and
|
||||
(FDateCreated = 0) and (FDateLastModified = 0);
|
||||
end;
|
||||
|
||||
|
@ -45,6 +45,7 @@ type
|
||||
procedure ReadCellProtection(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||
procedure ReadComment(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ACell: PCell);
|
||||
procedure ReadConditionalFormatting(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||
procedure ReadCustomDocumentProperties(ANode: TDOMNode);
|
||||
procedure ReadDocumentProperties(ANode: TDOMNode);
|
||||
procedure ReadExcelWorkbook(ANode: TDOMNode);
|
||||
procedure ReadFont(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||
@ -96,6 +97,7 @@ type
|
||||
procedure WriteConditionalFormat(AStream: TStream; AWorksheet: TsBasicWorksheet;
|
||||
AFormat: TsConditionalFormat);
|
||||
procedure WriteConditionalFormatting(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||
procedure WriteCustomDocumentProperties(AStream: TStream);
|
||||
procedure WriteDocumentProperties(AStream: TStream);
|
||||
procedure WriteExcelWorkbook(AStream: TStream);
|
||||
procedure WriteNames(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||
@ -1100,6 +1102,32 @@ begin
|
||||
sheet.WriteConditionalCellFormat(range, TsCFCondition(condition), op1, op2, fmtIndex);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Read the custom meta data fields
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadExcelXMLReader.ReadCustomDocumentProperties(ANode: TDOMNode);
|
||||
var
|
||||
book: TsWorkbook;
|
||||
value: String;
|
||||
nodeName: String;
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit;
|
||||
|
||||
book := TsWorkbook(FWorkbook);
|
||||
ANode := ANode.FirstChild;
|
||||
while ANode <> nil do
|
||||
begin
|
||||
nodeName := ANode.NodeName;
|
||||
if nodeName <> '#text' then
|
||||
begin
|
||||
value := GetNodeValue(ANode);
|
||||
book.MetaData.AddCustom(nodeName, value);
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the meta data etc.
|
||||
-------------------------------------------------------------------------------}
|
||||
@ -2069,6 +2097,7 @@ begin
|
||||
|
||||
// Read meta data
|
||||
ReadDocumentProperties(doc.DocumentElement.FindNode('DocumentProperties'));
|
||||
ReadCustomDocumentProperties(doc.DocumentElement.FindNode('CustomDocumentProperties'));
|
||||
|
||||
// Read style list
|
||||
ReadStyles(doc.DocumentElement.FindNode('Styles'));
|
||||
@ -2680,6 +2709,33 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadExcelXMLWriter.WriteCustomDocumentProperties(AStream: TStream);
|
||||
{ <CustomDocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<Comparny dt:dt="string">Disney</Comparny>
|
||||
<Status dt:dt="string">finished</Status>
|
||||
</CustomDocumentProperties> }
|
||||
var
|
||||
book: TsWorkbook;
|
||||
i: Integer;
|
||||
begin
|
||||
book := TsWorkbook(FWorkbook);
|
||||
if book.MetaData.Custom.Count = 0 then
|
||||
exit;
|
||||
|
||||
AppendToStream(AStream, INDENT1 +
|
||||
'<CustomDocumentProperties xmlns="urn:schemas-microsoft-com:office:office">' + LF);
|
||||
|
||||
for i := 0 to book.MetaData.Custom.Count-1 do
|
||||
AppendToStream(AStream, Format(INDENT2 +
|
||||
'<%0:s dt:dt="string">%1:s</%0:s>' + LF, [
|
||||
book.MetaData.Custom.Names[i],
|
||||
book.MetaData.Custom.ValueFromIndex[i]
|
||||
]));
|
||||
|
||||
AppendToStream(AStream, INDENT1 +
|
||||
'</CustomDocumentProperties>' + LF);
|
||||
end;
|
||||
|
||||
procedure TsSpreadExcelXMLWriter.WriteDateTime(AStream: TStream;
|
||||
const ARow, ACol: Cardinal; const AValue: TDateTime; ACell: PCell);
|
||||
var
|
||||
@ -2719,8 +2775,6 @@ begin
|
||||
end;
|
||||
|
||||
procedure TsSpreadExcelXMLWriter.WriteDocumentProperties(AStream: TStream);
|
||||
const
|
||||
LE = LineEnding;
|
||||
var
|
||||
sTitle: String;
|
||||
sSubject: String;
|
||||
@ -2733,32 +2787,30 @@ var
|
||||
begin
|
||||
book := TsWorkbook(FWorkbook);
|
||||
|
||||
if (book.MetaData.Title = '') and
|
||||
(book.MetaData.CreatedBy = '') and (book.MetaData.LastModifiedBy = '') and
|
||||
(book.MetaData.DateCreated <= 0) and (book.MetaData.DateLastModified <= 0) then
|
||||
if book.MetaData.IsEmpty then
|
||||
begin
|
||||
AppendToStream(AStream, INDENT1 +
|
||||
'<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office" />' + LE);
|
||||
'<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office" />' + LF);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if book.MetaData.Title <> '' then
|
||||
sTitle := '<Title>' + book.MetaData.Title + '</Title>' + LE + INDENT2
|
||||
sTitle := '<Title>' + book.MetaData.Title + '</Title>' + LF + INDENT2
|
||||
else
|
||||
sTitle := '';
|
||||
|
||||
if book.MetaData.Subject <> '' then
|
||||
sSubject := '<Subject>' + book.MetaData.Subject + '</Subject>' + LE + INDENT2
|
||||
sSubject := '<Subject>' + book.MetaData.Subject + '</Subject>' + LF + INDENT2
|
||||
else
|
||||
sSubject := '';
|
||||
|
||||
if book.MetaData.CreatedBy <> '' then
|
||||
sAuthor := '<Author>' + book.MetaData.CreatedBy + '</Author>' + LE + INDENT2
|
||||
sAuthor := '<Author>' + book.MetaData.CreatedBy + '</Author>' + LF + INDENT2
|
||||
else
|
||||
sAuthor := '';
|
||||
|
||||
if book.MetaData.LastModifiedBy <> '' then
|
||||
sLastAuthor := '<LastAuthor>' + book.MetaData.LastModifiedBy + '</LastAuthor>' + LE + INDENT2
|
||||
sLastAuthor := '<LastAuthor>' + book.MetaData.LastModifiedBy + '</LastAuthor>' + LF + INDENT2
|
||||
else
|
||||
sLastAuthor := '';
|
||||
|
||||
@ -2766,7 +2818,7 @@ begin
|
||||
if book.MetaData.DateCreated > 0 then begin
|
||||
dt := book.MetaData.DateCreated + GetLocalTimeOffset / (24*60);
|
||||
sDateCreated := FormatDateTime(ISO8601FormatExtendedUTC, dt);
|
||||
sDateCreated := '<Created>' + sDateCreated + '</Created>' + LE + INDENT2;
|
||||
sDateCreated := '<Created>' + sDateCreated + '</Created>' + LF + INDENT2;
|
||||
end else
|
||||
sDateCreated := '';
|
||||
|
||||
@ -2774,20 +2826,20 @@ begin
|
||||
begin
|
||||
dt := book.MetaData.DateLastModified + GetLocalTimeOffset / (24*60);
|
||||
sDateLastSaved := FormatDateTime(ISO8601FormatExtendedUTC, dt);
|
||||
sDateLastSaved := '<LastSaved>' + sDateLastSaved + '</LastSaved>' + LE + INDENT2;
|
||||
sDateLastSaved := '<LastSaved>' + sDateLastSaved + '</LastSaved>' + LF + INDENT2;
|
||||
end else
|
||||
sDateLastSaved := '';
|
||||
|
||||
AppendToStream(AStream, INDENT1 +
|
||||
'<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">' + LE + INDENT2 +
|
||||
'<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">' + LF + INDENT2 +
|
||||
sTitle +
|
||||
sSubject +
|
||||
sAuthor +
|
||||
sLastAuthor +
|
||||
sDateCreated +
|
||||
sDateLastSaved +
|
||||
'<Version>16.00</Version>' + LE + Indent1 +
|
||||
'</DocumentProperties>' + LE
|
||||
'<Version>16.00</Version>' + LF + INDENT1 +
|
||||
'</DocumentProperties>' + LF
|
||||
);
|
||||
end;
|
||||
|
||||
@ -3397,9 +3449,11 @@ begin
|
||||
' xmlns:o="urn:schemas-microsoft-com:office:office"' + LF +
|
||||
' xmlns:x="urn:schemas-microsoft-com:office:excel"' + LF +
|
||||
' xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"' + LF +
|
||||
' xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"' + LF +
|
||||
' xmlns:html="http://www.w3.org/TR/REC-html40">' + LF);
|
||||
|
||||
WriteDocumentProperties(AStream);
|
||||
WriteCustomDocumentProperties(AStream);
|
||||
WriteOfficeDocumentSettings(AStream);
|
||||
WriteExcelWorkbook(AStream);
|
||||
WriteStyles(AStream);
|
||||
|
@ -173,6 +173,7 @@ type
|
||||
procedure WriteComments(AWorksheet: TsBasicWorksheet);
|
||||
procedure WriteConditionalFormat(AStream: TStream; AFormat: TsConditionalFormat; var APriority: Integer);
|
||||
procedure WriteConditionalFormats(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||
procedure WriteCustomMetaData(AStream: TStream);
|
||||
procedure WriteDefinedNames(AStream: TStream);
|
||||
procedure WriteDifferentialFormat(AStream: TStream; AFormat: PsCellFormat);
|
||||
procedure WriteDifferentialFormats(AStream: TStream);
|
||||
@ -217,6 +218,7 @@ type
|
||||
FSWorkbook: TStream;
|
||||
FSWorkbookRels: TStream;
|
||||
FSMetaData: TStream;
|
||||
FSCustomMetaData: TStream;
|
||||
FSStyles: TStream;
|
||||
FSSharedStrings: TStream;
|
||||
FSSharedStrings_complete: TStream;
|
||||
@ -307,6 +309,7 @@ const
|
||||
OOXML_PATH_XL_THEME = 'xl/theme/theme1.xml';
|
||||
OOXML_PATH_XL_MEDIA = 'xl/media/';
|
||||
OOXML_PATH_DOCPROPS_CORE = 'docProps/core.xml';
|
||||
OOXML_PATH_DOCPROPS_CUSTOM = 'docProps/custom.xml';
|
||||
|
||||
{ OOXML schemas constants }
|
||||
SCHEMAS_TYPES = 'http://schemas.openxmlformats.org/package/2006/content-types';
|
||||
@ -314,6 +317,7 @@ const
|
||||
SCHEMAS_DOC_RELS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
||||
SCHEMAS_DOCUMENT = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
|
||||
SCHEMAS_META_CORE = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
|
||||
SCHEMAS_META_CUSTOM = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties';
|
||||
SCHEMAS_WORKSHEET = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet';
|
||||
SCHEMAS_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';
|
||||
SCHEMAS_STRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
|
||||
@ -330,6 +334,7 @@ const
|
||||
MIME_RELS = 'application/vnd.openxmlformats-package.relationships+xml';
|
||||
MIME_OFFICEDOCUMENT = 'application/vnd.openxmlformats-officedocument';
|
||||
MIME_CORE = 'application/vnd.openxmlformats-package.core-properties+xml';
|
||||
MIME_CUSTOM = 'application/vnd.openxmlformats-officedocument.custom-properties+xml';
|
||||
MIME_SPREADML = MIME_OFFICEDOCUMENT + '.spreadsheetml';
|
||||
MIME_SHEET = MIME_SPREADML + '.sheet.main+xml';
|
||||
MIME_WORKSHEET = MIME_SPREADML + '.worksheet+xml';
|
||||
@ -2695,9 +2700,11 @@ end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadMetaData(ANode: TDOMNode);
|
||||
var
|
||||
childNode: TDOMNode;
|
||||
nodeName: string;
|
||||
book: TsWorkbook;
|
||||
s: String;
|
||||
name: String;
|
||||
dt: TDateTime;
|
||||
fs: TFormatSettings;
|
||||
begin
|
||||
@ -2714,6 +2721,7 @@ begin
|
||||
nodeName := ANode.NodeName;
|
||||
s := GetNodeValue(ANode);
|
||||
case nodeName of
|
||||
// These fields are from "core.xml"
|
||||
'dc:title':
|
||||
book.MetaData.Title := s;
|
||||
'dc:subject':
|
||||
@ -2740,6 +2748,21 @@ begin
|
||||
'dcterms:modified':
|
||||
if s <> '' then
|
||||
book.MetaData.DateLastModified :=ISO8601StrToDateTime(s);
|
||||
|
||||
// This field is from "custom.xml"
|
||||
'property':
|
||||
begin
|
||||
name := GetAttrValue(ANode, 'name');
|
||||
childNode := ANode.Firstchild;
|
||||
while childNode <> nil do
|
||||
begin
|
||||
nodeName := childNode.NodeName;
|
||||
s := GetNodeValue(childNode);
|
||||
if (s <> '') then
|
||||
book.MetaData.AddCustom(name, s);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
@ -3798,6 +3821,18 @@ begin
|
||||
finally
|
||||
XMLStream.Free;
|
||||
end;
|
||||
// custom meta data
|
||||
XMLStream := CreateXMLStream;
|
||||
try
|
||||
if UnzipToStream(AStream, OOXML_PATH_DOCPROPS_CUSTOM, XMLStream) then
|
||||
begin
|
||||
ReadXMLStream(Doc, XMLStream);
|
||||
ReadMetaData(Doc.DocumentElement);
|
||||
FreeAndNil(Doc);
|
||||
end;
|
||||
finally
|
||||
XMLStream.Free;
|
||||
end;
|
||||
|
||||
finally
|
||||
FreeAndNil(Doc);
|
||||
@ -4516,6 +4551,37 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WriteCustomMetaData(AStream: TStream);
|
||||
var
|
||||
book: TsWorkbook;
|
||||
i: Integer;
|
||||
id: Integer;
|
||||
begin
|
||||
book := TsWorkbook(FWorkbook);
|
||||
if book.MetaData.Custom.Count = 0 then
|
||||
exit;
|
||||
|
||||
AppendToStream(AStream,
|
||||
'<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" ' +
|
||||
'xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">');
|
||||
|
||||
id := 2;
|
||||
for i := 0 to book.MetaData.Custom.Count-1 do
|
||||
begin
|
||||
AppendToStream(AStream, Format(
|
||||
'<property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="%d" name="%s">' +
|
||||
'<vt:lpwstr>%s</vt:lpwstr>' +
|
||||
'</property>', [
|
||||
id, book.MetaData.Custom.Names[i],
|
||||
book.MetaData.Custom.ValueFromIndex[i]
|
||||
]));
|
||||
inc(id);
|
||||
end;
|
||||
|
||||
AppendToStream(AStream,
|
||||
'</Properties>');
|
||||
end;
|
||||
|
||||
procedure TsSpreadOOXMLWriter.WriteDimension(AStream: TStream;
|
||||
AWorksheet: TsBasicWorksheet);
|
||||
var
|
||||
@ -6084,18 +6150,29 @@ begin
|
||||
|
||||
{ --- meta data ---- }
|
||||
WriteMetaData(FSMetaData);
|
||||
WriteCustomMetaData(FSCustomMetaData);
|
||||
|
||||
{ --- _rels/.rels --- }
|
||||
AppendToStream(FSRelsRels,
|
||||
XML_HEADER + LineEnding);
|
||||
|
||||
AppendToStream(FSRelsRels, Format(
|
||||
'<Relationships xmlns="%s">' + LineEnding, [SCHEMAS_RELS]));
|
||||
AppendToStream(FSRelsRels, Format(
|
||||
'<Relationship Id="rId2" Target="docProps/core.xml" Type="%s" />' + LineEnding,
|
||||
[SCHEMAS_META_CORE]));
|
||||
'<Relationships xmlns="%s">' + LineEnding,
|
||||
[SCHEMAS_RELS]));
|
||||
|
||||
AppendToStream(FSRelsRels, Format(
|
||||
'<Relationship Id="rId1" Target="xl/workbook.xml" Type="%s" />' + LineEnding,
|
||||
[SCHEMAS_DOCUMENT]));
|
||||
|
||||
AppendToStream(FSRelsRels, Format(
|
||||
'<Relationship Id="rId2" Target="docProps/core.xml" Type="%s" />' + LineEnding,
|
||||
[SCHEMAS_META_CORE]));
|
||||
|
||||
if TsWorkbook(FWorkbook).MetaData.Custom.Count > 0 then
|
||||
AppendToStream(FSRelsRels, Format(
|
||||
'<Relationship Id="rId3" Target="docProps/custom.xml" Type="%s" />' + LineEnding,
|
||||
[SCHEMAS_META_CUSTOM]));
|
||||
|
||||
AppendToStream(FSRelsRels,
|
||||
'</Relationships>');
|
||||
|
||||
@ -6378,6 +6455,10 @@ begin
|
||||
AppendToStream(FSContentTypes,
|
||||
'<Override PartName="/docProps/core.xml" ContentType="' + MIME_CORE + '" />');
|
||||
|
||||
if book.MetaData.Custom.Count > 0 then
|
||||
AppendToStream(FSContentTypes,
|
||||
'<Override PartName="/docProps/custom.xml" ContentType="' + MIME_CUSTOM + '" />');
|
||||
|
||||
AppendToStream(FSContentTypes,
|
||||
'</Types>');
|
||||
end;
|
||||
@ -6808,6 +6889,7 @@ begin
|
||||
FSSharedStrings := CreateTempStream(FWorkbook, 'fpsSS');
|
||||
FSSharedStrings_complete := CreateTempStream(FWorkbook, 'fpsSSC');
|
||||
FSMetaData := CreateTempStream(FWorkbook, 'fpsMETA');
|
||||
FSCustomMetaData := CreateTempStream(FWorkbook, 'fpsCM');
|
||||
{
|
||||
if boFileStream in FWorkbook.Options then
|
||||
begin
|
||||
@ -6848,6 +6930,7 @@ procedure TsSpreadOOXMLWriter.DestroyStreams;
|
||||
var
|
||||
stream: TStream;
|
||||
begin
|
||||
DestroyTempStream(FSCustomMetaData);
|
||||
DestroyTempStream(FSMetaData);
|
||||
DestroyTempStream(FSContentTypes);
|
||||
DestroyTempStream(FSRelsRels);
|
||||
@ -6897,6 +6980,7 @@ begin
|
||||
ResetStream(FSStyles);
|
||||
ResetStream(FSSharedStrings_complete);
|
||||
ResetStream(FSMetaData);
|
||||
ResetStream(FSCustomMetaData);
|
||||
for i:=0 to High(FSSheets) do ResetStream(FSSheets[i]);
|
||||
for i:=0 to High(FSSheetRels) do ResetStream(FSSheetRels[i]);
|
||||
for i:=0 to High(FSComments) do ResetStream(FSComments[i]);
|
||||
@ -6964,6 +7048,8 @@ begin
|
||||
if FSSharedStrings_complete.Size > 0 then
|
||||
FZip.Entries.AddFileEntry(FSSharedStrings_complete, OOXML_PATH_XL_STRINGS);
|
||||
FZip.Entries.AddFileEntry(FSMetaData, OOXML_PATH_DOCPROPS_CORE);
|
||||
if TsWorkbook(FWorkbook).MetaData.Custom.Count > 0 then
|
||||
FZip.Entries.AddFileEntry(FSCustomMetaData, OOXML_PATH_DOCPROPS_CUSTOM);
|
||||
|
||||
// Write embedded images
|
||||
WriteMedia(FZip);
|
||||
|
Reference in New Issue
Block a user