Products Technologies Demo Docs Blog Support Company

Using XRechnung / ZUGFeRD XML to Create PDF/A-3b Invoices with ASP.NET Core C#

This article shows how to create invoices with XRechnung and ZUGFeRD XML files using ASP.NET Core C# and the MailMerge class of TX Text Control .NET Server. The MailMerge class is used to merge data into templates to create invoices in PDF/A format.

Using XRechnung / ZUGFeRD XML to Create PDF/A-3b Invoices with ASP.NET Core C#

XRechnung is an XML-only format specifically created for processing digital invoices. ZUGFeRD, on the other hand, integrates a human-readable PDF format with a machine-readable XML format. Since the release of ZUGFeRD version 2.1, it is possible to combine the XML output from XRechnung with the method of embedding XML into a PDF file.

Generating ZUGFeRD Invoices

TX Text Control can be used to create ZUGFeRD documents by generating a PDF/A-3b document and attaching the XML content.

Learn More

This article shows how to create valid XRechnung and ZUGFeRD invoices with ASP.NET Core C#. The invoice is created with the help MailMerge component and the ZUGFeRD-csharp library.

Creating Valid XRechnung / ZUGFeRD Invoices with ASP.NET Core C#

The above article explains how to generate the XML that is required and how to attach the XML to a PDF document in order to generate a valid electronic invoice (e-invoice).

But what if you get the valid XML from your ERP system or any other billing system?

In this case, TX Text Control can be used to generate a human-readable, perfectly formatted invoice based on the valid XML data used as the data source for MailMerge.

MailMerge with XML Data Source

MailMerge takes a template with placeholder merge fields and repeating merge blocks and populates them with data from data sources such as JSON or XML. This example shows how to use the XRechnung / ZUGFeRD XML as a data source to create a PDF invoice.

Consider the following sample XRechnung 3.0 XML:

<?xml version="1.0" encoding="utf-8"?>
<rsm:CrossIndustryInvoice xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>471102</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20130605</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:IncludedSupplyChainTradeLineItem>
      <ram:AssociatedDocumentLineDocument>
        <ram:LineID>1</ram:LineID>
      </ram:AssociatedDocumentLineDocument>
      <ram:SpecifiedTradeProduct>
        <ram:Name>Item name</ram:Name>
        <ram:Description>Detail description</ram:Description>
      </ram:SpecifiedTradeProduct>
      <ram:SpecifiedLineTradeAgreement>
        <ram:GrossPriceProductTradePrice>
          <ram:ChargeAmount>11.9000</ram:ChargeAmount>
          <ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
        </ram:GrossPriceProductTradePrice>
        <ram:NetPriceProductTradePrice>
          <ram:ChargeAmount>10.0000</ram:ChargeAmount>
          <ram:BasisQuantity unitCode="H87">1.0000</ram:BasisQuantity>
        </ram:NetPriceProductTradePrice>
      </ram:SpecifiedLineTradeAgreement>
      <ram:SpecifiedLineTradeDelivery>
        <ram:BilledQuantity unitCode="H87">1.0000</ram:BilledQuantity>
      </ram:SpecifiedLineTradeDelivery>
      <ram:SpecifiedLineTradeSettlement>
        <ram:ApplicableTradeTax>
          <ram:TypeCode>VAT</ram:TypeCode>
          <ram:CategoryCode>S</ram:CategoryCode>
          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
        </ram:ApplicableTradeTax>
        <ram:SpecifiedTradeSettlementLineMonetarySummation>
          <ram:LineTotalAmount>10.00</ram:LineTotalAmount>
        </ram:SpecifiedTradeSettlementLineMonetarySummation>
      </ram:SpecifiedLineTradeSettlement>
    </ram:IncludedSupplyChainTradeLineItem>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:BuyerReference>AB-312</ram:BuyerReference>
      <ram:SellerTradeParty>
        <ram:ID>+4942142706710</ram:ID>
        <ram:Name>Lieferant GmbH</ram:Name>
        <ram:DefinedTradeContact>
          <ram:PersonName>Max Mustermann</ram:PersonName>
          <ram:TelephoneUniversalCommunication>
            <ram:CompleteNumber>+4942142706710</ram:CompleteNumber>
          </ram:TelephoneUniversalCommunication>
          <ram:EmailURIUniversalCommunication>
            <ram:URIID>max@mustermann.de</ram:URIID>
          </ram:EmailURIUniversalCommunication>
        </ram:DefinedTradeContact>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>80333</ram:PostcodeCode>
          <ram:LineOne>Lieferantenstraße</ram:LineOne>
          <ram:CityName>München</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">DE123456789</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:ID>22342424</ram:ID>
        <ram:Name>Kunden Mitte AG</ram:Name>
        <ram:DefinedTradeContact>
          <ram:PersonName>Hans Muster</ram:PersonName>
        </ram:DefinedTradeContact>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>69876</ram:PostcodeCode>
          <ram:LineOne>Kundenstraße</ram:LineOne>
          <ram:CityName>Frankfurt</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">DE234567890</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:BuyerTradeParty>
      <ram:BuyerOrderReferencedDocument>
        <ram:IssuerAssignedID>2013-471102</ram:IssuerAssignedID>
      </ram:BuyerOrderReferencedDocument>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery>
      <ram:ActualDeliverySupplyChainEvent>
        <ram:OccurrenceDateTime>
          <udt:DateTimeString format="102">20130603</udt:DateTimeString>
        </ram:OccurrenceDateTime>
      </ram:ActualDeliverySupplyChainEvent>
    </ram:ApplicableHeaderTradeDelivery>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementPaymentMeans>
        <ram:TypeCode>97</ram:TypeCode>
        <ram:Information />
      </ram:SpecifiedTradeSettlementPaymentMeans>
      <ram:ApplicableTradeTax>
        <ram:CalculatedAmount>1.90</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount>10.00</ram:BasisAmount>
        <ram:CategoryCode>S</ram:CategoryCode>
        <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
      </ram:ApplicableTradeTax>
      <ram:SpecifiedTradePaymentTerms>
        <ram:Description>Zahlbar innerhalb 30 Tagen netto bis 04.07.2023</ram:Description>
        <ram:DueDateDateTime>
          <udt:DateTimeString format="102">20230704</udt:DateTimeString>
        </ram:DueDateDateTime>
      </ram:SpecifiedTradePaymentTerms>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>10.00</ram:LineTotalAmount>
        <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
        <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
        <ram:TaxBasisTotalAmount>10.00</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">1.90</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>11.90</ram:GrandTotalAmount>
        <ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
        <ram:DuePayableAmount>11.90</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

We can use this XML directly as a data source to create the template and merge the data to generate the PDF. In TX Words, our sample application, you can load the XML as a data source to see all available node elements.

Creating templates with TX Text Control

The interesting node is SupplyChainTradeTransaction, which is used as our root node to generate the document. Now we can insert two merge blocks: ApplicableHeaderTradeAgreement and IncludedSupplyChainTradeLineItem.

Creating templates with TX Text Control

The first merge block is not inserted to repeat content, but to access the data of this node. Here we can add the fields for the seller party and the buyer party. The second block repeats all line items of the invoice.

Creating templates with TX Text Control

During the design of the template we can directly do a preview to see the results.

Creating templates with TX Text Control

Programmatically Merging Data

After the template is designed, we can merge the data programmatically using the MailMerge class. The following code snippet shows how to merge the data from the XML data source and save the document as a PDF file:

using System.Data;
using System.Text;
using TXTextControl.DocumentServer;

string xmlData = File.ReadAllText("data.xml");

using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
    tx.Create();
    tx.Load("zugferd_template.tx", TXTextControl.StreamType.InternalUnicodeFormat);

    MailMerge mailMerge = new MailMerge();
    mailMerge.TextComponent = tx;

    // dataset from XML
    DataSet ds = new DataSet();
    ds.ReadXml(new MemoryStream(Encoding.UTF8.GetBytes(xmlData)));

    // merge data
    mailMerge.Merge(ds.Tables["SupplyChainTradeTransaction"]);

    // save as PDF
    tx.Save("output.pdf", TXTextControl.StreamType.AdobePDF);
}

In line 20, you can see that we are using the SupplyChainTradeTransaction node as the root node for the merge process.

Embedding XML Data in PDF/A-3b

In the next step, we can embed the used XML data in the PDF/A document to generate a valid ZUGFeRD PDF/A-3b document. The following code snippet shows how to embed the XML data in the PDF document:

using System.Data;
using System.Text;
using TXTextControl.DocumentServer;

string xmlData = File.ReadAllText("data.xml");

using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
{
    tx.Create();
    tx.Load("zugferd_template.tx", TXTextControl.StreamType.InternalUnicodeFormat);

    MailMerge mailMerge = new MailMerge();
    mailMerge.TextComponent = tx;

    // dataset from XML
    DataSet ds = new DataSet();
    ds.ReadXml(new MemoryStream(Encoding.UTF8.GetBytes(xmlData)));

    // merge data
    mailMerge.Merge(ds.Tables["SupplyChainTradeTransaction"]);

    // load Xml file
    string metaData = File.ReadAllText("metadata.xml");

    TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings();

    // create a new embedded file
    var zugferdInvoice = new TXTextControl.EmbeddedFile(
       "ZUGFeRD-invoice.xml",
       Encoding.UTF8.GetBytes(xmlData),
       metaData);

    zugferdInvoice.Description = "ZUGFeRD-invoice";
    zugferdInvoice.Relationship = "Alternative";
    zugferdInvoice.MIMEType = "application/xml";
    zugferdInvoice.LastModificationDate = DateTime.Now;

    // set the embedded files
    saveSettings.EmbeddedFiles = new TXTextControl.EmbeddedFile[] { zugferdInvoice };

    // save as PDF
    tx.Save("output.pdf", TXTextControl.StreamType.AdobePDFA, saveSettings);
}

After the document is saved, it can be opened in any PDF viewer that supports PDF/A-3b such as Adobe Acrobat Reader.

ZUGFeRD PDF/A-3b document

Conclusion

TX Text Control provides a powerful template designer to create perfectly formatted invoices based on XML data sources. We learned how to generate the human readable part of the invoice based on the XML data. The MailMerge component can be used to merge the data into the template and generate a PDF document. By embedding the XML data in the PDF document, it is possible to generate valid ZUGFeRD PDF/A-3b documents.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

ASP.NET

Integrate document processing into your applications to create documents such as PDFs and MS Word documents, including client-side document editing, viewing, and electronic signatures.

ASP.NET Core
Angular
Blazor
JavaScript
React
  • Angular
  • Blazor
  • React
  • JavaScript
  • ASP.NET MVC, ASP.NET Core, and WebForms

Learn more Trial token Download trial

Related Posts

ASP.NETASP.NET CoreFactur-X

Visualize and Preview XRechnung, ZUGFeRD, and Factur-X Documents in .NET C#

This article shows how to visualize and preview ZUGFeRD, XRechnung, and Factur-X documents in .NET C#. It uses TX Text Control .NET Server to render the documents from the XML data.


ASP.NETASP.NET CoreFactur-X

Creating ZUGFeRD 2.3 (XRechnung, Factur-X) Documents with .NET C#

This article shows how to create ZUGFeRD 2.3 compliant invoices using TX Text Control .NET Server. ZUGFeRD 2.3 is the latest version of the ZUGFeRD data model and complies with the European…


ASP.NETASP.NET CoreElectronic Invoicing

Generating a ZUGFeRD PDF with Existing XML Data using .NET C#

This article shows how to generate a ZUGFeRD invoice with existing XML data using .NET C#. A valid PDF/A-3b file is created with a ZUGFeRD XML attachment using TX Text Control .NET Server.


ASP.NETMailMergeServerTextControl

Creating Valid XRechnung / ZUGFeRD Invoices with ASP.NET Core C#

This article shows how to create valid XRechnung and ZUGFeRD invoices with ASP.NET Core C#. The invoice is created with the help MailMerge component and the ZUGFeRD-csharp library.


ASP.NETASP.NET Core

Creating Trusted Document Containers with PDF/A-3b in .NET C#

TX Text Control allows developers to do more than just generate PDFs. They can also build trusted digital archives that combine human-readable documents and machine-readable data in one secure,…