11""" Tablib - XLSX Support.
22"""
3-
43import re
54from io import BytesIO
65
@@ -35,7 +34,8 @@ def detect(cls, stream):
3534 return False
3635
3736 @classmethod
38- def export_set (cls , dataset , freeze_panes = True , invalid_char_subst = "-" , escape = False ):
37+ def export_set (cls , dataset , freeze_panes = True , invalid_char_subst = "-" ,
38+ escape = False , column_width = "adaptive" ):
3939 """Returns XLSX representation of Dataset.
4040
4141 If ``freeze_panes`` is True, Export will freeze panes only after first line.
@@ -48,6 +48,12 @@ def export_set(cls, dataset, freeze_panes=True, invalid_char_subst="-", escape=F
4848 If ``escape`` is True, formulae will have the leading '=' character removed.
4949 This is a security measure to prevent formulae from executing by default
5050 in exported XLSX files.
51+
52+ If ``column_width`` is set to "adaptive", the column width will be set to the maximum
53+ width of the content in each column. If it is set to an integer, the column width will be
54+ set to that integer value. If it is set to None, the column width will be set as the
55+ default openpyxl.Worksheet width value.
56+
5157 """
5258 wb = Workbook ()
5359 ws = wb .worksheets [0 ]
@@ -59,6 +65,8 @@ def export_set(cls, dataset, freeze_panes=True, invalid_char_subst="-", escape=F
5965
6066 cls .dset_sheet (dataset , ws , freeze_panes = freeze_panes , escape = escape )
6167
68+ cls ._adapt_column_width (ws , column_width )
69+
6270 stream = BytesIO ()
6371 wb .save (stream )
6472 return stream .getvalue ()
@@ -166,3 +174,31 @@ def dset_sheet(cls, dataset, ws, freeze_panes=True, escape=False):
166174
167175 if escape and cell .data_type == 'f' and cell .value .startswith ('=' ):
168176 cell .value = cell .value .replace ("=" , "" )
177+
178+ @classmethod
179+ def _adapt_column_width (cls , worksheet , width ):
180+ if isinstance (width , str ) and width != "adaptive" :
181+ msg = (
182+ f"Invalid value for column_width: { width } . "
183+ "Must be 'adaptive' or an integer."
184+ )
185+ raise ValueError (msg )
186+
187+ if width is None :
188+ return
189+
190+ column_widths = []
191+ if width == "adaptive" :
192+ for row in worksheet .values :
193+ for i , cell in enumerate (row ):
194+ cell_width = len (str (cell ))
195+ if len (column_widths ) > i :
196+ if cell_width > column_widths [i ]:
197+ column_widths [i ] = cell_width
198+ else :
199+ column_widths .append (cell_width )
200+ else :
201+ column_widths = [width ] * worksheet .max_column
202+
203+ for i , column_width in enumerate (column_widths , 1 ): # start at 1
204+ worksheet .column_dimensions [get_column_letter (i )].width = column_width
0 commit comments