Open Event Web app now provides an option to its users to download the PDF of event schedule. Earlier it supported the download of list-view only, now it provides the support to download calendar-view as well. The problem incurred while downloading the calendar-view was that the view gets cropped due to limitations with the library used for PDF generation, thus only some parts of the calendar remained in the PDF. The problem is resolved by creating an image for every date in the schedule and adding the generated image to the PDF.
Selecting and adding the data for PDF generation
The data to be added to PDF depending on the filters and date-selectors applied is chosen from the DOM. Selection of data is done by looping through all the dates and adding only the ones which do not have ‘hide’ class added to them. The selected dates are first expanded such that their complete view is available while generating the image. The complete data is stored in a variable depending on if the complete schedule is requested for download or some filter is applied, which is later used for generating the image.
let fullScheduler = true; let mapValue = ''; pdf = new jsPDF('l', 'pt', 'a1'); $('.calendar').each(function() { let hidePresent = $(this).attr('class').split(' ').indexOf('hide') <= 0; if (hidePresent) { $timeline = $(this); // Expanding the schedule for current date ... ... } fullScheduler = hidePresent && fullScheduler; }); if(fullScheduler) { $timeline = $('.calendar').parent(); mapValue = $timeline.children(); }
Adding the notification while generating the PDF
A loader with the notification is added to provide better user experience, as the PDF generation takes place at the time of request itself it may take some time depending on the size of the schedule. The notifications are added using ‘sweetalert’ library already added for Add to calendar notifications.
swal("Generating the PDF",{ icon: "./images/loader.gif", buttons: false });
Downloading the PDF
The selected dates are stored in an array named ‘schedArr’ whose data sequentially is passed for canvas generation. A new page is added to the PDF of size equal to canvas and the generated canvas is added to that page. With every new page added to the calendar a count is increased to keep a track if all the selected dates are added to PDF.
async.eachSeries(schedArr, function (child, callback) { html2canvas(child, { onrendered: function (canvas) { pdf.addPage(canvas.width, canvas.height); child.style.width = initialWidth[count] + 'px'; pdf.addImage(canvas, 'png', 0, 0, canvas.width, canvas.height); currDate++; if(currDate === schedArr.length){ pdf.deletePage(1); swal.close(); pdf.save(scheduleDate + '.pdf'); } count++; callback(); } }); });
When the last page is added, the notification is closed and user is prompted to download pop-box.
Resources
- Open Event Webapp Repository: https://github.com/fossasia/open-event-webapp
- Pull Request: https://github.com/fossasia/open-event-webapp/pull/2037
- Issue: https://github.com/fossasia/open-event-webapp/issues/1977
- Additional Resources: https://github.com/niklasvh/html2canvas, https://gist.github.com/homam/3162383c8b22e7af691085e77cdbb414