Create PDF with Python script

ReportBro doesn't necessarily require a web application - you can use it directly with your Python script.

In this tutorial you will learn to:
Map parameters in ReportBro Designer
Generate PDF with a Python script

Getting ready

If you'd like join in and try the tutorial make sure to fulfill the following prerequisites:

- Installed ReportBro Lib: Find instructions here
- Initialized ReportBro Designer with Debug Mode enabled: Read the tutorial

1 Map parameters in ReportBro Designer

Let's assume that we would like to print a list of all files of a directory, as well as all subdirectories and its files.

In our Python script we use a function to iterate a directory and collect all files and subdirectories.


file_list = []

def add_files_recursive(path, level=1):
    for filename in os.listdir(path):
        full_path = os.path.join(path, filename)
        is_dir = os.path.isdir(full_path)
        file_list.append(dict(level=level, name=filename, is_dir=is_dir))
        if is_dir:
            add_files_recursive(full_path, level+1)

In our local ReportBro Designer instance we create a report template and map the parameters from the Python script accordingly.

In the header we'd like to show the directory we are listing, so we need a text parameter dir. To print all directories and subdirectories with their files we create a parameter of type list (which we call files) with the following fields:
- level (number) to indent subdirectories
- name (text) to print the file or directory name
- is_dir (boolean) to highlight directories

Using the debug mode we can then log the report template to the console and save its output in a file called 09_list_files.json.

2 Generate PDF with a Python script

Now we are ready to use the previously saved report template together with the file list and generate a PDF file with dynamic parameters.

We start by collecting the data:
add_files_recursive(start_path)
report_data = dict(dir=start_path, files=file_list)
Then it's time to get the report template:
with open('09_list-files.json', 'r') as f:
    report_definition = json.loads(f.read())
Finally, we can put together the report template and data to create the PDF and save it to a file:
report = Report(
    report_definition=report_definition,
    data=report_data)
report_file = report.generate_pdf()
with open('file_list.pdf', 'wb') as f:
    f.write(report_file)

Full Bro code of the Python script

import json
import os
import sys
from reportbro import Report, ReportBroError

file_list = []


def add_files_recursive(path, level=1):
    for filename in os.listdir(path):
        full_path = os.path.join(path, filename)
        is_dir = os.path.isdir(full_path)
        file_list.append(dict(level=level, name=filename, is_dir=is_dir))
        if is_dir:
            add_files_recursive(full_path, level+1)


def print_usage(error_msg):
    print('fatal: {}\n'.format(error_msg))
    print('usage: python 09_list-files.py <dir>')


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print_usage('You must specify an input directory')
        sys.exit(1)
    start_path = sys.argv[1]
    if not os.path.isdir(start_path):
        print_usage('"{}" is not a directory'.format(start_path))
        sys.exit(1)

    # prepare dynamic data for report
    add_files_recursive(start_path)
    report_data = dict(dir=start_path, files=file_list)

    # load previously saved report template
    with open('09_list-files.json', 'r') as f:
        report_definition = json.loads(f.read())
    try:
        # create report with existing template and dynamic data
        report = Report(report_definition=report_definition, data=report_data)
        report_file = report.generate_pdf()
        with open('file_list.pdf', 'wb') as f:
            f.write(report_file)
    except ReportBroError as e:
        print('error generating report:')
        print(e)

Try it yourself: Download the report and the Python script of this tutorial.

By the way, ReportBro is also available for everyone as open-source on github (see Download page). Star us on github if you like what you see!