Sample Project

The sample project includes:

Requirements

Visual Studio 2010 Solution

  • .NET Framework 4.0 or higher
  • Visual Studio 2010 or higher (optional)
  • Microsoft SQL Server 2008+ (Express) 

Visual Studio 2012 Solution

  • .NET Framework 4.0 or higher
  • Visual Studio 2012 or higher (optional)
  • Microsoft SQL Server 2012 (Express) 

Features

This tutorial shows how to export a weekly event calendar created using DayPilot event calendar to a PDF file.

  • Export to PNG
  • Export to PDF
  • Customized event calendar 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.

Event Calendar Control

asp.net-event-calendar-week.png

We will add a new DayPilot Calendar ASP.NET control to the page.

<DayPilot:DayPilotCalendar 
    runat="server" 
    ID="DayPilotCalendar1">
</DayPilot:DayPilotCalendar>

We will switch the event calendar to week view mode (ViewType="Week") and select the CSS theme (calendar_white).

<DayPilot:DayPilotCalendar 
ID="DayPilotCalendar1" 
runat="server" 

ClientIDMode="Static"
Theme="calendar_white"
ViewType="Week"
/>

Event Calendar Export to PNG

event-calendar-png-export.png

We will export the event calendar to an image first.

Add a "ExportToPngButton" control to the .aspx page:

<h2>Export to PNG</h2>

<div class="space">
<asp:Button runat="server" ID="ExportToPngButton" Text="Export to PNG" 
        onclick="ExportToPng_Click" />
</div>

The ExportToPng_Click event handler uses DayPilotCalendar.Export() method to export the current calendar view to PNG.

C#

protected void ExportToPng_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 = DayPilotCalendar1.Export(ImageFormat.Png);
  img.WriteTo(Response.OutputStream);
  Response.End();
}

Styling the Exported Image

Event calendar as it appears in the browser:

event-calendar-image-export-source.png

Exported event calendar PNG:

calendar-image-export.png

The event calendar doesn't apply the CSS theme we defined for the browser view. We need to adjust the appearance of the exported image using individual style properties.

private void SetExportProperties()
{
  DayPilotCalendar1.HourNameBackColor = ColorTranslator.FromHtml("#eee");
  DayPilotCalendar1.BackColor = Color.White;
  DayPilotCalendar1.NonBusinessBackColor = Color.White;
  DayPilotCalendar1.BorderColor = ColorTranslator.FromHtml("#999");
  DayPilotCalendar1.HeaderFontColor = ColorTranslator.FromHtml("#666");
  DayPilotCalendar1.CellBorderColor = ColorTranslator.FromHtml("#eee");
  DayPilotCalendar1.EventFontColor = ColorTranslator.FromHtml("#666");
  DayPilotCalendar1.EventCorners = CornerShape.Rounded;
  DayPilotCalendar1.EventFontSize = "10pt";
  DayPilotCalendar1.EventBorderColor = ColorTranslator.FromHtml("#999");
  DayPilotCalendar1.EventBackColor = ColorTranslator.FromHtml("#fafafa");
  DayPilotCalendar1.HourBorderColor = ColorTranslator.FromHtml("#eee");
  DayPilotCalendar1.HourHalfBorderColor = ColorTranslator.FromHtml("#eee");
  DayPilotCalendar1.DurationBarVisible = false;
}

PDF Export

We will use PDFSharp library for handling the PDF export.

  • open-source (commercial-friendly MIT license)
  • managed .NET
  • small footprint (570 kB DLL)

First, we will create an empty PDF document using PDFDocument class and save it to calendar.pdf file.

C#

private void ExportToPdf()
{
  PdfDocument doc = new PdfDocument();
  doc.Info.Title = "DayPilot Calendar PDF Export";
  doc.Info.Author = "DayPilot";

  PdfPage page = doc.AddPage();

  doc.Save("calendar.pdf");
}

VB

Private Sub ExportToPdf()
  ' create a new PDF document
  Dim doc As New PdfDocument()
  doc.Info.Title = "DayPilot Calendar PDF Export"
  doc.Info.Author = "DayPilot"

  ' add a page
  Dim page_Renamed As PdfPage = doc.AddPage()

  doc.Save("calendar.pdf")

End Sub

Writing the PDF File to Response.OutputStream

Instead of saving the PDF document to a file using PdfDocument.Save() we will write 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 Calendar 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=calendar.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 Calendar 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=calendar.pdf")
  mem.WriteTo(Response.OutputStream)
  Response.End()
End Sub

PDF Page Size (Letter, A4) and Orientation (Portrait, Landscape)

event-calendar-pdf-export-button.png

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 Calendar 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=calendar.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 Calendar 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=calendar.pdf")
  mem.WriteTo(Response.OutputStream)
  Response.End()
End Sub

Title of the PDF Document

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 Calendar 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 Calendar PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter)

Event Calendar in PDF Document

event-calendar-pdf-acrobat.png

Now it's the time to add the image exported from the event calendar to the PDF page.

C#

// create event calendar image
SetDataSourceAndBind();
SetExportProperties();
Bitmap bitmap = DayPilotCalendar1.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 event calendar image
SetDataSourceAndBind()
SetExportProperties()
Dim bitmap As Bitmap = DayPilotCalendar1.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)

GetPaddedRectForImage() method will calculate the target image dimensions and location. We want the image to fill the page and keep 10% padding.

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 Calendar 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 Calendar PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter);

  // create event calendar image
  SetDataSourceAndBind();
  SetExportProperties();
  Bitmap bitmap = DayPilotCalendar1.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=calendar.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;
}

VB

Private Sub ExportToPdf()
  ' create a new PDF document
  Dim doc As New PdfDocument()
  doc.Info.Title = "DayPilot Calendar 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 Calendar PDF Export", font, XBrushes.DarkGray, titleRect, XStringFormats.TopCenter)

  ' create event calendar image
  SetDataSourceAndBind()
  SetExportProperties()
  Dim bitmap As Bitmap = DayPilotCalendar1.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=calendar.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