我很难在多页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 for PdfStamper并取消注释这些行:
//if (cardIndex != 1)
// pdfConcatenate.AddPages(pdfReader);
//pdfConcatenate.Close();
我得到它来添加页面,但没有图像。
知道什么是错的?
解决方案:(感谢@mkl)
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();
答案 0 :(得分:2)
问题很可能是对PdfStamper
如何运作的误解。您似乎认为它以某种方式操纵PdfReader
标记中的数据,以及预先从该阅读器导出的页面。这是不的情况,PdfStamper
根据阅读器中的数据生成新的PDF文件(在其输出流中),但阅读器本身的内容未更新以反映所有更改(PdfReader
对象可能会在此过程中被触及,之后不可重复使用)。所以......
正如评论中已经提到的,你有PdfConcatenate
和未知数量的PdfStamper
个实例都在编写相同的`FileStream'输出。由于这些对象中的每一个都创建了一个独立的PDF,如果其中一个获胜,那么你很幸运,因为那样你将得到至少一个合适的PDF作为输出。否则,您会得到一些异常或由多个混合的PDF组成的垃圾。因此,只使PdfConcatenate定位您的输出文件。
如果您的实际意图是每次使用4张卡片的内容重复填充模板字段并合并结果,则应不添加模板PdfReader
中的页面到PdfConcatenate
---该读者的页面没有填写! ---但是将PdfStamper输出到MemoryStream
,填充其字段,展平其形式,关闭它,在新的PdfReader
中打开其输出,并将该读取器中的所有页面添加到PdfConcatenate。
我不敢把它放到代码中,因为我主要使用Java并写下未经测试的C#代码,最有可能包含多个错误......;)
PS:目前,您依靠打开的所有PdfReader
个实例在某处隐式关闭。虽然目前情况属实,但最近在iText SVN存储库中的签到似乎表明这些隐式关闭调用已从代码中删除。因此,请开始明确关闭您不再使用的PdfReader
个实例。否则你很快就会因为读者关闭太晚而不得不处理内存泄漏问题。