iTextSharp создание PDF из списка байтовых массивов - PullRequest
16 голосов
/ 18 октября 2010

У меня есть список байтов [], который я хотел бы объединить в один байт [], который будет последним PDf.

На странице "page = copy.GetImportedPage (new PdfReader (p), i); ссылка" я получаю ") не установлена ​​на ошибку экземпляра.

Я понятия не имею, что происходит, я уже проверил каждый объект, и нет нуля.

Есть идеи по этому поводу или другой кусок кода, который может сработать?!

У меня есть этот метод:

EDIT

      public static byte[] concatAndAddContent(List<byte[]> pdf)
    {
        byte [] todos;

        using(MemoryStream ms = new MemoryStream())
        {
            Document doc = new Document();
            doc.Open();

            PdfCopy copy = new PdfCopy(doc, ms);
            PdfCopyFields copy2 = new PdfCopyFields(ms);


            PdfReader reader;
            foreach (byte[] p in pdf)
            {
                reader = new PdfReader(p);
                int pages = reader.NumberOfPages;

                // loop over document pages
                for (int i = 1; i < pages; i++)
                {
                    PdfImportedPage page = copy.GetImportedPage(reader, i);
                    PdfCopy.PageStamp stamp = copy.CreatePageStamp(page);
                    PdfContentByte cb = stamp.GetUnderContent();
                    cb.SaveState();
                    stamp.AlterContents();
                    copy.AddPage(page);
                }
            }

            doc.Close();
            todos = ms.GetBuffer();
            ms.Flush();
            ms.Dispose();
        }

        return todos;
    }

Трассировка стека:

[NullReferenceException: Object reference not set to an instance of an object.]
   iTextSharp.text.pdf.PdfImportedPage..ctor(PdfReaderInstance readerInstance, PdfWriter writer, Int32 pageNumber) +45
   iTextSharp.text.pdf.PdfReaderInstance.GetImportedPage(Int32 pageNumber) +175
   iTextSharp.text.pdf.PdfCopy.GetImportedPage(PdfReader reader, Int32 pageNumber) +256
   SAM.Web.Classes.UtileriasReportes.concatAndAddContent(List`1 pdf) in \Classes\UtileriasReportes.cs:199
   SAM.Web.Classes.UtileriasReportes.ObtenReporteOdt(Int32 ordenTrabajoID, Boolean caratula, Boolean juntas, Boolean cortes, Boolean materiales, Boolean resumenMateriales) 

in D:\MIMOSS\Desarrollo\SAM 2.0\Desarrollo\WebSolution\SAM.Web\Classes\UtileriasReportes.cs:168
   SAM.Web.Produccion.PopupImpresionOdt.btnImprimir_Click(Object sender, EventArgs e) in \PopupImpresionOdt.aspx.cs:44
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

спасибо за ваше время!

Ответы [ 5 ]

40 голосов
/ 20 октября 2010

Я понял это, просто чтобы каждый мог иметь решение: вот оно:

    public static byte[] concatAndAddContent(List<byte[]> pdf)
    {
        byte [] all;

        using(MemoryStream ms = new MemoryStream())
        {
            Document doc = new Document();

            PdfWriter writer = PdfWriter.GetInstance(doc, ms);

            doc.SetPageSize(PageSize.LETTER);
            doc.Open();
            PdfContentByte cb = writer.DirectContent;
            PdfImportedPage page;

            PdfReader reader;
            foreach (byte[] p in pdf)
            {
                reader = new PdfReader(p);
                int pages = reader.NumberOfPages;

                // loop over document pages
                for (int i = 1; i <= pages; i++)
                {
                    doc.SetPageSize(PageSize.LETTER);
                    doc.NewPage();
                    page = writer.GetImportedPage(reader, i);
                    cb.AddTemplate(page, 0, 0);
                }
            }

            doc.Close();
            all = ms.GetBuffer();
            ms.Flush();
            ms.Dispose();
        }

        return all;
    }

Надеюсь, это поможет!

3 голосов
/ 06 октября 2016

Это работает:

используется iTextSharp-LGPL 4.1.6:

    public static byte[] ConcatenatePdfs(IEnumerable<byte[]> documents)
    {
        using (var ms = new MemoryStream())
        {
            var outputDocument = new Document();
            var writer = new PdfCopy(outputDocument, ms);
            outputDocument.Open();

            foreach (var doc in documents)
            {
                var reader = new PdfReader(doc);
                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    writer.AddPage(writer.GetImportedPage(reader, i));
                }
                writer.FreeReader(reader);
                reader.Close();
            }

            writer.Close();
            outputDocument.Close();
            var allPagesContent = ms.GetBuffer();
            ms.Flush();

            return allPagesContent;
        }
    }
0 голосов
/ 29 октября 2014

Первоначально я использовал ответ выше, и PDF были очень большими. Я подумал, что было бы полезно вернуться и предложить эту ссылку, которая полностью решила эту проблему вместе с большой проблемой PDF для меня.

https://stackoverflow.com/a/6752769

0 голосов
/ 19 октября 2010

Не уверен, что это исправит это для вас, но попробуйте инициализировать GetImportedPage, начиная со страницы 1, не с нуля, а используя int i = 1 в цикле for.Как это:

// loop over document pages 
//was (int i = 0; i < pages; i++) {
for (int i = 1; i < pages; i++) {
    page = copy.GetImportedPage(new PdfReader(p), i);
    stamp = copy.CreatePageStamp(page);
    PdfContentByte cb = stamp.GetUnderContent();
    cb.SaveState();
    stamp.AlterContents();
    copy.AddPage(page);
}
0 голосов
/ 19 октября 2010

Несмотря на то, что код itextsharp возможен, он не всегда хорошо работает с несколькими читателями на одном и том же контенте.

Предлагаю попробовать

page = copy.GetImportedPage(reader, i);

вместо создания нового считывателя для каждой страницы, которую вы пытаетесь прочитать.

ОБНОВЛЕНИЕ: Я не знаю, помогает ли, но

Я скопировал и вставил ваш код и получаю исключение NullReferenceException, но только в этой строке

 stamp.AlterContents();

Что странно, потому что это после того, где вы получаете это. +

При передаче неверного содержимого в Список я смог создать заголовок Missing PDF, Trailer Not found и т. Д., Поэтому я не думаю, что разница в содержании p

Я использую версию 5.0.4 с версией исходного кода, созданной в VS 2008. Клиент - против 2010. Возможно, это и есть разница.

...