我正在使用iTextSharp 5.0.6来读取现有PDF,在每个页面上迭代每个页面标记文本,然后写出新标记的PDF。我面临的问题是,这不是100%的工作时间。对于某些PDF,每个页面都按预期标记,对于其他页面,大多数页面都会加盖,而有些页面则没有。看起来似乎存在压模的GetOverContent()没有返回最顶层的问题,但这只是一个假设。有没有人有类似的问题?
using iTextSharp.text;
using iTextSharp.text.pdf;
const string WATERMARK_TEXT = "John Doe";
static void Main(string[] args)
{
string masterPdf = "master.pdf";
string pdfToCreate = "watermark.pdf";
byte[] bytes = StampPDF(masterPdf);
using (FileStream stream = new FileStream(pdfToCreate, FileMode.Create))
{
stream.Write(bytes, 0, bytes.Length);
}
}
static byte[] StampPDF(string PdfPath)
{
using (MemoryStream memoryStream = new MemoryStream())
{
PdfReader reader = new PdfReader(PdfPath);
int pageCount = reader.NumberOfPages;
PdfStamper stamper = new PdfStamper(reader, memoryStream);
float fontSize = 9;
float textAngle = 0f;
BaseFont font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.WINANSI, BaseFont.EMBEDDED);
BaseColor backgroundColor = new BaseColor(0, 0, 0);
BaseColor fontColor = new BaseColor(255, 255, 255);
float padding = 2f;
float fontWidth = font.GetWidthPoint(WATERMARK_TEXT, fontSize);
iTextSharp.text.Rectangle pageSize;
PdfContentByte pageContents;
for (int i = 1; i <= pageCount; i++)
{
pageSize = reader.GetPageSize(i);
pageContents = stamper.GetOverContent(i);
//draw a rectangle
pageContents.SetColorFill(backgroundColor);
pageContents.MoveTo(pageSize.Width - (fontWidth + padding), 0f);
pageContents.LineTo(pageSize.Width, 0f);
pageContents.LineTo(pageSize.Width, 14f);
pageContents.LineTo(pageSize.Width - (fontWidth + padding), 14f);
pageContents.Fill();
//drop our watermark on top of the rectangle we just created
pageContents.BeginText();
pageContents.SetColorFill(fontColor);
pageContents.SetFontAndSize(font, fontSize);
pageContents.ShowTextAligned(PdfContentByte.ALIGN_LEFT, WATERMARK_TEXT, pageSize.Width - fontWidth, 4, textAngle);
pageContents.EndText();
}
stamper.Close();
reader.Close();
return memoryStream.ToArray();
}
}
答案 0 :(得分:3)
对于那些可能遇到同样问题的人来说,关键是检查CropBox。由于PDF的CropBox的尺寸可能小于其PageSize的尺寸,因此您需要有条件地使用其中一个。因此,基于上面的代码示例,for
循环将被更改为:
for (int i = 1; i <= pageCount; i++)
{
mediaBox = reader.GetPageSize(i);
cropBox = reader.GetCropBox(i);
overContent = stamper.GetOverContent(i);
if (cropBox != null && (cropBox.Width < mediaBox.Width || cropBox.Height < cropBox.Height))
mediaBox = cropBox;
//draw a rectangle
overContent.SetColorFill(backgroundColor);
overContent.MoveTo(mediaBox.Right - (fontWidth + fontPadding), mediaBox.Bottom);
overContent.LineTo(mediaBox.Right, mediaBox.Bottom);
overContent.LineTo(mediaBox.Right, mediaBox.Bottom + rectangleHeight);
overContent.LineTo(mediaBox.Right - (fontWidth + fontPadding), mediaBox.Bottom + rectangleHeight);
overContent.ClosePathFillStroke();
//drop our watermark on top of the rectangle we just created
overContent.BeginText();
overContent.SetColorFill(fontColor);
overContent.SetFontAndSize(font, fontSize);
overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, WATERMARK_TEXT, mediaBox.Right - fontWidth, mediaBox.Bottom + (rectangleHeight - fontSize), textAngle);
overContent.EndText();
}
答案 1 :(得分:0)
你犯了两个错误:
您假设页面没有旋转,但它们可以是:90,180,270。请注意,我从未见过180页,但它是合法的。绘制到旋转页面时,必须在绘制时将该旋转考虑在内。有趣的转换矩阵。
您假设页面的(未旋转的)左下角是0,0。您的测量基于页面的宽度和高度(关闭),但不会调整左下角的任何偏移。
横向页面有三种方法:
11 “×8.5”
8.5“x11”@ 90度旋转
8.5“x11”@ 270度旋转
从技术上讲,第四种方法是建立一个11x8.5 @ 180,但任何人都应该惩罚这些代码。很多。
有各种各样的SO问题浮出水面,提供有关如何处理页面轮换的详细信息。按照你的代码,我会说你会很快找出llx,lly的东西。