Exporting Multiple QGIS Layouts to PDF Programmatically

To export multiple QGIS layouts to PDF programmatically, iterate through the active project’s layout manager using PyQGIS and call QgsLayoutExporter.exportToPdf() for each composition. This approach removes manual UI clicks, enforces consistent file naming, and scales reliably for Automated Map Layout Generation pipelines.

Complete PyQGIS Script

Run this directly in the QGIS Python Console or embed it in a standalone script:

from qgis.core import QgsProject, QgsLayoutExporter
import os
import re

def export_all_layouts_to_pdf(output_dir: str) -> None:
 """Exports every print layout in the active QGIS project to individual PDFs."""
 os.makedirs(output_dir, exist_ok=True)

 project = QgsProject.instance()
 manager = project.layoutManager()
 layouts = manager.printLayouts()

 if not layouts:
 print("No print layouts found in the current project.")
 return

 for layout in layouts:
 name = layout.name()
 # Sanitize filename for cross-platform safety
 safe_name = re.sub(r'[^\w\-_ ]', '', name).strip()
 pdf_path = os.path.join(output_dir, f"{safe_name}.pdf")

 exporter = QgsLayoutExporter(layout)
 settings = QgsLayoutExporter.PdfExportSettings()
 settings.dpi = 300
 settings.forceVectorOutput = True

 result, error = exporter.exportToPdf(pdf_path, settings)
 if result == QgsLayoutExporter.Success:
 print(f"✅ Exported: {pdf_path}")
 else:
 print(f"❌ Failed: {name} | Error: {error}")

# Usage in QGIS Python Console:
# export_all_layouts_to_pdf(r"C:\QGIS_Exports\PDFs")

Compatibility & Requirements

  • QGIS Version: 3.10+ (LTR 3.28+ recommended). The QgsLayoutExporter API replaces the legacy QgsComposition workflow from QGIS 2.x.
  • Python Environment: Runs natively in the QGIS Python Console (Python 3.8+). Standalone scripts require explicit QgsApplication bootstrapping (see headless section below).
  • Path Handling: Windows requires raw strings (r"C:\path") or escaped backslashes. Linux/macOS accept standard POSIX paths. Verify directory write permissions before execution.
  • Output Quality: settings.forceVectorOutput = True preserves crisp vector geometry. Raster layers (satellite imagery, hillshades) still render at the configured dpi value.

Troubleshooting Common Errors

Error CodeLikely CauseFix
Canceled / FileErrorDirectory locked by antivirus, cloud sync, or missing write permissionsExport to a local temp folder first, then move files. Disable real-time scanning for the target path.
PrintErrorUninitialized layout or missing page dimensionsCall layout.initializeDefaults() on dynamically created layouts before exporting.
Blank/Partial PDFBroken data sources or missing system fontsValidate layers with layer.isValid() before export. Install required fonts or enable font fallback in QGIS settings.
OutOfMemoryHigh DPI + complex atlas pagesLower settings.dpi to 150 for tests. Insert QgsApplication.processEvents() between iterations to flush Qt event queues and free RAM.

Running Headless (CI/CD & Docker)

For automated pipelines, GitHub Actions, or cron jobs, you must initialize the QGIS application environment before loading the project:

from qgis.core import QgsApplication, QgsProject

# 1. Bootstrap QGIS (adjust prefix path to your OS/install)
QgsApplication.setPrefixPath("/usr/share/qgis", True)
QgsApplication.initQgis()

# 2. Load project & run export
project = QgsProject.instance()
project.read("/path/to/your/project.qgz")
export_all_layouts_to_pdf("/path/to/output")

# 3. Clean exit
QgsApplication.exitQgis()

Performance & Best Practices

Batch rendering can bottleneck on disk I/O and Qt threads. Optimize throughput by:

  • Pre-validating paths: Use os.path.abspath() to resolve relative directories and prevent silent export failures.
  • Disabling canvas rendering: When running inside the QGIS desktop, call iface.mapCanvas().setRenderFlag(False) to free GPU/CPU cycles for background exports.
  • Structured logging: Replace print() statements with CSV or JSON logging for reliable audit trails in production Spatial Data Processing & Automation environments.
  • CRS alignment: Ensure all map items share a consistent projected coordinate system. Mixed CRS definitions force on-the-fly transformations that can distort scale bars and grid lines during export.

Standardizing DPI, output paths, and error handling removes manual variability and guarantees cartographic consistency across team deliverables.