Creating a HTML table with Python with multiple columns for a specific row

Chang Zhao picture Chang Zhao · Oct 12, 2018 · Viewed 8.9k times · Source

I wrote this code:

tr = ""
for author, projects in data.iteritems():
    tr + = "<tr><td>{}</td>".format(author)
    for project, branches in projects.iteritems():
        tr += "<td>{}</td>".format(project)
        for branch in branches:
            tr += "<td>{}</td>".format(branch)
    tr += </td></tr>
end = "</table>"

I have this dataset

{
'user_one': {'project_a': ['branch_1', 'branch_2'],
          'project_b': ['branch_1']},
'user_two': {'project_x': ['branch_x1', 'branch_b'] }
}

I want to print table like below:

+-------------------------------------------+
|    User    |    Project    |    Branch    |
+------------+---------------+--------------+
|  user_one  |   project_a   |   branch_1   |
+------------+---------------+--------------+
|            |               |   branch_2   |
+------------+---------------+--------------+
|            |   project_b   |   branch_1   |
+------------+---------------+--------------+
|  user_two  |  project_x    |   branch_x1  |
+------------+---------------+--------------+
|            |               |   branch_b   |
+------------+---------------+--------------+

if its single project it works fine but when it comes multiple projects, it doesn't. I can get the result using PrettyTable but I since I want project_a, _b , _x etc to be hyperlinks. I cannot achieve it in while using PrettyTable, so I started writing my own html generator based on data.

Answer

djromero picture djromero · Oct 12, 2018

Beyond trivial HTML (a table maybe not) I recommend using a template library.

I'd pick Jinja2. Its syntax is quite simple and intuitive (if you have seen aany other template language), it's well documented, and it's quite popular (=more SO support).

An example to render a table.

<table class="table table-striped">
    <thead><tr>
        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th>Four</th>
    </tr></thead>
    <tbody>
    {% for row in tabular_data %}
    <tr>
        <td>{{ row.one }}</td>
        <td>{{ row.two }}</td>
        <td>{{ row.three }}</td>
        <td>{{ row.four }}</td>
    </tr>
    {% endfor %}
    </tbody>
</table>

If you're using a web framework it's probably supported out of the box, if not, rendering it are just a few lines:

from jinja2 import Environment, FileSystemLoader  # pip install Jinja2

env = Environment(loader=FileSystemLoader("/path/to/templates/folder")
template = env.get_template("TableTemplate.html")  # the template file name
html = template.render(**context_data)

Where context_data is a dictionary with the needed data. In the example above it expects a tabular_data field holding an array of objects (or dictionaries) with properties one, two, ...:

context_data = {
    # Row = namedtuple("Row", ["one", "two", "three", "four"])
    'tabular_data': [             
        Row(1, 2, 3, 4), 
        Row("a", "b", "c", "d"),
        ..., 
    ]
}