---
title: Report Templates
---

## Report Templates

Report templates are used to generate formal PDF documents - such as order reports, packing lists, or test reports - rendered against a particular database item (or list of items).

Like all InvenTree templates, report templates are written using a mixture of HTML / CSS and the django template language, and are rendered to a PDF file using the WeasyPrint engine:

- Refer to the [template overview](./index.md) for information on creating and managing templates.
- Refer to the [template rendering documentation](./weasyprint.md) for information on the WeasyPrint engine and the django template language.
- Refer to the [context variables documentation](./context_variables.md) for the variables available when rendering a template.

## Report Options

In addition to the [options common to all templates](./index.md#creating-templates), each report template provides the following options:

### Page Size

The page size (e.g. `A4` or `Letter`) used when rendering the report to a PDF file. When a new report template is created, this value defaults to the [default page size](./index.md#default-page-size) specified in the global settings.

### Landscape

If enabled, the report is rendered in landscape orientation, rather than the default portrait orientation.

### Merge

If enabled, a single report document is generated for all selected items, rather than a separate document for each item. Refer to the [merging reports](#merging-reports) section below for further information.

!!! info "Context Variables"
    The `page_size`, `landscape` and `merge` values are also made available to the template as [context variables](./context_variables.md#report-context).

## Generating Reports

Reports are generated directly from the web interface, from the pages where the target items are displayed. To generate a report against one or more items:

1. Select the items to print - either from a table (using the row checkboxes), or by viewing the detail page of a single item
2. Select the *Print* action, and choose the *Print Report* option
3. Select the desired report template - only *enabled* templates which match the selected model type (and pass any [template filters](./index.md#template-filters)) are available for selection
4. The report is generated by the server, and the resulting PDF file is made available for download

!!! info "Enable Reports"
    Report generation must be [enabled in the global settings](./index.md#enable-reports) before reports can be generated.

## Merging Reports

When rendering reports for multiple items, the default behaviour is that each item is rendered as a separate report. The chosen template is rendered multiple times, once for each item selected, and expects a single item in the context variable.

However, it is possible to merge multiple items into a single report document. This is achieved by enabling the `merge` attribute of the report template:

{{ image("report/report_merge.png", alt="Report Merge Option") }}

When the `merge` is enabled, all selected items are passed to the report template in the `instances` context variable, which is a list of all selected items. The user can then iterate over this list to render multiple items in a single report document.

### Instance Context

When rendering a single template against multiple *instances* of a particular model (e.g. multiple parts, multiple stock items, etc), each instance being rendered has its own unique context data.

Each "instance" is provided to the report template as a dictionary of context variables, which can be accessed using standard django template syntax.

Refer to the [context variable documentation](./context_variables.md) for more information about the available context variables for each model type.

The `instances` variable is provided as a list of all selected items, where each item in the list is a dictionary of context variables for that particular instance. Within the report template, the user can iterate over the `instances` list to render each item in turn.

### Example

As an example, let's consider a report template where we are printing multiple parts in a single report document.

When the `merge` option is enabled, the report template is provided with an `instances` variable, which is a list of all selected parts.

Each *instance* in the `instances` list is a dictionary of context variables for that particular part, which conforms to the standard [part context structure](./context_variables.md#part).

```django
{% raw %}

{% for instance in instances %}
Part Name: {{ instance.part.name }} <br>
IPN: {{ instance.part.IPN }} <br>
Description: {{ instance.part.description }} <br>

{% endraw %}
```

!!! tip "Instance Prefix"
    Note that the context variable is prefixed with `instance.` when accessing variables for each item in the `instances` list.
