0

I am trying to add water mark on a pdf file which is saved in Document Library. I don't want to modify the file in document library although when User clicks the Print Button, it should add Water Mark and file should be downloaded without modifying the original document.

I am following this and this

The file is getting downloaded but when I open the file, it shows a message that the file is damaged. Please let me know the solution

The following is the code of my Print Button:

protected void btn_Print_Click(object sender, EventArgs e)
        {
            //Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "<script type='text/javascript' >OpenDialPrint();</script>", false);

            SPFile pdfOriginalFile = obj_RequestDocuments.GetFile(ViewState["DocumentNumber"].ToString());


        //get byte[] of uploaded file
        byte[] contentPdfOriginalFile = pdfOriginalFile.OpenBinary();

        //Initialize PdfReader
        var reader = new PdfReader(new RandomAccessFileOrArray(contentPdfOriginalFile), null);

        //We will write output file into memory. You can use temp file of course.
        var ms = new MemoryStream();

        //Initialize PdfStamper
        var stamper = new PdfStamper(reader, ms);

        //Tell stamper not to close stream when stamper itself is being closed
        stamper.Writer.CloseStream = false;

        // Getting total number of pages of the Existing Document
            int pageCount = reader.NumberOfPages;

            // Create New Layer for Watermark
            PdfLayer layer = new PdfLayer("WatermarkLayer", stamper.Writer);
            // Loop through each Page
            for (int i = 1; i <= pageCount; i++)
            {
                // Getting the Page Size
                Rectangle rect = reader.GetPageSize(i);

                // Get the ContentByte object
                PdfContentByte cb = stamper.GetUnderContent(i);

                // Tell the cb that the next commands should be "bound" to this new layer
                cb.BeginLayer(layer);
                cb.SetFontAndSize(BaseFont.CreateFont(
                  BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 50);

                PdfGState gState = new PdfGState();
                gState.FillOpacity = 0.25f;
                cb.SetGState(gState);

                cb.SetColorFill(BaseColor.BLACK);
                cb.BeginText();
                cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Confidential", rect.Width / 2, rect.Height / 2, 45f);
                cb.EndText();

                // Close the layer
                cb.EndLayer();


            }
            string[] stringParts = pdfOriginalFile.Name.Split(new char[] { '.' });
            string strType = stringParts[1];
            Page.Response.Clear();
            Page.Response.ClearContent();
            Page.Response.ClearHeaders();
            Page.Response.AddHeader("content-disposition", "attachment; filename=" + pdfOriginalFile.Name);
            //Set the content type as file extension type
            Page.Response.ContentType = strType;
            //Write the file content
            Page.Response.BinaryWrite(reader.GetPageContent(1));
            Page.Response.End();


        //Close stamper, readed
        stamper.Close();
        reader.Close();

        //Flush memory stream and set it position to start
        ms.Flush();
        ms.Position = 0;

        }

UPDATE:

I've used Itexsharp to achieve the same, the target is achieved, I am having some problems with the text alignments. the Water Mark must be started from the Bottom Left Corner of the Page. the Page size could be A3,A4 etc

Here is my Print Button Code:

protected void btn_Print_Click(object sender, EventArgs e)
        {
            //Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "<script type='text/javascript' >OpenDialPrint();</script>", false);
            DataTable dt_comments = obj_comments.GetRequestComments(ViewState["DocumentNumber"].ToString());

            Paragraph CInfoPara=new Paragraph();

            SPFile pdfOriginalFile = obj_RequestDocuments.GetFile(ViewState["DocumentNumber"].ToString());


        //get byte[] of uploaded file
        byte[] contentPdfOriginalFile = pdfOriginalFile.OpenBinary();

        //Initialize PdfReader
        var reader = new PdfReader(new RandomAccessFileOrArray(contentPdfOriginalFile), null);

        //We will write output file into memory. You can use temp file of course.
        var ms = new MemoryStream();

        //Initialize PdfStamper
        var stamper = new PdfStamper(reader, ms);

        //Tell stamper not to close stream when stamper itself is being closed
        stamper.Writer.CloseStream = false;

        // Getting total number of pages of the Existing Document
            int pageCount = reader.NumberOfPages;

            // Create New Layer for Watermark
            PdfLayer layer = new PdfLayer("WatermarkLayer", stamper.Writer);
            // Loop through each Page
            for (int i = 1; i <= pageCount; i++)
            {
                // Getting the Page Size
                Rectangle rect = reader.GetPageSize(i);

                // Get the ContentByte object
//                PdfContentByte cb = stamper.GetUnderContent(i);
                PdfContentByte cb = stamper.GetOverContent(i);

                // Tell the cb that the next commands should be "bound" to this new layer
                cb.BeginLayer(layer);
                cb.SetFontAndSize(BaseFont.CreateFont(
                  BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 8);

                PdfGState gState = new PdfGState();
                //gState.FillOpacity = 0.25f;
                gState.FillOpacity = 0.3f;
                cb.SetGState(gState);

                cb.SetColorFill(BaseColor.BLACK);
                cb.BeginText();
                 float width = rect.Width;
                float height = rect.Height;

               // int verticalValue = 211;
                //int HorizontalValue = 100;
                float HorizontalValue =width/6 ;
                float verticalValue =height/6;


                for (int j = 0; j < dt_comments.Rows.Count; j++)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append(dt_comments.Rows[j]["Action"] + " By:");
                    sb.Append(dt_comments.Rows[j]["CommentBy"].ToString());
                    sb.Append(" On " + dt_comments.Rows[j]["Created"].ToString());

                    cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, sb.ToString(), HorizontalValue, verticalValue, 0f);
                    verticalValue = verticalValue - 10;//to change the line come down
                } 
                //cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Confidential", rect.Width / 2, rect.Height / 2, 45f);




                cb.EndText();

                // Close the layer
                cb.EndLayer();


            }



        //Close stamper, readed
        stamper.Close();
        reader.Close();
        //obj_RequestDocuments.UploadFile(pdfOriginalFile.Name, ms.ToArray(), "1234");
        string[] stringParts = pdfOriginalFile.Name.Split(new char[] { '.' });
        string strType = stringParts[1];
        Page.Response.Clear();
        Page.Response.ClearContent();
        Page.Response.ClearHeaders();
        Page.Response.AddHeader("content-disposition", "attachment; filename=" + pdfOriginalFile.Name);
        //Set the content type as file extension type
        Page.Response.ContentType = strType;
        //Write the file content
        Page.Response.BinaryWrite(ms.ToArray());
        Page.Response.End();

        //Flush memory stream and set it position to start
        ms.Flush();
        ms.Position = 0;

        }
1
  • This is a complex area (to do it right). I know because I spent a lot of time on a component that does exactly this. So here you go, shameless plug: blog.muhimbi.com/2011/04/… Jan 20, 2020 at 9:57

1 Answer 1

0

We can achieve this with the help of itext sharp dll and http handler configuration in the web.config file. Long back I had implemented this using this approach.

You can refer the below sample code:

private string AddWaterMark(string watermarkText, SPFile file, SPFolder documentLibrayName)
        {
            string NewURL = string.Empty;
          
                SPFile fwatermarkfile = file;
              
                byte[] content = fwatermarkfile.OpenBinary();

                PdfReader pdfReader = new PdfReader(content);
                using (MemoryStream outputStream = new MemoryStream())
                using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
                {
                    for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++)
                    {
                        //Rectangle class in iText represent geometric representation...
                        //in this case, rectangle object would contain page geometry
                        Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex);
                        //PdfContentByte object contains graphics and text content of page returned by PdfStamper
                        PdfContentByte pdfData = pdfStamper.GetUnderContent(pageIndex);
                        //create font size for watermark
                        pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 13);
                        //create new graphics state and assign opacity
                        PdfGState graphicsState = new PdfGState();
                        graphicsState.FillOpacity = 0.4F;
                        //set graphics state to PdfContentByte
                        pdfData.SetGState(graphicsState);
                        //indicates start of writing of text
                        pdfData.BeginText();
                        //show text as per position and rotation
                        pdfData.ShowTextAligned(Element.ALIGN_CENTER, watermarkText, pageRectangle.Width / 2, pageRectangle.Height / 44, 0);
                        //call endText to invalid font set
                        pdfData.EndText();
                    }
                    pdfStamper.Close();
                    content = outputStream.ToArray();
                    SPUser user = SPContext.Current.Web.CurrentUser;
                        NewURL = "WaterMarked" + file.Name;
                      documentLibrayName.Files.Add(NewURL, content,true);
                }
          
          
          
            return NewURL;
        }
    }
}

For details code refer the below :

Programmatically adding watermark on PDF files in Sharepoint

Deployment:

  • Deploy the solution/dll in the gac

  • Register the water mark webpart dll in the web.config file in the http handler section.

1
  • Thanks , Please see my update. I've implemented the same but have some issues in Orientation settings Jan 21, 2020 at 6:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.