c#itextsharp在每页上创建带水印的PDF文件

我正在尝试使用itextsharp(Java的itext的C#端口)以编程方式在每个页面上创建一些带有水印的PDF文档。

在使用PdfStamper创建文档后,我能够执行此操作。 然而,这似乎涉及重新打开阅读它的文档,然后在每页上创建一个带有水印的新文档。

在文档创建过程中有没有办法做到这一点?

干杯,

蒂姆。

在深入研究之后,我发现最好的方法是在创建每个页面时添加水印。 为此,我创建了一个新类并实现了IPdfPageEvent接口,如下所示:

class PdfWriterEvents : IPdfPageEvent { string watermarkText = string.Empty; public PdfWriterEvents(string watermark) { watermarkText = watermark; } public void OnOpenDocument(PdfWriter writer, Document document) { } public void OnCloseDocument(PdfWriter writer, Document document) { } public void OnStartPage(PdfWriter writer, Document document) { float fontSize = 80; float xPosition = 300; float yPosition = 400; float angle = 45; try { PdfContentByte under = writer.DirectContentUnder; BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED); under.BeginText(); under.SetColorFill(BaseColor.LIGHT_GRAY); under.SetFontAndSize(baseFont, fontSize); under.ShowTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, xPosition, yPosition, angle); under.EndText(); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } } public void OnEndPage(PdfWriter writer, Document document) { } public void OnParagraph(PdfWriter writer, Document document, float paragraphPosition) { } public void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { } public void OnChapterEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) { } public void OnSectionEnd(PdfWriter writer, Document document, float paragraphPosition) { } public void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { } } } 

注册此对象以处理事件,如下所示:

 PdfWriter docWriter = PdfWriter.GetInstance(document, new FileStream(outputLocation, FileMode.Create)); PdfWriterEvents writerEvent = new PdfWriterEvents(watermark); docWriter.PageEvent = writerEvent; 

虽然Tim的解决方案看起来非常好,但我设法使用以下代码做同样的事情(我相信)(也许iTextSharp从那时起有所改进……):

  private byte[] AddWatermark(byte[] bytes, BaseFont bf) { using(var ms = new MemoryStream(10 * 1024)) { using(var reader = new PdfReader(bytes)) using(var stamper = new PdfStamper(reader, ms)) { int times = reader.NumberOfPages; for (int i = 1; i <= times; i++) { var dc = stamper.GetOverContent(i); PdfHelper.AddWaterMark(dc, AppName, bf, 48, 35, new BaseColor(70, 70, 255), reader.GetPageSizeWithRotation(i)); } stamper.Close(); } return ms.ToArray(); } } public static void AddWaterMark(PdfContentByte dc, string text, BaseFont font, float fontSize, float angle, BaseColor color, Rectangle realPageSize, Rectangle rect = null) { var gstate = new PdfGState { FillOpacity = 0.1f, StrokeOpacity = 0.3f }; dc.SaveState(); dc.SetGState(gstate); dc.SetColorFill(color); dc.BeginText(); dc.SetFontAndSize(font, fontSize); var ps = rect ?? realPageSize; /*dc.PdfDocument.PageSize is not always correct*/ var x = (ps.Right + ps.Left) / 2; var y = (ps.Bottom + ps.Top) / 2; dc.ShowTextAligned(Element.ALIGN_CENTER, text, x, y, angle); dc.EndText(); dc.RestoreState(); } 

这将在PDF文档的所有页面上添加水印,该文档作为字节数组提供。

(创建PDF时不需要这样做。)

它似乎适用于横向和纵向,它可能适用于具有混合方向的文档。

干杯! 🙂

 string WatermarkLocation = "D:\\Images\\superseded.png"; Document document = new Document(); PdfReader pdfReader = new PdfReader(FileLocation); PdfStamper stamp = new PdfStamper(pdfReader, new FileStream(FileLocation.Replace(".pdf", "[temp][file].pdf"), FileMode.Create)); iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(WatermarkLocation); img.SetAbsolutePosition(125, 300); // set the position in the document where you want the watermark to appear (0,0 = bottom left corner of the page) PdfContentByte waterMark; for (int page = 1; page <= pdfReader.NumberOfPages; page++) { waterMark = stamp.GetOverContent(page); waterMark.AddImage(img); } stamp.FormFlattening = true; stamp.Close(); // now delete the original file and rename the temp file to the original file File.Delete(FileLocation); File.Move(FileLocation.Replace(".pdf", "[temp][file].pdf"), FileLocation); 

我用了第一个解决方案。 起初我无法让它工作。 在我所有的公开空洞下,我得到绿色下划线,说它会隐藏一些inheritance成员。

基本上我意识到我已经添加了一个PagePageEventHelper,我基本上只是删除了OnStartPage的代码。 也! 出于某种原因,我必须使我的所有公共虚空的公共覆盖无效。

  public override void OnStartPage(PdfWriter writer, Document document) { if (condition) { string watermarkText = "-whatever you want your watermark to say-"; float fontSize = 80; float xPosition = 300; float yPosition = 400; float angle = 45; try { PdfContentByte under = writer.DirectContentUnder; BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED); under.BeginText(); under.SetColorFill(iTextSharp.text.pdf.CMYKColor.LIGHT_GRAY); under.SetFontAndSize(baseFont, fontSize); under.ShowTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, xPosition, yPosition, angle); under.EndText(); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } } } 

你做完之后不能只在每页上放下水印吗?

是的,水印类似乎不再 – 奇怪。 但是在转换为iTextSharp 5.3的过程中,我找到了一种向新文档添加水印的简单方法。

 MemoryStream mem = new MemoryStream(); Document document = new Document(); PdfWriter writer = PdfWriter.GetInstance(document, mem); PdfContentByte cb = writer.DirectContent; document.Open(); document.NewPage(); Image watermark = Image.GetInstance(WATERMARK_URI); watermark.SetAbsolutePosition(80, 200); document.Add(watermark); BaseFont bf = BaseFont.CreateFont(FONT, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); cb.BeginText(); ... cb.EndText(); document.Close(); 

在iTextSharp中,您应该能够以编程方式添加水印,例如

 Watermark watermark = new Watermark(Image.getInstance("watermark.jpg"), 200, 420); document.Add(watermark);