Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to build reports with Python Pandas?

Tags:

python

pandas

I am currently using MS Access to produce reports but am somewhat limited with some of the calculations that I need to do.

I was looking into perhaps using Python to run the reports i.e. one report per row of data which takes the column fields and puts them in text boxes going down, which looks like:

Report template

How would this be possible with Python?

like image 367
ScoutEU Avatar asked May 16 '17 12:05

ScoutEU


1 Answers

This goes a little beyond Pandas, but you can create a PDF report from each row of your Pandas DataFrame (tested with version 1.2.5) with the help of the following Python libraries:

  • jinja2: template engine, tested with version 3.0.1
  • xhtml2pdf: converts HTML into PDF, tested with version 0.2.5

First, define the structure and the looks of the report in report_template.html:

<html>
    <head>
        <style type="text/css">
            html, body {
                width: 500px;
                font-size: 12px;
                background: #fff;
                padding: 0px;
            }
            #my-custom-table {
                width: 500px;
                border: 0;
                margin-top: 20px;
            }
            #my-custom-table td {
                padding: 5px 0px 1px 5px;
                text-align: left;
            }
        </style>
    </head>
    <body>
        <table cellspacing="0" border="0" style="width:500px; border:0; font-size: 14px;">
            <tr>
                <td style="text-align:left;">
                    <b><span>Title of the PDF report - Row {{ row_ix + 1 }}</span></b>
                </td>
                <td style="text-align:right;">
                    <b><span>{{ date }}</span></b>
                </td>
            </tr>
        </table>
        <table cellspacing="0" border="0" id="my-custom-table">
            {% for variable_name, variable_value in row.iteritems() %}
            {% if loop.index0 == 0 %}
            <tr style="border-top: 1px solid black;
                       border-bottom: 1px solid black;
                       font-weight: bold;">
                <td>Variable name</td>
                <td>Variable value</td>
            </tr>
            {% else %}
            <tr>
                <td>{{ variable_name }}</td>
                <td>{{ variable_value }}</td>
            </tr>
            {% endif %}
            {% endfor %}
        </table>
    </body>
</html>

Then, run this Python 3 code, which converts each row of DataFrame into HTML string via jinja2 and then converts the HTML to PDF via xhtml2pdf:

from datetime import date

import jinja2
import pandas as pd
from xhtml2pdf import pisa

df = pd.DataFrame(
    data={
        "Average Introducer Score": [9, 9.1, 9.2],
        "Reviewer Scores": ["Academic: 6, 6, 6", "Something", "Content"],
        "Average Academic Score": [5.7, 5.8, 5.9],
        "Average User Score": [1.2, 1.3, 1.4],
        "Applied for (RC)": [9.2, 9.3, 9.4],
        "Applied for (FEC)": [5.5, 5.6, 5.7],
        "Duration (Months)": [36, 37, 38],
    }
)

for row_ix, row in df.iterrows():

    # Pandas DataFrame to HTML
    html = (
        jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=""))
        .get_template(name="report_template.html")
        .render(
            date=date.today().strftime("%d, %b %Y"),
            row_ix=row_ix,
            row=row,
        )
    )

    # Convert HTML to PDF
    with open("report_row_%s.pdf" % (row_ix + 1), "w+b") as out_pdf_file_handle:
        pisa.CreatePDF(
            # HTML to convert
            src=html,
            # File handle to receive the result
            dest=out_pdf_file_handle,
        )

For the DataFrame specified in the Python code, 3 PDFs will be outputted. The first PDF looks like this (converted to PNG to be able to show it here): One row of Pandas DataFrame converted to PDF via HTML by using Jinja2 and xhtml2pdf

like image 85
tuomastik Avatar answered Sep 21 '22 05:09

tuomastik