Last active
March 28, 2022 06:08
-
-
Save tourist/5872810 to your computer and use it in GitHub Desktop.
modified _xls.py from tablib for auto row height & auto colum width and proper alignment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" Tablib - XLS Support. | |
""" | |
import math | |
import sys | |
import itertools | |
from tablib.compat import BytesIO, xlwt | |
title = 'xls' | |
extentions = ('xls',) | |
# special styles | |
wrap = xlwt.easyxf("alignment: wrap on") | |
bold = xlwt.easyxf("font: bold on") | |
# min & max row width | |
min_row_width = 20 | |
max_row_width = 80 | |
def export_set(dataset): | |
"""Returns XLS representation of Dataset.""" | |
wb = xlwt.Workbook(encoding='utf8') | |
ws = wb.add_sheet(dataset.title if dataset.title else 'Tablib Dataset') | |
dset_sheet(dataset, ws) | |
stream = BytesIO() | |
wb.save(stream) | |
return stream.getvalue() | |
def export_book(databook): | |
"""Returns XLS representation of DataBook.""" | |
wb = xlwt.Workbook(encoding='utf8') | |
for i, dset in enumerate(databook._datasets): | |
ws = wb.add_sheet(dset.title if dset.title else 'Sheet%s' % (i)) | |
dset_sheet(dset, ws) | |
stream = BytesIO() | |
wb.save(stream) | |
return stream.getvalue() | |
def dset_sheet(dataset, ws): | |
"""Completes given worksheet from given Dataset.""" | |
_package = dataset._package(dicts=False) | |
for i, sep in enumerate(dataset._separators): | |
_offset = i | |
_package.insert((sep[0] + _offset), (sep[1],)) | |
max_widths = [] | |
for i, row in enumerate(_package): | |
for j, col in enumerate(row): | |
row_max_widths = [] | |
column_len = len(str(col.encode('utf-8'))) | |
# note widest cells for every column | |
try: | |
if column_len > max_widths[j]: | |
max_widths[j] = column_len | |
if column_len > row_max_widths[j]: | |
row_max_widths[j] = column_len | |
except IndexError: | |
max_widths.append(column_len) | |
row_max_widths.append(column_len) | |
# bold headers | |
if (i == 0) and dataset.headers: | |
ws.write(i, j, col, bold) | |
# frozen header row | |
ws.panes_frozen = True | |
ws.horz_split_pos = 1 | |
# bold separators | |
elif len(row) < dataset.width: | |
ws.write(i, j, col, bold) | |
# wrap the rest | |
else: | |
try: | |
alignment = xlwt.Alignment() | |
alignment.horz = xlwt.Alignment.HORZ_LEFT | |
alignment.vert = xlwt.Alignment.VERT_TOP | |
alignment.wrap = xlwt.Alignment.WRAP_AT_RIGHT | |
style = xlwt.XFStyle() | |
style.alignment = alignment | |
if '\n' in col: | |
ws.write(i, j, col, style) | |
else: | |
ws.write(i, j, col, style) | |
except TypeError: | |
ws.write(i, j, col) | |
# set row min/max values within min/max col width | |
row_max_widths_range = [] | |
for max_width in row_max_widths: | |
if max_width < min_row_width: | |
max_width = min_row_width | |
row_max_widths_range.append(max_width) | |
elif max_width > max_row_width: | |
max_width = max_row_width | |
row_max_widths_range.append(max_width) | |
else: | |
row_max_widths_range.append(max_width) | |
# set row height basing on cell with bigest content | |
if i != 0: | |
ws.row(i).height = int(math.ceil(max(row_max_widths) / max(row_max_widths_range))) * 255 | |
# set original min/max values within min/max col width | |
max_widths_range = [] | |
for max_width in max_widths: | |
if max_width < min_row_width: | |
max_width = min_row_width | |
max_widths_range.append(max_width) | |
elif max_width > max_row_width: | |
max_width = max_row_width | |
max_widths_range.append(max_width) | |
else: | |
max_widths_range.append(max_width) | |
# set col width base on max cell width | |
try: | |
for i in itertools.count(): | |
ws.col(i).width = max_widths_range[i] * 256 | |
except (ValueError, IndexError): | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment