创建一个 HTML table with Python 为特定行创建多列

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

我写了这段代码:

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>"

我有这个数据集

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

我想打印 table 如下:

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

如果它的单个项目工作正常,但当涉及多个项目时,它就不行了。我可以使用 PrettyTable 获得结果,但我希望 project_a、_b、_x 等成为超链接。我无法在使用 PrettyTable 时实现它,所以我开始编写自己的 html 基于数据的生成器。

如果您的需要只是渲染 table !

,为什么要依赖整个包
table = "<table border=1 ><tr><th>user</th><th>Project</th><th>Branch</th></tr>"
tr = ""
td_1 = ""
td_2 = ""
for author, projects in data.iteritems():
    # reset the value for new input.
    td_1 = ""
    td_2 = ""
    for project, branches in projects.iteritems():
        td_1 += "{}<hr>".format(project)
        for branch in branches:
            td_2 += "{}<hr>".format(branch)
    tr += "<tr><td valign='top'>{}</td><td valign='top'>{}</td><td valign='top'>{}</td></tr>".format(author, td_1, td_2)

end = "</table>"
table = table + tr + end

这呈现

您可以使用 css 并自定义外观.. 希望对您有所帮助!

超越琐碎的HTML(table可能不是)我建议使用template library

我会选择 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).

渲染 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>

如果您使用的是 Web 框架,它可能是开箱即用的,如果不是,渲染它只是几行:

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)

其中 context_data 是包含所需数据的字典。在上面的示例中,它需要一个 tabular_data 字段来保存具有属性 onetwo、...:[=​​19=] 的对象数组(或字典)

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

我会先将您的词典转换成具有更简单 table 结构的列表列表,并根据需要包含空单元格。

def dicts_to_lists(data):
    """ Convert data stored as lists within dicts within a dict, to a simple
        list of lists """
    r = []
    for user, projects in data.items():
        user_cell = user
        for project, branches in projects.items():
            project_cell = project
            for branch in branches:
                r.append([user_cell, project_cell, branch])
                user_cell = ""
                project_cell = ""
    return r

词典在 Python 中没有排序,因此函数可能会在 'project_A' 之前输出 'project_B'。如果您需要保持相同的顺序,请使用 OrderedDict 来存储数据。否则你可以编写一个更复杂的函数来按字母顺序对键进行排序。

然后,您可以使用模板语言或编写简短的通用函数将任何列表列表转换为 html table:

def lists_to_html(data, has_header=True):
    html = "<table>"
    for i, row in enumerate(data):
        if has_header and i == 0:
            tag = "th"
        else:
            tag = "td"
        tds = ''.join("<{}>{}</{}>".format(tag, cell, tag) for cell in row)
        html += "<tr>{}</tr>".format(tds)
    html += "</table>"
    return html


data = {
'user_one': {'project_a': ['branch_1', 'branch_2'],
          'project_b': ['branch_1']},
'user_two': {'project_x': ['branch_x1', 'branch_b'] }
}
table_cells = dicts_to_lists(data)
table_cells = [["User", "Project", "Branch"]] + table_cells
print (lists_to_html(table_cells))

lists_to_html 函数可以使用像这样的 jinja2 模板来完成:

def lists_to_html(data):
    template = """
    <table><tr><th>User</th><th>Project</th><th>Branch</th></tr>
    {% for r in data %}
    <tr><td>{{ r.author }}</td><td<{{ r.project }}</td><td>{{ r.branch }}</td></tr>
    {% endfor %}</table>"""
    return jinja2.Environment().from_string(template).render(data=data)

或者,您可以用稍微复杂一些的 jinja2 模板替换这两个函数:

template = """
<table>
<tr><th>User</th><th>Project</th><th>Branch</th></tr>
{% for author, projects in data.items() %}
{% for project, branches in projects.items() %}
{% set project_loop = loop %}
{% for branch in branches %}
<tr><td>{% if project_loop.first and loop.first %}{{ author }}{% endif %}</td>
<td>{% if loop.first %}{{ project }}{% endif %}</td>
<td>{{ branch }}</td></tr>
{% endfor %}
{% endfor %}
{% endfor %}
</table>
"""
print jinja2.Environment().from_string(template).render(data=data)