Skip to main content Skip to footer

Saving WebPage Using C1PDF

The C1Pdf control provides support for creating pdf files from HTML pages using 'DrawStringHtml()' method. However, there is no direct method to create a pdf from ASPX webpage. This blog discusses two approaches of creating pdf documents from webpage when :

  1. Webpage contains only HTML text
  2. Webpage contains Input or ASP.Net controls.

Webpage with HTML text only

When a ASPX webpage contains only HTML text, then it is quite easy to create pdf. Following code is used to read the aspx page and save the contents in a string object :

System.Net.WebClient client = new System.Net.WebClient();  
 string text = client.DownloadString(Server.MapPath("Default.aspx"));  
 int pos = text.IndexOf("<html");  
 text = text.Substring(pos); 

Now that we have HTML string, we can use the DrawStringHTML() method to create the pdf file. The complete code is as follows :

       C1.C1Pdf.C1PdfDocument pdf = new C1.C1Pdf.C1PdfDocument();  
        System.Drawing.RectangleF[] _cols = new System.Drawing.RectangleF[1];  
        int _currentColumn;  
        System.Net.WebClient client = new System.Net.WebClient();  
        string text = client.DownloadString(Server.MapPath("Default.aspx"));  
        int pos = text.IndexOf("<html");  
        text = text.Substring(pos);  

        // create one rectangle per column  
        System.Drawing.RectangleF rcPage = pdf.PageRectangle;  
        rcPage.Inflate(-50, -50);  
        for (int i = 0; i < 1; i++)  
        {  
            System.Drawing.RectangleF rcc = rcPage;  
            rcc.Width /= 1;  
            rcc.Offset(rcc.Width * i, 0);  
            rcc.Inflate(-10, -10);  
            _cols[i] = rcc;  
        }  

        // print the HTML string spanning multiple pages  
        _currentColumn = 0;  
        System.Drawing.Font font = new System.Drawing.Font("Times New Roman", 12);  
        System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.LightCoral, 0.01f);  
        for (int start = 0; ; )  
        {  
            System.Drawing.RectangleF rc = \_cols[\_currentColumn];  
            start = pdf.DrawStringHtml(text, font, System.Drawing.Brushes.Black, rc, start);  
            pdf.DrawRectangle(pen, rc);  

            // done?  
            if (start >= int.MaxValue)  
            {  
                break;  
            }  

            // skip page/column  
            _currentColumn++;  
            if (\_currentColumn >= \_cols.Length)  
            {  
                _currentColumn = 0;  
                pdf.NewPage();  
            }  
        }  

        pdf.Save(Server.MapPath("StringHtmlToPdfFile.pdf"));

Webpage with Input and ASPX controls

In this approach, we will use a class 'Thumbnail' class which basically loads the webpage content in a WebBrowser winforms control and then generates an image for the same. This image is then used to generate the pdf file using 'C1Pdf.DrawImage()' method. The class code is as follows :

  public class Thumbnail  
    {  
        // Image's properties  
        public string Url  
        {  
            get;  
            set;  
        }  

        public Bitmap ThumbnailImage  
        {  
            get;  
            set;  
        }  
        public int Width  
        {  
            get;  
            set;  
        }  

        public int Height  
        {  
            get;  
            set;  
        }  

        public int BrowserWidth  
        {  
            get;  
            set;  
        }  

        public int BrowserHeight  
        {  
            get;  
            set;  
        }  

        public string Html  
        {  
            get;  
            set;  
        }  

        public ThumbnailMethod Method  
        {  
            get;  
            set;  
        }  

        public enum ThumbnailMethod  
        {  
            Url,  
            Html  
        };  

        // Constructor method  
        public Thumbnail(string data, int browserWidth, int browserHeight, int thumbnailWidth, int thumbnailHeight, ThumbnailMethod method)  
        {  
            this.Method = method;  
            if (method == ThumbnailMethod.Url)  
                this.Url = data;  
            else if (method == ThumbnailMethod.Html)  
                this.Html = data;  
            this.BrowserWidth = browserWidth;  
            this.BrowserHeight = browserHeight;  
            this.Height = thumbnailHeight;  
            this.Width = thumbnailWidth;  
        }  

        /// <summary>  
        /// Create a thread to execute GenerateThumbnailInteral method.  
        /// Because the System.Windows.Forms.WebBrowser control has to   
        /// run on a STA thread while the current thread is MTA.  
        /// </summary>  
        /// <returns></returns>  
        public Bitmap GenerateThumbnail()  
        {  
            Thread thread = new Thread(new ThreadStart(GenerateThumbnailInteral));  
            thread.SetApartmentState(ApartmentState.STA);  
            thread.Start();  
            thread.Join();  
            return ThumbnailImage;  
        }  

        /// <summary>  
        /// This method creates WebBrowser instance retrieve the html code. Invoke WebBrowser_DocumentCompleted   
        /// method and convert html code to a bmp image.  
        /// </summary>  
        private void GenerateThumbnailInteral()  
        {  
            WebBrowser webBrowser = new WebBrowser();  
            try  
            {  
                webBrowser.ScrollBarsEnabled = false;  
                if (this.Method == ThumbnailMethod.Url)  
                    webBrowser.Navigate(this.Url);  
                else  
                    webBrowser.DocumentText = this.Html;  
                webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);  
                while (webBrowser.ReadyState != WebBrowserReadyState.Complete)  
                    Application.DoEvents();  
            }  
            catch (Exception)  
            {  
                // Record the exception  
                throw;  
            }  
            finally  
            {  
                webBrowser.Dispose();  
            }  
        }  

        private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)  
        {  
            WebBrowser webBrowser = (WebBrowser)sender;  
            webBrowser.ClientSize = new Size(this.BrowserWidth, this.BrowserHeight);  
            webBrowser.ScrollBarsEnabled = false;  
            this.ThumbnailImage = new Bitmap(webBrowser.Bounds.Width, webBrowser.Bounds.Height);  
            webBrowser.BringToFront();  
            webBrowser.DrawToBitmap(ThumbnailImage, webBrowser.Bounds);  
            this.ThumbnailImage = (Bitmap)ThumbnailImage.GetThumbnailImage(Width, Height, null, IntPtr.Zero);  
        }  
    }

To create an image of the webpage we need to know the size of the browser window. The size is captured using following Javascript function which saves the size of the window in two hidden textboxes :

 <script type="text/javascript">  
        function savesize() {  
            $('#TextBox1').val($(window).width());  
            $('#TextBox2').val($(window).height());  
        }  
    </script>

Now to create the pdf file, first we need to create the image. For this we will use a Button and generate the image in the 'Render' event of the webpage :

protected override void Render(HtmlTextWriter htmlWriter)  
{  
    try  
    {  
        if (flag)  
        {  
            //Image's size  
            int imgWidth = 1000;  
            int imgheight = 1500;  
            StringBuilder strbBuilder = new StringBuilder();  

            // Just display pervious content of the page    
            HtmlTextWriter htwCotent = new HtmlTextWriter(new StringWriter(strbBuilder));  
            base.Render(htwCotent);  

            // Save web page as an image in root diectory, add an image in page.  
            string strHtml = strbBuilder.ToString();  
            int browserWidth = Convert.ToInt32(this.TextBox1.Text);  
            int browserheight = Convert.ToInt32(this.TextBox2.Text);  
            Thumbnail thumbnail = new Thumbnail(strHtml, browserWidth, browserheight, browserWidth, browserheight, Thumbnail.ThumbnailMethod.Html);//strHtml, browserWidth, browserheight, imgWidth, imgheight, Thumbnail.ThumbnailMethod.Html);  
            Bitmap imageWebpage = thumbnail.GenerateThumbnail();  
            if (File.Exists(Server.MapPath("~") + "/image.bmp"))  
            {  
                File.Delete(Server.MapPath("~") + "/image.bmp");  
            }  
            imageWebpage.Save(Server.MapPath("~") + "/image.bmp");  
            htmlWriter.Write(strHtml);  
            htmlWriter.Write("<img src=\\"image.bmp\\" />");  
            imageWebpage.Dispose();  
        }  
        else  
        {  
            base.Render(htmlWriter);  
        }  
    }  
    catch (Exception e)  
    {  
        htmlWriter.Write("generate image not complete, please refresh this page:" + e.Message);  
    }  
}

All we now need to do is create a pdf file. The code for this is :

flag = false;  
C1PdfDocument pdf = new C1PdfDocument();  
System.Drawing.Image img = System.Drawing.Image.FromFile(Server.MapPath("~") + "/image.bmp");  
pdf.DrawImage(img, pdf.PageRectangle);  
pdf.Save(Server.MapPath("ImageToPdfFile.pdf"));

Download Sample

MESCIUS inc.

comments powered by Disqus