iTextSharp从字节数组列表中创建pdf

时间:2010-10-18 17:43:48

标签: c# pdf pdf-generation itextsharp itext

我有一个byte []列表,我希望将其连接成一个字节[],这将是最终的PDf。

在“page = copy.GetImportedPage(new PdfReader(p),i);”我得到一个“对象引用未设置为实例错误。

我不知道发生了什么,我已经检查了每个对象并且没有空。

有关此问题的任何想法,或其他可能成功的代码吗?!

我有这个方法:

修改

      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
谢谢你的时间!

6 个答案:

答案 0 :(得分:40)

我已经弄明白了,所以每个人都可以得到解决方案: 这是:

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

希望有所帮助!

答案 1 :(得分:3)

这有效:

使用iTextSharp-LGPL 4.1.6:

if (pLostMem==NULL)

答案 2 :(得分:0)

虽然看看itextsharp代码可能与同一内容上的多个读者并不总是一致。

我建议你试试

page = copy.GetImportedPage(reader, i);

而不是为您尝试阅读的每个页面创建一个新的阅读器。

更新:我不知道是否有帮助,但

我复制并粘贴了你的代码,我得到了一个N​​ullReferenceException但只在这一行

 stamp.AlterContents();

这很奇怪,因为那是在你得到它之后。+

当传入List中的不良内容时,我能够生成Missing PDF标题,Trailer Not found等,所以我认为它的内容不同于p

我正在使用版本5.0.4,其中包含VS 2008中内置的源代码版本。客户端是vs 2010.也许这些可以解释差异。

答案 3 :(得分:0)

不确定这是否会为您解决,但尝试从第1页开始初始化GetImportedPage,而不是零,但在for循环中使用int i = 1。像这样:

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

答案 4 :(得分:0)

我最初使用了上面的答案而PDF非常大..我认为回来提供这个链接可以帮助我完全解决这个问题以及大型PDF问题。

https://stackoverflow.com/a/6752769

答案 5 :(得分:0)

此解决方案在iText 7.1.8中有效:

它基于先前的答案和新的API Examples

nesterov=True