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
QgsLayoutExporterAPI replaces the legacyQgsCompositionworkflow from QGIS 2.x. - Python Environment: Runs natively in the QGIS Python Console (Python 3.8+). Standalone scripts require explicit
QgsApplicationbootstrapping (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 = Truepreserves crisp vector geometry. Raster layers (satellite imagery, hillshades) still render at the configureddpivalue.
Troubleshooting Common Errors
| Error Code | Likely Cause | Fix |
|---|---|---|
Canceled / FileError | Directory locked by antivirus, cloud sync, or missing write permissions | Export to a local temp folder first, then move files. Disable real-time scanning for the target path. |
PrintError | Uninitialized layout or missing page dimensions | Call layout.initializeDefaults() on dynamically created layouts before exporting. |
| Blank/Partial PDF | Broken data sources or missing system fonts | Validate layers with layer.isValid() before export. Install required fonts or enable font fallback in QGIS settings. |
OutOfMemory | High DPI + complex atlas pages | Lower 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.