使用Python为特定行创建具有多个列的HTML表

时间:2018-10-12 09:54:11

标签: python html-table tablecolumn

我写了这段代码:

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'] }
}

我要打印如下表格:

+-------------------------------------------+
|    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生成器。

3 个答案:

答案 0 :(得分:2)

除了普通的HTML(也许不是表格)之外,我建议使用template library

我选择Jinja2。它的语法非常简单直观(如果您曾经使用过其他模板语言),它是well documented,并且非常流行(= {more SO support)。

呈现表的示例。

<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,...:

的对象(或字典)的数组
context_data = {
    # Row = namedtuple("Row", ["one", "two", "three", "four"])
    'tabular_data': [             
        Row(1, 2, 3, 4), 
        Row("a", "b", "c", "d"),
        ..., 
    ]
}

答案 1 :(得分:1)

如果仅需要呈现表,为什么要依赖整个程序包!

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

此呈现

enter image description here

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

答案 2 :(得分:-1)

我首先将您的字典转换为具有更简单表结构的列表列表,并根据需要使用空单元格。

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表:

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

可以使用jinja2模板来完成lists_to_html函数:

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)