iTextSharp creation of a pdf from a list of byte arrays

 ̄綄美尐妖づ 提交于 2019-11-29 01:26:01

I've figured it out, just so everbody can have the solution: here it is:

    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;
    }

Hope that helps!

This works:

used 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;
        }
    }

Not sure if this will fix it for you, but try initializing GetImportedPage starting at page 1, not zero but usng int i = 1 in your for loop. Like this:

// 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);
}

Looking though the itextsharp code its possible that it doesn't always work well with multiple readers on the same content.

I suggest you try

page = copy.GetImportedPage(reader, i);

rather than create a new reader for each page you're trying to read.

UPDATE: I don't know if the helps but

I copied and pasted your code and I get a NullReferenceException but only on this line

 stamp.AlterContents();

Which is strange because that's after where you are getting it.+

When passing in bad contents in the List I was able to produce Missing PDF header, Trailer Not found etc., so I don't think its a difference in the content of p

I'm using version 5.0.4 with the source code version built in VS 2008. The client is vs 2010. Perhaps these account for the difference.

Mike Wallace

I had initially used the answer above and the PDF's were very large.. I thought it would be helpful to come back and offer up this link which completely solved this issue along with the LARGE PDF issue for me.

https://stackoverflow.com/a/6752769

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!