C# 如何将图像添加到pdf中,并使用页面模板和模板
我很难在多页PDF中插入图像。 为了创建多个页面,我正在使用PdfConcatenate,它很有效。我可以完美地添加我的模板页面。当我尝试添加图像时,问题就开始了。它只是不加载它们 以下是用于添加图像的代码: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
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();