Add a watermark to the PDF document exported by ReportViewer.

Source: Internet
Author: User

[Go to] Add a watermark to the PDF document exported by ReportViewer, and add reportviewerpdf

To meet a challenging requirement, the Reporting Service or RDLC marketing table can be used as an Excel, PDF, or other legal case format. For the general user of the G-shaped user, PDF is only applicable, the Excel worksheet can be modified, and the business unit needs to be divided when the primary table is obtained. In other words, if the printing result of the PDF and Excel sheet is different, it can be used to determine whether the results of the tables are only valid and whether there is any possible dependency that cannot be modified. (Excluding the situation in which the user can modify a PDF file or copy an Excel file as a PDF file)

I thought of adding a floating watermark to the exported PDF file. The Word, Excel, and PDF File Content in the same region are consistent. When the PDF file is added with a floating watermark, it is sufficient to form a partition. Adding a float watermark to a PDF file is not an issue. You can use iTextSharp to handle the issue. However, when you release a PDF file, you can use the ReportViewer internal operation to avoid external intervention, to make a PDF file, you need to click Hacking to make it a tough challenge for programmers!

The first step to analyze the problem is to analyze the principles of ReportViwer PDF program:

When a line of PDF is triggered, the HttpHandler called ReportViewer and example is displayed. The related settings are displayed in web. config:

<Add path = "Reserved. reportViewerWebControl. axd "verb =" * "type =" Microsoft. reporting. webForms. httpHandler, Microsoft. reportViewer. webForms, Version = 11.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91 "validate =" false "/>

When the webpage is pushed out, the browser is redirected to a specific URL, and the OpMode = Export and Format = PDF are imported, the HttpHandler handler calls back the PDF example of the table. If you want to change the mobile phone number here, there is a non-dynamic starting point that passes through Global. asax or HttpModule callback intercepts the BeginRequest event and calls Reserved. reportViewerWebControl. when the axd primary case is used, add the self-built primary keys to modify the content of the primary case to be restored. But after the production of the PDF file, the HttpHandler of ReportViewer immediately enters the HttpRepsonse and returns to the client without our intervention, therefore, the next challenge is how to intercept and modify its content.

At this time, ASP. NET is another easy-to-use device: Response. filter, which allows us to submit the Stream object processing from our own before HttpResponse returns the result byte [] bytes to the Stream, the modification can be implemented before the modification ends on the client.

Typographical text
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
 
public class ExpFileFilterStream : MemoryStream
{
    private Stream output = null;
    Func<byte[], byte[]> modifier = null;
    private HttpResponse response = null;
    private bool firstFlush = false;
    public ExpFileFilterStream(HttpResponse resp, Func<byte[], byte[]> modifier)
    {
        response = resp;
        output = resp.Filter;
        this.modifier = modifier;
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
// The ReportViewer will disable BufferOutput and split it into multiple Flush tables and return them to the front end,
// Re-utilize the Buffer function here (because it is necessary to obtain the complete content and re-handle the case ),
// But the first Flush () will be missed, so that the following attempts will avoid the first partial Flush ()
// Volume: The size of ReportViewer Flush in segments is 81920. If this value is less than, it means that the Flush is not needed.
        if (!response.BufferOutput && count == 81920)
        {
            response.BufferOutput = true;
            firstFlush = true;
        }
        base.Write(buffer, offset, count);
    }
    public override void Flush()
    {
        if (firstFlush)
        {
            firstFlush = false;
            return;
        }
// During the Flush operation, bytes will be sent back to the internal storage [] for external processing and retrieval.
        byte[] buff = base.ToArray();
        if (modifier != null)
            buff = modifier(buff);
        output.Write(buff, 0, buff.Length);
    }
}

I wrote a simple Filter Stream object. The principle is that when writing (), I first set the content of the response to be rolled back by ReportViewer HttpHandler. When Flush () when you want to restore the result, submit the previously received PDF file content (byte []) to external hosts, Func <byte [], byte []>, add the floating watermark processing, and then upload the modified version to the real OutputStream.

Here are some tips: ReportViewer HttpHandler will respond in order to reduce the memory consumption and improve the Response efficiency. set BufferOutput to false, so that the content in the Publish case is divided into multiple Flush () values (each segment does not exceed 81920 bytes ). Because we need to receive the complete ICP filing before making changes and returning the changes, we cannot recover some unmodified content first. In Write (), change Response. if BufferOutput is changed to true, the segment rollback can be secretly canceled. However, the Flush () of the first segment is already on the string, so a firstFlush flag is used to avoid the first Flush (). Because of Response. bufferOutput has been set to true. It will wait until all PDF files pass through Write () before calling Flush (). At this time, MemoryStream stores the complete PDF content.

Add Response. Filter to the BeginRequest event to construct an HttpModule. The program is very simple. It takes a lot of time to print the PDF yyyy/MM/dd HH: mm: ss translucent floating watermark in the upper left corner of the PDF via iTextSharp, iText has a long history and has a large number of functions. It is very profitable to find the current example on the Internet.

Typographical text
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Web;
using iTextSharp.text.pdf;
using iText = iTextSharp.text;
using iTextSharp.text;
using System.IO;
 
namespace ReportViewerHacking
{
    public class WaterMarkModule : IHttpModule
    {
        #region IHttpModule Members
 
        public void Dispose()
        {
        }
 
        public void Init(HttpApplication context)
        {
            context.BeginRequest += context_BeginRequest;
        }
 
        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            string url = app.Context.Request.RawUrl;
            var context = app.Context;
            if (url.Contains("Reserved.ReportViewerWebControl.axd"))
            {
                var req = context.Request;
                var resp = context.Response;
                string opType = req["OpType"];
                string name = req["Name"];
                string format = req["Format"];
                if (opType == "Export" && format == "PDF")
                {
                    resp.BufferOutput = true;
                    resp.Filter = new ExpFileFilterStream(resp, (buff) =>
                    {
// Add a watermark to the PDF content.
                        PdfReader pr = new PdfReader(buff);
                        iText.Rectangle dimension = pr.GetPageSize(1);
                        MemoryStream ms = new MemoryStream();
                        PdfStamper stmp = new PdfStamper(pr, ms);
                        //REF: http://bit.ly/10qirzK
                        BaseFont bf =
                            BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
                        iText.Font fnt = new iText.Font(bf, 6, iText.Font.NORMAL, BaseColor.BLACK);
                        PdfContentByte cb = stmp.GetOverContent(1);
// Set translucent text
                        PdfGState gstate = new PdfGState();
                        gstate.FillOpacity = 0.2f;
                        gstate.StrokeOpacity = 0.2f;
                        cb.SetGState(gstate);
                        cb.BeginText();
                        cb.SetFontAndSize(bf, 6);
                        cb.SetColorFill(BaseColor.BLACK);
                        cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT,
                            string.Format("PDF {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now),
                            dimension.GetLeft(1), dimension.GetTop(5), 0);
                        cb.EndText();
 
                        stmp.Close();
                        pr.Close();
                        return ms.ToArray();
                    });
                }
            }
        }
        #endregion
    }
}

Import HttpModule into ASP. NET website, as long as ReportViewer returns a PDF file, it will be secretly added with a floating watermark, so that I have been a small guest, haha !!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.