Python xlwt - доступ к существующему содержимому ячейки, автоматическая настройка ширины столбца
Я пытаюсь создать книгу Excel, где я могу автоматически установить или автоматическую настройку ширины столбцов перед сохранением книги.
Я читал учебник Python-Excel в надежде найти некоторые функции в xlwt, которые эмулируют xlrd (например, sheet_names()
, cellname(row, col)
, cell_type
, cell_value
и т.д.)) Например, предположим, что у меня есть следующее:
from xlwt import Workbook
wb = Workbook()
sh1 = wb.add_sheet('sheet1' , cell_overwrite_ok = True)
sh2 = wb.get_sheet(0)
wb.get_sheet(0)
похож на функцию rb.sheet_by_index(0)
, предлагаемую в xlrd, за исключением того, что первая позволяет вам изменять содержимое (при условии, что пользователь установил cell_overwrite_ok = True
)
Предполагая, что xlwt DOES предлагают функции, которые я ищу, я планировал продолжить каждый лист, но на этот раз отслеживая содержимое, которое занимает больше всего места для определенного столбца, и установите ширину столбца на основе этого, Конечно, я также могу отслеживать максимальную ширину для определенного столбца, когда я пишу на листе, но я чувствую, что было бы проще устанавливать ширину после того, как все данные уже были записаны.
Кто-нибудь знает, смогу ли я это сделать? Если нет, что вы рекомендуете делать, чтобы настроить ширину столбцов?
Ответы
Ответ 1
Я только что реализовал класс-оболочку, который отслеживает ширину элементов при их вводе. Кажется, он работает очень хорошо.
import arial10
class FitSheetWrapper(object):
"""Try to fit columns to max size of any entry.
To use, wrap this around a worksheet returned from the
workbook add_sheet method, like follows:
sheet = FitSheetWrapper(book.add_sheet(sheet_name))
The worksheet interface remains the same: this is a drop-in wrapper
for auto-sizing columns.
"""
def __init__(self, sheet):
self.sheet = sheet
self.widths = dict()
def write(self, r, c, label='', *args, **kwargs):
self.sheet.write(r, c, label, *args, **kwargs)
width = arial10.fitwidth(label)
if width > self.widths.get(c, 0):
self.widths[c] = width
self.sheet.col(c).width = width
def __getattr__(self, attr):
return getattr(self.sheet, attr)
Вся магия находится в модуле John Yeung arial10
. Это имеет хорошую ширину для Arial 10, которая является шрифтом Excel по умолчанию. Если вы хотите писать рабочие листы с использованием других шрифтов, вам нужно будет изменить функцию fitwidth, в идеале с учетом аргумента style
, переданного в FitSheetWrapper.write
.
Ответ 2
В xlwt нет автоматического средства для этого. Вы должны следовать общему шаблону, который вы описываете, отслеживать максимальную ширину при написании и устанавливать ширину столбца в конце, когда-нибудь после того, как вы просмотрите все данные, но до того, как сохраните книгу.
Обратите внимание, что это самый чистый и эффективный подход, доступный при работе с файлами Excel. Если ваше понятие "после того, как данные уже были написаны" означает, что после того, как вы уже зафиксировали значения ячейки ( "запись" ), но до фактического сохранения рабочей книги, метод, описанный выше, выполняет именно это. Если вы имеете в виду, что после того, как вы уже сохранили книгу, вы хотите прочитать ее снова, чтобы получить максимальную ширину, а затем снова сохранить ее с новыми ширинами столбцов, это будет намного медленнее и будет включать использование как xlwt, так и xlrd (и, возможно, xlutils). Также обратите внимание, что, когда вы используете подлинный Microsoft Excel, нет понятия "обновления" файла. Это может показаться с точки зрения пользователя, но то, что происходит за кулисами, заключается в том, что каждый раз, когда вы делаете сохранение, Excel сбрасывает существующий файл и пишет совершенно новый с нуля.
Ответ 3
Если вы не заинтересованы в использовании другого класса (FitSheetWrapper), это можно реализовать с помощью столбца WorkSheet Method.
work = xlwt.WorkBook()
sheet = work.add_sheet('Sheet1')
for row_index in range(0,max_row):
for column_index in range(0,max_col) :
cwidth = sheet.col(column_index).width
if (len(column_data)*367) > cwidth:
sheet.col(column_index).width = (len(column_data)*367) #(Modify column width to match biggest data in that column)
sheet.write(row_index,column_index,column_data,style)
Значение по умолчанию для ширины составляет 2962 единицы, а excel - 8,11 единиц. Поэтому я умножаю 367 на длину данных.
Это адаптировано для Kevins FitSheetWrapper.
Ответ 4
FitSheetWrapper должен немного изменить с помощью xlwt3 в 3.3.4
строка 19:
изменение:
width = arial10.fitwidth(label)
в
width = int(arial10.fitwidth(label))
Причина: \ Python\3.3.3\Lib\сайт-пакеты\xlwt3\biffrecords.py
1624 def __init__(self, first_col, last_col, width, xf_index, options):
1625 self._rec_data = pack('<6H', first_col, last_col, width, xf_index, options, 0)
width должно быть целым.
Ответ 5
Это может быть немного поздно, но я создал метод, который делает это для всего
лист сразу. Это быстро и выполняет свою работу. Дополнительный параметр подушки. требуется только в том случае, если вы считаете, что расчет 256 не будет точным (если у вас больше текстовых полей).
from xlrd import *
from xlwt import *
def autoAdjustColumns(workbook, path, writerSheet, writerSheet_index, extraCushion):
readerSheet = open_workbook(path).sheet_by_index(writerSheet_index)
for row in range(readerSheet.nrows):
for column in range(readerSheet.ncols):
thisCell = readerSheet.cell(row, column)
neededWidth = int((1 + len(str(thisCell.value))) * 256)
if writerSheet.col(column).width < neededWidth:
writerSheet.col(column).width = neededWidth + extraCushion
workbook.save(path)
Ответ 6
Я использую этот метод:
wb = Workbook()
ws = wb.add_sheet('Sheet1')
columnwidth = {}
row = 0
for rowdata in data:
column = 0
for colomndata in rowdata:
if column in columnwidth:
if len(colomndata) > columnwidth[column]:
columnwidth[column] = len(colomndata)
else:
columnwidth[column] = len(colomndata)
ws.write(row, column, colomndata, style0)
column = column + 1
row = row + 1
for column, widthvalue in columnwidth.items():
ws.col(column).width = (widthvalue + 4) * 367