Skip to main content Skip to footer

How to Create ZUGFeRD-compliant PDF Invoices in C#

Electronic invoicing, also known as e-invoicing, is the exchange of an electronic invoice document issued, transmitted, received, and processed electronically. It is digital throughout its entire life cycle and offers cost savings and increased efficiencies in a business-to-business (B2B) environment. That value extends to both buyers and sellers.

In an era driven by computer and communication technology, as millions of companies move forward to take advantage of the benefits offered by e-invoices, standards are needed to ensure complete interoperability of e-invoices so that once generated, any software can read them.

Out of the many data formats for e-invoices, the ZUGFeRD standard has become increasingly established in German-speaking and EU countries. Hence, Document Solutions for PDF (DsPdf), previously GrapeCity Documents for PDF (GcPdf), can now be used (with the help of the ZUGFeRD-csharp package) to create or load ZUGFeRD-compliant invoices (in C#).

Ready to Try it Out? Download Document Solutions for PDF Today!

In this blog, we will learn what the ZUGFeRD standard is, understand how to create ZUGFeRD-compliant PDF invoices, and how to extract ZUGFeRD information from the PDF Invoice using DsPdf.

ZUGFeRD-compliant PDF with structured XML attached

ZUGFeRD-compliant PDF with structured XML attached

What is ZUGFeRD?

ZUGFeRD - “Zentraler User Guide des Forums Elektronische Rechnung Deutschland” is a German e-invoicing standard developed by FeRD - “Forum Elektronische Rechnung Deutschland” as a uniform data format for exchanging the data structurally in public and private sectors.

ZUGFeRD format is based on PDF/A-3 and contains structured data in XML. The hybrid approach enables the PDF to be used as a “container” and presents the invoice data in a fixed-layout PDF that ZUGFeRD-compliant applications can process. PDF/A-3 is an ISO standard for long-term archiving. Because the ZUGFeRD XML format is based on the international standard UN CEFACT, it is therefore compatible across the EU and internationally.

Creating ZUGFeRD-compliant PDF invoices in C# 

GcPdf enables the creation of a ZUGFeRD-compliant PDF by building the invoice in HTML and then converting it to PDF using Document Solutions for HTML or DsHtml. The structured XML file containing invoice information is added to the PDF through the EmbeddedFiles collection of the DsPdfDocument class.

To understand how DsPdf performs these actions, let’s generate a sample invoice using data from the GcNWind database. The whole process of creating a ZUGFeRD-compliant PDF invoice consists of the following phases:

  1. Fetching Data
  2. Building ZUGFeRD-compliant XML in C#
  3. Building invoice as HTML in C#
  4. Converting HTML invoice to PDF in C#
  5. Creating PDF/3-A compliant PDF and attaching XML invoice in C#

Fetching Data

Invoices are order-specific documents, so we must first access the order details corresponding to the specific Order ID. For this, we’ll use the ‘Suppliers ‘, ‘OrdersCustomersEmployees’, and ‘EmployeesProductsOrders’ tables from the GcNwind.xml database and extract the details of a random order.

var orderDetails = dtOrdersDetails.Select() 
                  .Select(it => new 
                  { 
                        OrderID = Convert.ToInt32(it["OrderID"]), 
                        ItemDescription = it["ProductName"].ToString(), 
                        Rate = Convert.ToDecimal(it["UnitPrice"]), 
                        Quantity = Convert.ToDecimal(it["Quantity"]) 
                  }) 
                  .Where(it => it.OrderID == order.OrderID) 
                  .OrderBy(it => it.ItemDescription).ToList(); 

The above code fetches the details ‘orderDetails’ of an order whose OrderID matches the OrderID of the Order ‘order’ for which the invoice is being generated. 

Building ZUGFeRD-compliant XML in C#

As mentioned earlier, ZUGFeRD standard calls for adding a structured XML to PDF. To build ZUGFeRD-compliant XML, we’ll use the ZUGFeRD-csharp package and add invoice information to it.

var zugferdDesc = InvoiceDescriptor.CreateInvoice( order.OrderID.ToString(), 
                  order.OrderDate, CurrencyCodes.USD); 
                
// Fill the invoice buyer info: 
zugferdDesc.SetBuyer( order.ShipName, order.ShipPostalCode, 
                  order.ShipCity, order.ShipAddress, 
                  GetCountryCode(order.ShipCountry), order.CompanyName); 
zugferdDesc.SetBuyerContact($"{order.FirstName} {order.LastName}"); 

The above code builds ZUGFeRD-compliant XML and adds buyer information. Similarly, information for the seller, delivery date, due date, etc., can also be added.

After building ZUGFeRD-compliant XML, we can save it to a temporary stream to be added as an attachment to the PDF invoice later and set the version of the standard to Version1 as, at this time, only 1.x version is properly supported.

  zugferdDesc.Save(ms, ZUGFeRDVersion.Version1, Profile.Basic);

Building invoice as HTML in C#

*Note: We only use HTML as an intermediate state to simplify formatting. Building HTML is not related to ZUGFeRD, so if you want, you can use DsPdfGraphics instead to draw the invoice.

To ease up the HTML creation, we'll create HTML templates for invoice sections, where the templates will have data placeholders and can be reused. For instance, we can create the following data row HTML template and use it for each invoice record:

const string c_dataRowFmt = @" 
          <tr> 
            <td class='no'>{0}</td> 
            <td class='desc'><h3>{1}</h3></td> 
            <td class='unit'>{2}</td> 
            <td class='qty'>{3}</td> 
            <td class='total'>{4}</td> 
          </tr> 
        "; 

Similarly, we can create HTML templates for other invoice sections like header, body, styles, etc. This blog will use HTML templates for invoice tables, rows/records, and styles. Creating HTML templates is out of the scope of this blog, so you can refer to the attached application for code.

Once the HTML templates are ready, we can build HTML invoice by adding data to these templates.

var html = string.Format(c_tableTpl, detailsHtml.ToString(), 
           supplier.CompanyName, 
           $"{supplier.Address}, {supplier.Region} {supplier.PostalCode}, {supplier.City} {supplier.Country}", 
           supplier.Phone, 
           supplier.HomePage, 
           $"{order.FirstName} {order.LastName} {order.CompanyName}", 
           $"{order.ShipAddress}, {order.ShipRegion} {order.ShipPostalCode}, {order.ShipCity} {order.ShipCountry}", 
           order.OrderDate.ToString("MM/dd/yyyy"), 
           order.RequiredDate.ToString("MM/dd/yyyy"), 
           orderSubTotal.ToString("C", culture), 
           orderTax.ToString("C", culture), 
           (orderSubTotal + orderTax).ToString("C", culture), c_tableStyles); 

This will build the invoice in HTML format, which will later be converted to PDF.

Converting HTML invoice to PDF in C#

To convert the HTML build in the previous step (only to ease up the formatting of the invoice), import the following namespace:

using GrapeCity.Documents.Html;

Create an instance of the GcHtmlBrowser class and invoke the NewPage method to generate a browser page (of the HtmlPage class type), rendering the HTML string -

using var browser = Common.Util.NewHtmlBrowser();
using var htmlPage = browser.NewPage(html);

Additionally, while creating the PDF file, we can customize it. Margins, header, and footer can all be added to the PDF file while converting the HTML template using the PdfOptions class. The PdfOptions instance is created to specify the PDF-related settings that will show up in the generated PDF. The source webpage is then saved to PDF using the SaveAsPdf method of the HtmlPage class.

var tmpPdf = Path.GetTempFileName();
// Set up HTML headers, margins etc.:
var pdfOptions = new PdfOptions()
{
   Margins = new PdfMargins(0.2f, 1, 0.2f, 1),
   DisplayHeaderFooter = true,
   HeaderTemplate = "<div style='color:#1a5276; font-size:12px; width:1000px; margin-left:0.2in; margin-right:0.2in'>" +
                    "<span style='float:left;'>Invoice</span>" +
                    "<span style='float:right'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></span>" +
                    "</div>",
   FooterTemplate = "<div style='color: #1a5276; font-size:12em; width:1000px; margin-left:0.2in; margin-right:0.2in;'>" +
                    "<span>(c) GrapeCity, Inc. All Rights Reserved.</span>" +
                    "<span style='float:right'>Generated on <span class='date'></span></span></div>"
};
// Render the source Web page to the temporary file:
htmlPage.SaveAsPdf(tmpPdf, pdfOptions);

Creating PDF/3-A compliant PDF and attaching XML invoice in C#

Finally, we’ll use the PDF created above and create a PDF/A-3 compliant document with the ZUGFeRD XML attachment. To create the PDF, we’ll use the GcPdfDocument class, set the ConformanceLevel to PdfA3a and use the EmbeddedFiles collection to add the XML invoice as an attachment:

// Create the result PDF as a PDF/A-3 compliant document with the ZUGFeRD XML attachment:
var doc = new GcPdfDocument();
var tmpZugferd = Path.GetTempFileName();
using (var fs = File.OpenRead(tmpPdf))
{
       doc.Load(fs);
       doc.ConformanceLevel = PdfAConformanceLevel.PdfA3a;
       var ef1 = EmbeddedFileStream.FromBytes(doc, ms.ToArray());
       ef1.ModificationDate = DateTime.Now;
       ef1.MimeType = "text/xml";
       // According to the ZUGFeRD 1.x standard naming, the filename should be ZUGFeRD-invoice.xml:
       var fspec = FileSpecification.FromEmbeddedStream("ZUGFeRD-invoice.xml", ef1);
       fspec.Relationship = AFRelationship.Alternative;
       fspec.UnicodeFile.FileName = fspec.File.FileName;
       // The attachment dictionary key can be anything:
       doc.EmbeddedFiles.Add("ZUGfERD-Attachment", fspec);
       doc.Save(tmpZugferd);
}

structured XML embedded in ZUGFeRD-compliant PDF

The image shows structured XML embedded in ZUGFeRD-compliant PDF

Extracting ZUGFeRD information in C#

In addition to creating a ZUGFeRD-compliant PDF, DsPdf also allows extracting ZUGFeRD information from the PDF invoice.

To extract the ZUGFeRD information, DsPdf accesses the structured XML attached to the PDF and stores the invoice information in an instance of the InvoiceDescriptor class provided by the ZUGFeRD-csharp package.

var doc = new GcPdfDocument(); 
using (FileStream fs = File.OpenRead(invoicePdf)) 
{ 
	// Load the ZUGFeRD compliant invoice PDF: 
    var invoice = new GcPdfDocument(); 
    invoice.Load(fs); 
    
	// Get the ZUGFeRD attachment from the invoice by the ZUGFeRD 1.x standard file name: 
    var attachment = invoice.EmbeddedFiles.Values.FirstOrDefault(it => it.File.FileName == "ZUGFeRD-invoice.xml"); 
    if (attachment != null) 
    { 
    	using (var xmlstream = attachment.GetStream()) 
        { 
        	// Load the invoice descriptor: 
            var descriptor = InvoiceDescriptor.Load(xmlstream); 
        } 
    } 
} 

The InvoiceDescriptor object will store all invoice information of the loaded PDF. We can use this information as needed and even render the extracted invoice information in a new PDF using DsPdf API.

PDF file with extracted information rendered

The image shows a PDF file with extracted information rendered

Viewing ZUGFeRD Invoice Attachment in DsPdfViewer

Using GcPdf, we don't need to rely on the browser to open the PDF. Document Solutions includes a cross-platform Document Solutions PDF viewer, or DsPdfViewer, using which we can view the ZUGFeRD-compliant PDFs on the web, along with the structured XML.

The image shows ZUGFeRD compliant PDF shown in DsPdfViewer

Visit the Documents for PDF | ZUGFeRD section to find sample applications with complete code, and to learn more about how to work with ZUGFeRD format PDFs using DsPdf. 

Ready to Try it Out? Download Document Solutions for PDF Today!

comments powered by Disqus