diff --git a/components/fpspreadsheet/examples/other/metadata/demo_metadata.lpr b/components/fpspreadsheet/examples/other/metadata/demo_metadata.lpr index 2ed050264..f2af53a8b 100644 --- a/components/fpspreadsheet/examples/other/metadata/demo_metadata.lpr +++ b/components/fpspreadsheet/examples/other/metadata/demo_metadata.lpr @@ -63,6 +63,8 @@ begin try book.MetaData.CreatedBy := 'Donald Duck'; book.MetaData.DateCreated := EncodeDate(2020, 1, 1) + EncodeTime(12, 30, 40, 20); + book.MetaData.DateLastModified := Now(); + book.MetaData.LastModifiedBy := 'Dagobert Duck'; book.MetaData.Title := 'Test of metadata äöü'; book.MetaData.Comments.Add('This is a test of spreadsheet metadata.'); book.MetaData.Comments.Add('Assign the author to the field CreatedBy.'); @@ -81,9 +83,7 @@ begin book := TsWorkbook.Create; try - book.ReadFromFile('test.xlsx'); - book.MetaData.DateLastModified := Now(); - book.MetaData.LastModifiedBy := GetUserName; + book.ReadFromFile('test.ods'); WriteLn('Created by : ', book.MetaData.CreatedBy); WriteLn('Date created : ', DateTimeToStr(book.MetaData.DateCreated)); WriteLn('Modified by : ', book.MetaData.LastModifiedBy); diff --git a/components/fpspreadsheet/source/common/fpsopendocument.pas b/components/fpspreadsheet/source/common/fpsopendocument.pas index 4a1f672bf..5e35e6f65 100644 --- a/components/fpspreadsheet/source/common/fpsopendocument.pas +++ b/components/fpspreadsheet/source/common/fpsopendocument.pas @@ -133,6 +133,7 @@ type var AFontSize: Double; var AFontStyle: TsHeaderFooterFontStyles; var AFontColor: TsColor); function ReadHeaderFooterText(ANode: TDOMNode): String; + procedure ReadMetaData(ANode: TDOMNode); procedure ReadPictures(AStream: TStream); procedure ReadPrintRanges(ATableNode: TDOMNode; ASheet: TsBasicWorksheet); procedure ReadRowsAndCells(ATableNode: TDOMNode); @@ -1951,6 +1952,40 @@ begin end; end; +procedure TsSpreadOpenDocReader.ReadMetaData(ANode: TDOMNode); +var + book: TsWorkbook; + nodeName: String; + s: String; +begin + book := TsWorkbook(FWorkbook); + + ANode := ANode.FirstChild; + while ANode <> nil do + begin + nodeName := ANode.NodeName; + s := GetNodeValue(ANode); + case nodeName of + 'meta:initial-creator': + book.MetaData.CreatedBy := s; + 'meta:creation-date': + if s <> '' then + book.MetaData.DateCreated := ISO8601StrToDateTime(s); + 'meta:keyword': + if s <> '' then + book.MetaData.KeyWords.Add(s); + 'dc:date': + if s <> '' then + book.MetaData.DateLastModified := ISO8601StrToDateTime(s); + 'dc:description': + book.MetaData.Comments.Text := s; + 'dc:title': + book.MetaData.Title := s; + end; + ANode := ANode.NextSibling; + end; +end; + procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal; AStyleIndex: Integer; ACellNode: TDOMNode); var @@ -2826,6 +2861,18 @@ begin FreeAndNil(Doc); end; + // process the meta.xml file + XMLStream := CreateXMLStream; + try + if UnzipToStream(AStream, 'meta.xml', XMLStream) then + begin + ReadXMLStream(Doc, XMLStream); + ReadMetaData(Doc.DocumentElement.FindNode('office:meta')); + end; + finally + XMLStream.Free; + end; + // process the settings.xml file (Note: it does not always exist!) XMLStream := CreateXMLStream; try @@ -5728,19 +5775,77 @@ begin end; procedure TsSpreadOpenDocWriter.WriteMeta; +var + book: TsWorkbook; + i: Integer; + s: String; begin + book := TsWorkbook(FWorkbook); + AppendToStream(FSMeta, XML_HEADER); + AppendToStream(FSMeta, + ''); + { AppendToStream(FSMeta, ''); + } AppendToStream(FSMeta, '', 'FPSpreadsheet Library' + - '', + ''); + + if book.Metadata.Title <> '' then + begin + s := book.Metadata.Title; + AppendToStream(FSMeta, Format( + '%s', [s])); + end; + + if book.Metadata.CreatedBy <> '' then + AppendToStream(FSMeta, Format( + '%s', [book.MetaData.CreatedBy])); + + if book.MetaData.DateCreated > 0 then + begin + s := FormatDateTime(ISO8601FormatExtended, book.MetaData.DateCreated); + AppendToStream(FSMeta, Format( + '%s', [s])); + end; + + if book.MetaData.DateLastModified > 0 then + begin + s := FormatDateTime(ISO8601FormatExtended, book.MetaData.DateLastModified); + AppendToStream(FSMeta, Format( + '%s', [s])); + end; + + if book.MetaData.Keywords.Count > 0 then + for i := 0 to book.MetaData.Keywords.Count-1 do + AppendToStream(FSMeta, Format( + '%s', [book.MetaData.Keywords[i]])); + + if book.MetaData.Comments.Count > 0 then + begin + s := book.MetaData.Comments[0]; + for i := 1 to book.MetaData.Comments.Count-1 do + s := s + #10 + book.MetaData.Comments[i]; + AppendToStream(FSMeta, Format( + '%s', [s])); + end; + + AppendToStream(FSMeta, ''); AppendToStream(FSMeta, ''); diff --git a/components/fpspreadsheet/source/common/fpstypes.pas b/components/fpspreadsheet/source/common/fpstypes.pas index 506998f3a..fd23fe64a 100644 --- a/components/fpspreadsheet/source/common/fpstypes.pas +++ b/components/fpspreadsheet/source/common/fpstypes.pas @@ -980,7 +980,7 @@ type destructor Destroy; function IsEmpty: Boolean; property CreatedBy: String read FCreatedBy write FCreatedBy; - property LastModifiedBy: String read FLastModifiedBy write FlastModifiedBy; + property LastModifiedBy: String read FLastModifiedBy write FLastModifiedBy; property DateCreated: TDateTime read FDateCreated write FDateCreated; property DateLastModified: TDatetime read FDateLastModified write FDateLastModified; property Title: String read FTitle write FTitle;