簡體   English   中英

在使用itext編輯pdf時獲得異常

[英]getting exception while redacting pdf using itext

在嘗試使用itext編輯pdf文檔時,我遇到了異常。 這個問題非常零星,有時它正在工作,有時它會拋出錯誤。

at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.access$6100(PdfContentStreamProcessor.java:60)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor$Do.invoke(PdfContentStreamProcessor.java:991)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpContentOperator.invoke(PdfCleanUpContentOperator.java:140)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.invokeOperator(PdfContentStreamProcessor.java:286)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.processContent(PdfContentStreamProcessor.java:425)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpProcessor.cleanUpPage(PdfCleanUpProcessor.java:160)
at com.itextpdf.text.pdf.pdfcleanup.PdfCleanUpProcessor.cleanUp(PdfCleanUpProcessor.java:135)
at RedactionClass.tgestRedactJavishsInput(RedactionClass.java:56)
at RedactionClass.main(RedactionClass.java:23)

我用來編輯的代碼如下:

public static void testRedact() throws IOException, DocumentException {

    InputStream resource = new FileInputStream("D:/itext/edited_120192824_5 (1).pdf");
    OutputStream result = new FileOutputStream(new File(OUTPUTDIR,
            "aviteshs.pdf"));

    PdfReader reader = new PdfReader(resource);
    PdfStamper stamper = new PdfStamper(reader, result);
    int pageCount = reader.getNumberOfPages();
    Rectangle linkLocation1 = new Rectangle(440f, 700f, 470f, 710f);
    Rectangle linkLocation2 = new Rectangle(308f, 205f, 338f, 215f);
    Rectangle linkLocation3 = new Rectangle(90f, 155f, 130f, 165f);
    List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
    for (int currentPage = 1; currentPage <= pageCount; currentPage++) {
        if (currentPage == 1) {
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation1, BaseColor.BLACK));
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation2, BaseColor.BLACK));
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation3, BaseColor.BLACK));
        } else {
            cleanUpLocations.add(new PdfCleanUpLocation(currentPage,
                    linkLocation1, BaseColor.BLACK));
        }
    }
    PdfCleanUpProcessor cleaner = new PdfCleanUpProcessor(cleanUpLocations,
            stamper);
    try {
        cleaner.cleanUp();
    } catch (Exception e) {
        e.printStackTrace();
    }
    stamper.close();
    reader.close();

}

由於客戶文檔我無法共享它,試圖找出一些相同的測試數據。

請在這里找到文檔:

https://drive.google.com/file/d/0B-zalNTEeIOwM1JJVWctcW8ydU0/view?usp=drivesdk

簡而言之:這里NullPointerException的原因是iText不支持從它們顯示的頁面上形成XObject資源繼承。 根據PDF規范, 此構造已過時,但在遵循早期PDF引用而不是規范的PDF中可能會遇到此構造

原因

有問題的文檔的第1頁包含4個名為I1M0P1Q0的 XObject資源:

RUPS截圖

正如您在屏幕截圖中看到的, Q0特別沒有自己的資源字典。 但它的最后指示是

q
413 0 0 125 75 3086 cm
/I1 Do
Q

Id est它引用了資源I1

現在,在XObjects形式的情況下,iText假定其內容引用的資源包含在它們自己的Resources字典中。

結果:iText訪問null字典並發生NullPointerException

規范

PDF規范ISO 32000-1規定:

資源字典應通過以下方式之一與內容流相關聯:

  • 對於作為頁面內容條目的值的內容流(或者是作為該條目的值的數組的元素),資源字典應由頁面字典的資源指定或繼承,如7.7中所述。 3.4,頁面對象的某些祖先節點的“頁面屬性的繼承”。

  • 對於其他內容流,符合規范的編寫者應在流的字典中包含一個Resources條目,該條目指定包含該內容流使用的所有資源的資源字典。 這適用於定義表單XObject,模式,Type 3字體和注釋的內容流。

  • 遵循早期版本的PDF編寫的PDF文件可能省略了頁面上使用的所有形式的XObjects和Type 3字體的Resources條目。 從這些表單和字體引用的所有資源都應從使用它們的頁面的資源字典繼承。 此構造已過時,不應由符合規范的編寫者使用。

(ISO 32000-1,第7.8.3節 - 資源字典)

因此,在手頭的情況下我們處於過時選項三的情況, Q0引用在頁面Q0的資源字典中定義的XObject I1用於。

該文檔的版本標題聲稱PDF 1.5符合性(與PDF規范的PDF 1.7相反)。 那么讓我們看一下PDF Reference 1.5。 那里對應於備選方案三的段落是:

  • 表單XObject或Type 3字體的字形描述可以省略Resources條目,在這種情況下,將在使用表單或字體的頁面的Resources條目中查找資源 不推薦這種做法。

因此,總結一下,有問題的PDF使用了PDF規范(2008年發布,使用了9年!)的結構,稱為過時甚至是文件聲稱符合推薦的PDF參考。 另一方面,iText不支持這個過時的結構。

想法如何解決這個問題

基本上,PDF清理代碼必須擴展到

  • 記住PdfCleanUpProcessor當前頁面的資源
  • 如果Do操作符引用沒有自己資源的表單XObject,則在PdfCleanUpContentOperator方法invoke中使用這些當前頁面資源。

不幸的是, invoke中使用的某些成員是私有的。 因此,必須復制PdfCleanUp代碼或重新反射。

(iText 5.5.12-SNAPSHOT)

iText 7

iText 7 PDF CleanUp工具也遇到了PDF的問題,這里的例外是IllegalStateException聲稱"Graphics state is always deleted after event dispatching. If you want to preserve it in renderer info, use preserveGraphicsState method after receiving renderer info."

由於在事件調度期間拋出此異常,因此此錯誤消息沒有意義。 不幸的是,PDF CleanUp工具已經成為iText 7中的封閉源代碼,所以要解決這個問題並不容易。

(iText 7.0.3-SNAPSHOT; PDF CleanUp 1.0.2-SNAPSHOT)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM