When trying to automate your GIS workflows, one important step is the production of maps. Creating and exporting maps in QGIS is done via the Print Layout. One can automate creation of maps via the a rich Python API using the QgsLayout class.
It is recommended to use the Processing Framework for writing python scripts in QGIS. Here I will show you how to write a processing script that takes a saved map template and renders the current project as a PDF file.
For this example, I am assuming a simple map template with 2 items
- A label item for the title named ‘Label 1’
- A map item named ‘Map 1’

To use this layout as a template, we should first use Layout → Save as Template... This will save the layout configuration as a .qpt file.

Next open the Processing Toolbox and go to Scripts → Create New Script…

In the Script Editor, copy/paste the following code.
from PyQt5.QtCore import QCoreApplication
from qgis.core import (QgsProject, QgsLayout, QgsLayoutExporter,
QgsReadWriteContext, QgsMapSettings, QgsProcessingAlgorithm,
QgsProcessingParameterFileDestination, QgsProcessingParameterFile,
QgsProcessingParameterString)
from PyQt5.QtXml import QDomDocument
class ExportLayoutAlgorithm(QgsProcessingAlgorithm):
"""Exports the current map view to PDF"""
TEMPLATE = 'TEMPLATE'
OUTPUT = 'OUTPUT'
TITLE = 'TITLE'
def flags(self):
return super().flags() | QgsProcessingAlgorithm.FlagNoThreading
def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterFile(
self.TEMPLATE,
self.tr('Template File'),
)
)
self.addParameter(
QgsProcessingParameterString(
self.TITLE,
self.tr('Map Title'),
'My Map'
)
)
# We add a file output of type CSV.
self.addParameter(
QgsProcessingParameterFileDestination(
self.OUTPUT,
self.tr('Output File'),
'PDF File (*.pdf)',
)
)
def processAlgorithm(self, parameters, context, feedback):
template = self.parameterAsFile(parameters, 'TEMPLATE', context)
title = self.parameterAsString(parameters, 'TITLE', context)
pdf = self.parameterAsFileOutput(parameters, 'OUTPUT', context)
# Load template from file
project = context.project()
layout = QgsLayout(project)
layout.initializeDefaults()
with open(template) as f:
template_content = f.read()
doc = QDomDocument()
doc.setContent(template_content)
# adding to existing items
items, ok = layout.loadFromTemplate(doc, QgsReadWriteContext(), False)
title_item = layout.itemById('Label 1')
title_item.setText(title)
exporter = QgsLayoutExporter(layout)
exporter.exportToPdf(
pdf, QgsLayoutExporter.PdfExportSettings())
return {'OUTPUT': pdf}
def name(self):
return 'export_layout_pdf'
def displayName(self):
return self.tr('Export Layout As PDF')
def group(self):
return self.tr(self.groupId())
def groupId(self):
return ''
def tr(self, string):
return QCoreApplication.translate('Processing', string)
def createInstance(self):
return ExportLayoutAlgorithm()
Save the script and close the Script Editor. You will see the script appear as a new algorithm under Scripts → Export Layout as PDF

Double-click to open it. Choose the saved .qpt file as the Template File. Enter a map title of your choice and choose an output file. Click Run.

The current project will be rendered in the Map element of the template and a PDF file will be created.

Another advantage of writing our export algorithm as a processing script is that it can be used as part of a model and create maps without human input. So if you have a workflow where you need to get source data, process, analyze and produce a map – you can use scripts such as this to create a model and run it without having to click any buttons.
Hello, I did run the process but I get the error below, I attached the template file (.qpt) and the script, I appreciate the help.
regards
Eddison
https://www.dropbox.com/sh/f9pfflntsorxhxl/AAC5BPy9uxPg1qLpBPwEGRf-a?dl=0
Procesando algoritmo…
Algoritmo ‘Export Layout As PDF’ comenzando…
Parámetros de entrada:
{ ‘OUTPUT’ : ‘C:/BORRAR/MAPA.pdf’, ‘TEMPLATE’ : ‘C:\\HACER_MAPA\\plantilla.qpt’, ‘TITLE’ : ‘MAPA BORRADOR’ }
Traceback (most recent call last):
File “C:\Users\Usuario\AppData\Roaming\QGIS\QGIS3\profiles\default\processing\scripts\IMPRIMIR_LAYOUT_PDF.py”, line 58, in processAlgorithm
title_item.setText(title)
AttributeError: ‘NoneType’ object has no attribute ‘setText’
La ejecución falló después de 0.48 segundos
Hi Edison,
The script assumes the title element in your layout is called ‘Label 1’. Whereas in your template, the title is named ‘Mapa de Uso de la Tierra de San Carlos’. See https://imgur.com/Vl0hEFw . Change it to ‘Label 1’ and it will work.
Hola muchas gracias, voy a revisar!
Muchas gracias!!
Hello, it has been processed again, but I notice a detail: if I use a logo in the design when I use the script in the sale … there is an “X”.
Adjacent design image: https://ibb.co/v3TKTXK
Attached image of the pdf processed by the script: https://ibb.co/Jm1cdqz
Is there any way to solve this detail?
Thank you
Eddison
This was very useful thanks!
Great. What was your use case? Would love to know how you used it.
Great into to the subject, but if you want a portrait layout set clearExisting to True in loadFromTemplate().
Super cool! Thanks! I want to automate the printing/providing layout in qgis. It was a great luck that I could find your script! But I have some questions:
1. I need to add some more input variables from the use, like name, version and …! I followed same as Title prepration and etc. It shows all the required fied now when I run the script. But I get always an error that the title_item = layout.itemById(‘Label 1’)
title_item.setText(title) is empty!
2. How can I implement this script for Atlas? I am so new in these part of QGIS and programming with pyqgis (I have quite good experience with python but not pyqgis)
For 1) Did you first add those items to your layout? As you add them in QGIS, note their ids and make sure they match (Label 1).
2) You don’t need this script if you are using atlas. Atlas can read those from the current feature using the @atlas_featureid variable and set them. See this tutorial https://www.qgistutorials.com/en/docs/3/automating_map_creation.html