# How MobileAudit Generates and Exports PDF Scan Reports: A Technical Deep Dive

> Learn how MobileAudit generates and exports PDF scan reports. Discover the technical process involving Django templates, pdfkit, and wkhtmltopdf for seamless report delivery.

- Repository: [Mónica Pastor/mobileaudit](https://github.com/mpast/mobileaudit)
- Tags: deep-dive
- Published: 2026-03-07

---

**MobileAudit generates PDF scan reports by rendering Django templates with scan data, converting the resulting HTML to PDF using pdfkit and wkhtmltopdf, and streaming the binary file back to the client as a downloadable attachment.**

MobileAudit is an open-source mobile application security testing framework built with Django. When users complete a security scan, the platform provides a PDF export feature that packages all findings, certificates, permissions, and metadata into a polished, printable report. This article examines the complete technical pipeline—from URL routing to PDF delivery—based on the actual implementation in the `mpast/mobileaudit` repository.

## The PDF Generation Pipeline

The export process follows a clear five-step pipeline: request handling, data aggregation, template rendering, PDF conversion, and HTTP response streaming. Each stage is implemented in specific modules within the Django application structure.

### Request Routing and URL Handling

When a user clicks the Export button for a specific scan, Django routes the request through the URL configuration defined in [`app/config/urls.py`](https://github.com/mpast/mobileaudit/blob/main/app/config/urls.py). The system maps the `/export/<int:id>` endpoint to the `views.export` function:

```python

# app/config/urls.py

path('export/<int:id>', views.export, name="export")

```

This pattern captures the scan ID from the URL and passes it as an integer parameter to the view function, ensuring that each PDF export corresponds to a specific, existing scan record in the database.

### Data Collection and Context Building

The `export` function in [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py) serves as the orchestration layer for PDF generation. Located at lines 418-456, this view performs several critical operations:

1. **Retrieves the scan object** using the provided ID
2. **Queries related entities** including certificates, permissions, activities, and findings
3. **Constructs a context dictionary** that mirrors the data structure used in the standard scan detail page

```python

# app/views.py

@login_required
def export(request, id):
    scan = Scan.objects.get(pk=id)
    
    # Gather all related objects

    certificates = Certificate.objects.filter(scan=id)
    permissions = Permission.objects.filter(scan=id)
    activities = Activity.objects.filter(scan=id)
    # Additional queries for findings, etc.

    
    # Build context for template rendering

    c = {
        'scan': scan,
        'certificates': certificates,
        'permissions': permissions,
        'activities': activities,
        # Remaining context data

    }
    
    # Rendering and PDF conversion follows...

```

This approach ensures that the PDF contains the same comprehensive security analysis data available in the web interface, maintaining consistency across different output formats.

## HTML Template Rendering and Conversion

Once the data context is prepared, MobileAudit transitions from data aggregation to document generation through Django's templating system and external PDF conversion tools.

### The Export Template Structure

The system loads the [`export.html`](https://github.com/mpast/mobileaudit/blob/main/export.html) template from `app/templates/` using Django's `get_template` function. This template implements a compact, table-based HTML layout specifically designed for PDF output:

```python

# Inside views.export function

t = get_template('export.html')
html = t.render(c)

```

The template structure (visible in the first part of [`app/templates/export.html`](https://github.com/mpast/mobileaudit/blob/main/app/templates/export.html)) organizes the scan metadata, permission lists, security findings, certificate details, and statistical summaries into a printable format. Unlike the interactive web interface, this template uses static tables and simplified styling to ensure consistent rendering across different PDF viewers.

### PDF Conversion with pdfkit and wkhtmltopdf

MobileAudit utilizes **pdfkit** as a Python wrapper around **wkhtmltopdf**, a command-line tool that converts HTML to PDF using the WebKit rendering engine. The conversion happens in-memory without writing temporary files to disk:

```python
options = {
    'page-size': 'Letter',
    'encoding': "UTF-8",
}
pdf = pdfkit.from_string(html, False, options)

```

The `False` parameter instructs pdfkit to return the PDF as a byte string rather than saving to a file. The options dictionary specifies standard Letter page sizing and UTF-8 encoding to support international characters in security findings.

**Dependency Management:**

The wkhtmltopdf binary is installed at the system level in the Docker image via `apt-get`:

```dockerfile

# Dockerfile

RUN apt-get install -y wkhtmltopdf

```

The Python wrapper is pinned to version 0.6.1 in [`requirements.txt`](https://github.com/mpast/mobileaudit/blob/main/requirements.txt):

```text

# requirements.txt

pdfkit==0.6.1

```

This separation ensures the rendering engine is available at the OS level while the Python application maintains a stable API interface through the pdfkit library.

## Delivering the PDF to the Client

The final stage involves configuring the HTTP response to trigger a file download in the user's browser while properly handling the binary PDF data.

### HTTP Response Configuration

The `export` view constructs an `HttpResponse` object with the appropriate content type and disposition headers:

```python
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = "attachment; filename = scan.pdf"
return response

```

Setting `content_type='application/pdf'` informs the browser that the response contains PDF data rather than HTML. The `Content-Disposition` header with the `attachment` value forces the browser to download the file as **scan.pdf** rather than attempting to display it inline.

When a user accesses the export endpoint (e.g., `/export/12`), the complete flow executes in real-time: the scan data is retrieved, the template is rendered, HTML is converted to PDF, and the binary stream is returned to the client as a downloadable document containing the complete security analysis.

## Summary

MobileAudit's PDF export functionality demonstrates a practical implementation of HTML-to-PDF conversion within a Django web application:

- **URL Routing**: The `/export/<int:id>` endpoint in [`app/config/urls.py`](https://github.com/mpast/mobileaudit/blob/main/app/config/urls.py) maps to the `views.export` function
- **Data Aggregation**: The view collects scan metadata, certificates, permissions, activities, and findings into a unified context dictionary
- **Template Rendering**: The [`export.html`](https://github.com/mpast/mobileaudit/blob/main/export.html) template in `app/templates/` provides a print-optimized HTML layout
- **PDF Conversion**: The system uses `pdfkit` (version 0.6.1) as a Python wrapper around the `wkhtmltopdf` binary to convert HTML to PDF
- **File Delivery**: The view returns an `HttpResponse` with `content_type='application/pdf'` and a `Content-Disposition` header set to `attachment; filename=scan.pdf`

## Frequently Asked Questions

### What library does MobileAudit use to convert HTML to PDF?

MobileAudit uses **pdfkit** version 0.6.1, a Python wrapper library that interfaces with the **wkhtmltopdf** command-line tool. The wrapper is defined in [`requirements.txt`](https://github.com/mpast/mobileaudit/blob/main/requirements.txt), while the actual binary is installed at the system level via the `Dockerfile` using `apt-get install wkhtmltopdf`.

### How is the wkhtmltopdf binary installed in MobileAudit?

The wkhtmltopdf binary is installed in the Docker container at build time. The `Dockerfile` contains a `RUN apt-get install -y wkhtmltopdf` command that installs the binary from the Ubuntu package repositories. This ensures the HTML-to-PDF conversion engine is available when the Django application calls pdfkit functions.

### Can I customize the PDF report template in MobileAudit?

Yes, the PDF layout is controlled by the [`export.html`](https://github.com/mpast/mobileaudit/blob/main/export.html) template located in `app/templates/`. This Django template uses standard HTML and CSS with table-based layouts optimized for print output. You can modify this template to change the report branding, reorganize sections, or adjust styling, and the changes will reflect in subsequent PDF exports.

### What file name does MobileAudit use for downloaded PDF reports?

MobileAudit uses the static filename **scan.pdf** for all downloaded reports. This is set in the `Content-Disposition` header within the `export` view in [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py): `response['Content-Disposition'] = "attachment; filename = scan.pdf"`. Users can rename the file after download, or developers can modify this line to generate dynamic filenames based on scan ID or date.