Openpyxl - регулировка ширины столбца
У меня есть следующий script, который преобразует CSV файл в файл XLSX, но размер столбца очень узкий. Каждый раз, когда мне приходится перетаскивать их мышью, чтобы читать данные. Кто-нибудь знает, как установить ширину столбца в openpyxl
?
Вот код, который я использую.
#!/usr/bin/python2.6
import csv
from openpyxl import Workbook
from openpyxl.cell import get_column_letter
f = open('users_info_cvs.txt', "rU")
csv.register_dialect('colons', delimiter=':')
reader = csv.reader(f, dialect='colons')
wb = Workbook()
dest_filename = r"account_info.xlsx"
ws = wb.worksheets[0]
ws.title = "Users Account Information"
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = cell
wb.save(filename = dest_filename)
Ответы
Ответ 1
Вы можете оценить (или использовать моноширинный шрифт) для достижения этой цели. Предположим, что данные - это вложенный массив, например [['a1', 'a2'], ['b1', 'b2']]
Мы можем получить максимальное количество символов в каждом столбце. Затем установите ширину для этого. Ширина точно соответствует ширине моноширинного шрифта (если не меняет другие стили, по крайней мере). Даже если вы используете шрифт переменной ширины, это достойная оценка. Это не будет работать с формулами.
column_widths = []
for row in data:
for i, cell in enumerate(row):
if len(column_widths) > i:
if len(cell) > column_widths[i]:
column_widths[i] = len(cell)
else:
column_widths += [len(cell)]
for i, column_width in enumerate(column_widths):
worksheet.column_dimensions[get_column_letter(i+1)].width = column_width
Немного взломать, но ваши отчеты будут более читабельными.
Ответ 2
Мой вариант ответа Буфке. Избегает небольшого ветвления с массивом и игнорирует пустые ячейки/столбцы.
Теперь исправлено для нестроковых значений ячеек.
ws = your current worksheet
dims = {}
for row in ws.rows:
for cell in row:
if cell.value:
dims[cell.column] = max((dims.get(cell.column, 0), len(str(cell.value))))
for col, value in dims.items():
ws.column_dimensions[col].width = value
Ответ 3
Еще более питоновский способ установить ширину всех столбцов, которые работают хотя бы в openpyxl версии 2.4.0:
for column_cells in worksheet.columns:
length = max(len(as_text(cell.value)) for cell in column_cells)
worksheet.column_dimensions[column_cells[0].column].width = length
Функция as_text должна быть чем-то, что преобразует значение в строку правильной длины, например, для Python 3:
def as_text(value):
if value is None:
return ""
return str(value)
Ответ 4
У меня проблема с merged_cells, и autosize не работает правильно, если у вас есть та же проблема, вы можете решить следующий код:
for col in worksheet.columns:
max_length = 0
column = col[0].column # Get the column name
for cell in col:
if cell.coordinate in worksheet.merged_cells: # not check merge_cells
continue
try: # Necessary to avoid error on empty cells
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except:
pass
adjusted_width = (max_length + 2) * 1.2
worksheet.column_dimensions[column].width = adjusted_width
Ответ 5
Небольшое улучшение принятого выше ответа, которое, я думаю, более pythonic (просить прощения лучше, чем просить разрешения)
column_widths = []
for row in workSheet.iter_rows():
for i, cell in enumerate(row):
try:
column_widths[i] = max(column_widths[i], len(cell.value))
except IndexError:
column_widths.append(len(cell.value))
for i, column_width in enumerate(column_widths):
workSheet.column_dimensions[get_column_letter(i + 1)].width = column_width
Ответ 6
Это моя версия со ссылкой на фрагмент кода @Virako
def adjust_column_width_from_col(ws, min_row, min_col, max_col):
column_widths = []
for i, col in \
enumerate(
ws.iter_cols(min_col=min_col, max_col=max_col, min_row=min_row)
):
for cell in col:
value = cell.value
if value is not None:
if isinstance(value, str) is False:
value = str(value)
try:
column_widths[i] = max(column_widths[i], len(value))
except IndexError:
column_widths.append(len(value))
for i, width in enumerate(column_widths):
col_name = get_column_letter(min_col + i)
value = column_widths[i] + 2
ws.column_dimensions[col_name].width = value
И как использовать это следующим образом,
adjust_column_width_from_col(ws, 1,1, ws.max_column)
Ответ 7
Все вышеприведенные ответы порождают проблему, заключающуюся в том, что col [0].column возвращает число, в то время как worksheet.column_dimensions [column] принимает только такие символы, как "A", "B", "C" вместо столбца. Я изменил код @Virako, и теперь он работает нормально.
import re
import openpyxl
..
for col in _ws.columns:
max_lenght = 0
print(col[0])
col_name = re.findall('\w\d', str(col[0]))
col_name = col_name[0]
col_name = re.findall('\w', str(col_name))[0]
print(col_name)
for cell in col:
try:
if len(str(cell.value)) > max_lenght:
max_lenght = len(cell.value)
except:
pass
adjusted_width = (max_lenght+2)
_ws.column_dimensions[col_name].width = adjusted_width
Ответ 8
Мы можем преобразовать числа в их значения ASCII и передать их параметру column_dimension
import openpyxl as xl
work_book = xl.load_workbook('file_location')
sheet = work_book['Sheet1']
column_number = 2
column = str(chr(64 + column_number))
sheet.column_dimensions[column].width = 20
work_book.save('file_location')
Ответ 9
Я должен был изменить @User3759685 выше ответ на этот вопрос при обновлении openpxyl. Я получил ошибку. Ну, @phihag сообщил об этом и в комментариях
for column_cells in ws.columns:
new_column_length = max(len(as_text(cell.value)) for cell in column_cells)
new_column_letter = (openpyxl.utils.get_column_letter(column_cells[0].column))
if new_column_length > 0:
ws.column_dimensions[new_column_letter].width = new_column_length + 1