Sample code for 30+ languages & platforms
Dart

PDF Update or Add XML Metadata

Demonstrates how to add or update the XML metadata stored in a PDF.

Note: This example requires Chilkat v10.1.0 or later.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  final pdf = CkPdf();

  // Load a PDF file.
  // If the PDF file already has metadata, we'll update it.
  // Otherwise this example adds the metadata.
  try {
    pdf.loadFile('qa_data/pdf/blank_with_metadata.pdf');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  final xml = CkXml();
  final sbExisting = CkStringBuilder();

  try {
    pdf.getMetadata(sbExisting);
    xml.loadSb(sbExisting, true);
  } on ChilkatException {

    // Otherwise create the bare minimum XMP metadata.
    xml.tag = 'x:xmpmeta';
    xml.addAttribute('xmlns:x', 'adobe:ns:meta/');
    xml.addAttribute('x:xmptk', 'Adobe XMP Core 9.1-c001 79.675d0f7, 2023/06/11-19:21:16 ');
    xml.updateAttrAt('rdf:RDF', true, 'xmlns:rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'rdf:about', '');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:xmp', 'http://ns.adobe.com/xap/1.0/');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:dc', 'http://purl.org/dc/elements/1.1/');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:xmpMM', 'http://ns.adobe.com/xap/1.0/mm/');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:pdf', 'http://ns.adobe.com/pdf/1.3/');
    xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:xmpRights', 'http://ns.adobe.com/xap/1.0/rights/');

    final dt = CkDateTime();
    dt.setFromCurrentSystemTime();
    final ts = dt.getAsTimestamp(true);

    xml.updateChildContent('rdf:RDF|rdf:Description|xmp:ModifyDate', ts);
    xml.updateChildContent('rdf:RDF|rdf:Description|xmp:CreateDate', ts);
    xml.updateChildContent('rdf:RDF|rdf:Description|xmp:MetadataDate', ts);

    xml.updateChildContent('rdf:RDF|rdf:Description|xmp:CreatorTool', 'My Custom Application');
    xml.updateChildContent('rdf:RDF|rdf:Description|dc:format', 'application/pdf');

    final sbDocId = CkStringBuilder();
    sbDocId.append('uuid:');
    sbDocId.appendUuid(true);
    xml.updateChildContent('rdf:RDF|rdf:Description|xmpMM:DocumentID', sbDocId.getAsString());

    final sbInstanceId = CkStringBuilder();
    sbInstanceId.append('uuid:');
    sbInstanceId.appendUuid(true);
    xml.updateChildContent('rdf:RDF|rdf:Description|xmpMM:InstanceID', sbInstanceId.getAsString());
  }

  // Add our custom metadata tags to either the existing XML metdata, or the newly created metadata.
  xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'xmlns:zf', 'urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#');
  xml.updateAttrAt('rdf:RDF|rdf:Description', true, 'rdf:about', ' ');
  xml.updateChildContent('rdf:RDF|rdf:Description|zf:ConformanceLevel', 'BASIC');
  xml.updateChildContent('rdf:RDF|rdf:Description|zf:DocumentFileName', 'ZZZZZZ-invoice.xml');
  xml.updateChildContent('rdf:RDF|rdf:Description|zf:DocumentType', 'INVOICE');
  xml.updateChildContent('rdf:RDF|rdf:Description|zf:Version', '1.0');

  // Create a new PDF with the updated metadata.
  final sb = CkStringBuilder();
  xml.getXmlSb(sb);
  try {
    pdf.updateMetadata(sb, 'c:/temp/qa_output/out.pdf');
    print('Success');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
  }

  // To see the metadata in Adobe Acrobat DC,
  // 1) Open the PDF.
  // 2) CTRL-D to show the Document Properties dialog.
  // 3) In the dialog, click on the "Additional Metadata" button.
  // 4) In the Additional Data dialog, click on "Advanced"
  // 5) Expand the namespace tree for the metadata you added.

  print('OK');
}