This probably exist but I couldn’t find it. I wanted to export a bunch of data from a Python/Django application into something a non-coder could understand. The data was not going to be a plain CSV, but a document, with various tables and explanations of what each table is. Because ReStructured Text seems to be the winning format in the Python world I decided to go with that.
Generating the text part was easy and straightforward. The question was how to export tables. I decided to represent tables as lists of dicts and thus, I ended up building this little module:
def dict_to_rst_table(data):
field_names, column_widths = _get_fields(data)
with StringIO() as output:
output.write(_generate_header(field_names, column_widths))
for row in data:
output.write(_generate_row(row, field_names, column_widths))
return output.getvalue()
def _generate_header(field_names, column_widths):
with StringIO() as output:
for field_name in field_names:
output.write(f"+-{'-' * column_widths[field_name]}-")
output.write("+\n")
for field_name in field_names:
output.write(
f"| {field_name} {' ' * (column_widths[field_name] - len(field_name))}"
)
output.write("|\n")
for field_name in field_names:
output.write(f"+={'=' * column_widths[field_name]}=")
output.write("+\n")
return output.getvalue()
def _generate_row(row, field_names, column_widths):
with StringIO() as output:
for field_name in field_names:
output.write(
f"| {row[field_name]}{' ' * (column_widths[field_name] - len(str(row[field_name])))} "
)
output.write("|\n")
for field_name in field_names:
output.write(f"+-{'-' * column_widths[field_name]}-")
output.write("+\n")
return output.getvalue()
def _get_fields(data):
field_names = []
column_widths = defaultdict(lambda: 0)
for row in data:
for field_name in row:
if field_name not in field_names:
field_names.append(field_name)
column_widths[field_name] = max(
column_widths[field_name], len(field_name), len(str(row[field_name]))
)
return field_names, column_widths
It’s straightforward and simple. It currently cannot deal very well with cases in which dicts have different set of columns.
Should this be turned into a reusable library?
Leave a Reply