Skip to content

Creating PDF Documents

HorstOeko edited this page Jan 19, 2025 · 30 revisions

Table of contents

Related issues

Additional documentation

Examples

Write a pdf file with attached xml file

If you already have a created PDF file - for example from an external ERP system or from your own PDF generation process - you can use the class ZugferdDocumentPdfBuilder to connect an XML to this already existing PDF. The constructor of this class takes two parameters: First, an instance of ZugferdDocumentBuilder and second, a fully qualified path to an existing PDF file:

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');

Alternatively, you can also pass a string variable as the second parameter, which already contains the binary content of a PDF:

$pdfContent = file_get_contents('/path/to/existing/pdf.pdf');
$pdfDocument = new ZugferdDocumentPdfBuilder($document, $pdfContent);

Next, it is necessary to start the process of generating the PDF with the XML attachment:

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->generateDocument();

Finally, you have two options to retrieve the finished PDF (with XML attachment):

Save the generated PDF to a file

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->generateDocument();
$pdfDocument->saveDocument('/path/to/new/pdf.pdf');

Retrieve the content of the generated PDF

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->generateDocument();
$pdfContent = $pdfDocument->downloadString('dummyfilename.pdf');

And that was it. ZugferdDocumentPdfBuilder takes care of attaching the XML file to the PDF and also generating the correct XMP metadata.

Change the relationship type of the attached XML

By default, the invoice XML is integrated as a file with the relationship type ‘Data’. However, this is not possible and valid in Germany, for example. The ‘Alternative’ relationship type must be selected here. To define the relationship type of the attached invoice XML, 3 methods are available which must be called before generateDocument is called:

Relationship Type "Data"

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->setAttachmentRelationshipTypeToData();
$pdfDocument->generateDocument();

Relationship Type "Alternative" (Mandatory in Germany)

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->setAttachmentRelationshipTypeToAlternative();
$pdfDocument->generateDocument();

Relationship Type "Source"

$pdfDocument = new ZugferdDocumentPdfBuilder($document, '/path/to/existing/pdf.pdf');
$pdfDocument->setAttachmentRelationshipTypeToSource();
$pdfDocument->generateDocument();

Add addtional attachments to PDF

You can add further attachments to the PDF to be created. The following methods are available for this:

  • attachAdditionalFileByRealFile(string $fullFilename, string $displayName = "", string $relationshipType = "")

    Adds a real existing file to the PDF as an attachment. You can specify a different display name and the type of relationship. If the display name is omitted, it is derived from the file name of the file to be attached. If you omit the relationship, “Supplement” is assumed by default.

    See Class Documentation

  • attachAdditionalFileByContent(string $content, string $filename, string $displayName = "", string $relationshipType = "")

    Adds a content string to the PDF as an attachment. You must specify a file name. However, this file does not have to exist but is only used for proper embedding in the PDF. You can specify a different display name and the type of relationship. If the display name is omitted, this is derived from the file name. If you omit the relationship, “Supplement” is assumed by default.

    See Class Documentation

An example

$documentPdfBuilder = new ZugferdDocumentPdfBuilder($document, $existingPdf);
$documentPdfBuilder
    ->attachAdditionalFileByRealFile(dirname(__FILE__) . '/addattchment.txt')
    ->attachAdditionalFileByContent("Test Content", "test.txt", "Test")
    ->generateDocument()
    ->saveDocument($mergeToPdf);

Corresponding constants are available in the class ZugferdDocumentPdfBuilder for the optional relationship types to be specified:

  • ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_DATA
  • ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_ALTERNATIVE
  • ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_SOURCE
  • ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_SUPPLEMENT
  • ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_UNSPECIFIED

Examples:

$documentPdfBuilder = new ZugferdDocumentPdfBuilder($document, $existingPdf);
$documentPdfBuilder
    ->attachAdditionalFileByRealFile(
        dirname(__FILE__) . '/addattchment.txt',
        'Some diffent display name',
        ZugferdDocumentPdfBuilder::AF_RELATIONSHIP_UNSPECIFIED)
    ->generateDocument()
    ->saveDocument($mergeToPdf);

Customize Metadata

It is possible to customize the meta information such as title, subject, author and keywords. There are two ways to do this:

  • Customize via templates
  • Customize via callback function

Customize via templates

The following methods are available to customize the Author, Title, Subject and Keywords sections

The methods each accept a string. In addition to free text, the following placeholders can also be used in this string:

Placeholder Description
%1$s Invoice No.
%2$s Document Type (INVOICE, etc.)
%3$s Seller Name
%4$s Invoice Date

The following example illustrates the use

$pdfBuilder = new ZugferdDocumentPdfBuilder($someDocument, $somePdfFile);
$pdfBuilder->setTitleTemplate('%3$s : %2$s %1$s');
$pdfBuilder->setSubjectTemplate('%2$s-Document, Issued by %3$s');
$pdfBuilder->setAuthorTemplate('Issued by seller with name %3$s');
$pdfBuilder->generateDocument();
$pdfBuilder->saveDocument('/tmp/test.pdf');

This will result in the following meta data (for example)

Which Value
Title Lieferant GmbH : Invoice 471102
Subject Invoice-Document, Issued by Lieferant GmbH
Author Issued by seller with name Lieferant GmbH

Customize via callback function

The setMetaInformationCallback method is available to perform the adjustment via a callback function. The call could look like this, for example:

$pdfBuilder = new ZugferdDocumentPdfBuilder($someDocument, $somePdfFile);
$pdfBuilder->setMetaInformationCallback(function ($which, $xmlContent, $invoiceInformation, $default) {
    if ($which === 'title') {
        return "DummyTitle";
    }
    if ($which === 'author') {
        return "DummyAuthor";
    }
    if ($which === 'subject') {
        return "DummySubject";
    }
});

$pdfBuilder->generateDocument();
$pdfBuilder->saveDocument('/tmp/test.pdf');

The parameters that are sent to the callback function are shown below:

Which Value
$which Which metadata-field, one of 'author', 'subject', 'title', 'keywords'
$xmlContent Contains the XML-content of the attached XML-file
$invoiceInformation An array with the parsed information of the XML-attachment
$default A default value that is used if the callback function returns NULL or an empty string. This default value is assigned by the system

The example above will produce the following information:

Which Value
Title DummyTitle
Subject DummySubject
Author DummyAuthor

Special notes for users in Germany

The german law says:

In Deutschland ist aus rechtlichen Gründen nur der Wert "Alternative" zulässig; das bedeutet, dass alle Information, die im menschlesbaren Teil gegenwärtig sind, auch im XML-Teil enthalten sein müssen, selbst wenn sie in nicht strukturiertem Text vorkommen („identisches Mehrstück“).

... or in english.

In Germany, only the value ‘Alternative’ is permitted for legal reasons; this means that all information that is present in the human-readable part must also be contained in the XML part, even if it occurs in non-structured text (‘identical multipart’).

As already described in post #147 and #232, the invoice attachment is to be embedded as an ‘Alternative’. This is easy to do:

$pdfBuilder = new ZugferdDocumentPdfBuilder($someDocument, $somePdfFile);
$pdfBuilder->setAttachmentRelationshipTypeToAlternative();
$pdfBuilder->generateDocument();
$pdfBuilder->saveDocument('uploads/pdf/test.pdf');
Clone this wiki locally