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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2372041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:51:43  来源:igfitidea点击:

c# itextsharp PDF creation with watermark on each page

c#pdfitext

提问by tim harrison

I am trying to programmatically create a number of PDF documents with a watermark on each page using itextsharp (a C# port of Java's itext).

我正在尝试使用 itextsharp(Java 的 itext 的 C# 端口)以编程方式创建许多带有水印的 PDF 文档。

I am able to do this after the document has been created using a PdfStamper. However this seems to involve re-opening the document reading it and then creating a new document with the watermark on each page.

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

Is there a way of doing this during document creation?

在文档创建期间有没有办法做到这一点?

采纳答案by tim harrison

After digging into it I found the best way was to add the watermark to each page as it was created. To do this I created a new class and implemented the IPdfPageEvent interface as follows:

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

    }
}

This object is registered to handle the events as follows:

这个对象被注册来处理如下事件:

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

回答by plinth

Can't you just lay down the watermark on each page after you've made it?

你不能在你制作完成后在每一页上放水印吗?

回答by James

In iTextSharp you should be able to programmatically add a watermark e.g.

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

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

回答by Curt

Yes, the Watermark class seems to be no more - odd. However in the process of converting to iTextSharp 5.3, I found a simple way to add a watermark to a new document.

是的,Watermark 类似乎不再存在 - 奇怪。但是在转换为 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();

回答by kirk

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);

回答by NoOne

Although Tim's solution seems very nice, I have managed to do the same thing (I believe) using the following code (perhaps iTextSharp was improved a bit since then...):

虽然 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();
    }

This will add a watermark on all pages of a PDF document that is provided as a byte array.

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

(You don't need to do it while creating the PDF.)

(您无需在创建 PDF 时执行此操作。)

It seems working for both landscape and portrait and it probably works for documents with mixed orientations.

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

Cheers! :)

干杯! :)

回答by Connor Williams

I used the first solution. I was having trouble getting it to work at first. I getting green underlines under all of my public voids saying that it was going to hide some inherit member.

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

Basically I realized that I already had added a PagePageEventHelper and I basically just cut out the code for the OnStartPage. ALSO! For some reason I had to make all of my public void's public override void.

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