C# 如何将图像添加到pdf中,并使用页面模板和模板

C# 如何将图像添加到pdf中,并使用页面模板和模板,c#,.net-4.0,itextsharp,C#,.net 4.0,Itextsharp,我很难在多页PDF中插入图像。 为了创建多个页面,我正在使用PdfConcatenate,它很有效。我可以完美地添加我的模板页面。当我尝试添加图像时,问题就开始了。它只是不加载它们 以下是用于添加图像的代码: string pdfTemplate = @"Tools\template.pdf"; string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFold

我很难在多页PDF中插入图像。 为了创建多个页面,我正在使用PdfConcatenate,它很有效。我可以完美地添加我的模板页面。当我尝试添加图像时,问题就开始了。它只是不加载它们

以下是用于添加图像的代码:

        string pdfTemplate = @"Tools\template.pdf";
        string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf");

        FileStream output = new FileStream(targetPdfPath, FileMode.Create);
        PdfConcatenate pdfConcatenate = new PdfConcatenate(output);

        PdfReader pdfReader = new PdfReader(pdfTemplate);
        MemoryStream memoryStream = getMemoryStream(output);
        PdfStamper pdfStamper = new PdfStamper(pdfReader, output);

        int cardIndex = 1;

        foreach (Registry reg in registries)
        {
            setFields(reg, pdfStamper, cardIndex);

            if (cardIndex == 4)
            {
                pdfConcatenate.AddPages(pdfReader);
                pdfReader = new PdfReader(pdfTemplate);
                pdfStamper = new PdfStamper(pdfReader, output);

                cardIndex = 1;
            }
            else
            {
                cardIndex++;
            }
        }

        //if (cardIndex != 1)
        //    pdfConcatenate.AddPages(pdfReader);

        //make the form no longer editable
        pdfStamper.FormFlattening = true;

        pdfStamper.Close();
        pdfReader.Close();
        //pdfConcatenate.Close();
如果将MemoryStream用于PdfStamper并取消注释这些行:

//if (cardIndex != 1)
//    pdfConcatenate.AddPages(pdfReader);
//pdfConcatenate.Close();
我让它添加页面,但没有图像

你知道怎么回事吗

解决方案:(感谢@mkl)


问题很可能是对
PdfStamper
如何工作的一些误解。您似乎认为它以某种方式操纵了
PdfReader
it stamps中的数据,以及事先从该阅读器导出的页面。在这种情况下,
PdfStamper
会根据读卡器中的数据生成一个新的PDF文件(在其输出流中),但读卡器本身的内容不会更新,也不会反映所有的更改(不过,
PdfReader
对象可能会在过程中被触碰,并且以后不能重复使用)。所以

正如评论中已经提到的,您有
PdfConcatenate
和数量未知的
PdfStamper
实例都在编写相同的“FileStream”输出。当这些对象中的每一个都创建一个独立的PDF时,如果其中一个获胜,那么您就很幸运了,因为这样您至少可以得到一个正确的PDF作为输出。否则,您将得到一些异常或垃圾,这些异常或垃圾由多个混合的PDF组成。因此,只将PdfConcatenate作为输出文件的目标

如果您的实际意图是每次重复使用4张卡片的内容填充模板字段并合并结果,则应而不是将模板的
PdfReader
中的页面添加到
PdfConcatenate
——该读卡器中的页面未填充而是将PdfStamper输出到
MemoryStream
,填充其字段,展平其表单,关闭它,在新的
PdfReader
中打开其输出,并将该读卡器中的所有页面添加到PdfConcatenate

我不敢把它写进代码中,因为我主要使用Java并编写未经测试的C语言(代码很可能包含多个错误…)


PS:目前,您指望所有打开的
PdfReader
实例在某个地方被隐式关闭。尽管目前情况确实如此,但最近在iText SVN存储库中的签入似乎表明这些隐式关闭调用已从代码中删除。因此,也请开始显式关闭不再使用的
PdfReader
实例。否则,您将很快不得不处理由于读卡器关闭太晚而导致的内存泄漏。

您有PdfConcatenate和数量未知的PdfStamper实例,它们都在写入同一个文件。如果你幸运的话,其中一个会赢。否则你可能会得到一些例外或垃圾。我对这个答案投了赞成票,我希望从问题中删除代码,否则我将投反对票,因为我不希望其他人读到这个,复制出完全错误的代码;eestein应该先读一读:谢谢你的回答。我真的希望每次都重复填充模板并合并结果。我有一个PDF表单,我正在使用它作为模板,但是生成的PDF可能包含多个页面,而不仅仅是一个页面。这就是我遇到麻烦的地方。我现在研究一下你的方法,然后带着结果回来。再次感谢。@BrunoLowagie感谢您提供的图书样本链接,我会调查的。关于问题中的代码,这是一个问题,不是答案,不应该被认为是正确的。我知道,但尽管如此:很多人只是复制/粘贴代码而没有阅读上下文。此外,您还说“这是用于添加图像的代码”。无论如何:我看到问题已经更新了。非常感谢。
        string pdfTemplate = @"Tools\template.pdf";
        string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf");

        FileStream output = new FileStream(targetPdfPath, FileMode.Create);
        PdfConcatenate pdfConcatenate = new PdfConcatenate(output);

        PdfReader pdfReader = new PdfReader(pdfTemplate);
        MemoryStream memoryStream = new MemoryStream();
        PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream);

        int cardIndex = 1;

        foreach (Registry reg in registries)
        {
            setFields(reg, pdfStamper, cardIndex);

            if (cardIndex == 4)
            {
                pdfStamper.FormFlattening = true;
                pdfStamper.Close();
                PdfReader tempReader = new PdfReader(memoryStream.ToArray());

                pdfConcatenate.AddPages(tempReader);

                memoryStream = new MemoryStream();
                pdfReader = new PdfReader(pdfTemplate);
                pdfStamper = new PdfStamper(pdfReader, memoryStream);

                cardIndex = 1;
            }
            else
            {
                cardIndex++;
            }
        }

        if (cardIndex != 1)
        {
            pdfStamper.FormFlattening = true;
            pdfStamper.Close();
            PdfReader tempReader = new PdfReader(memoryStream.ToArray());

            pdfConcatenate.AddPages(tempReader);

            tempReader.Close();
        }

        pdfStamper.Close();
        pdfReader.Close();
        pdfConcatenate.Close();