bool StoreTempImage(string fileName) { try { const float resolution = 96; int horzPixels = (int)(GetShapeWidth().Inch *resolution); int vertPixels = (int)(GetShapeHeight().Inch *resolution); Bitmap bmp = new Bitmap(horzPixels, vertPixels); #if true XGraphics gfx = XGraphics.CreateMeasureContext(new XSize(horzPixels, vertPixels), XGraphicsUnit.Point, XPageDirection.Downwards); #else #if GDI XGraphics gfx = XGraphics.FromGraphics(Graphics.FromImage(bmp), new XSize(horzPixels, vertPixels)); #endif #if WPF // TODOWPF XGraphics gfx = null; //XGraphics.FromGraphics(Graphics.FromImage(bmp), new XSize(horzPixels, vertPixels)); #endif #endif //REM: Should not be necessary: gfx.ScaleTransform(resolution / 72); //gfx.PageUnit = XGraphicsUnit.Point; DocumentRenderer renderer = new DocumentRenderer(_chart.Document); renderer.RenderObject(gfx, 0, 0, GetShapeWidth().Point, _chart); bmp.SetResolution(resolution, resolution); bmp.Save(fileName, ImageFormat.Png); } catch (Exception) { return(false); } return(true); }
/// <summary> /// Prepares this instance for rendering. /// </summary> public void PrepareDocument() { PdfFlattenVisitor visitor = new PdfFlattenVisitor(); visitor.Visit(_document); _previousListNumbers = new Dictionary <ListType, int>(3); _previousListNumbers[ListType.NumberList1] = 0; _previousListNumbers[ListType.NumberList2] = 0; _previousListNumbers[ListType.NumberList3] = 0; _formattedDocument = new FormattedDocument(_document, this); //REM: Size should not be necessary in this case. #if true XGraphics gfx = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); #else #if GDI XGraphics gfx = XGraphics.FromGraphics(Graphics.FromHwnd(IntPtr.Zero), new XSize(2000, 2000)); #endif #if WPF XGraphics gfx = XGraphics.FromDrawingContext(null, new XSize(2000, 2000), XGraphicsUnit.Point); #endif #endif // _previousListNumber = int.MinValue; //gfx.MUH = _unicode; //gfx.MFEH = _fontEmbedding; _previousListInfo = null; _formattedDocument.Format(gfx); }
private static void FixTableSize(Table table) { XGraphics graphics = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); var fontSize = table.Document.Styles["Table"].Font.Size.Value; var gdiFont = new PdfSharp.Drawing.XFont("Arial", fontSize); for (int j = 0; j < table.Columns.Count; j++) { double columnWidth = 0; for (int i = 0; i < table.Rows.Count; i++) { foreach (Paragraph paragraph in table[i, j].Elements.OfType <Paragraph>()) { string contents = string.Empty; foreach (DocumentObject paragraphElement in paragraph.Elements) { if (paragraphElement is MigraDoc.DocumentObjectModel.Text) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Text).Content; } else if (paragraphElement is MigraDoc.DocumentObjectModel.Hyperlink) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Hyperlink).Name; } } XSize size = graphics.MeasureString(contents, gdiFont); columnWidth = Math.Max(columnWidth, size.Width); } } table.Columns[j].Width = Unit.FromPoint(columnWidth) + 5; } }
/// <summary> /// Initializes appropriate GDI+ objects. /// </summary> XGraphics Realize() { if (_graphics == null) { _graphics = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); } //this.graphics.PageUnit = GraphicsUnit.Point; if (_gdiFont == null) { XFontStyle style = XFontStyle.Regular; if (_font.Bold) { style |= XFontStyle.Bold; } if (_font.Italic) { style |= XFontStyle.Italic; } _gdiFont = new XFont(_font.Name, _font.Size, style /*, System.Drawing.GraphicsUnit.Point*/); } return(_graphics); }
/// <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(); // get the size of each page to layout the HTML in var orgPageSize = PageSizeConverter.ToSize(config.PageSize); 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(); page.Size = config.PageSize; 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); }
/// <summary>Creates the table.</summary> /// <param name="section">The section.</param> /// <param name="tableObj">The table to convert to html.</param> /// <param name="workingDirectory">The working directory.</param> private void CreateTable(Section section, AutoDocumentation.Table tableObj, string workingDirectory) { // Create a 2 column, 1 row table. Image in first cell, X/Y data in second cell. Table table = section.AddTable(); table.Style = "Table"; table.Borders.Color = Colors.Blue; table.Borders.Width = 0.25; table.Borders.Left.Width = 0.5; table.Borders.Right.Width = 0.5; table.Rows.LeftIndent = 0; foreach (DataColumn column in tableObj.data.Columns) { Column column1 = table.AddColumn(); column1.Format.Alignment = ParagraphAlignment.Right; } Row row = table.AddRow(); row.HeadingFormat = true; row.Format.Font.Bold = true; row.Shading.Color = Colors.LightBlue; XFont gdiFont = new XFont("Arial", 10); XGraphics graphics = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); for (int columnIndex = 0; columnIndex < tableObj.data.Columns.Count; columnIndex++) { string heading = tableObj.data.Columns[columnIndex].ColumnName; // Get the width of the column double maxSize = graphics.MeasureString(heading, gdiFont).Width; for (int rowIndex = 0; rowIndex < tableObj.data.Rows.Count; rowIndex++) { string cellText = tableObj.data.Rows[rowIndex][columnIndex].ToString(); XSize size = graphics.MeasureString(cellText, gdiFont); maxSize = Math.Max(maxSize, size.Width); } table.Columns[columnIndex].Width = Unit.FromPoint(maxSize + 10); row.Cells[columnIndex].AddParagraph(heading); } for (int rowIndex = 0; rowIndex < tableObj.data.Rows.Count; rowIndex++) { row = table.AddRow(); for (int columnIndex = 0; columnIndex < tableObj.data.Columns.Count; columnIndex++) { string cellText = tableObj.data.Rows[rowIndex][columnIndex].ToString(); row.Cells[columnIndex].AddParagraph(cellText); } } section.AddParagraph(); }
/// <summary> /// Prepares this instance for rendering. /// </summary> public void PrepareDocument() { PdfFlattenVisitor visitor = new PdfFlattenVisitor(); visitor.Visit(this.document); this.previousListNumbers = new Hashtable(3); this.previousListNumbers[ListType.NumberList1] = 0; this.previousListNumbers[ListType.NumberList2] = 0; this.previousListNumbers[ListType.NumberList3] = 0; this.formattedDocument = new FormattedDocument(this.document, this); //REM: Size should not be necessary in this case. XGraphics gfx = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); // this.previousListNumber = int.MinValue; //gfx.MUH = this.unicode; //gfx.MFEH = this.fontEmbedding; this.previousListInfo = null; this.formattedDocument.Format(gfx); }
/// <summary>Creates the table.</summary> /// <param name="section">The section.</param> /// <param name="tableObj">The table to convert to html.</param> private void CreateTable(Section section, AutoDocumentation.Table tableObj) { var table = section.AddTable(); table.Style = "Table"; table.Borders.Color = Colors.Blue; table.Borders.Width = 0.25; table.Borders.Left.Width = 0.5; table.Borders.Right.Width = 0.5; table.Rows.LeftIndent = 0; var gdiFont = new XFont("Arial", 10); XGraphics graphics = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); // Add the required columns to the table. foreach (DataColumn column in tableObj.data.Table.Columns) { var column1 = table.AddColumn(); column1.Format.Alignment = ParagraphAlignment.Right; } // Add a heading row. var headingRow = table.AddRow(); headingRow.HeadingFormat = true; headingRow.Format.Font.Bold = true; headingRow.Shading.Color = Colors.LightBlue; for (int columnIndex = 0; columnIndex < tableObj.data.Table.Columns.Count; columnIndex++) { // Get column heading string heading = tableObj.data.Table.Columns[columnIndex].ColumnName; headingRow.Cells[columnIndex].AddParagraph(heading); // Get the width of the column double maxSize = graphics.MeasureString(heading, gdiFont).Width; for (int rowIndex = 0; rowIndex < tableObj.data.Count; rowIndex++) { // Add a row to our table if processing first column. MigraDoc.DocumentObjectModel.Tables.Row row; if (columnIndex == 0) { table.AddRow(); } // Get the row to process. row = table.Rows[rowIndex + 1]; // Convert potential HTML to the cell in our row. HtmlToMigraDoc.Convert(tableObj.data[rowIndex][columnIndex].ToString(), row.Cells[columnIndex], WorkingDirectory); // Update the maximum size of the column with the value from the current row. foreach (var element in row.Cells[columnIndex].Elements) { if (element is Paragraph) { var paragraph = element as Paragraph; var contents = string.Empty; foreach (var paragraphElement in paragraph.Elements) { if (paragraphElement is MigraDoc.DocumentObjectModel.Text) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Text).Content; } else if (paragraphElement is MigraDoc.DocumentObjectModel.Hyperlink) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Hyperlink).Name; } } var size = graphics.MeasureString(contents, gdiFont); maxSize = Math.Max(maxSize, size.Width); } } } // maxWidth is the maximum allowed width of the column. E.g. if tableObj.ColumnWidth // is 50, then maxWidth is the amount of space taken up by 50 characters. // maxSize, on the other hand, is the length of the longest string in the column. // The actual column width is whichever of these two values is smaller. // MigraDoc will automatically wrap text to ensure the column respects this width. double maxWidth = graphics.MeasureString(new string('m', tableObj.ColumnWidth), gdiFont).Width; table.Columns[columnIndex].Width = Unit.FromPoint(Math.Min(maxWidth, maxSize) + 10); } section.AddParagraph(); }
/// <summary> /// Create PDF pages from given HTML and appends them to the provided PDF document /// </summary> /// <param name="template">template to use for the page, if null just make a blank page</param> /// <param name="document"></param> /// <param name="html"></param> /// <param name="config"></param> /// <param name="cssData"></param> /// <param name="stylesheetLoad"></param> /// <param name="imageLoad"></param> public static void AddPdfPages(PdfDocument template, 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) { PdfPage page; if (template != null) { var templatePage = template.Pages[0]; page = document.AddPage(templatePage); } else { 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); } } }
/// <summary>Creates the table.</summary> /// <param name="section">The section.</param> /// <param name="tableObj">The table to convert to html.</param> private void CreateTable(Section section, AutoDocumentation.Table tableObj) { var table = section.AddTable(); table.Style = "Table"; table.Borders.Color = Colors.Blue; table.Borders.Width = 0.25; table.Borders.Left.Width = 0.5; table.Borders.Right.Width = 0.5; table.Rows.LeftIndent = 0; var gdiFont = new XFont("Arial", 10); XGraphics graphics = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards); // Add the required columns to the table. foreach (DataColumn column in tableObj.data.Table.Columns) { var column1 = table.AddColumn(); column1.Format.Alignment = ParagraphAlignment.Right; } // Add a heading row. var headingRow = table.AddRow(); headingRow.HeadingFormat = true; headingRow.Format.Font.Bold = true; headingRow.Shading.Color = Colors.LightBlue; for (int columnIndex = 0; columnIndex < tableObj.data.Table.Columns.Count; columnIndex++) { // Get column heading string heading = tableObj.data.Table.Columns[columnIndex].ColumnName; headingRow.Cells[columnIndex].AddParagraph(heading); // Get the width of the column double maxSize = graphics.MeasureString(heading, gdiFont).Width; for (int rowIndex = 0; rowIndex < tableObj.data.Count; rowIndex++) { // Add a row to our table if processing first column. MigraDoc.DocumentObjectModel.Tables.Row row; if (columnIndex == 0) { table.AddRow(); } // Get the row to process. row = table.Rows[rowIndex + 1]; // Convert potential HTML to the cell in our row. HtmlToMigraDoc.Convert(tableObj.data[rowIndex][columnIndex].ToString(), row.Cells[columnIndex], WorkingDirectory); // Update the maximum size of the column with the value from the current row. foreach (var element in row.Cells[columnIndex].Elements) { if (element is Paragraph) { var paragraph = element as Paragraph; var contents = string.Empty; foreach (var paragraphElement in paragraph.Elements) { if (paragraphElement is MigraDoc.DocumentObjectModel.Text) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Text).Content; } else if (paragraphElement is MigraDoc.DocumentObjectModel.Hyperlink) { contents += (paragraphElement as MigraDoc.DocumentObjectModel.Hyperlink).Name; } } var size = graphics.MeasureString(contents, gdiFont); maxSize = Math.Max(maxSize, size.Width); } } } table.Columns[columnIndex].Width = Unit.FromPoint(maxSize + 10); } //for (int rowIndex = 0; rowIndex < tableObj.data.Count; rowIndex++) //{ // row = table.AddRow(); // for (int columnIndex = 0; columnIndex < tableObj.data.Table.Columns.Count; columnIndex++) // { // string cellText = tableObj.data[rowIndex][columnIndex].ToString(); // // var match = hrefRegEx.Match(cellText); // if (match.Success) // { // var paragraph = row.Cells[columnIndex].AddParagraph(); // var hyperlink = paragraph.AddHyperlink(match.Groups[1].ToString().TrimStart('#'), HyperlinkType.Bookmark); // hyperlink.AddFormattedText(match.Groups[2].ToString(), TextFormat.Underline); // } // else // { // match = italicsRegEx.Match(cellText); // if (match.Success) // { // var para = row.Cells[columnIndex].AddParagraph(match.Groups[1].ToString()); // para.AddLineBreak(); // para.AddFormattedText(match.Groups[2].ToString(), TextFormat.Italic); // } // else // row.Cells[columnIndex].AddParagraph(cellText); // } // } // //} section.AddParagraph(); }
/// <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); } } }
/// <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); } } }
/// <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); } } } }