2014-06-06 89 views
1

我有一些代碼結合了幾頁acro格式(與acrofields in tact),然後在最後寫入一些JS到整個文檔。iText PDFReader極其緩慢地打開

它是PdfReader在函數中添加實例化時間很長的JS(對於1MB文件,大約需要12秒)。

下面是代碼(非常簡單):

public static byte[] AddJavascript(byte[] document, string js) 
    { 
     PdfReader reader = new PdfReader(new RandomAccessFileOrArray(document), null); 
     MemoryStream msOutput = new MemoryStream(); 
     PdfStamper stamper = new PdfStamper(reader, msOutput); 
     PdfWriter writer = stamper.Writer; 

     writer.AddJavaScript(js); 

     stamper.Close(); 
     reader.Close(); 

     byte[] withJS = msOutput.GetBuffer(); 
     return withJS; 
    } 

我已基準以上,並且是慢的線是第一個。我試圖從文件而不是內存讀取它,並嘗試使用MemoryStream而不是RandomAccessFileOrArray。沒有什麼比這更快。

如果我將JS添加到單個頁面文檔,速度非常快。所以我的想法是,結合這些頁面的代碼以某種方式使得PDF慢到PdfReader

這裏是結合代碼:

public static byte[] CombineFiles(List<byte[]> sourceFiles) 
    { 
     MemoryStream output = new MemoryStream(); 

     PdfCopyFields copier = new PdfCopyFields(output); 

     try 
     { 
      output.Position = 0; 

      foreach (var fileBytes in sourceFiles) 
      { 
       PdfReader fileReader = new PdfReader(fileBytes); 

       copier.AddDocument(fileReader); 
      } 
     } 
     catch (Exception exception) 
     { 
      //throw 
     } 
     finally 
     { 
      copier.Close(); 
     } 

     byte[] concat = output.GetBuffer(); 

     return concat; 
    } 

我使用PdfCopyFields,因爲我需要保存表單字段,因此不能使用PdfCopyPdfSmartCopy。這個組合代碼非常快(幾毫秒),並生成工作文檔。上面的AddJS代碼在它之後被調用,並且PdfReader打開是緩慢的。

任何想法?

+1

你可以分享該pdf嗎?我已經習慣了iText PdfReader以更快的速度打開幾MB的文件。因此,無論你的pdf是什麼特殊的或你的環境中的東西。 – mkl

+2

與您的問題無關,但如果您使用'GetBuffer()',您偶爾會創建損壞的PDF。相反,你應該使用'ToArray()'。請參閱http://stackoverflow.com/a/5119739/231316 –

+0

我無法使用C#重現速度問題。您是否可以發佈您的PDF和JavaScript或具有相同問題的代表性示例版本? –

回答

2

(註釋轉換爲回答)

MemoryStream使用GetBuffer()偶爾會創造腐敗的PDF文件。相反,ToArray()應該總是被使用。關於這方面的更多信息可以在here找到。

1

如文件所述,PdfCopyFields確實很慢。然而,PdfCopyFields已被棄用或即將被棄用,以支持PdfCopy。沙箱中有兩個示例顯示了它的完成方式:MergeForms(複製表單時未重命名字段)和MergeForms2(重命名字段後複製表單)。這是MergeForms樣子:

Document document = new Document(); 
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename)); 
copy.setMergeFields(); 
document.open(); 
for (PdfReader reader : readers) { 
    copy.addDocument(reader); 
} 
document.close(); 
for (PdfReader reader : readers) { 
    reader.close(); 
} 

請注意,您需要最新版本的iText運行該代碼。

+0

謝謝布魯諾。但是PdfCopyFields對我來說並不那麼慢。 200毫秒結合7頁(我沒有問題)。問題是在AddJavascript函數中實例化新的PdfReader需要大約12-14秒來加載該7頁組合文件。這很奇怪。 – Wbmstrmjb

+0

確實很奇怪。不幸的是,我無法重現這一點。我只使用Java版本。我不熟悉C#端口。 iText集團公司支付的開發人員持續將iText移植到iTextSharp。因此,您將不會獲得對iTextSharp的免費支持。付費開發者只能在付費支持系統上工作(這很有意義)。 –