Features

  • Client-side PDF export of HTML5 Scheduler (pure JavaScript)
  • Uses jsPDF library (open-source, MIT license)
  • Uses DayPilot Pro for JavaScript (trial version)
  • Generates multi-page PDF, one month per page

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript. Buy a license.

Initialize the HTML5 Scheduler

html5-scheduler-pdf-export-javascript.png

We will create a DayPilot HTML5 Scheduler instance that will display a timeline (one day per cell) for 20 resources:

<div id="dp"></div>

<script>
    var dp = new DayPilot.Scheduler("dp");
    dp.scale = "Day";
    dp.timeHeaders = [
        { groupBy: "Month"},
        { groupBy: "Day", format: "d"}
    ];
    dp.heightSpec = "Max";
    dp.height = 300;

    dp.startDate = new DayPilot.Date("2016-01-01");
    dp.days = 366;
    dp.resources = [
        {name: "Resource 1", id: 1},
        {name: "Resource 2", id: 2},
        // ...
    ];
    dp.events.list = [
        {
            start: "2016-01-04",
            end: "2016-01-09",
            id: 1,
            resource: 2,
            text: "Reservation #1"
        }

    ];
    dp.init();

</script>

Create a New PDF Document

html5-scheduler-pdf-export-document.png

For creating the PDF document, we will use the open-source jsPDF library.

Creating a new PDF document

function createPdfAsBlob() {
  var doc = new jsPDF("landscape", "in", "letter");
  return doc.output("blob");
}

jsPDF constructor lets you define the PDF document properties:

new jsPDF(orientation, unit, size);

Parameteres

  • orientation: "landscape" | "portrait" (default)
  • unit: "pt" | "cm" | "in" | "mm" (default)
  • page size: "a0" - "a10" | "b0" - "b10" | "c0" - "c10" | "d1" | "letter" | "government-letter" | "legal" | "junior-legal" | "ledger" | "tabloid" | "credit-card" (default is "a4")

Add a Header to the PDF Document

html5-scheduler-pdf-export-header.png

We will add a header ("Scheduler" text) to the PDF document using jsPDF.text() method:

function createPdfAsBlob() {
  var doc = new jsPDF("landscape", "in", "letter");
  doc.setFontSize(40);
  doc.text(0.5, 1, "Scheduler");
  return doc.output("blob");
}

Add a JPEG Image

You can add a JPEG image to the PDF file using addImage(dataURI, format, x, y, width, height) method:

function createPdfAsBlob() {
  var doc = new jsPDF("landscape", "in", "letter");
  doc.setFontSize(40);
  doc.text(0.5, 1, "Scheduler");

  doc.addImage("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wB....", 'JPEG', 1, 2, 4, 2);

  return doc.output("blob");
}

Add a PNG Image

jsPDF also supports PNG images:

function createPdfAsBlob() {
  var doc = new jsPDF("landscape", "in", "letter");
  doc.setFontSize(40);
  doc.text(0.5, 1, "Scheduler");

  doc.addImage("data:image/png;base64,iVBORw0KGgoAAAANSUhE....", 'PNG', 1, 2, 4, 2);

  return doc.output("blob");
}

PNG is a better format for images produced by the Scheduler exportAs() method. However, jsPDF seems to include the PNG filed uncompressed in the PDF file which makes the output extremely big.

The same PDF file with 12 images exported from the Scheduler (one per month):

  • JPEG images: 2,89 MB
  • PNG images: 128 MB

In this sample we will use JPEG format for the Scheduler export.

Export the Scheduler Viewport as a JPEG Image

html5-scheduler-pdf-export-jpeg.png

This code will export the current Scheduler viewport as a JPEG image.

var image = dp.exportAs("jpeg").toDataUri();

Export the Full Scheduler

If you add { area: "full" } options parameter the exported image will include the full Scheduler grid (as defined using .startDate and .days properties).

var image = dp.exportAs("jpeg", { area: "full" }).toDataUri();

Export a Time Range

We will use {area: "range"} option and export only a selected time range (January 2016):

var image = dp.exportAs("jpeg", {
  area: "range",
  dateFrom: "2016-01-01",
  dateTo: "2016-02-01",
}).toDataUri();

Set the JPEG Image Quality

When exporting the Scheduler to JPEG, it is possible to specify the output JPEG quality (0-1, the higher the better quality):

var image = dp.exportAs("jpeg", {
  area: "range",
  dateFrom: "2016-01-01",
  dateTo: "2016-02-01",
  quality: 0.95
}).toDataUri();

Adjust the Image DPI

html5-scheduler-pdf-export-scale.png

The exported image that includes January is 1320 pixels wide. If we include this image in a Letter-size landscape page (11 inches wide minus 1 inch for borders) we get a 132 DPI resolution:

dpi = 1320 / (11 - 1) = 132

Most office printers operate at 300 dpi so we need to export the image in a higher resolution.

Increasing the scale export parameter to 2 will produce a 2640px image which gets us twice the resolution (264 dpi):

dpi = 2540 / (11 - 1) = 264

This will result in much better print quality.

Our export configuration now looks like this:

var image = dp.exportAs("jpeg", {
  area: "range",
  scale: 2,
  dateFrom: "2016-01-01",
  dateTo: "2016-02-01",
  quality: 0.95
}).toDataUri();

Insert the Image in the PDF Document

html5-scheduler-pdf-export-month.png

The following function will export January 2016 and add it to a new PDF document:

function createPdfAsBlob() {

  var doc = new jsPDF("landscape", "mm", "a4");
  doc.setFontSize(40);
  doc.text(35, 25, "Scheduler");

  var image = dp.exportAs("jpeg", {
        area: "range",
        scale: 2,
        dateFrom: "2016-01-01",
        dateTo: "2016-02-01",
        quality: 0.95
  });
  var dimensions = image.dimensions();
  var ratio = dimensions.width / dimensions.height;
  var width = 280;
  var height = width/ratio;
  doc.addImage(image.toDataUri(), 'JPEG', 10, 40, width, height);

  return doc.output("blob");
}

Export the Scheduler as a Multi-Page PDF Document (One Month per Page)

html5-scheduler-pdf-export-multi-page.png

We want to export the full Scheduler grid. However, the grid is too wide and doesn't fit a single PDF page.

The updated createPdfAsBlob() function add each months to a special page:

function createPdfAsBlob() {
    var doc = new jsPDF("landscape", "mm", "a4");
    doc.setFontSize(40);
    doc.text(35, 25, "Scheduler");

    for (var i = 1; i <= 12; i++) {
        var image = dp.exportAs("jpeg", {
            area: "range",
            scale: 2,
            dateFrom: dp.startDate.addMonths(i-1),
            dateTo: dp.startDate.addMonths(i),
            quality: 0.95
        });
        var dimensions = image.dimensions();
        var ratio = dimensions.width / dimensions.height;
        var width = 280;
        var height = width/ratio;
        doc.addImage(image.toDataUri(), 'JPEG', 10, 40, width, height);

        var last = i === 12;
        if (!last) {
            doc.addPage();
        }
    }

    return doc.output("blob");
}

Download the PDF Document

html5-scheduler-pdf-export-download.png

Now we have the PDF document available as Blob.

Not supported in older IE versions (only 10+).

<div id="out" style="margin:10px;">PDF: <button id="download">Download</button></div>

<script>
    $("#download").click(function() {
        var blob = createPdfAsBlob();
        DayPilot.Util.downloadBlob(blob, "scheduler.pdf");
    });
</script>