Sample Project
The sample project includes:
C# Source Code
VB.NET Source Code
Visual Studio Solution
Requirements
.NET Framework 4.0 or higher
Visual Studio
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.
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