Y a-t-il un moyen d'auto-ajuster la largeur des colonnes Excel avec pandas.ExcelWriter?

on me demande de générer des rapports Excel. Je suis en train d'utiliser pandas assez lourdement pour mes données, donc naturellement je voudrais utiliser les pandas.ExcelWriter méthode pour générer ces rapports. Cependant les largeurs de colonne fixes sont un problème.

le code que j'ai jusqu'à présent est assez simple. Supposons que j'ai une base de données appelée 'df':

writer = pd.ExcelWriter(excel_file_path)
df.to_excel(writer, sheet_name="Summary")

je regardais le code pandas, et je ne vois pas vraiment d'options pour définir les largeurs de colonne. Est-il un truc là dans l'univers pour faire en sorte que les colonnes d'auto-ajuster aux données? Ou y a-t-il quelque chose que je puisse faire après le fait dans le fichier xlsx pour ajuster la largeur des colonnes?

(j'utilise la bibliothèque OpenPyXL, et generating .fichiers xlsx, si cela fait une différence.)

je vous Remercie.

39
demandé sur badideas 2013-06-26 21:44:08

5 réponses

il n'y a probablement pas de moyen automatique pour le faire maintenant, mais comme vous utilisez openpyxl, la ligne suivante (adapté d'une autre réponse de l'utilisateur Bufkecomment le faire manuellement) permet de spécifier une valeur saine (dans la largeur des caractères):

writer.sheets['Summary'].column_dimensions['A'].width = 15
16
répondu ojdo 2017-05-23 12:10:38

Inspiré par user6178746 réponse, j'ai le code suivant:

# Given a dict of dataframes, for example:
# dfs = {'gadgets': df_gadgets, 'widgets': df_widgets}

writer = pd.ExcelWriter(filename, engine='xlsxwriter')
for sheetname, df in dfs.items():  # loop through `dict` of dataframes
    df.to_excel(writer, sheet_name=sheetname)  # send df to writer
    worksheet = writer.sheets[sheetname]  # pull worksheet object
    for idx, col in enumerate(df):  # loop through all columns
        series = df[col]
        max_len = max((
            series.astype(str).map(len).max(),  # len of largest item
            len(str(series.name))  # len of column name/header
            )) + 1  # adding a little extra space
        worksheet.set_column(idx, idx, max_len)  # set column width
writer.save()
16
répondu alichaudry 2018-10-03 21:28:36

je poste ceci parce que je viens de tomber dans le même problème et j'ai trouvé que la documentation officielle pour xlsxwriter et pandas ont toujours cette fonctionnalité listée comme non supportée. J'ai bidouillé une solution qui a résolu le problème que j'avais. J'ai simplement itérer à travers chaque colonne et utiliser la feuille de travail.set_column définir la largeur de colonne == la longueur max du contenu de cette colonne.

une note importante, cependant. Cette solution ne convient pas aux en-têtes de colonne, simplement les valeurs de la colonne. Cela devrait être un changement facile si vous avez besoin d'adapter les headers à la place. Espérons que cela aide quelqu'un :)

import pandas as pd
import sqlalchemy as sa
import urllib


read_server = 'serverName'
read_database = 'databaseName'

read_params = urllib.quote_plus("DRIVER={SQL Server};SERVER="+read_server+";DATABASE="+read_database+";TRUSTED_CONNECTION=Yes")
read_engine = sa.create_engine("mssql+pyodbc:///?odbc_connect=%s" % read_params)

#Output some SQL Server data into a dataframe
my_sql_query = """ SELECT * FROM dbo.my_table """
my_dataframe = pd.read_sql_query(my_sql_query,con=read_engine)

#Set destination directory to save excel.
xlsFilepath = r'H:\my_project' + "\" + 'my_file_name.xlsx'
writer = pd.ExcelWriter(xlsFilepath, engine='xlsxwriter')

#Write excel to file using pandas to_excel
my_dataframe.to_excel(writer, startrow = 1, sheet_name='Sheet1', index=False)

#Indicate workbook and worksheet for formatting
workbook = writer.book
worksheet = writer.sheets['Sheet1']

#Iterate through each column and set the width == the max length in that column. A padding length of 2 is also added.
for i, col in enumerate(my_dataframe.columns):
    # find length of column i
    column_len = my_dataframe[col].astype(str).str.len().max()
    # Setting the length if the column header is larger
    # than the max column value length
    column_len = max(column_len, len(col)) + 2
    # set the column length
    worksheet.set_column(i, i, column_len)
writer.save()
11
répondu TrigonaMinima 2018-02-08 16:01:06

il y a un joli paquet que j'ai commencé à utiliser récemment appelé StyleFrame.

il obtient DataFrame et vous permet de le style très facilement...

par défaut, la largeur des colonnes s'ajuste automatiquement.

par exemple:

from StyleFrame import StyleFrame
import pandas as pd

df = pd.DataFrame({'aaaaaaaaaaa': [1, 2, 3], 'bbbbbbbbb': [1, 1, 1], 'ccccccccccc': [2, 3, 4]})
excel_writer = StyleFrame.ExcelWriter('example.xlsx')
sf = StyleFrame(df)
sf.to_excel(excel_writer=excel_writer, row_to_add_filters=0, columns_and_rows_to_freeze='B2')
excel_writer.save()

vous pouvez aussi changer la largeur des colonnes:

sf.set_column_width(columns=['aaaaaaaaaaa', 'bbbbbbbbb'], width=35.3)



UPDATE

dans la version 1.4 best_fit argument a été ajouté à StyleFrame.to_excel. Voir la documentation.

7
répondu AsafSH 2018-10-05 07:27:00

la solution la plus simple est de spécifier la largeur de la colonne dans la méthode set_column.

    for worksheet in writer.sheets.values():
        worksheet.set_column(0,last_column_value, required_width_constant)
0
répondu Ashish Jith 2018-10-03 03:35:29