Слияние тегов PDF без разрушения тегов

Я пытаюсь объединить два файла PDF с тегами с файлом версии iTextPDF 5.4.4. После выполнения всех операций при закрытии документа на строке: document.close();): . Выкидывает ошибку ниже

java.lang.NullPointerException
PDF Creation Failed java.lang.NullPointerException
[B@1d5c1d5c
at com.itextpdf.text.pdf.PdfCopy.fixTaggedStructure(PdfCopy.java:878)
at com.itextpdf.text.pdf.PdfCopy.flushTaggedObjects(PdfCopy.java:799)
at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:836)
at com.itextpdf.text.Document.close(Document.java:416)
at PDFMerger.mergePDF(PDFMerger.java:189)

Пожалуйста, дайте мне знать, что может быть причиной этой проблемы.

Ниже приведен код, который я использую.

PdfReader reader = new PdfReader(pdf);

boolean setTagged=reader.isTagged() ; 

Document document = new Document();

PdfCopy copy = new PdfCopy(document, new FileOutputStream("Merged.pdf"));

copy.setTagged();

document.open();

int n;
n = reader.getNumberOfPages();
for (int page = 0; page < n; ) {

    copy.addPage(copy.getImportedPage(reader, ++page,true));

}
copy.freeReader(reader);
document.close();
reader.close();

2 ответа

Это похоже на ошибку в текущих версиях iText.

@ Бруно, может быть, кто-то должен посмотреть на это

PdfCopy есть метод fixTaggedStructure который пытается исправить помеченную структуру, которая была несколько искажена при копировании помеченных страниц. До текущего iText 5.4.6-SNAPSHOT включительно вы найдете следующий код

PdfDictionary dict = (PdfDictionary)iobj.object;
PdfIndirectReference pg = (PdfIndirectReference)dict.get(PdfName.PG);
//if pg is real page - do nothing, else set correct pg and remove first MCID if exists
if (!pageReferences.contains(pg) && !pg.equals(currPage)){
    dict.put(PdfName.PG, currPage);
    PdfArray kids = dict.getAsArray(PdfName.K);
    if (kids != null) {
        PdfObject firstKid = kids.getDirectObject(0);
        if (firstKid.isNumber()) kids.remove(0);
    }
}

для тегового элемента StructElem dict из некоторого массива. Этот код неявно предполагает наличие записи для ключа PdfName.PG в этом словаре dict при выполнении pg.equals(currPage), К сожалению, эта запись является необязательной, например, образец документа, предоставленный OP, содержит такие словари StructElem, на которые ссылаются из некоторого массива без записи Pg. Это вызывает вопрос NPE.

В этом случае достаточно изменить порядок в equals звоните, т.е. вместо

if (!pageReferences.contains(pg) && !pg.equals(currPage)){

надо использовать

if (!pageReferences.contains(pg) && !currPage.equals(pg)){

или же

if (pg != null && !pageReferences.contains(pg) && !pg.equals(currPage)){

в зависимости от фактической логики программы здесь.

@ Bruno Пожалуйста, проверьте, какой вариант является семантически правильным; В конце концов, я не очень люблю эту структуру с тегами...

Кодекс был написан на C#

  public static byte[] mergeTest(byte[] pdf) {
        PdfReader reader = null;
        Document doc = null;
        PdfCopy copy = null;
        MemoryStream stream = new MemoryStream();
        byte[] output = null;

        try {
            reader = new PdfReader(pdf);
            doc = new Document();

            copy = new PdfCopy(doc, stream);
            bool tagged = reader.IsTagged();

            if (tagged)
                copy.SetTagged();


            doc.Open();

            for (int x = 1; x <= reader.NumberOfPages; x++) {
                copy.AddPage(copy.GetImportedPage(reader, x, tagged));
            }

            copy.FreeReader(reader);
            doc.Close();
            copy.Close();

            output = stream.ToArray();

            stream.Flush();
            stream.Dispose();

        } catch (Exception ex) {

        } finally {
            try {
                if (reader != null)
                    reader.Close();
            } catch (Exception) { }
        }
        return output;
    }
Другие вопросы по тегам