2016-11-03 2 views
0

Мне нужно объединить N файлов PDF в один. Я создаю пустой файл первыйОбъединение файлов N PDF, созданных из html с использованием ITextSharp, в другой пустой файл pdf

byte[] pdfBytes = null; 

var ms = new MemoryStream(); 
var doc = new iTextSharp.text.Document(); 
var cWriter = new PdfCopy(doc, ms); 

Позже я цикл через HTML строк массива

foreach (NBElement htmlString in someElement.Children()) 
        { 
         byte[] msTempDoc = getPdfDocFrom(htmlString.GetString(), cssString.GetString()); 
         addPagesToPdf(cWriter, msTempDoc); 
        } 

В getPdfDocFrom создать PDF-файл с помощью XMLWorkerHelper и вернуть его как массив байт

private byte[] getPdfDocFrom(string htmlString, string cssString) 
    { 
     var tempMs = new MemoryStream(); 
     byte[] tempMsBytes; 
     var tempDoc = new iTextSharp.text.Document(); 
     var tempWriter = PdfWriter.GetInstance(tempDoc, tempMs); 
     tempDoc.Open(); 

     using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssString))) 
     { 
      using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(htmlString))) 
      { 
       //Parse the HTML 
       iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(tempWriter, tempDoc, msHtml, msCss); 
       tempMsBytes = tempMs.ToArray(); 
      } 
     } 

     tempDoc.Close(); 
     return tempMsBytes; 
    } 

Позже Я пытаюсь добавить страницы из этого файла PDF в пустой.

private static void addPagesToPdf(PdfCopy mainDocWriter, byte[] sourceDocBytes) 
    { 

     using (var msOut = new MemoryStream()) 
     { 
      PdfReader reader = new PdfReader(new MemoryStream(sourceDocBytes)); 
      int n = reader.NumberOfPages; 
      PdfImportedPage page; 
      for (int i = 1; i <= n; i++) 
      { 
       page = mainDocWriter.GetImportedPage(reader, i); 
       mainDocWriter.AddPage(page); 
      } 
     }} 

Он ломается, когда пытается создать PdfReader из массива байтов. Я перехожу к функции. «Не удалось восстановить: трейлер не найден. Исходное сообщение: PDF startxref не найден».

Раньше я использовал другую библиотеку для работы с PDF. Я передал 2 PdfDocuments как объекты и просто добавил страницы из одного в другое в цикле. Однако он не поддерживал Css, поэтому мне пришлось переключиться на ITextSharp.

Я не совсем понимаю разницу между PdfWriter и PdfCopy.

ответ

0

В коде есть логическая ошибка. Когда вы создаете документ с нуля, как это делается в методе getPdfDocFrom(), документ не завершен до тех пор, пока вы не активируете метод Close(). В этом методе Close() создается трейлер, а также таблица перекрестных ссылок (xref). Ошибка говорит вам, что они отсутствуют.

В самом деле, вы называете Close() метод:

tempDoc.Close(); 

Но к тому времени, когда вы Close() документ, это слишком поздно: вы уже создали tempMsBytes массив. Вам нужно создать этот массив после, вы закрываете документ.

Edit: Я ничего о C# не знаю, но если MemoryStream очищает свой буфер после его закрытия, вы можете использовать mainDocWriter.CloseStream = false; так что MemoryStream не закрывается при закрытии документа.

В Java было бы плохой настройкой для параметра «закрыть поток» значение false. Когда я прочитал ответы на вопрос Create PDF in memory instead of physical file, я вижу, что C#, вероятно, не всегда требует этой дополнительной строки.

Примечание: слияния файлов путем добавления PdfImportedPage экземпляров в PdfWriter пример дурного вкуса. Если вы используете iTextSharp 5 или ранее, вы должны использовать PdfCopy или PdfSmartCopy. Если вы используете PdfWriter, вы выбрасываете много информации (например, аннотации ссылок).

+0

Но MemoryStream становится пустым после закрытия документа. Я не могу создать массив байтов из него –

+0

Вероятно, поэтому люди используют 'mainDocWriter.CloseStream = false;' Я разработчик Java, и мне сложно понять, почему C# освобождает поток памяти после его закрытия. У C# есть некоторые странные загадки, которые я не смог полностью понять. Например, это работает: http: // stackoverflow.ком/вопросы/2815761/создать-PDF-в-памяти-вместо-о-физико-файл –

Смежные вопросы