How to Generate ZUGFeRD-Compliant Invoices from Word or HTML in .NET

syncfusionsyncfusion
11 min read

TL;DR: This blog post walks you through generating ZUGFeRD-compliant e-invoices in a .NET application using the Syncfusion® PDF Library. It begins by explaining the purpose of hybrid standards, which merge PDF/A-3 with embedded XML for readability and automation. You’ll learn how to convert Word or HTML templates into compliant PDFs, embed machine-readable XML, and validate invoices to meet international standards like EN 16931.

In today’s rapidly evolving business environment, efficiency and compliance are paramount. Electronic invoicing has become an essential component, transitioning from luxury to necessity for seamless global trade.

The ZUGFeRD standard, short for Zentraler User Guide des Forums elektronische Rechnung Deutschland, which integrates a PDF/A-3 document with embedded XML data, has revolutionized the industry. By adopting ZUGFeRD invoices, businesses can streamline processes, minimize errors, and adhere to international standards such as EN 16931, the European e-invoicing standard set to take effect on January 1st, 2025. These standards ensure that business invoices meet the highest levels of accuracy and legal acceptability, allowing them to operate confidently.

The blog post will delve into how developers can use the Syncfusion® .NET PDF Library to generate ZUGFeRD invoices from Word and HTML. Whether you’re unfamiliar with ZUGFeRD or seeking a reliable .NET PDF library, this guide will lead you through each step and show how seamlessly these tools can be integrated into your current workflow.

  1. The history of ZUGFeRD and Factur-X

  2. How ZUGFeRD and Factur-X Hybrid Invoices work

  3. Creating ZUGFeRD invoices with the Syncfusion® PDF Library

Let’s get started!

The history of ZUGFeRD and Factur-X

ZUGFeRD, an acronym for “Zentraler User Guide Forum elektronische Rechnung Deutschland,” or “Central User Guide of the German Electronic Invoice Forum” in English. Factur-X is derived from the French word “ facture,” meaning invoice. The “X” symbolizes the standard’s cross-border applicability, indicating its functionality across various countries and systems.

Since version 2.1, the ZUGFeRD and Factur-X standards have been fully compatible. Both countries have collaborated to advance the standard further, and although it is officially unified under the Factur-X name, it is still commonly referred to as ZUGFeRD.

VersionRelease DateKey FeaturesProfiles
1.0June 2014Hybrid invoice format (PDF/A-3 + XML). Not EN 16931 compliant.BASIC, COMFORT, EXTENDED
2.0March 2019UN/CEFACT CII schema. Enhanced interoperability. EN 16931 compliant.MINIMUM, BASIC WL
2.1March 2020Compatible with Factur-X 1.0.05. Supports German CIUS "XRechnung."EXTENDED
2.2February 2022Aligned with Factur-X 1.0.06. Added profiles for France and Germany, including EXTENDED_B2B_FR.EXTENDED, EXTENDED_B2B_FR
2.3September 2024Uses CII D22B schema. Improved compliance with French B2B requirements. Updated EXTENDED profile.EXTENDED

How ZUGFeRD and Factur-X hybrid invoices work

ZUGFeRD and Factur-X hybrid invoices uniquely integrate visual and machine-readable data, making them suitable for human users and automated systems. Here’s how they function:

  • PDF/A-3 format: These invoices are built on the PDF/A-3 standard, a variant of the PDF format designed for long-term archiving. The PDF contains the human-readable version of the invoice, which can be easily printed or viewed.

  • Embedded XML data: Within the PDF, an XML file is embedded. This XML follows specific schemas like UN/CEFACT CII to include all invoice data in a structured, machine-readable format. This enables seamless integration with accounting and ERP systems.

  • Attachments and the /AF key: The embedding of XML is facilitated using the /AF (Associated Files) key in the PDF document catalog. This feature, introduced in PDF/A-2 and extended in PDF/A-3, allows any file type, including XML, to be attached to the PDF.

  • Fixed XML file names by version: Each ZUGFeRD and Factur-X version specifies a standard file name for the XML attachment:

    1. ZUGFeRD 1.0: ZUGFeRD-invoice.xml

    2. ZUGFeRD 2.0: zugferd-invoice.xml

    3. ZUGFeRD 2.1+ and Factur-X: factur-x.xml

  • Hybrid nature: The dual format ensures compliance with legal requirements for human-readable documents while supporting automation. This hybrid approach eliminates the need for separate systems to handle paper and electronic invoices.

  • Profiles: The standards offer profiles like BASIC, COMFORT, and EXTENDED to cater to business needs, from simple to complex invoicing scenarios. Profiles define the level of information included in the invoice, allowing businesses to choose the one that best suits their requirements.

  • Automation and interoperability: Hybrid invoices streamline workflows by enabling automation. They also ensure interoperability across systems, making them ideal for cross-border transactions.

By utilizing the .NET PDF Library, developers can effortlessly generate these hybrid invoices by embedding XML into a PDF during its generation. This ensures that businesses adhere to international standards and fully capitalize on the benefits of ZUGFeRD and Factur-X.

Creating ZUGFeRD invoices with the .NET PDF Library

The .NET PDF library offers robust features for working with PDFs, including creating ZUGFeRD-compliant invoices. Let’s break down the process into two parts:

  • Generating an invoice from a Word document

  • Generating an invoice from an HTML template. With these methods, you can quickly create and embed data-rich invoices that are both user-friendly and legally compliant.

1. Generate a ZUGFeRD invoice from Word documents

If your invoices are designed in Word, the Syncfusion® library simplifies the conversion to ZUGFeRD invoices, making it easy to incorporate existing templates into your workflow.

Step 1. Create a new console application and install the following NuGet packages

# Convert Word to PDF in .NET applications.
Install-Package Syncfusion.DocIORenderer.Net.Core

# Supports handling ZUGFeRD e-invoice format in .NET.
Install-Package ZUGFeRD-csharp

# Library for parsing and serializing JSON in .NET.
Install-Package Newtonsoft.Json

Step 2. Prepare your Word template

Design an invoice template in Word with merge fields for dynamic data. These fields allow you to automate the inclusion of details like customer name, invoice number, and itemized lists.

We have used the mail merge fields to design the Word template. For more details about mail merge, refer to our documentation.

Refer to the following image.

ZUGFeRD invoice template in Word

Step 3. Deserialize the invoice data into the invoice class object

Invoice invoice = JsonConvert.DeserializeObject<Invoice>(File.ReadAllText("../../../Data/InvoiceData.json"));
//Create zugferd xml file
MemoryStream stream = invoice.CreateXml();

Step 4. Bind the data to the mail merge fields in the Word template

Using the mail merge feature of the Syncfusion Word library, bind the data to the Word template as follows:

using (WordDocument document = new WordDocument(fileStream, FormatType.Automatic))
{
    //Gets the invoice details as an “IEnumerable” collection.
    List<Invoice> invoiceCollection = new List<Invoice>();
    invoiceCollection.Add(invoice);
    //Creates an instance of “MailMergeDataTable” by specifying the mail merge group name and “IEnumerable” collection.
    MailMergeDataTable dataTable = new MailMergeDataTable("Invoice", invoiceCollection);
    //Enables the flag to start each record on a new page.
    document.MailMerge.StartAtNewPage = true;
    //Performs Mail merge.
    document.MailMerge.ExecuteNestedGroup(dataTable);
}

Step 5. Convert Word to PDF and attach the ZUGFeRD XML

Use Syncfusion’s Word-to-PDF converter to create a PDF representation of your Word invoice and attach ZUGFeRD XML. The XML file ensures that your PDF includes machine-readable invoice data.

Refer to the following example code.

using (DocIORenderer renderer = new DocIORenderer())
{   
    //Set conformance level to Pdf_A3B
    renderer.Settings.PdfConformanceLevel = PdfConformanceLevel.Pdf_A3B;
    //Embed all fonts
    renderer.Settings.EmbedFonts = true;

    //Converts Word document into a PDF document.
    using (PdfDocument pdfDocument = renderer.ConvertToPDF(document))
    { 
        //Set Zugferd conformance level to Extended
        pdfDocument.ZugferdConformanceLevel = ZugferdConformanceLevel.Extended;
        //Attach the zugferd xml file to PDF document
        PdfAttachment attachment = new PdfAttachment("factur-x.xml", stream);
        attachment.Relationship = PdfAttachmentRelationship.Alternative;
        attachment.ModificationDate = DateTime.Now;
        attachment.Description = "factur-x";
        attachment.MimeType = "application/xml";
        //Add attachment to PDF document
        pdfDocument.Attachments.Add(attachment);

        //Saves the PDF file to the file system.    
        using (FileStream outputStream = new FileStream("Zugferd.pdf", FileMode.Create, FileAccess.ReadWrite))
        {
            pdfDocument.Save(outputStream);
        }
    }
}

With these steps, you can transform your Word invoices into fully compliant ZUGFeRD documents, enabling your business to align with modern e-invoicing practices.

Refer to the following image.

ZUGFeRD compliant documents

2. Generating a ZUGFeRD invoice from HTML

HTML is a versatile format for designing templates, and the PDF library makes it easy to convert HTML content into ZUGFeRD-compliant invoices. Follow these steps:

Step 1. Install the following NuGet package

# Converts HTML to PDF in .NET applications for Windows.
Install-Package Syncfusion.HtmlToPdfConverter.Net.Windows

# Provides imaging functionalities for the Syncfusion PDF library.
Install-Package Syncfusion.Pdf.Imaging.Net.Core

# Supports handling ZUGFeRD e-invoice format in .NET.
Install-Package ZUGFeRD-csharp

# High-performance template engine for generating text-based outputs.
Install-Package Scriban

# Library for parsing and serializing JSON in .NET.
Install-Package Newtonsoft.Json

Step 2. Create an HTML template

An HTML template contains placeholders with {{mustache}} syntax. It is used to bind the actual data to the HTML template. For this example, we’ll use the Scriban scripting language to create the placeholders. It’s a lightweight scripting language and engine for .NET.

The following code example shows the data model for the invoice.

public class Invoice
{
    public string Number { get; set; }
    public DateTime InvoiceDate { get; set; }
    public CurrencyCodes CurrencyCode { get; set; } = CurrencyCodes.USD;
    public InvoiceType Type { get; set; }
    public TradeParty Buyer { get; set; }
    public TradeParty Seller { get; set; }
    public Profile Profile { get; set; } = Profile.Extended;

    public List<LineItem> LineItems = new List<LineItem>();
    public DateTime DueDate { get; set; }
    public float ApplicableTax { get; set; }

    public Invoice(string invoiceNumber, DateTime invoiceDate, CurrencyCodes currencyCode)
    {
        Number = invoiceNumber;
        InvoiceDate = invoiceDate;
        CurrencyCode = currencyCode;
    }

    public decimal LineTotalAmount
    {
        get
        {
            return (decimal)LineItems.Sum(x => x.Price * x.Quantity);
        }
    }

    public float TaxTotalAmount
    {
        get
        {
            return (float)LineTotalAmount * (ApplicableTax / 100);
        }
    }

    public float GrandTotalAmount
    {
        get
        {
            return (float)LineTotalAmount + TaxTotalAmount;
        }
    }
}

Based on this model, we design the template as follows. By default, the properties and methods of .NET objects are automatically exposed with lowercase and _names. This means that a property like Invoice.Seller.Name will be exposed as invoice.seller.name. This is the default convention.

<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Invoice</title>
    <link rel="stylesheet" href="style.css" media="all" />
  </head>
  <body>
    <header class="clearfix">
      <div id="logo">
        <img src="logo.png">
      </div>
      <div id="company">
        <h2 class="name">{{invoice.seller.name}}</h2>
        <div>{{invoice.seller.street}}</div>
        <div>{{invoice.seller.city}}</div>
        <div>{{invoice.seller.post_code}}</div>
        <div>{{invoice.seller.country}}</div>
      </div>
    </header>
    <main>
      <div id="details" class="clearfix">
        <div id="client">
          <div class="to">INVOICE TO:</div>
          <h2 class="name">{{invoice.buyer.name}}</h2>
          <div class="address">{{invoice.buyer.street}}</div>
          <div class="email">{{invoice.buyer.city}}</div>
          <div class="email">{{invoice.buyer.post_code}}</div>
          <div class="email">{{invoice.buyer.country}}</div>
        </div>
        <div id="invoice">
          <h1>{{invoice.invoice_number}}</h1>
          <div class="date">Date of Invoice: {{invoice.invoice_date}}</div>
          <div class="date">Due Date: {{invoice.due_date}}</div>
        </div>
      </div>
      <table border="0" cellspacing="0" cellpadding="0">
        <thead>
          <tr>
            <th class="no">#</th>
            <th class="desc">DESCRIPTION</th>
            <th class="unit">UNIT PRICE</th>
            <th class="qty">QUANTITY</th>
            <th class="total">TOTAL</th>
          </tr>
        </thead>
        <tbody id="invoiceItems">
          {{- index = 1 -}}
          {{ for item in invoice.line_items }}
          <tr>
            <td class="no">{{index}}</td>
            <td class="desc"><h3>{{item.name}}</h3>{{item.description}}</td>
            <td class="unit">${{item.price}}</td>
            <td class="qty">{{item.quantity}}</td>
            <td class="total">${{item.total_price}}</td>
          </tr>
          {{index = index + 1}}
          {{end}}
        </tbody>
        <tfoot>
          <tr>
            <td colspan="2"></td>
            <td colspan="2">SUBTOTAL</td>
            <td>${{invoice.line_total_amount}}</td>
          </tr>
          <tr>
            <td colspan="2"></td>
            <td colspan="2">TAX 25%</td>
            <td>${{invoice.tax_total_amount}}</td>
          </tr>
          <tr>
            <td colspan="2"></td>
            <td colspan="2">GRAND TOTAL</td>
            <td>${{invoice.grand_total_amount}}</td>
          </tr>
        </tfoot>
      </table>
      <div id="thanks">Thank you!</div>
      <div id="notices">
        <div>NOTICE:</div>
        <div class="notice">A finance charge of 1.5% will be made on unpaid balances after 30 days.</div>
      </div>
    </main>
  </body>
</html>

Step 3. Access the data and bind it with the HTML template

To simplify this article, we have used a custom JSON file to store and retrieve the data. The following code snippet is used to create the invoice model.

//Bind data to invoice model.
Invoice invoice = JsonConvert.DeserializeObject<Invoice>(File.ReadAllText("../../../Data/InvoiceData.json"));

//Create zugferd xml file.
MemoryStream stream = invoice.CreateXml();

Now, we use Scriban to bind the data from the model to the HTML template, as explained in the following code example.

var invoiceTemplate = File.ReadAllText("../../../Template/index.html");
var template = Template.Parse(invoiceTemplate);
var templateData = new { invoice };

//Fill out the template with real invoice data.
var pageContent = template.Render(templateData);

Step 4. Convert HTML string to PDF and create a ZUGFeRD invoice PDF

Generate invoice PDF from the bound HTML created in the previous section, convert the generated PDF document to PDF/A-3, and attach the factur-x.xml.

//Initialize HTML to PDF converter with Blink rendering engine.
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink);

BlinkConverterSettings blinkConverterSettings = new BlinkConverterSettings();
blinkConverterSettings.ViewPortSize = new Size(1024, 768);
//Convert HTML string to PDF. 
PdfDocument document = htmlConverter.Convert(pageContent, Path.GetFullPath("Template"));
document.ZugferdConformanceLevel = ZugferdConformanceLevel.Extended;

using (MemoryStream fs = new MemoryStream())
{
    //Save and close the PDF document.
    document.Save(fs);
    document.Close(true);
    //Convert a normal PDF document to a Zugferd PDF document.
    ZugferdPDFConverter converter = new ZugferdPDFConverter();
    var pdfStream = converter.ConvetToZugFerdPDF(fs, stream);
    pdfStream.Position = 0;
    //Save the Zugferd PDF document.
    FileStream fileStream = new FileStream("Invoice.pdf", FileMode.Create, FileAccess.Write);
    pdfStream.CopyTo(fileStream);
    fileStream.Close();
    stream.Close();
}

After the conversion, you will get a PDF document like the screenshot below.

ZUGFeRD invoice in .NET PDF Library

Validating ZUGFeRD and Factur-X invoices

You can validate the ZUGFeRD invoice using the Mustang command line tool, an officially approved validator that ensures the data complies with EN 16931 standards.

java -jar Mustang-CLI-2.16.0.jar --action validate --source invoice.pdf

Conclusion

Thank you for reading! In this blog, we explored how to create ZUGFeRD invoices from a Word document and HTML with the .NET PDF Library. By integrating these steps into your workflow, you can:

  • Ensure compliance: Meet global e-invoicing standards like EN 16931 and stay ahead of regulatory requirements.

  • Boost efficiency: Reduce manual tasks and streamline processes, enabling faster invoice generation and payment cycles.

  • Enhance accuracy: Minimize errors with automated invoice generation and embedded machine-readable data.

The .NET PDF library’s robust features, such as HTML-to-PDF conversion, make it a reliable choice for developers. Whether you are using .NET or seeking an HTML-to-PDF solution, Syncfusion offers the necessary tools to streamline ZUGFeRD invoice creation. These tools enable businesses to update their invoicing processes, enhance efficiency in cross-border trade, and maintain full legal compliance.

Are you ready to integrate ZUGFeRD invoices into your system? Begin today with the .NET PDF library and enjoy the benefits of seamless e-invoicing. Download our free trialor explore the library’s documentation today. If you have any questions or need assistance with these features, please feel free to comment below or contact us through our support forum, support portal, or feedback portal. We are always here to assist you!

0
Subscribe to my newsletter

Read articles from syncfusion directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

syncfusion
syncfusion

Syncfusion provides third-party UI components for React, Vue, Angular, JavaScript, Blazor, .NET MAUI, ASP.NET MVC, Core, WinForms, WPF, UWP and Xamarin.