How to Generate a PDF Report

Options for different setups

Overview

There are several ways to turn your analysis into a polished PDF report. Which option works best depends on what software you already have installed. This guide covers six approaches, from the most feature-rich to the most minimal.

Option 2: R Markdown

Requires: R + rmarkdown package + pandoc + LaTeX

The predecessor to Quarto. Uses .Rmd files with R code chunks. Very mature ecosystem with many templates.

If you do not use RStudio or Quarto, install pandoc separately (see Option 4).

Install:

# In R console
install.packages("rmarkdown")

# For LaTeX (minimal distribution, ~250 MB)
install.packages("tinytex")
tinytex::install_tinytex()

Verify setup:

rmarkdown::find_pandoc()
tinytex::is_tinytex()

Render:

rmarkdown::render("report.Rmd", output_format = "pdf_document")
rmarkdown::render("report.Rmd", output_format = "html_document")  # no LaTeX needed

Option 3: Python + LaTeX

Requires: Python (pandas, matplotlib) + xelatex or pdflatex

Python generates figures as PNGs and writes a .tex file. A LaTeX engine compiles it to PDF. This gives you full control over layout.

Install:

# Python packages
pip install pandas matplotlib numpy

# LaTeX -- pick one:
# Windows: MiKTeX (smaller/easier) or TeX Live
# https://miktex.org/download
# https://tug.org/texlive/
# macOS:
brew install --cask basictex     # minimal (~100 MB)
brew install --cask mactex       # full (~5 GB)
# Or use TinyTeX via R (see Option 2)

Verify setup:

xelatex --version   # or: pdflatex --version

Run:

python report.py
# Typical flow: your script writes report.tex, then you compile with xelatex

Manual compilation (if needed):

xelatex report.tex    # run twice for table of contents
xelatex report.tex

Option 4: Python + pandoc

Requires: Python (pandas, matplotlib) + pandoc + LaTeX

Python generates figures, you write the narrative in plain Markdown, and pandoc converts everything to PDF. Easier than writing raw LaTeX.

Install:

# Python packages
pip install pandas matplotlib numpy

# pandoc
# Windows:
winget install --source winget --exact --id JohnMacFarlane.Pandoc
# macOS:
brew install pandoc

# You still need LaTeX for PDF output (see Option 3)

Verify setup:

pandoc --version

Run:

# First generate your figures
python generate_figures.py

# Then convert Markdown to PDF
pandoc report.md -o report.pdf --pdf-engine=xelatex

# Or to HTML (no LaTeX needed)
pandoc report.md -o report.html --standalone

Option 5: Jupyter Notebook export

Requires: Python + Jupyter + nbconvert + pandoc + LaTeX (for PDF)

Write code and narrative together in .ipynb notebook cells, then export.

Install:

pip install jupyter nbconvert
# For PDF export, also install:
# - pandoc (see Option 4)
# - LaTeX (see Option 3)

Export:

jupyter nbconvert --to pdf notebook.ipynb     # needs pandoc + LaTeX
jupyter nbconvert --to html notebook.ipynb    # no LaTeX needed

Notebook UIs also offer Export/Download-as-PDF actions, but menu labels vary by app/version.

Option 6: Python + fpdf2 (no LaTeX needed)

Requires: Python 3.10+ (pandas, matplotlib, fpdf2)

A pure-Python option that produces text and figures in a PDF without any LaTeX or pandoc install. Limited typographic control but zero external dependencies.

Install:

pip install pandas matplotlib fpdf2

Verify setup:

python -c "from fpdf import FPDF; print('fpdf2 ok')"

Example:

from fpdf import FPDF

pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)

# Title page
pdf.add_page()
pdf.set_font("Helvetica", "B", 24)
pdf.cell(w=0, h=20, text="My Report Title", new_x="LMARGIN", new_y="NEXT", align="C")

# Section with text
pdf.set_font("Helvetica", "B", 14)
pdf.cell(w=0, h=12, text="1. Introduction", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("Helvetica", size=11)
pdf.multi_cell(w=0, h=6, text="Your narrative text goes here...")

# Insert a figure
pdf.image("exhibits/fig1.png", w=170)

pdf.output("report.pdf")

Quick reference

Option Tools needed LaTeX required? Notes
Quarto Quarto (+ R/Python if executing code) Yes (or use typst) Best overall experience
R Markdown R, rmarkdown, pandoc Yes (use tinytex) Mature, many templates
Python + LaTeX Python, LaTeX engine Yes Full layout control
Python + pandoc Python, pandoc Yes (HTML fallback: no) Write in Markdown
Jupyter export Python, Jupyter, nbconvert, pandoc Yes (HTML fallback: no) Good for notebooks
Python + fpdf2 Python, fpdf2 No Lowest barrier to PDF

Which should I pick?

  • Already have Quarto? Use Option 1. It’s the simplest end-to-end workflow.
  • Already have R? Use Option 2. Install tinytex for LaTeX and you’re set.
  • Only have Python + LaTeX? Use Option 3 (this is what we used for the earnings report).
  • Have Python but no LaTeX? Use Option 6 (fpdf2) for a quick PDF, or Option 4/5 with --to html as a fallback.
  • Want to avoid installing anything heavy? Use Quarto with format: typst (Option 1) or fpdf2 (Option 6) — neither needs LaTeX.