Skip to content

Instantly share code, notes, and snippets.

@tourist
Last active March 28, 2022 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tourist/5872810 to your computer and use it in GitHub Desktop.
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
# -*- 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