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 ?
#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?
<?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: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:
Jimmy wrote:hi Otto,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.
i have no Idea about XML File.
there seems to be a WebSite which can create it online
https://xrechnung-erstellen.com/
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.
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>
Return to FiveWin for Harbour/xHarbour
Users browsing this forum: MaxP and 51 guests