A common topic for automation is exporting print layouts (formerly known as print compositions). This example shows you how to export a print layout to PDF. This code can be easily adapted to export to image or SVG as well.

We already used the QgsProject object in the previous example to add Processing results to our project. Now, we use the QgsProject to access the corresponding QgsLayoutManager which takes care of managing all configured layouts in a project.

If we open a project that has a print layout configured and run the following two lines of code in the Python console:

manager = QgsProject.instance().layoutManager()
print(manager.printLayouts())

we get a list of QgsPrintLayout objects. If the project has just one layout, the list will only contain one item, like this:

[<qgis._core.QgsPrintLayout object at 0x000001D288C020D8>]

Of course, we can also print out the names of the layouts in our project using our favorite loop, the for loop:

for layout in manager.printLayouts():
    print(layout.name())

These names can be used to access specific layouts. So, for example, to get the layout named “my_layout”, we use the layoutByName() function:

layout = manager.layoutByName("my_layout")

So far so good! Now there’s just one issue: layout objects do not have an export function! Instead, the documentation of QgsLayout (which is the base class of QgsPrintLayout*) tells us:

While the raw QGraphicsScene API can be used to render the contents of a QgsLayout to a QPainter, it is recommended to instead use a QgsLayoutExporter to handle rendering layouts instead.

So to export our layout, we need a QgsLayoutExporter. These exporters can export to image, SVG, and PDF. To create an exporter for our layout object, we use:

exporter = QgsLayoutExporter(layout)

Finally, we can export the layout, for example, to PDF:

exporter.exportToPdf("C:/temp/layout.pdf",QgsLayoutExporter.PdfExportSettings())

* Before we wrap up this example, there was this notion of QgsLayout being the base class of QgsPrintLayout or conversely, as stated in the QgsPrintLayout  documentation:

Print layout [is] a QgsLayout subclass for static or atlas-based layouts.

A class is like a “blueprint” for creating objects. The class defines which attributes and functions an object has. In this example, our layout is a QgsPrintLayout object. It therefore has all the functions and attributes defined by the QgsLayout class, as well as the QgsPrintLayout class. This concept is called inheritance and you can read more about it, for example, at python-course.eu.

These are the basics of exporting map layouts to PDF. You also saw an example of inheritance with QgsLayout as the base class and QgsPrintLayout as the subclass.


On a quick side note: If all we need is a quick export of the current map canvas, we can also use:

iface.mapCanvas().saveAsImage("your_path/file_name.png")

Next


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

14 comments
  1. Alen Mangafić said:

    Nice post!
    The main problem I have in printLayouts, within a plugin of mine, is that the Layout Manager is storing somewhere (literally I can’t find where) a predefined template (I made a QPT template that can be changed by the plugin), which is not updated within the Layout manager after a template change is committed (the QPT is changed and saved). When I change the QPT file, I have to delete the Layout from the Layout Manager and recreate the specific Layout from scratch. Any ideas how to solve this, like refresh for example?
    Best regards,
    Alen

    • That’s a very interesting topic which I haven’t investigated yet. I don’t think there is any built-in functionality to refresh a layout based on a template but to make sure, I’d recommend asking on the mailing list.

  2. Geert Soet said:

    Thank you very much for this tutorial, setting my first baby steps into the Pyqgis world. I have one error though running it on windows, on osx it works like a charm. The code I run:

    layout = manager.layoutByName(“Regio”)
    exporter = QgsLayoutExporter(layout)
    exporter.exportToPdf(“C:/Users/Geert/Desktop”,QgsLayoutExporter.PdfExportSettings())

    The error I get:

    Traceback (most recent call last):
    File “C:\OSGEO4~1\apps\Python37\lib\code.py”, line 90, in runcode
    exec(code, self.locals)
    File “”, line 1, in
    File “”, line 1, in
    NameError: name ‘manager’ is not defined

    My end goal is to run this as an external python script that outputs atlas images based on an external query.

    • Geert Soet said:

      Ah, I forgot the step to store the returned request in the vlayer object. Problem solved, thanks again.

  3. Leni said:

    Hi Anita,
    this is a very good starting point for using Python in QGis for newbies.
    I would appreciate an example for looping through lists.
    As example: I have pleanty of print layouts and I want to export them all in one hand so that I get an image/pdf for every print layout with the given name (of course it can be done with the extension MapsPrinter but that’s not the point in learning python ;-))

    • Hi Leni,
      We’re looping through the list of print layouts using
      for layout in manager.printLayouts():
      but it’s a good idea, so I’ll add a code snippet when I get around to testing it.

  4. Hello Anita,
    First of all thank you for your tutorial.

    For the rest, I try, like Léni, to export several layouts in a pdf, but I can’t do it. I can only list the layouts:
    manager = QgsProject.instance (). LayoutManager ()
    layouts_list = manager.printLayouts ()
    for layout_list in manager.printLayouts ():
    print (layout_list.name ())

    would you have a track Thank you

    • Hi,

      Inside the for loop, you can create an exporter for the layout and call exportToPdf():

      manager = QgsProject.instance().layoutManager()
      for layout in manager.printLayouts():
          exporter = QgsLayoutExporter(layout)
          exporter.exportToPdf("C:/temp/{}.pdf".format(layout.name()),
              QgsLayoutExporter.PdfExportSettings())
      
  5. Hello Anita,
    Thank you very much for your return.
    It is therefore possible to export, one by one, to pdf, all the layouts of a project.It may be useful. I tried to export them all in one pdf but I can’t get there directly.
    I added a piece of script which allows to merge the pdf obtained:
    from PyPDF2 import PdfFileMerger
    import os
    pdfs= os.listdir(‘F:/export_pdf’)
    merger = PdfFileMerger()
    for pdf in pdfs:
    merger.append(pdf)
    merger.write(“F:/export_pdf/result.pdf”)
    merger.close()

    Have a good week-end.

    • I think you’re right that there is no direct way to export multiple layouts into one PDF. Thanks for sharing your solution!

  6. Hi Anita,

    Thank you for the tutorial and the replies to questions.
    I have applied the loop you mentioned above it worked.

    My situation is a little bit different since I want to export each layer to the PDF.
    My result so far is all the layers are loaded into one PDF. I am trying to understand your statement above ” I think you’re right that there is no direct way to export multiple layouts into one PDF….”

    What scenario could that be?

    Would you help me on the export of each PDF, please.

  7. hola buenas tardes,
    como puedo exportar directamente la pantalla a pdf y no así desde diseño e impresión?

      • Muchas gracias recien estoy iniciando con programacion PyQgis, tengo una consulta, como puedo exportar a pdf con diseñador de impresion pero con la misma escala del lienzo?

Leave a Reply to eribertocz Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: