Ich habe folgendes Skript, das eine CSV-Datei in eine XLSX-Datei konvertiert, aber meine Spaltengröße ist sehr eng. Jedes Mal muss ich sie mit der Maus ziehen, um Daten zu lesen. Weiß jemand, wie man die Spaltenbreite einstellt openpyxl
?
Hier ist der Code, den ich benutze.
#!/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)
Antworten:
Sie können dies schätzen (oder eine Schriftart mit Monobreite verwenden), um dies zu erreichen. Nehmen wir an, Daten sind ein verschachteltes Array wie [['a1', 'a2'], ['b1', 'b2']]
Wir können die maximalen Zeichen in jeder Spalte erhalten. Stellen Sie dann die Breite darauf ein. Die Breite ist genau die Breite einer Monospace-Schriftart (wenn nicht zumindest andere Stile geändert werden). Selbst wenn Sie eine Schriftart mit variabler Breite verwenden, ist dies eine anständige Schätzung. Dies funktioniert nicht mit Formeln.
from openpyxl.utils import get_column_letter 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
Ein bisschen hacken, aber Ihre Berichte werden besser lesbar sein.
quelle
Meine Variation von Bufkes Antwort. Vermeidet ein wenig Verzweigung mit dem Array und ignoriert leere Zellen / Spalten.
Jetzt behoben für Nicht-String-Zellenwerte.
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
Ab openpyxl Version 3.0.3 müssen Sie verwenden
dims[cell.column_letter] = max((dims.get(cell.column_letter, 0), len(str(cell.value))))
Da die openpyxl-Bibliothek einen TypeError auslöst, wenn Sie
column_dimensions
eine Zahl anstelle eines Spaltenbuchstabens übergeben, kann alles andere gleich bleiben.quelle
Noch pythonischer, um die Breite aller Spalten festzulegen, die zumindest in openpyxl Version 2.4.0 funktioniert:
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
Die as_text-Funktion sollte etwas sein, das den Wert in eine Zeichenfolge mit der richtigen Länge konvertiert, wie bei Python 3:
def as_text(value): if value is None: return "" return str(value)
quelle
def as_text(value): return str(value) if value is not None else ""
len(cell.value or "")
, keine Notwendigkeit für zusätzliche Funktionen__len__
, wird dies eine Ausnahmeint
NoneType
TypeError: expected <class 'str'>
. Man muss einen Spaltennamen angeben jetzt, dhws.column_dimensions[openpyxl.utils.get_column_letter(column_cells[0].column)].width = length
.Siehe bitbucket.org/openpyxl/openpyxl/issues/1240/...Ich habe ein Problem mit Merged_Cells und Autosize funktioniert nicht richtig. Wenn Sie das gleiche Problem haben, können Sie es mit dem nächsten Code lösen:
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
quelle
Eine leichte Verbesserung der oben akzeptierten Antwort, die ich für pythonischer halte (um Vergebung zu bitten ist besser als um Erlaubnis zu bitten)
column_widths = [] for row in workSheet.iter_rows(): for i, cell in enumerate(row): try: column_widths[i] = max(column_widths[i], len(str(cell.value))) except IndexError: column_widths.append(len(str(cell.value))) for i, column_width in enumerate(column_widths): workSheet.column_dimensions[get_column_letter(i + 1)].width = column_width
quelle
Alle obigen Antworten erzeugen ein Problem, das darin besteht, dass col [0] .column eine Nummer zurückgibt, während worksheet.column_dimensions [column] nur Zeichen wie 'A', 'B', 'C' anstelle von column akzeptiert. Ich habe den Code von @ Virako geändert und er funktioniert jetzt einwandfrei.
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
quelle
Mit openpyxl 3.0.3 können Sie die Spalten am besten mit dem DimensionHolder- Objekt ändern . Hierbei handelt es sich um ein Wörterbuch, das jede Spalte einem ColumnDimension- Objekt zuordnet . ColumnDimension kann Parameter wie bestFit , auto_size (ein Alias von bestFit) und width abrufen . Persönlich funktioniert auto_size nicht wie erwartet und ich musste width verwenden und stellte fest, dass die beste Breite für die Spalte ist
len(cell_value) * 1.23
.Um den Wert jeder Zelle zu erhalten, muss jede einzelne durchlaufen werden, aber ich persönlich habe sie nicht verwendet, da ich in meinem Projekt nur Arbeitsblätter schreiben musste, sodass ich die längste Zeichenfolge in jeder Spalte direkt in meinen Daten erhielt.
Das folgende Beispiel zeigt nur, wie Sie die Spaltenabmessungen ändern:
import openpyxl from openpyxl.worksheet.dimensions import ColumnDimension, DimensionHolder from openpyxl.utils import get_column_letter wb = openpyxl.load_workbook("Example.xslx") ws = wb["Sheet1"] dim_holder = DimensionHolder(worksheet=ws) for col in range(ws.min_column, ws.max_column + 1): dim_holder[get_column_letter(col)] = ColumnDimension(ws, min=col, max=col, width=20) ws.column_dimensions = dim_holder
quelle
Dies ist meine Version, die auf das Code-Snippet von @Virako verweist
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
Und wie man es benutzt, ist wie folgt:
adjust_column_width_from_col(ws, 1,1, ws.max_column)
quelle
Wir können Zahlen in ihre ASCII-Werte konvertieren und sie dem Parameter column_dimension geben
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')
quelle
Ich musste @ User3759685 oben ändern, um darauf zu antworten, als das openpxyl aktualisiert wurde. Ich habe einen Fehler bekommen. Nun, @phihag hat dies auch in den Kommentaren gemeldet
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
quelle
Nach dem Update von openpyxl2.5.2a auf die neueste Version 2.6.4 (endgültige Version für die Unterstützung von Python 2.x) trat das gleiche Problem bei der Konfiguration der Spaltenbreite auf.
Grundsätzlich berechne ich immer die Breite für eine Spalte (dims ist ein Diktat, bei dem jede Spaltenbreite beibehalten wird):
dims[cell.column] = max((dims.get(cell.column, 0), len(str(cell.value))))
Danach ändere ich die Skala auf etwas, das kurz größer als die ursprüngliche Größe ist, aber jetzt müssen Sie den "Buchstaben" -Wert einer Spalte und nicht mehr einen int-Wert angeben (Spalte unten ist der Wert und wird in den richtigen Buchstaben übersetzt):
worksheet.column_dimensions[get_column_letter(col)].width = value +1
Dies behebt den sichtbaren Fehler und weist Ihrer Spalte die richtige Breite zu;) Hoffe diese Hilfe.
quelle
Hier ist eine Antwort für Python 3.8 und OpenPyXL 3.0.0.
Ich habe versucht, die Verwendung der
get_column_letter
Funktion zu vermeiden, bin jedoch fehlgeschlagen.Diese Lösung verwendet die neu eingeführten Zuweisungsausdrücke, auch bekannt als "Walrossoperator":
import openpyxl from openpyxl.utils import get_column_letter workbook = openpyxl.load_workbook("myxlfile.xlsx") worksheet = workbook["Sheet1"] MIN_WIDTH = 10 for i, column_cells in enumerate(worksheet.columns, start=1): width = ( length if (length := max(len(str(cell_value) if (cell_value := cell.value) is not None else "") for cell in column_cells)) >= MIN_WIDTH else MIN_WIDTH ) worksheet.column_dimensions[get_column_letter(i)].width = width
quelle
max(len(str(cell.value)) for cell in filter(None, column_cells))
scheint mir klarer.Dies ist eine schmutzige Lösung. Aber openpyxl unterstützt tatsächlich
auto_fit
. Es gibt jedoch keine Methode, um auf die Eigenschaft zuzugreifen.import openpyxl from openpyxl.utils import get_column_letter wb = openpyxl.load_workbook("Example.xslx") ws = wb["Sheet1"] for i in range(1, ws.max_column+1): ws.column_dimensions[get_column_letter(i)].bestFit = True ws.column_dimensions[get_column_letter(i)].auto_size = True
quelle