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

tim*_*son 31 c# pdf itext

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

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

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

干杯,

蒂姆.

tim*_*son 43

在深入研究之后,我发现最好的方法是在创建每个页面时添加水印.为此,我创建了一个新类并实现了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) { }

    }
}
Run Code Online (Sandbox Code Playgroud)

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

PdfWriter docWriter = PdfWriter.GetInstance(document, new FileStream(outputLocation, FileMode.Create));
PdfWriterEvents writerEvent = new PdfWriterEvents(watermark);
docWriter.PageEvent = writerEvent;
Run Code Online (Sandbox Code Playgroud)


NoO*_*One 18

虽然蒂姆的解决方案看起来非常好,但我设法使用以下代码做同样的事情(我相信)(也许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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

干杯! :)

  • 如果您的用例是*创建一个新的PDF并添加水印*,您可能更喜欢Tim提供的一遍变体,因为它使用的资源更少.如果您的用例是*采用现有PDF并将其加水印*,则您的解决方案是合适的. (3认同)

kir*_*irk 6

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);
Run Code Online (Sandbox Code Playgroud)


小智 6

我使用了第一个解决方案。一开始我很难让它工作。我在我所有的公共空白下得到绿色下划线,说它会隐藏一些继承成员。

基本上我意识到我已经添加了一个 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);
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)