Export Jupyter Notebooks to PDF with Custom LaTeX Templates via nbconvert
Step-by-step guide to producing publication-ready PDFs from .ipynb files using nbconvert's LaTeX backend with custom templates for margins, fonts, and layout.
18 Aug 2026, 00:05 UTC

Desired outcome
Produce a publication-ready PDF from a .ipynb file using nbconvert's LaTeX backend, with a custom template that controls margins, fonts, header/footer layout, and any other typographic details your document requires.
Prerequisites
- Jupyter Notebook or JupyterLab installed (nbconvert is bundled).
- A working TeX distribution: TeX Live (Linux/macOS), MiKTeX (Windows), or MacTeX (macOS). The distribution must provide
pdflatexorxelatex/lualatexfor Unicode support. - The notebook's kernel available if you plan to execute cells during export (
--executeflag). - Python 3.10+ and nbconvert 7.x (pin the version in
requirements.txtto avoid template breakage across releases).
Create a custom LaTeX template
nbconvert uses Jinja2 templates with a .tplx extension. Start by copying the built-in article template, then modify it.
# Locate the base template (path varies by install)
jupyter nbconvert --show-template=article > base_article.tplx
Edit base_article.tplx and save as mytemplate.tplx. A minimal customization that sets 1‑inch margins, uses a system font via fontspec (requires XeLaTeX/LuaLaTeX), and adds a centered footer:
{% extends 'article.tplx' %}
{% block preamble %}
{{ super() }}
\usepackage[margin=1in]{geometry}
\usepackage{fontspec}
\setmainfont{DejaVu Serif} % choose a font installed on your system
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\fancyfoot[C]{\thepage}
{% endblock preamble %}
If you must stick with pdflatex, drop fontspec and use a standard LaTeX font package (e.g., \usepackage{mathptmx} for Times).
Export the notebook
Run nbconvert from the directory containing the notebook and the template.
# Static export (no execution)
jupyter nbconvert --to pdf --template=mytemplate.tplx notebook.ipynb
# Execute cells before export (use timeout to avoid hangs)
jupyter nbconvert --to pdf --template=mytemplate.tplx --execute \
--ExecutePreprocessor.timeout=120 notebook.ipynb
In JupyterLab the same command runs behind File → Export Notebook As → PDF; you can pass a custom template via the --template CLI flag only.
Expected checks
- Open the generated
notebook.pdf— it must render without LaTeX errors. - Confirm page count matches the notebook's logical structure.
- Inspect margins, font consistency, and header/footer placement.
- Verify that code cell outputs (matplotlib plots, tables, HTML) appear correctly.
- Test hyperlinks and bookmarks if your template enables
hyperref.
Recovery options for common failures
LaTeX compilation errors
Run with --debug to keep the intermediate .tex file:
jupyter nbconvert --to pdf --template=mytemplate.tplx --debug notebook.ipynb
Examine notebook.tex for missing packages, syntax errors, or Unicode characters that pdflatex cannot handle. Fix the template or install missing packages via tlmgr install <package> (TeX Live) or MiKTeX Console.
Unicode / non‑ASCII characters
Switch the engine to XeLaTeX or LuaLaTeX and ensure the template loads fontspec with a system font that covers the needed glyphs. Add to the template's preamble block:
\usepackage{fontspec}
\setmainfont{Noto Serif} % example font with broad coverage
Then invoke nbconvert with --PDFExporter.latex_command=xelatex (or lualatex).
Large notebooks / memory limits
High‑resolution images can exceed LaTeX's memory. Downsample images before export or set a lower DPI:
jupyter nbconvert --to pdf --PDFExporter.image_dpi=150 notebook.ipynb
Execution hangs
Long‑running or interactive cells block the export. Increase the timeout or skip execution for problematic notebooks. You can also tag cells with skip-execution metadata and configure the preprocessor to ignore them.
Automation in CI/CD
Wrap the command in a reproducible pipeline. Example GitHub Actions step using a Docker image that bundles TeX Live:
jobs:
build-pdf:
runs-on: ubuntu-latest
container: jupyter/datascience-notebook:python-3.11
steps:
- uses: actions/checkout@v4
- name: Install TeX Live
run: |
apt-get update && apt-get install -y texlive-full
- name: Export notebook
run: |
jupyter nbconvert --to pdf --template=mytemplate.tplx \
--execute --ExecutePreprocessor.timeout=180 notebook.ipynb
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: notebook-pdf
path: notebook.pdf
Pin the base image digest and nbconvert version for repeatable builds.
Limitations and verification
- Template compatibility can break across nbconvert minor versions; always pin
nbconvert==7.*in your environment. - Complex notebooks with interactive widgets (ipywidgets) will not render in PDF; export to HTML instead.
- Font licensing may restrict embedding; verify the chosen font's license before distribution.
Verification checklist:
- Run
jupyter nbconvert --versionandpdflatex --version(orxelatex --version) to confirm toolchain presence. - Generate a test PDF from a minimal notebook containing markdown, a code cell, a matplotlib plot, and a pandas DataFrame table.
- Add a unique comment (e.g.,
%% CUSTOM_TEMPLATE_MARKER) in your template and search for it in the.texfile produced with--debugto confirm the template loads. - In CI, push a test commit and ensure the artifact PDF is produced and downloadable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.