Oct 27 2022 · Aleksandra Płońska, Piotr Płoński

The 2 ways to convert Jupyter Notebook Presentation to PDF slides

Convert Jupyter Notebook Presentation to PDF slidesJupyter Notebook can be used to create data-rich presentations. They can be presented as interactive slideshow thanks to Reveal.js library. What if you would like to export it to PDF slides? I will show you two approaches that you can use to export Jupyter Notebook presentation into PDF slides.

1. Print to PDF

This simplest approach is to use web browser functionality to print presentation to PDF file. However, we need to do one trick. In the URL address of our presentation you need to add ?print-pdf at the end.

For example, you are serving the slides locally with command:

jupyter nbconvert --to slides --post serve presentation.ipynb 

You can check the presentation in the web browser at address:

  • slides http://127.0.0.1:8000/presentation.slides.html
  • printable slides http://127.0.0.1:8000/presentation.slides.html?print-pdf.

There can be added #/ at the end: http://127.0.0.1:8000/presentation.slides.html?print-pdf#/.

Please open print dialog (Ctrl+P) and select Save as PDF:

Print slides to PDf

2. Convert HTML presentation to PDF with pyppeteer

What if you would like to convert Jupyter Notebook to PDF slides automatically? The next approach is to use pyppeteer. It is a headless chrome automation library. We will need to write small script that will accept HTML slides as input and produce PDF slides as an output.

Please install pyppeteer:

pip install pyppeteer

Create HTML slides from your Jupyter Notebook:

jupyter nbconvert --to slides presentation.slides.ipynb 

There will be HTML file presentation.slides.html created.

Our Python script that produces PDF slides from HTML file:

import asyncio
import os
import tempfile

from subprocess import PIPE, Popen
from pyppeteer import launch

import concurrent.futures

async def html_to_pdf(html_file, pdf_file, pyppeteer_args=None):
    """Convert a HTML file to a PDF"""
    browser = await launch(
        handleSIGINT=False,
        handleSIGTERM=False,
        handleSIGHUP=False,
        headless=True,
        args=["--no-sandbox"],
    )

    page = await browser.newPage()
    await page.setViewport(dict(width=994, height=768))
    await page.emulateMedia("screen")

    await page.goto(f"file://{html_file}", {"waitUntil": ["networkidle2"]})

    page_margins = {
        "left": "20px",
        "right": "20px",
        "top": "30px",
        "bottom": "30px",
    }

    dimensions = await page.evaluate(
        """() => {
        return {
            width: document.body.scrollWidth,
            height: document.body.scrollHeight,
            offsetWidth: document.body.offsetWidth,
            offsetHeight: document.body.offsetHeight,
            deviceScaleFactor: window.devicePixelRatio,
        }
    }"""
    )
    width = dimensions["width"]
    height = dimensions["height"]

    await page.pdf(
        {
            "path": pdf_file,
            "format": "A4",
            "printBackground": True,
            "margin": page_margins,
        }
    )

    await browser.close()



if __name__ == "__main__":
    
    html_input_file = "/you/need/full/path/here/presentation.slides.html?print-pdf"
    pdf_output_file = "slides.pdf"

    pool = concurrent.futures.ThreadPoolExecutor()
    pool.submit(
        asyncio.run,
        html_to_pdf(
            html_input_file,
            pdf_output_file
        ),
    ).result()

Please note that you need to provide the full path to the HTML file (html_input_file variable). It will be opened in a headless web browser. The output PDF file is saved to pdf_output_file. Below is an example output:

Slides PDf

If you would like to apply styling, here is a longer version of the script.

Summary

Jupyter Notebook presentation is a great way to show data-rich results. Sometimes, you need to export slides to PDF (Portable Document Format). You can do this manually or automatically with simple Python script. In both approaches, please remember about adding ?print-pdf - it does the trick of converting Reveal.js slides into printable version.

We are working on a framework for sharing Jupyter Notebook with non-technical users. It is called Mercury. It can be used to create parameterized Jupyter Notebook presentations. Yes, presentations with widgets and slides that are recomputed during the slideshow!