我有一个现有的pdf文件,其中包含多个页面,我想为所有页面添加边框。
因此,我创建了一个继承自PdfPageEventHelper的类,并覆盖OnEndPage并将该类的实例分配给PdfWriter实例的PageEvent:
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace My.Apps.WPF.Classes
{
public class PdfEventHelper : PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document)
{
// Add border to page
PdfContentByte content = writer.DirectContent;
iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
rectangle.Left += document.LeftMargin;
rectangle.Right -= document.RightMargin;
rectangle.Top -= document.TopMargin;
rectangle.Bottom += document.BottomMargin;
content.SetColorStroke(BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
}
}
然后在主程序中,我有一个方法,返回一个新的PDF,所有页面都有边框(源pdf文档'pdfFilePath'是横向的,所以我保持新方向):
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
PdfEventHelper pdfEvent = new PdfEventHelper();
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
writer.PageEvent = pdfEvent;
document.Open();
document.Close(); // here it crashes, see below in post exception thrown
writer.Close();
}
}
return newPdf;
}
在运行时,在行中:
document.Close();
我得到一个IO。例外说:
该文档没有页面。
在这种情况下,Pdf文档只有1页。
我做错了什么?我不想写任何东西到现有的pdf文件,我只想创建一个新的PDF文件,与源代码完全相同,但所有页面都有边框。
更新:
尝试#1:
我已经做了下面,但我得到了黑色的所有页面(我不知道如何做矩形未填充):
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
int PageCount = reader.NumberOfPages;
for (int p = 1; p <= PageCount; p++)
{
// Add border to page
PdfContentByte cb = pdfStamper.GetOverContent(p);
iTextSharp.text.Rectangle rectangle = pdfReader.GetPageSizeWithRotation(p);
rectangle.BackgroundColor = iTextSharp.text.BaseColor.BLACK;
cb.Rectangle(rectangle);
}
}
}
}
return newPdf;
}
尝试#2:
在这次尝试中,我得到了一个ObjectDisposedException:
无法访问已关闭的文件。
退出使用pdfStamper时:
private string PutBorderToPdfPages(string pdfFilePath)
{
string newPdf = @"C:\Output.pdf";
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
for (int p = 0; p < pdfStamper.Reader.NumberOfPages; p++)
{
// Add border to page
PdfContentByte content = writer.DirectContent;
iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
rectangle.Left += document.LeftMargin;
rectangle.Right -= document.RightMargin;
rectangle.Top -= document.TopMargin;
rectangle.Bottom += document.BottomMargin;
content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
document.Close();
writer.Close();
}
}
}
return newPdf;
}
你做的
document.Open();
document.Close(); // here it crashes, see below in post exception thrown
IE。您启动一个新文档,不向其添加任何内容,然后关闭它。因此,它将是空的,iText使用响应该文档没有页面。
因此,例外是完全正确的。
“现有pdf文件”的“所有页面放置边框”的正确方法是
PdfReader
中打开文档,PdfReader
上操作的PdfStamper
,PdfStamper
。例如。像这样的源文件source
和目标文件的
:
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
{
for (int pageNumber = 1; pageNumber <= reader.NumberOfPages; pageNumber++)
{
Rectangle cropBox = reader.GetCropBox(pageNumber);
Rectangle rectangle = new Rectangle(cropBox);
rectangle.Left += 20;
rectangle.Right -= 20;
rectangle.Top -= 20;
rectangle.Bottom += 20;
PdfContentByte content = stamper.GetOverContent(pageNumber);
content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
}
因为您创建了一个没有页面的文档,所以会引发文档没有页面错误。就这么简单。
看看你的代码:
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
document.Close();
您没有在document.Open()之间添加任何内容;
和文档。关闭();
将其更改为:
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
document.Add(new Paragraph("Some content"));
document.Close();
错误将消失。如果您不想在文档中添加任何内容,那么…创建文档有什么意义?
额外说明:我看到你创建了一个页面大小取自另一个文档的文档:read. GetPageSizeWellRotation(1)
。你的目的是什么?如果你想从另一个文档复制一页,你就做错了!你应该使用PdfStamper
来代替;也就是说,如果你坚持使用旧版本的iText。
真正的解决方案:升级到iText 7,你就不会有这个问题了。
该问题发生了一些重大变化,因此我将发布一个新答案来回复更新后的问题,而不是更新我的初始答案(我认为这是对初始问题的正确答案)。
您将PdfWriter
代码与PdfStamper
代码混合在一起,这是错误的。当您创建PdfStamper
实例时,您会在内部自动创建一个PdfWriter
实例。
这是错误的:
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
for (int p = 0; p < pdfStamper.Reader.NumberOfPages; p++)
{
// Add border to page
PdfContentByte content = writer.DirectContent;
Rectangle rectangle = new Rectangle(document.PageSize);
rectangle.Left += document.LeftMargin;
rectangle.Right -= document.RightMargin;
rectangle.Top -= document.TopMargin;
rectangle.Bottom += document.BottomMargin;
content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
document.Close();
writer.Close();
}
}
}
请试试这个:
using (var reader = new PdfReader(pdfFilePath))
{
using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
{
using (var pdfStamper = new PdfStamper(reader, fileStream))
{
for (int p = 1; p <= reader.NumberOfPages; p++)
{
// Add border to page
PdfContentByte content = pdfStamper.GetOverContent(p);
Rectangle rectangle = new Rectangle(pdfReader.GetPageSize(p));
rectangle.Left += margin;
rectangle.Right -= margin;
rectangle.Top -= margin;
rectangle.Bottom += margin;
content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
content.Stroke();
}
}
}
}