Sample Project
The sample project includes:
- DayPilot Pro for ASP.NET WebForms 8.4 Trial
- C# Source Code
- VB.NET Source Code
- Visual Studio 2017 Solution
Requirements
- .NET Framework 4.0 or higher
- Visual Studio 2017
- Microsoft SQL Server 2014+
Features
This tutorial shows how to export a visual schedule created using DayPilot ASP.NET Scheduler control to a PDF file.
- Export to PNG
- Export to PDF
- Customized scheduler appearance (fonts, colors)
- Multiple PDF page sizes (letter, A4)
- PDF page orientation (portrait, landscape)
- Custom PDF page header
- Automatic image scaling to fill the page
License
Licensed for testing and evaluation purposes. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for ASP.NET WebForms. Buy a license.
Scheduler Control
We will add a new DayPilot Scheduler control to the page.
<DayPilot:DayPilotScheduler runat="server" ID="DayPilotScheduler1"> </DayPilot:DayPilotScheduler>
Now we will adjust the Scheduler appearance.
- cell width (CellWidth property)
- event/row height (EventHeight property)
- scale (day and hour levels) and format of the time header (TimeHeaders property)
<DayPilot:DayPilotScheduler runat="server" ID="DayPilotScheduler1" ClientIDMode="Static" EventHeight="25" CellWidth="40" > <TimeHeaders> <DayPilot:TimeHeader GroupBy="Day" Format="d" /> <DayPilot:TimeHeader GroupBy="Cell" /> </TimeHeaders> </DayPilot:DayPilotScheduler>
Export to PNG
First, we will export the Scheduler to a PNG image.
Add a "ButtonExportPng" button to the .aspx page:
<h2>Export to PNG</h2> <div> <asp:Button runat="server" ID="ButtonExportPng" Text="Export to PNG" onclick="ButtonExportPng_Click" /> </div>
Add a Click event handler:
C#
protected void ButtonExportPng_Click(object sender, EventArgs e) { ExportToPng(); } private void ExportToPng() { SetDataSourceAndBind(); SetExportProperties(); Response.Clear(); Response.ContentType = "image/png"; Response.AddHeader("content-disposition", "attachment;filename=print.png"); MemoryStream img = DayPilotScheduler1.Export(ImageFormat.Png); img.WriteTo(Response.OutputStream); Response.End(); }
VB
Protected Sub ButtonExportPng_Click(ByVal sender As Object, ByVal e As EventArgs) ExportToPng() End Sub Private Sub ExportToPng() SetDataSourceAndBind() SetExportProperties(); Response.Clear() Response.ContentType = "image/png" Response.AddHeader("content-disposition", "attachment;filename=print.png") Dim img As MemoryStream = DayPilotScheduler1.Export(ImageFormat.Png) img.WriteTo(Response.OutputStream) Response.End() End Sub
Image Appearance (Fonts, Colors)
The Scheduler is not able to apply the CSS theme we defined for the browser. We need to adjust the appearance of the exported image using individual style properties.
C#
private void SetExportProperties() { DayPilotScheduler1.Width = Unit.Percentage(100); // match the theme DayPilotScheduler1.HourNameBackColor = ColorTranslator.FromHtml("#eee"); DayPilotScheduler1.BackColor = Color.White; DayPilotScheduler1.NonBusinessBackColor = Color.White; DayPilotScheduler1.BorderColor = ColorTranslator.FromHtml("#999"); DayPilotScheduler1.HeaderFontColor = ColorTranslator.FromHtml("#666"); DayPilotScheduler1.CellBorderColor = ColorTranslator.FromHtml("#eee"); DayPilotScheduler1.EventFontColor = ColorTranslator.FromHtml("#666"); DayPilotScheduler1.EventCorners = CornerShape.Rounded; DayPilotScheduler1.EventFontSize = "10pt"; DayPilotScheduler1.EventBorderColor = ColorTranslator.FromHtml("#999"); DayPilotScheduler1.EventBackColor = ColorTranslator.FromHtml("#fafafa"); }
VB
Private Sub SetExportProperties() DayPilotScheduler1.Width = Unit.Percentage(100) ' match the theme DayPilotScheduler1.HourNameBackColor = ColorTranslator.FromHtml("#eee") DayPilotScheduler1.BackColor = Color.White DayPilotScheduler1.NonBusinessBackColor = Color.White DayPilotScheduler1.BorderColor = ColorTranslator.FromHtml("#999") DayPilotScheduler1.HeaderFontColor = ColorTranslator.FromHtml("#666") DayPilotScheduler1.CellBorderColor = ColorTranslator.FromHtml("#eee") DayPilotScheduler1.EventFontColor = ColorTranslator.FromHtml("#666") DayPilotScheduler1.EventCorners = CornerShape.Rounded DayPilotScheduler1.EventFontSize = "10pt" DayPilotScheduler1.EventBorderColor = ColorTranslator.FromHtml("#999") DayPilotScheduler1.EventBackColor = ColorTranslator.FromHtml("#fafafa") End Sub
Create a PDF File
We will use PDFSharp library for handling the PDF export.
- open-source (commercial-friendly MIT license)
- managed .NET
- small footprint (570 kB DLL)
Let's start with an empty PDF document. We will save it to a file.
C#
private void ExportToPdf() { PdfDocument doc = new PdfDocument(); doc.Info.Title = "DayPilot Scheduler PDF Export"; doc.Info.Author = "DayPilot"; PdfPage page = doc.AddPage(); doc.Save("file.pdf"); }
VB
Private Sub ExportToPdf() ' create a new PDF document Dim doc As New PdfDocument() doc.Info.Title = "DayPilot Scheduler PDF Export" doc.Info.Author = "DayPilot" ' add a page Dim page_Renamed As PdfPage = doc.AddPage() doc.Save("file.pdf") End Sub
Send the PDF File to the Browser for Download
Now we have a new PDF document that saves to a file. Now we will send it to the browser by writing it to Response.OutputStream.
As it is not possible to write the PDF file directly to Response.OutputStream (Response.OutputStream doesn't support random access) we will use a temporary MemoryStream.
C#
private void ExportToPdf() { PdfDocument doc = new PdfDocument(); doc.Info.Title = "DayPilot Scheduler PDF Export"; doc.Info.Author = "DayPilot"; PdfPage page = doc.AddPage(); MemoryStream mem = new MemoryStream(); doc.Save(mem, false); Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf"); mem.WriteTo(Response.OutputStream); Response.End(); }
VB
Private Sub ExportToPdf() ' create a new PDF document Dim doc As New PdfDocument() doc.Info.Title = "DayPilot Scheduler PDF Export" doc.Info.Author = "DayPilot" ' add a page Dim page_Renamed As PdfPage = doc.AddPage() ' save the PDF file to MemoryStream Dim mem As New MemoryStream() doc.Save(mem, False) ' send the output stream to the browser Response.Clear() Response.ContentType = "application/pdf" Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf") mem.WriteTo(Response.OutputStream) Response.End() End Sub
Set PDF Page Size (Letter, A4) and Orientation (Portrait, Landscape)
Let's add the controls for specifying the PDF page size (letter or A4) and orientation (portrait, landscape).
<div> Page Size: <asp:RadioButtonList runat="server" ID="ListPageSize" RepeatDirection="Horizontal" RepeatLayout="Flow"> <asp:ListItem Selected="True">Letter</asp:ListItem> <asp:ListItem>A4</asp:ListItem> </asp:RadioButtonList> </div> <div> Orientation: <asp:RadioButtonList runat="server" ID="ListPageOrientation" RepeatDirection="Horizontal" RepeatLayout="Flow"> <asp:ListItem Selected="True">Portrait</asp:ListItem> <asp:ListItem>Landscape</asp:ListItem> </asp:RadioButtonList> </div>
These settings will be used in our PDF code:
C#
private void ExportToPdf() { PdfDocument doc = new PdfDocument(); doc.Info.Title = "DayPilot Scheduler PDF Export"; doc.Info.Author = "DayPilot"; PdfPage page = doc.AddPage(); page.Size = (PageSize) Enum.Parse(typeof (PageSize), ListPageSize.SelectedValue); page.Orientation = (PageOrientation)Enum.Parse(typeof(PageOrientation), ListPageOrientation.SelectedValue); MemoryStream mem = new MemoryStream(); doc.Save(mem, false); Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf"); mem.WriteTo(Response.OutputStream); Response.End(); }
VB
Private Sub ExportToPdf() ' create a new PDF document Dim doc As New PdfDocument() doc.Info.Title = "DayPilot Scheduler PDF Export" doc.Info.Author = "DayPilot" ' add a page Dim page_Renamed As PdfPage = doc.AddPage() ' set PDF page properties (size and orientation) page_Renamed.Size = CType(System.Enum.Parse(GetType(PageSize), ListPageSize.SelectedValue), PageSize) page_Renamed.Orientation = CType(System.Enum.Parse(GetType(PageOrientation), ListPageOrientation.SelectedValue), PageOrientation) ' save the PDF file to MemoryStream Dim mem As New MemoryStream() doc.Save(mem, False) ' send the output stream to the browser Response.Clear() Response.ContentType = "application/pdf" Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf") mem.WriteTo(Response.OutputStream) Response.End() End Sub
Add Title to PDF
We have an empty PDF file so let's write a simple header to the page.
C#
// create a graphics object for PDF page modification XGraphics gfx = XGraphics.FromPdfPage(page); // write title XRect titleRect = new XRect(new XPoint(), gfx.PageSize); titleRect.Inflate(-10, -15); XFont font = new XFont("Tahoma", 14, XFontStyle.Bold); gfx.DrawString("DayPilot Scheduler PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter);
VB
' create a graphics object for PDF page modification Dim gfx As XGraphics = XGraphics.FromPdfPage(page_Renamed) ' write title Dim titleRect As New XRect(New XPoint(), gfx.PageSize) titleRect.Inflate(-10, -15) Dim font As New XFont("Tahoma", 14, XFontStyle.Bold) gfx.DrawString("DayPilot Scheduler PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter)
Add Scheduler to the PDF file
Now it's the time to add the image exported from the Scheduler to the PDF page.
C#
// create Scheduler image SetDataSourceAndBind(); SetExportProperties(); Bitmap bitmap = DayPilotScheduler1.ExportBitmap(); // add the image to the PDF page XImage image = XImage.FromGdiPlusImage(bitmap); XRect imageRect = GetPaddedRectForImage(gfx, image, 10); double y = 40; imageRect.Y = y; gfx.DrawImage(image, imageRect);
VB
' create Scheduler image SetDataSourceAndBind() SetExportProperties() Dim bitmap As Bitmap = DayPilotScheduler1.ExportBitmap() ' add the image to the PDF page Dim image As XImage = XImage.FromGdiPlusImage(bitmap) Dim imageRect As XRect = GetPaddedRectForImage(gfx, image, 10) Dim y As Double = 40 imageRect.Y = y gfx.DrawImage(image, imageRect)
We want the image to use the full page width while keeping a 10% padding. This helper GetPaddedRectForImage() method will calculate the target rectangel dimensions while keeping the aspect ratio of the source image.
C#
private XRect GetPaddedRectForImage(XGraphics gfx, XImage image, int paddingWidthPct) { double ratio = image.PixelWidth / (double)image.PixelHeight; double width = gfx.PageSize.Width; double height = width / ratio; XRect imageRect = new XRect(0, 0, width, height); imageRect.Scale((100 - paddingWidthPct) / 100.0, (100 - paddingWidthPct) / 100.0); double x = (gfx.PageSize.Width - imageRect.Width) / 2; imageRect.X = x; return imageRect; }
VB
Private Function GetPaddedRectForImage(ByVal gfx As XGraphics, ByVal image As XImage, ByVal paddingWidthPct As Integer) As XRect Dim ratio As Double = image.PixelWidth / CDbl(image.PixelHeight) Dim width As Double = gfx.PageSize.Width Dim height As Double = width / ratio Dim imageRect As New XRect(0, 0, width, height) imageRect.Scale((100 - paddingWidthPct) / 100.0, (100 - paddingWidthPct) / 100.0) Dim x As Double = (gfx.PageSize.Width - imageRect.Width) \ 2 imageRect.X = x Return imageRect End Function
Export to PDF (Full Source Code)
C#
private void ExportToPdf() { // create a new PDF document PdfDocument doc = new PdfDocument(); doc.Info.Title = "DayPilot Scheduler PDF Export"; doc.Info.Author = "DayPilot"; // add a page PdfPage page = doc.AddPage(); // set PDF page properties (size and orientation) page.Size = (PageSize) Enum.Parse(typeof (PageSize), ListPageSize.SelectedValue); page.Orientation = (PageOrientation)Enum.Parse(typeof(PageOrientation), ListPageOrientation.SelectedValue); // create graphics object for PDF page modification XGraphics gfx = XGraphics.FromPdfPage(page); // write title XRect titleRect = new XRect(new XPoint(), gfx.PageSize); titleRect.Inflate(-10, -15); XFont font = new XFont("Tahoma", 14, XFontStyle.Bold); gfx.DrawString("DayPilot Scheduler PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter); // create Scheduler image SetDataSourceAndBind(); SetExportProperties(); Bitmap bitmap = DayPilotScheduler1.ExportBitmap(); // add the image to the PDF page XImage image = XImage.FromGdiPlusImage(bitmap); XRect imageRect = GetPaddedRectForImage(gfx, image, 10); double y = 40; imageRect.Y = y; gfx.DrawImage(image, imageRect); // save the PDF file to MemoryStream MemoryStream mem = new MemoryStream(); doc.Save(mem, false); // send the output stream to the browser Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf"); mem.WriteTo(Response.OutputStream); Response.End(); } private XRect GetPaddedRectForImage(XGraphics gfx, XImage image, int paddingWidthPct) { double ratio = image.PixelWidth / (double)image.PixelHeight; double width = gfx.PageSize.Width; double height = width / ratio; XRect imageRect = new XRect(0, 0, width, height); imageRect.Scale((100 - paddingWidthPct) / 100.0, (100 - paddingWidthPct) / 100.0); double x = (gfx.PageSize.Width - imageRect.Width) / 2; imageRect.X = x; return imageRect; } private void SetDataSourceAndBind() { DayPilotScheduler1.DataSource = GetData(DayPilotScheduler1.StartDate, DayPilotScheduler1.EndDate); DayPilotScheduler1.DataStartField = "eventstart"; DayPilotScheduler1.DataEndField = "eventend"; DayPilotScheduler1.DataIdField = "id"; DayPilotScheduler1.DataTextField = "name"; DayPilotScheduler1.DataResourceField = "resource"; DayPilotScheduler1.DataBind(); } private void SetExportProperties() { DayPilotScheduler1.Width = Unit.Percentage(100); // match the theme DayPilotScheduler1.HourNameBackColor = ColorTranslator.FromHtml("#eee"); DayPilotScheduler1.BackColor = Color.White; DayPilotScheduler1.NonBusinessBackColor = Color.White; DayPilotScheduler1.BorderColor = ColorTranslator.FromHtml("#999"); DayPilotScheduler1.HeaderFontColor = ColorTranslator.FromHtml("#666"); DayPilotScheduler1.CellBorderColor = ColorTranslator.FromHtml("#eee"); DayPilotScheduler1.EventFontColor = ColorTranslator.FromHtml("#666"); DayPilotScheduler1.EventCorners = CornerShape.Rounded; DayPilotScheduler1.EventFontSize = "10pt"; DayPilotScheduler1.EventBorderColor = ColorTranslator.FromHtml("#999"); DayPilotScheduler1.EventBackColor = ColorTranslator.FromHtml("#fafafa"); }
VB
Private Sub ExportToPdf() ' create a new PDF document Dim doc As New PdfDocument() doc.Info.Title = "DayPilot Scheduler PDF Export" doc.Info.Author = "DayPilot" ' add a page Dim page_Renamed As PdfPage = doc.AddPage() ' set PDF page properties (size and orientation) page_Renamed.Size = CType(System.Enum.Parse(GetType(PageSize), ListPageSize.SelectedValue), PageSize) page_Renamed.Orientation = CType(System.Enum.Parse(GetType(PageOrientation), ListPageOrientation.SelectedValue), PageOrientation) ' create graphics object for PDF page modification Dim gfx As XGraphics = XGraphics.FromPdfPage(page_Renamed) ' write title Dim titleRect As New XRect(New XPoint(), gfx.PageSize) titleRect.Inflate(-10, -15) Dim font As New XFont("Tahoma", 14, XFontStyle.Bold) gfx.DrawString("DayPilot Scheduler PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter) ' create Scheduler image SetDataSourceAndBind() SetExportProperties() Dim bitmap As Bitmap = DayPilotScheduler1.ExportBitmap() ' add the image to the PDF page Dim image As XImage = XImage.FromGdiPlusImage(bitmap) Dim imageRect As XRect = GetPaddedRectForImage(gfx, image, 10) Dim y As Double = 40 imageRect.Y = y gfx.DrawImage(image, imageRect) ' save the PDF file to MemoryStream Dim mem As New MemoryStream() doc.Save(mem, False) ' send the output stream to the browser Response.Clear() Response.ContentType = "application/pdf" Response.AddHeader("content-disposition", "attachment;filename=scheduler.pdf") mem.WriteTo(Response.OutputStream) Response.End() End Sub Private Function GetPaddedRectForImage(ByVal gfx As XGraphics, ByVal image As XImage, ByVal paddingWidthPct As Integer) As XRect Dim ratio As Double = image.PixelWidth / CDbl(image.PixelHeight) Dim width As Double = gfx.PageSize.Width Dim height As Double = width / ratio Dim imageRect As New XRect(0, 0, width, height) imageRect.Scale((100 - paddingWidthPct) / 100.0, (100 - paddingWidthPct) / 100.0) Dim x As Double = (gfx.PageSize.Width - imageRect.Width) \ 2 imageRect.X = x Return imageRect End Function Private Sub SetDataSourceAndBind() DayPilotScheduler1.DataSource = GetData(DayPilotScheduler1.StartDate, DayPilotScheduler1.EndDate) DayPilotScheduler1.DataStartField = "eventstart" DayPilotScheduler1.DataEndField = "eventend" DayPilotScheduler1.DataIdField = "id" DayPilotScheduler1.DataTextField = "name" DayPilotScheduler1.DataResourceField = "resource" DayPilotScheduler1.DataBind() End Sub Private Sub SetExportProperties() DayPilotScheduler1.Width = Unit.Percentage(100) ' match the theme DayPilotScheduler1.HourNameBackColor = ColorTranslator.FromHtml("#eee") DayPilotScheduler1.BackColor = Color.White DayPilotScheduler1.NonBusinessBackColor = Color.White DayPilotScheduler1.BorderColor = ColorTranslator.FromHtml("#999") DayPilotScheduler1.HeaderFontColor = ColorTranslator.FromHtml("#666") DayPilotScheduler1.CellBorderColor = ColorTranslator.FromHtml("#eee") DayPilotScheduler1.EventFontColor = ColorTranslator.FromHtml("#666") DayPilotScheduler1.EventCorners = CornerShape.Rounded DayPilotScheduler1.EventFontSize = "10pt" DayPilotScheduler1.EventBorderColor = ColorTranslator.FromHtml("#999") DayPilotScheduler1.EventBackColor = ColorTranslator.FromHtml("#fafafa") End Sub