Создание XFA в PDFBox 1.8.12, а не в 2.0.4

Я пытался извлечь XFA из файла, и у меня все работало нормально, пока я не обновил PDFBox с 1.8.12 до 2.0.4.

У меня есть файл, который я могу извлечь XFA, используя 1.8.12, но не используя 2.0.4.

Когда я извлекаю это с помощью PDFBox с использованием 2.0.4, я получаю структуру XFA, но почти все значения отсутствуют. С другой стороны, когда я пытаюсь извлечь ту же форму, используя 1.8.12, все получается нормально.

Я рассмотрел аналогичную проблему на ТАК. Говорят, что это исправлено в 2.0.4, но я все еще сталкиваюсь с проблемами.

Любые идеи?

Я включил файлы

Сгенерированный XFA-1.8.12

Сгенерированный XFA-2.0.4

Используемый файл

РЕДАКТИРОВАТЬ №1

Для версии 2.0.4

    // returns PDXFA
    public static byte[] getParsableXFAForm(File file) {
        if (file == null)
            return null;
        PDDocument doc;
        PDDocumentCatalog catalog;
        PDAcroForm acroForm;

        PDXFAResource xfa;
        try {
//            String pass = null;
            doc = PDDocument.load(file);
            if (doc == null)
                return null;
//             flattenPDF(doc);
            doc.setAllSecurityToBeRemoved(true);
            // System.out.println("Security " + doc.isAllSecurityToBeRemoved());
            catalog = doc.getDocumentCatalog();
            if (catalog == null) {
                doc.close();
                return null;
            }
            acroForm = catalog.getAcroForm();
            if (acroForm == null) {
                doc.close();
                return null;
            }
            xfa = acroForm.getXFA();
            if (xfa == null) {
                doc.close();
                return null;
            }
            // TODO return byte[]
            byte[] xfaBytes = xfa.getBytes();
            doc.close();
            return xfaBytes;
        } catch (IOException e) {
            // handle IOException
            // happens when the file is corrupt.
            e.printStackTrace();
            System.out.println("XFAUtils-getParsableXFAForm-IOException");
            return null;
        }
    }

Для версии 1.8.12

public static byte[] getParsableXFAForm(File file) {
        if (file == null)
            return null;
        PDDocument doc;
        PDDocumentCatalog catalog;
        PDAcroForm acroForm;
        PDXFA xfa;
        try {
            doc = PDDocument.loadNonSeq(file, null);
            if (doc == null)
                return null;
            // flattenPDF(doc);
            doc.setAllSecurityToBeRemoved(true);
            // System.out.println("Security " + doc.isAllSecurityToBeRemoved());
            catalog = doc.getDocumentCatalog();
            if (catalog == null) {
                doc.close();
                return null;
            }
            acroForm = catalog.getAcroForm();

            if (acroForm == null) {
                doc.close();
                return null;
            }
            xfa = acroForm.getXFA();
            if (xfa == null) {
                doc.close();
                return null;
            }
            // TODO return byte[]
            byte[] xfaBytes = xfa.getBytes();
            doc.close();
            return xfaBytes;
        } catch (IOException e) {
            // handle IOException
            // happens when the file is corrupt.
//          e.printStackTrace();
            System.out.println("XFAUtils-getParsableXFAForm-IOException");
            return null;
        }
}

person Mayank    schedule 17.03.2017    source источник
comment
В вашем PDF 6 правок, в ходе которых форма XFA заполнялась все больше и больше. Похоже, ваш код 1.8.12 извлекает самую последнюю версию формы XFA, а ваш код 2.0.4 извлекает ее самую старую версию. Можете ли вы добавить свой ключевой код поиска XFA для обеих версий PDFBox к своему вопросу для анализа?   -  person mkl    schedule 17.03.2017
comment
@mkl Я добавил код, если вы могли бы взглянуть на него. Если я могу спросить, как вы узнали, сколько раз это было заполнено? Спасибо.   -  person Mayank    schedule 17.03.2017
comment
@mkl Ты что-то понял?   -  person Mayank    schedule 18.03.2017
comment
Я не за компьютером в выходные, только смартфон. Скорее всего, я не смогу разобраться в этом раньше понедельника.   -  person mkl    schedule 18.03.2017
comment
@mkl Я знаю, что надоедаю, но не могли бы вы разобраться в этом. Я действительно озадачен. Спасибо   -  person Mayank    schedule 20.03.2017


Ответы (1)


С первого взгляда

В вашем PDF 6 правок, в ходе которых форма XFA заполнялась все больше и больше. Ваш код 1.8.12 извлекает самую последнюю версию формы XFA, а ваш код 2.0.4 извлекает ее самую старую версию.

Я запустил ваш код версии 2.0.4, используя PDFBox версии 2.0.4, 2.0.5 и текущий моментальный снимок разработки 2.1.0-SNAPSHOT. В версии 2.0.4 я действительно мог воспроизвести, что была загружена самая старая версия формы XFA, но при использовании 2.0.5 или 2.1.0-SNAPSHOT загружалась текущая версия.

Похоже, это недостаток PDFBox 2.0.0...2.0.4, который был исправлен в версии 2.0.5.

При ближайшем рассмотрении

Поскольку ошибка в PDFBox 2.0.4, читающая форму XFA из неправильной версии файла, казалась совершенно неправдоподобной, я еще немного изучил ее.

В частности, я внимательно рассмотрел сам файл PDF. И действительно, оказалось, что файл имеет 10 мусорных байт перед собственно заголовком PDF-файла!

Эти дополнительные мусорные байты сделали перекрестные ссылки и смещения относительно начала файла неправильными. Таким образом, PDFBox не может анализировать файл обычным образом, а вместо этого должен выполнить какое-то восстановление.

Глядя на различия между 2.0.4 и 2.0.5, в частности, были внесены существенные изменения в код для восстановления PDF-файлов с неработающими перекрестными ссылками и смещениями. В то время как PDFBox 2.0.4 смог восстановить файл только частично (найдя только начальную версию XFA), PDFBox 2.0.5 удалось выполнить более полное восстановление, обнаружив, в частности, новейшую версию XFA.


Исправив PDF-файл OP (т.е. удалив начальные байты мусора, см. XFA-File-fixed.pdf), я смог успешно извлечь текущую версию формы XFA, используя версии PDFBox 2.0.0.. .2.0.4 тоже.

Таким образом, это не ошибка PDFBox, как я первоначально предполагал, а просто сломанный файл PDF, который функции восстановления файлов PDFBox не могли должным образом исправить до улучшений PDFBox 2.0.5.

person mkl    schedule 20.03.2017
comment
О проблеме с мусорными байтами ему рассказали в stackoverflow.com/a/42702545/535646. - person Tilman Hausherr; 21.03.2017