-
Notifications
You must be signed in to change notification settings - Fork 51
Creating PDF Documents
- Related issues
- Additional documentation
- Examples
- Write a pdf file with attached xml file
- Change the relationship type of the attached XML
- Add addtional attachments to PDF
- Customize Metadata
- Special notes for users in Germany
- #21 Unable to find PDF file header
- #208 Customizable PDF Metadata
- #147 How change AFRelationship From "Data" to "Alternative"
- #232 Datev Unternehmen Online not valid
- Create XML in EN16931 profile and attach it to PDF
- Create XML in XRECHNUNG3.x profile and attach it to PDF
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.
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();
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.
-
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.
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);
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
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 |
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 |
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');