hi,
in Europa i need, for B2B Business, to create a Bill which a Human and a Machine can read.
i need to create a PDF/A include XML File (EN 16931)
how to insert XML File into existing PDF/A File ?
how to read XML File inside PDF/A ?
Jimmy
hi,
in Europa i need, for B2B Business, to create a Bill which a Human and a Machine can read.
i need to create a PDF/A include XML File (EN 16931)
how to insert XML File into existing PDF/A File ?
how to read XML File inside PDF/A ?
Dear Jimmy,
can you post some basic information here?
Do you possibly have the legal basis?
How should the XML be structured?
It will probably be the same here in Austria or the EU regulation is already in force.
Kind regards,
Otto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <poppler.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#define MAX_PATH 1024
void embed_xml_in_pdf(const char* pdf_path, const char* xml_path, const char* output_path) {
PopplerDocument *doc;
GError *error = NULL;
char *xml_content;
gsize xml_length;
// Load the PDF
doc = poppler_document_new_from_file(pdf_path, NULL, &error);
if (!doc) {
fprintf(stderr, "Error loading PDF: %s\n", error->message);
g_error_free(error);
return;
}
// Read the XML file
if (!g_file_get_contents(xml_path, &xml_content, &xml_length, &error)) {
fprintf(stderr, "Error reading XML file: %s\n", error->message);
g_error_free(error);
g_object_unref(doc);
return;
}
// Embed the XML
if (!poppler_document_embed_file(doc, xml_path, xml_content, xml_length, NULL, &error)) {
fprintf(stderr, "Error embedding XML: %s\n", error->message);
g_error_free(error);
} else {
printf("XML embedded successfully.\n");
}
// Save the PDF
if (!poppler_document_save(doc, output_path, &error)) {
fprintf(stderr, "Error saving PDF: %s\n", error->message);
g_error_free(error);
} else {
printf("PDF saved successfully.\n");
}
g_free(xml_content);
g_object_unref(doc);
}
void extract_xml_from_pdf(const char* pdf_path) {
PopplerDocument *doc;
GError *error = NULL;
GList *attachments, *l;
// Load the PDF
doc = poppler_document_new_from_file(pdf_path, NULL, &error);
if (!doc) {
fprintf(stderr, "Error loading PDF: %s\n", error->message);
g_error_free(error);
return;
}
// Get attachments
attachments = poppler_document_get_attachments(doc);
for (l = attachments; l; l = l->next) {
PopplerAttachment *attachment = (PopplerAttachment *)l->data;
if (g_str_has_suffix(attachment->name, ".xml")) {
gchar *xml_content;
gsize xml_length;
if (poppler_attachment_save(attachment, &xml_content, &xml_length, &error)) {
// Parse XML
xmlDocPtr doc = xmlReadMemory(xml_content, xml_length, NULL, NULL, 0);
if (doc != NULL) {
xmlChar *xmlbuff;
int buffersize;
xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
printf("Extracted XML:\n%s\n", (char *)xmlbuff);
xmlFree(xmlbuff);
xmlFreeDoc(doc);
} else {
fprintf(stderr, "Error parsing XML\n");
}
g_free(xml_content);
} else {
fprintf(stderr, "Error extracting XML: %s\n", error->message);
g_error_free(error);
}
}
}
g_list_free_full(attachments, (GDestroyNotify)g_object_unref);
g_object_unref(doc);
}
int main() {
const char *pdf_path = "input.pdf";
const char *xml_path = "invoice.xml";
const char *output_path = "output_with_xml.pdf";
embed_xml_in_pdf(pdf_path, xml_path, output_path);
extract_xml_from_pdf(output_path);
return 0;
}import io
from PyPDF2 import PdfReader, PdfWriter
from lxml import etree
def embed_xml_in_pdf(pdf_path, xml_path, output_path):
# Read the existing PDF
reader = PdfReader(pdf_path)
writer = PdfWriter()
# Copy pages from reader to writer
for page in reader.pages:
writer.add_page(page)
# Read the XML file
with open(xml_path, 'rb') as xml_file:
xml_content = xml_file.read()
# Add the XML as an embedded file
writer.add_attachment(xml_path, xml_content)
# Write the output PDF
with open(output_path, 'wb') as output_file:
writer.write(output_file)
def extract_xml_from_pdf(pdf_path):
reader = PdfReader(pdf_path)
# Get the embedded files
embedded_files = reader.attachments
for filename, content in embedded_files.items():
if filename.endswith('.xml'):
# Parse the XML content
root = etree.fromstring(content)
# You can now work with the XML data
print(etree.tostring(root, pretty_print=True).decode())
# Usage
embed_xml_in_pdf('input.pdf', 'invoice.xml', 'output_with_xml.pdf')
extract_xml_from_pdf('output_with_xml.pdf')Otto wrote:can you post some basic information here?i have just the Information which i have read in Germen Xbase++ Forum about ZUFERD or X-RECHNUNG.

<?xml version="1.0" encoding="UTF-8"?>i use SUMATRAPDF v3.1.2 to show PDF an extract include *.XML File
<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:10" 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:xoev-de:kosit:standard:xrechnung_2.2</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>99676</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20240528</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:SellerAssignedID>32515.00860</ram:SellerAssignedID>
<ram:Name>Innenraumgebläse</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>136.00</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="H87">1.00</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>136.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>2</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:SellerAssignedID>0</ram:SellerAssignedID>
<ram:Name>Fehlerspeicher auslesen/löschen PKW/Transporter</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>35.00</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="H87">1.00</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>35.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>3</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:SellerAssignedID>1</ram:SellerAssignedID>
<ram:Name>Arbeitslohn</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>79.00</ram:ChargeAmount>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="HUR">2.00</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>158.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:BuyerReference></ram:BuyerReference>
<ram:SellerTradeParty>
<ram:Name>Reimers-Kfz-Reparatur-Service GmbH</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName>Daniel Schwaß</ram:PersonName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>040/7211863</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>reimers-kfz-service@gmx.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>21035</ram:PostcodeCode>
<ram:LineOne>Gerhard-Falk-Str. 2</ram:LineOne>
<ram:CityName>Hamburg</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="FC">44/754/00068</ram:ID>
</ram:SpecifiedTaxRegistration>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE118683157</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>1538</ram:ID>
<ram:Name>Yiu</ram:Name>
<ram:DefinedTradeContact>
<ram:PersonName></ram:PersonName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>Fr. Yiu 01718118882</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>yiuimex@t-online.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>21509</ram:PostcodeCode>
<ram:LineOne>Siemensstr. 14</ram:LineOne>
<ram:CityName>Glinde</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
<!-- pdffile -->
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20240522</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<!-- creditor -->
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>1</ram:TypeCode>
<!-- iban -->
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>62.51</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>329.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Bei Zahlung bitte Kd-Nr und Beleg-Nr angeben. Zahlbar bis 07.06.2024.</ram:Description>
<!-- debitor -->
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>329.00</ram:LineTotalAmount>
<ram:TaxBasisTotalAmount>329.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">62.51</ram:TaxTotalAmount>
<ram:GrandTotalAmount>391.51</ram:GrandTotalAmount>
<ram:DuePayableAmount>391.51</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Antonio Linares wrote:Using Python:THX for Sample, but i have no Idea how to use it with Fivewin
Jimmy wrote:hi Otto,In Belgium we also have to deal with "PEPPOL". A way of sending and validating the XML files for invoicing to the gouvernement etc.. Business will also more and more request peppol use for transactions.can you post some basic information here?i have just the Information which i have read in Germen Xbase++ Forum about ZUFERD or X-RECHNUNG.
i have no Idea about XML File.
there seems to be a WebSite which can create it online
https://xrechnung-erstellen.com/
in Italy electronic invoicing has existed for years, they have practically inserted the invoice in all its forms in an xlm file but this needs another file where the style is stored, generally two types of style are associated, one such as a small page with all the data and an invoice type in graphic format. I started making a class to create electronic invoicing but then I didn't continue it due to family problems, on GitHub there are many examples also in c++(cs) or VB.
I didn't continue also because no one is interested and the fwh users are from different countries where electronic invoicing is very different, the Italians who in my opinion are the only ones who could help me were careful not to help me, but it could have been done something unique, I know that there is data stored in the invoice which can be different from one application to another but in Italy the government has imposed particular tables with particular codes, VAT rates, types of payment and many other tables.
Most likely it will be a good idea to keep some xml invoices that all of us already receive from parties that have made the transition to xml and pdf.
These we can that use (copy the used codes) and base our program on them.
These samples I have are for 95% identical (not the specific invoice detail ))))), so it should not be to complex, once base my layout on them.
Marc Venken wrote:Most likely it will be a good idea to keep some xml invoices that all of us already receive from parties that have made the transition to xml and pdf.Good Ideas.
These we can that use (copy the used codes) and base our program on them.
<?xml version="1.0" encoding="UTF-8" ?>
<rsm:CrossIndustryDocument xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:1p0" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15">
<rsm:SpecifiedExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:basic</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:SpecifiedExchangedDocumentContext>
<rsm:HeaderExchangedDocument>
<ram:ID>1224134726</ram:ID>
<ram:Name>Rechnung</ram:Name>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20240731</udt:DateTimeString>
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:Content>identNummer:WDD1690331J005389X</ram:Content>
</ram:IncludedNote>
</rsm:HeaderExchangedDocument>
<rsm:SpecifiedSupplyChainTradeTransaction>
<ram:ApplicableSupplyChainTradeAgreement>
<ram:SellerTradeParty>
<ram:Name>NORD-OSTSEE AUTOMOBILE</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>21465</ram:PostcodeCode>
<ram:LineOne>GUTENBERGSTRAßE 26</ram:LineOne>
<ram:CityName>REINBEK</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE812877788</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:ID>383564</ram:ID>
<ram:Name>Herrn Shung Yang Yiu</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>21509</ram:PostcodeCode>
<ram:LineOne>Siemensstr. 14</ram:LineOne>
<ram:CityName>Glinde</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
</ram:BuyerTradeParty>
</ram:ApplicableSupplyChainTradeAgreement>
<ram:ApplicableSupplyChainTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20240731</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableSupplyChainTradeDelivery>
<ram:ApplicableSupplyChainTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount currencyID="EUR">167.70</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount currencyID="EUR">882.64</ram:BasisAmount>
<ram:ApplicablePercent>19.00</ram:ApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementMonetarySummation>
<ram:LineTotalAmount currencyID="EUR">882.64</ram:LineTotalAmount>
<ram:ChargeTotalAmount currencyID="EUR">0.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount currencyID="EUR">0.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount currencyID="EUR">882.64</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">167.70</ram:TaxTotalAmount>
<ram:GrandTotalAmount currencyID="EUR">1050.34</ram:GrandTotalAmount>
</ram:SpecifiedTradeSettlementMonetarySummation>
</ram:ApplicableSupplyChainTradeSettlement>
</rsm:SpecifiedSupplyChainTradeTransaction>
</rsm:CrossIndustryDocument>