2016-06-22 6 views
1

Я создаю приложение, которое должно генерировать тысячи PDF-файлов за раз. Я использую ITextSharp для этого, и кажется, что PdfReader замедляет процесс. Ниже мой код.Itextsharp PdfReader is slow

using (MemoryStream foutput = new MemoryStream()) 
{ 
    using (PdfReader pdf = new PdfReader(templateByteArray)) // slow 
    { 
      using (PdfStamper stamper = new PdfStamper(pdf, foutput)) 
      { 
       AcroFields form = stamper.AcroFields; 
       form.SetField(_dic[@"1,1"], "some string1"); 
       form.SetField(_dic[@"1,2"], "some string2"); 
       stamper.FormFlattening = true; 
      } 
      pdf.RemoveUsageRights(); 
     } 
     EnqueueFile(foutput.ToArray()); 
} 

У меня есть отдельный потребительский поток, который принимает каждый массив байтов и записывает документы PDF на жесткий диск из очереди. После того, как я перепутал код, кажется, что узкое место находится в классе PdfReader. Есть ли альтернативный способ делать то, что я пытаюсь сделать, или у вас есть какие-то предложения?

+0

У меня такая же проблема, заполняя некоторые формы и сплющивая их. Я профилировал программу и PdfStampler.Close и get_AcroFields являются самыми медленными. Использование FieldCache не имеет никакого значения в моем случае. Вы в конечном итоге использовали itext 7? Спасибо – costa

+0

Я преобразовал свою программу в itext 7, и она медленнее! Буду признателен, если вы сможете поделиться своим опытом. – costa

ответ

1

Вы читаете свойства полей _dic[@"1,1"] и _dic[@"1,1"] снова и снова. Вы должны кэшировать эти свойства. В Java, что это делается так:

HashMap<String,TextField> fieldCache = new HashMap<String,TextField>(); 

Этот кэш хранит информацию о каждом TextField, что встречается. Вводите его с помощью метода setFieldCache():

public void manipulatePdf(String src, String dest, 
    HashMap<String,TextField> cache, String name, String login) 
    throws IOException, DocumentException { 
    PdfReader reader = new PdfReader(src); 
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
    AcroFields form = stamper.getAcroFields(); 
    form.setFieldCache(cache); 
    form.setField("test", "test"); 
    stamper.close(); 
    reader.close(); 
} 

В первый раз поле с именем "test" встречается, информация будет считываться из существующего файла. В следующий раз, когда он встретится, информация TextField будет извлечена из кеша вместо существующего файла.

+0

Спасибо. Это помогло, но не так много. Основная часть потраченного времени остается, когда PdfReader считывает байтовый массив. Есть ли в любом случае, что я могу выполнить PdfReader только один раз, а затем использовать этот ридер для написания нескольких документов PDF? Просто не нужно ждать, пока читатель будет читать файл шаблона снова и снова каждый раз. – rottenbanana

+0

Невозможно повторно использовать 'PdfReader', если вы используете экземпляр' reader' в контексте 'PdfStamper', потому что' PdfStamper' изменяет структуру PDF. Вы можете попробовать [прочитать PDF частично] (http://developers.itextpdf.com/examples/itext-action-second-edition/chapter-6#262-memoryinfo.java)), но так как необходим полный PDF-файл во всяком случае, я не думаю, что это будет иметь большое значение. Если производительности iText 5 недостаточно для вас, вы должны переключиться на [iText 7] (http://itextpdf.com/blog/itext-7-and-itext-5-roadmaps-differences-updates). iText 7 быстрее, чем iText 5, особенно читатель. –

+0

Я дам iText 7 выстрел. Большое спасибо. – rottenbanana