Пример #1
1
        /// <summary>
        /// Create PDF pages from given HTML and appends them to the provided PDF document.<br/>
        /// </summary>
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            XSize orgPageSize;
            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            else
                orgPageSize = config.ManualPageSize;

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                        container.StylesheetLoad += stylesheetLoad;
                    if (imageLoad != null)
                        container.ImageLoad += imageLoad;

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);
                    container.PageSize = pageSize;
                    container.MarginBottom = config.MarginBottom;
                    container.MarginLeft = config.MarginLeft;
                    container.MarginRight = config.MarginRight;
                    container.MarginTop = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards))
                    {
                        container.PerformLayout(measure);
                    }

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    // add web links and anchors
                    HandleLinks(document, container, orgPageSize, pageSize);
                }
            }
        }
Пример #2
1
        /// <summary>
        /// Create PDF pages from given HTML and appends them to the provided PDF document.<br/>
        /// </summary>
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            XSize orgPageSize;
            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            else
                orgPageSize = config.ManualPageSize;

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                        container.StylesheetLoad += stylesheetLoad;
                    if (imageLoad != null)
                        container.ImageLoad += imageLoad;

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);
                    container.PageSize = pageSize;                    
                    container.MarginBottom = config.MarginBottom;  
                    container.MarginLeft = config.MarginLeft;
                    container.MarginRight = config.MarginRight;
                    container.MarginTop = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards);              
                    container.PerformLayout(measure);                    

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    //SL: if there is more than one page, increase the bottom margin to allow space for the page number
                    container.MarginBottom += scrollOffset > -container.ActualSize.Height ?  20 : 0;
                    container.PerformLayout(measure); //SL: This still does not increase the margin for the first page of a multi page.. welp
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    if (config.AddPageCountFoooter && document.PageCount > 1)  //Only add page numbers if more than one page
                        AddPageCountFoooter(document, pageSize);

                    // SL: Set config option to handle links or not as it crashes for 
                    // some valid html links. 
                    // TODO: Investigate reason for crashing. 
                    if (config.HandleLinks)
                        HandleLinks(document, container, orgPageSize, pageSize);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Handle HTML links by create PDF Documents link either to external URL or to another page in the document.
        /// </summary>
        private static void HandleLinks(PdfDocument document, HtmlContainer container, XSize orgPageSize, XSize pageSize)
        {
            foreach (var link in container.GetLinks())
            {
                int i = (int)(link.Rectangle.Top / pageSize.Height);
                for (; i < document.Pages.Count && pageSize.Height * i < link.Rectangle.Bottom; i++)
                {
                    var offset = pageSize.Height * i;

                    // f*****g position is from the bottom of the page
                    var xRect = new XRect(link.Rectangle.Left, orgPageSize.Height - (link.Rectangle.Height + link.Rectangle.Top - offset), link.Rectangle.Width, link.Rectangle.Height);

                    if (link.IsAnchor)
                    {
                        // create link to another page in the document
                        var anchorRect = container.GetElementRectangle(link.AnchorId);
                        if (anchorRect.HasValue)
                        {
                            // document links to the same page as the link is not allowed
                            int anchorPageIdx = (int)(anchorRect.Value.Top / pageSize.Height);
                            if (i != anchorPageIdx)
                                document.Pages[i].AddDocumentLink(new PdfRectangle(xRect), anchorPageIdx);
                        }
                    }
                    else
                    {
                        // create link to URL
                        document.Pages[i].AddWebLink(new PdfRectangle(xRect), link.Href);
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Create PDF document from given HTML.<br/>
        /// </summary>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static PdfDocument GeneratePdf(string html, PdfGenerateConfig config, CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null)
        {
            // create PDF document to render the HTML into
            var document = new PdfDocument();

            XSize orgPageSize;

            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
            {
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            }
            else
            {
                orgPageSize = config.ManualPageSize;
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                    {
                        container.StylesheetLoad += stylesheetLoad;
                    }
                    if (imageLoad != null)
                    {
                        container.ImageLoad += imageLoad;
                    }

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize  = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);

                    // layout the HTML with the page width restriction to know how many pages are required
                    using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards))
                    {
                        container.PerformLayout(measure);
                    }

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        if (config.PageSize != PageSize.Undefined)
                        {
                            page.Size = config.PageSize;
                        }
                        else
                        {
                            page.Height = config.ManualPageSize.Height;
                            page.Width  = config.ManualPageSize.Width;
                        }

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    // add web links and anchors
                    HandleLinks(document, container, orgPageSize, pageSize);
                }
            }

            return(document);
        }
Пример #5
0
        /// <summary>
        /// Create PDF pages from given HTML and appends them to the provided PDF document.<br/>
        /// </summary>
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null)
        {
            XSize orgPageSize;

            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
            {
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            }
            else
            {
                orgPageSize = config.ManualPageSize;
            }

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                    {
                        container.StylesheetLoad += stylesheetLoad;
                    }
                    if (imageLoad != null)
                    {
                        container.ImageLoad += imageLoad;
                    }

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize  = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);
                    container.PageSize     = pageSize;
                    container.MarginBottom = config.MarginBottom;
                    container.MarginLeft   = config.MarginLeft;
                    container.MarginRight  = config.MarginRight;
                    container.MarginTop    = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards))
                    {
                        container.PerformLayout(measure);
                    }

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;

                    int totalPages = (int)(container.ActualSize.Height / pageSize.Height) + 1;

                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width  = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);

                            if (config.EnablePageNumbering)
                            {
                                string pageNumbersStr     = string.Format(config.PageNumbersPattern, (-scrollOffset / pageSize.Height) + 1, totalPages);
                                var    pageNumbersStrSize = g.MeasureString(pageNumbersStr, config.PageNumbersFont);

                                double xCord = 0;
                                switch (config.PageNumberLocation)
                                {
                                case PageNumberLocation.Left:
                                    xCord = config.MarginLeft + pageNumbersStrSize.Width / 2;
                                    break;

                                case PageNumberLocation.Middle:
                                    xCord = config.MarginLeft + pageSize.Width / 2 - pageNumbersStrSize.Width / 2;
                                    break;

                                case PageNumberLocation.Right:
                                    xCord = pageSize.Width - pageNumbersStrSize.Width / 2;
                                    break;
                                }

                                //draw page numbers
                                g.DrawString(
                                    pageNumbersStr,
                                    config.PageNumbersFont,
                                    new XSolidBrush(),
                                    new XPoint(xCord, page.Height - config.PageNumbersMarginBottom));

                                //g.DrawString(
                                //	"middle",
                                //	config.PageNumbersFont,
                                //	new XSolidBrush(),
                                //	new XPoint(0, page.Height - config.PageNumbersMarginBottom));

                                //g.DrawString(
                                //	"right",
                                //	config.PageNumbersFont,
                                //	new XSolidBrush(),
                                //	new XPoint(pageSize.Width/2 + config.MarginLeft - g.MeasureString("x", config.PageNumbersFont).Width, page.Height - config.PageNumbersMarginBottom));

                                //g.DrawString(
                                //	"left",
                                //	config.PageNumbersFont,
                                //	new XSolidBrush(),
                                //	new XPoint(config.MarginLeft + g.MeasureString("left", config.PageNumbersFont).Width / 2, page.Height - config.PageNumbersMarginBottom));
                            }
                        }

                        scrollOffset -= pageSize.Height;
                    }

                    // add web links and anchors
                    HandleLinks(document, container, orgPageSize, pageSize);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Create PDF pages from given HTML and appends them to the provided PDF document.<br/>
        /// </summary>
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static async Task AddPdfPages(PdfDocument document,
                                             IResourceServer resourceServer,
                                             PdfGenerateConfig config
                                             )
        {
            XSize orgPageSize;

            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
            {
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            }
            else
            {
                orgPageSize = config.ManualPageSize;
            }

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            var html = await resourceServer.GetHtmlAsync();

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize  = new XSize(pageSize.Width, 0);
                    await container.SetResourceServerAsync(resourceServer);

                    container.PageSize     = pageSize;
                    container.MarginBottom = config.MarginBottom;
                    container.MarginLeft   = config.MarginLeft;
                    container.MarginRight  = config.MarginRight;
                    container.MarginTop    = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards))
                    {
                        container.PerformLayout(measure);
                    }

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width  = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    // add web links and anchors
                    HandleLinks(document, container, orgPageSize, pageSize);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Create PDF pages from given HTML and appends them to the provided PDF document.<br/>
        /// </summary>
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null)
        {
            XSize orgPageSize;

            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
            {
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            }
            else
            {
                orgPageSize = config.ManualPageSize;
            }

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                    {
                        container.StylesheetLoad += stylesheetLoad;
                    }
                    if (imageLoad != null)
                    {
                        container.ImageLoad += imageLoad;
                    }

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize  = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);
                    container.PageSize     = pageSize;
                    container.MarginBottom = config.MarginBottom;
                    container.MarginLeft   = config.MarginLeft;
                    container.MarginRight  = config.MarginRight;
                    container.MarginTop    = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards);
                    container.PerformLayout(measure);

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    //SL: if there is more than one page, increase the bottom margin to allow space for the page number
                    container.MarginBottom += scrollOffset > -container.ActualSize.Height ?  20 : 0;
                    container.PerformLayout(measure); //SL: This still does not increase the margin for the first page of a multi page.. welp
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width  = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    if (config.AddPageCountFoooter && document.PageCount > 1)  //Only add page numbers if more than one page
                    {
                        AddPageCountFoooter(document, pageSize);
                    }

                    // SL: Set config option to handle links or not as it crashes for
                    // some valid html links.
                    // TODO: Investigate reason for crashing.
                    if (config.HandleLinks)
                    {
                        HandleLinks(document, container, orgPageSize, pageSize);
                    }
                }
            }
        }