pCOS Cookbook

cookbook

interchange/zugferd_retrieve_XML

Retrieve the XML invoice data from ZUGFeRD 1.0, ZUGFeRD 2.0 or Factur-X documents.

Download Java Code  Show Output  Show Input (zugferd_invoice.pdf) 

/*
 * Retrieve the XML invoice data from ZUGFeRD 1.0, ZUGFeRD 2.0 or Factur-X documents.
 * <p>
 * Required software: pCOS interface 3 (PDFlib+PDI/PPS 7.x, TET 2.2, PLOP 3.x)<br>
 * 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 names of the XML invoice data vary among standards
        final String[] xml_invoice_name = {
        		"ZUGFeRD-invoice.xml",		/* ZUGFeRD 1.0 */
        		"zugferd-invoice.xml",		/* ZUGFeRD 2.0 */
        		"factur-x.xml"				/* Factur-X */
        };

        /*
         * ZUGFeRD/Factur-X XML invoice data is stored as "associated file"
         * in the /AF array.
         */
        
        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; !found && 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");

                    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.
                         */
                        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(
                                    "Wrote XML invoice attachment to file \""
                                    + name + "\"");
                        }
                        else
                        {
                            bad_format_exception(filename,
                                "/UF embedded file stream with XML file "
                                + "contents is missing");
                        }
                    }
                }
                else {
                    System.err.println("Warning: /UF key is missing in "
                        + "associated file");
                }
            }

            if (!found) {
                bad_format_exception(filename,
                    "Didn't find an invoice attachment with expected name (\""
                        + xml_invoice_name[0] + "\", \"" + xml_invoice_name[1] + "\"" + xml_invoice_name[2] + "\"");
            }
        }
        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 Invoice", SEARCH_PATH);
        example.execute();
    }
}