118 votes

openpyxl - ajuster la taille de la largeur des colonnes

J'ai le script suivant qui convertit un fichier CSV en un fichier XLSX, mais la taille de mes colonnes est très étroite. A chaque fois je dois les faire glisser avec la souris pour lire les données. Est-ce que quelqu'un sait comment régler la largeur des colonnes dans openpyxl ?

Voici le code que j'utilise.

#!/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)

108voto

Bufke Points 585

Vous pouvez estimer (ou utiliser une police à largeur unique) pour y parvenir. Supposons que les données soient un tableau emboîté tel que

[['a1','a2'],['b1','b2']]

Nous pouvons obtenir le nombre maximum de caractères dans chaque colonne. Puis définir la largeur en fonction de cela. La largeur est exactement la largeur d'une police monospace (si elle ne change pas d'autres styles au moins). Même si vous utilisez une police à largeur variable, c'est une bonne estimation. Cette méthode ne fonctionne pas avec les formules.

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,1):  # ,1 to start at 1
    worksheet.column_dimensions[get_column_letter(i)].width = column_width

C'est un peu compliqué, mais vos rapports seront plus lisibles.

76voto

velis Points 641

Ma variation de la réponse de Bufke. Elle évite un peu de branchement avec le tableau et ignore les cellules / colonnes vides.

Maintenant corrigé pour les valeurs de cellules qui ne sont pas des chaînes de caractères.

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

A partir de la version 3.0.3 d'openpyxl vous devez utiliser

 dims[cell.column_letter] = max((dims.get(cell.column_letter, 0), len(str(cell.value))))

car la bibliothèque openpyxl lèvera une TypeError si vous passez column_dimensions un chiffre au lieu d'une lettre de la colonne, tout le reste peut rester inchangé.

50voto

User3759685 Points 533

Une façon encore plus pythique de définir la largeur de toutes les colonnes qui fonctionne au moins dans la version 2.4.0 d'openpyxl :

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

La fonction as_text devrait être quelque chose qui convertit la valeur en une chaîne de longueur appropriée, comme pour Python 3 :

def as_text(value):
    if value is None:
        return ""
    return str(value)

23voto

G.I. Jack Points 231

Avec openpyxl 3.0.3, la meilleure façon de modifier les colonnes est avec la fonction Porte-dimension qui est un dictionnaire qui associe chaque colonne à un objet ColumnDimension objet. ColumnDimension peut obtenir des paramètres comme bestFit , taille automatique (qui est un alias de bestFit) et largeur . Personnellement, auto_size ne fonctionne pas comme prévu et j'ai dû utiliser width et j'ai découvert que la meilleure largeur pour la colonne est de len(cell_value) * 1.23 .

Pour obtenir la valeur de chaque cellule, il est nécessaire d'itérer sur chacune d'entre elles, mais personnellement je ne l'ai pas utilisé car dans mon projet je devais juste écrire des feuilles de calcul, donc j'ai obtenu la chaîne la plus longue dans chaque colonne directement sur mes données.

L'exemple ci-dessous montre simplement comment modifier les dimensions des colonnes :

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

10voto

Virako Points 396

J'ai un problème avec merged_cells et autosize ne fonctionne pas correctement, si vous avez le même problème, vous pouvez résoudre avec le code suivant :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X