interchange/zugferd_retrieve_XML
Retrieve XML invoice data and explanatory documents from ZUGFeRD 1.0, 2.0, 2.1 or Factur-X invoices
Download Java Code Show Output Show Input (zugferd_invoice.pdf)
/*
* Retrieve XML invoice data and explanatory documents from ZUGFeRD 1.0, 2.0,
* 2.1 or Factur-X documents.
*
* If explanatory documents (additional attachments for invoice verification)
* according to Factur-X 1.0.05 or ZUGFeRD 2.x are found their names are listed.
*
* Required software: pCOS interface 8 (PDFlib+PDI/PPS 9, TET 4.1, PLOP 4.2)
* Required data: PDF document
*/
package com.pdflib.cookbook.pcos.interchange;
import java.io.FileOutputStream;
import java.io.OutputStream;
import com.pdflib.IpCOS;
import com.pdflib.cookbook.pcos.pcos_cookbook_example;
public class zugferd_retrieve_XML extends pcos_cookbook_example {
/* This is where the data files are. Adjust as necessary. */
private final static String SEARCH_PATH = "../input";
public void example_code(IpCOS p, int doc) throws Exception {
String filename = p.pcos_get_string(doc, "filename");
System.out.println("Input file name '" + filename + "'");
get_zugferd_invoice(p, filename, doc);
}
private void bad_format_exception(String filename, String text)
throws Exception
{
throw new Exception(
"Input document '" + filename
+ "' doesn't conform to the ZUGFeRD or Factur-X standard\n("
+ text + ")");
}
private void get_zugferd_invoice(IpCOS p, String filename, int doc)
throws Exception {
// The name of the XML invoice data varies among standards
final String[] xml_invoice_name = {
"ZUGFeRD-invoice.xml", /* ZUGFeRD 1.0 */
"zugferd-invoice.xml", /* ZUGFeRD 2.0 */
"factur-x.xml" /* Factur-X and ZUGFeRD 2.1 */
};
/*
* ZUGFeRD/Factur-X XML invoice data is stored as associated file
* in the /AF array at the document level.
*/
if (p.pcos_get_string(doc, "type:/Root/AF").equals("array")) {
boolean found = false;
int associated_files_count = (int) p.pcos_get_number(doc, "length:/Root/AF");
for (int i = 0; i < associated_files_count; i += 1) {
String associated_file = "/Root/AF[" + i + "]";
/*
* PDF/A-3 requires the presence of the /UF entry in the
* File Specification Dictionarry
*/
String objtype = p.pcos_get_string(doc, "type:"
+ associated_file + "/UF");
if (objtype.equals("string")) {
String name = p.pcos_get_string(doc, associated_file + "/UF");
/* Check standard invoice XML file names */
if (xml_invoice_name[0].equals(name) ||
xml_invoice_name[1].equals(name) ||
xml_invoice_name[2].equals(name)) {
/*
* There must be a corresponding "/UF" entry in the
* EF dictionary. Check whether it is a stream object.
*/
objtype = p.pcos_get_string(doc, "type:"
+ associated_file + "/EF/UF");
if (objtype.equals("stream")) {
/*
* Get the contents of the invoice and write it to a
* file.
*/
byte[] invoice_contents = p.pcos_get_stream(doc,
"", associated_file + "/EF/UF");
OutputStream os = new FileOutputStream(name);
os.write(invoice_contents);
os.close();
found = true;
System.out
.println(
"Invoice attachment written to file '" + name + "'");
}
else
{
bad_format_exception(filename,
"/UF embedded file stream with XML file "
+ "contents is missing");
}
}
else {
/* Attachments with other names are explanatory documents */
System.out.println("Found explanatory document '" + name + "'");
}
}
else {
System.err.println("Warning: /UF key is missing in "
+ "associated file number" + i);
}
}
if (!found) {
bad_format_exception(filename,
"Didn't find any invoice attachment with standard name (\""
+ xml_invoice_name[0] + "\", \"" + xml_invoice_name[1] + "\", \"" + xml_invoice_name[2] + "\"");
}
if (associated_files_count == 1)
System.out.println("No explanatory documents found");
}
else {
bad_format_exception(filename,
"PDF document does not contain any associated files");
}
}
public zugferd_retrieve_XML(String[] argv, String readable_name,
String search_path) {
super(argv, readable_name, search_path);
}
public static void main(String argv[]) {
zugferd_retrieve_XML example = new zugferd_retrieve_XML(argv,
"Extract ZUGFeRD or Factur-X invoice", SEARCH_PATH);
example.execute();
}
}