Wednesday, April 8, 2015

Programmatically adding watermark on PDF files in Sharepoint



This Blog will put some light on how to add watermark on PDF files from sharepoint document libraries and display selected in Iframe.

to achieve this we will be using itextsharp dll version 5.5.5.0 you can dowload it from here

steps to achieve PDFViewer with watermark
1. Create Visual Web Part name it according to your convenience

2. Add reference in your project to itextsharp dll

3. this is very important step don't forget to add itextsharp dll to GAC using gacutil or drag and drop feature

4. Now add two drop down control ,one iframe control and one submit button  in ascx page of visual webpart

first drop down will be used to bind names of document libraries
second will be used to select pdf files from selected document library

on click of submit button , Iframe will be used to display PDF file selected.

here is how ascx page looks like

<table style="width:100%; padding:2px;">

            <tr>
          <td class="auto-style1">Please select document libraries</td>
        <td class="auto-style1">
<asp:DropDownList ID="DocumentLibraries" runat="server" CssClass="auto-style2" AutoPostBack="true"  OnSelectedIndexChanged="DocumentLibraries_SelectedIndexChanged"></asp:DropDownList>
            </td>
    </tr>
    <tr>
        <td class="auto-style1">Please select PDF File to view</td>
        <td class="auto-style1">
<asp:DropDownList ID="pdffiles" runat="server" CssClass="auto-style2"></asp:DropDownList>
            </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button runat="server" ID="btnAggregrator" Text="Submit" onclick="btnAggregrator_Click"/>
        </td>
    </tr>

    </table>
<div>

<asp:Literal ID="l1" runat="server" ></asp:Literal>
</div>


5. In the ascx.cs file replace the page load method with below code

 protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                DocumentLibraries.Items.Clear();
                LoadDocumentLibraryDropdown();
            }
        }

6. Add new method as below

  private void LoadDocumentLibraryDropdown()
        {
                     SPWeb web = SPContext.Current.Web;
                 
                        DocumentLibraries.Items.Add("Please Select");
                        foreach (SPList libraries in web.Lists)
                        {
                            if (libraries.BaseType == SPBaseType.DocumentLibrary && libraries.BaseTemplate == SPListTemplateType.DocumentLibrary)
                            {
                                if (libraries.Title != "Form Templates" && libraries.Title != "Style Library" && libraries.Title != "Site Assets" && libraries.Title != "Site Collection Documents" && libraries.Title != "Translation Packages" && libraries.Title != "WaterMarkedDocuments")
                                {
                                    DocumentLibraries.Items.Add(libraries.Title);
                                }
                            }

                        }

7. Add the dropdown select index change as below

     protected void DocumentLibraries_SelectedIndexChanged(object sender, EventArgs e)
        {
         
                string documentLibrarySelected = DocumentLibraries.SelectedValue;
                if (documentLibrarySelected != "Please Select" && !string.IsNullOrEmpty(documentLibrarySelected))
                {

                             SPWeb web = SPContext.Current.Web;
                            SPDocumentLibrary library = (SPDocumentLibrary)web.Lists[documentLibrarySelected];
                            foreach (SPListItem files in library.Items)
                            {

                                if (files.File.Url.Contains(".pdf"))
                                {
                                    pdffiles.Items.Add(new System.Web.UI.WebControls.ListItem(files.File.Name, files.File.Url));

                                }                      
                    }              
                else
                {
                    pdffiles.Items.Clear();
                }
            }
}

8. Add Button click event

   protected void btnAggregrator_Click(object sender, EventArgs e)
        {
         
                string documentLibrarySelected = DocumentLibraries.SelectedValue;
                if (!string.IsNullOrEmpty(documentLibrarySelected))
                {
                    SPWeb web = SPContext.Current.Web;
                    SPWeb rootweb = SPContext.Current.Site.RootWeb;
                    SPList list = web.Lists[documentLibrarySelected];


                    SPFolder folder = rootweb.GetFolder(rootweb.Url + "/WaterMarkedDocuments");
                    if (folder.Exists == false)
                    {
                        rootweb.AllowUnsafeUpdates = true;
                        rootweb.Lists.Add("WaterMarkedDocuments", "library to store water arked documents", SPListTemplateType.DocumentLibrary);
                        rootweb.AllowUnsafeUpdates = false;
                        web.Update();
                        folder = rootweb.Folders["WaterMarkedDocuments"];

                    }

                    SPFile file = web.GetFile(pdffiles.SelectedValue);


                    SPUser currentUser = web.CurrentUser;
                    string watermark = null;
                    if (currentUser != null)
                        watermark = "Controlled Copy: " + SPContext.Current.Site.Url + "\\" + file.Title + "\\" + currentUser.Name + "\\" + System.DateTime.Now;

                    string url = web.Url + "/" + pdffiles.SelectedValue;

                    byte[] content = file.OpenBinary();


                    string newUrl = AddWaterMark(watermark, file, folder);


                    string modifiedUrl = rootweb.Url + "/WaterMarkedDocuments" + "/" + newUrl + "#toolbar=0&navpanes=0";

                    l1.Text = "<object id='AcrobatFrame' type='application/pdf' data='" + modifiedUrl + "' width='609' height='509'></object>";


                }
            }
9. add AddWaterMark event as below ( this method writes watermark over PDF files

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


The above webpart will not modify the original pdf file it will copy the content of selected pdf file and it will create new pdf file with watermark in document library WaterMarkedDocuments ( code takes care of creating this document library .


if u have any doubts over this article please feel free to contact me over vishalkd@gmail.com. Happy coding !!