webentwicklung-frage-antwort-db.com.de

Gibt es eine Möglichkeit, Excel-Spaltenbreiten mit pandas.ExcelWriter automatisch anzupassen?

Ich werde gebeten, einige Excel-Berichte zu erstellen. Ich verwende derzeit sehr häufig Pandas für meine Daten. Daher möchte ich natürlich die Methode pandas.ExcelWriter verwenden, um diese Berichte zu generieren. Die festen Spaltenbreiten sind jedoch ein Problem. 

Der Code, den ich bisher habe, ist einfach genug. Angenommen, ich habe ein Datenframe namens 'df':

writer = pd.ExcelWriter(Excel_file_path)
df.to_Excel(writer, sheet_name="Summary")

Ich habe mir den Pandas-Code angesehen und sehe keine Optionen zum Einstellen der Spaltenbreite. Gibt es da draußen im Universum einen Trick, damit die Spalten sich automatisch an die Daten anpassen? Oder gibt es nach der Tatsache etwas, was ich tun kann, um die Spaltenbreite der xlsx-Datei anzupassen? 

(Ich verwende die OpenPyXL-Bibliothek und generiere .xlsx-Dateien - falls dies einen Unterschied macht.)

Vielen Dank.

50
badideas

Inspiriert von user6178746's Antwort habe ich folgendes:

# 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()
18
alichaudry

Es gibt wahrscheinlich keine automatische Möglichkeit, dies im Moment zu tun, aber wenn Sie openpyxl verwenden, können Sie in der folgenden Zeile (angepasst an eine andere Antwort durch den Benutzer Bufke on how to - in - manuell)/- einen gesunden Zustand angeben Wert (in Zeichenbreite):

writer.sheets['Summary'].column_dimensions['A'].width = 15
17
ojdo

Ich poste dies, weil ich gerade auf dieselbe Ausgabe gestoßen bin und festgestellt habe, dass die offizielle Dokumentation für Xlsxwriter und Pandas diese Funktionalität immer noch nicht unterstützt hat. Ich habe zusammen eine Lösung gehackt, die das Problem löste, das ich hatte. Im Grunde iteriere ich einfach durch jede Spalte und stelle mit arbeitsblatt.set_column die Spaltenbreite == die maximale Länge des Inhalts dieser Spalte ein. 

Ein wichtiger Hinweis jedoch. Diese Lösung passt nicht in die Spaltenüberschriften, sondern nur in die Spaltenwerte. Dies sollte jedoch eine einfache Änderung sein, wenn Sie stattdessen die Header anpassen müssen. Hoffe das hilft jemandem :)

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()
16
user6178746

Es gibt ein Nice-Paket, das ich vor kurzem mit dem Namen StyleFrame verwendete.

es wird DataFrame und ermöglicht es Ihnen, es sehr einfach zu gestalten ...

standardmäßig wird die Spaltenbreite automatisch angepasst.

zum Beispiel:

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()

sie können auch die Spaltenbreite ändern:

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


UPDATE

In Version 1.4 wurde best_fit ein Argument zu StyleFrame.to_Excel..__ hinzugefügt. Siehe Dokumentation .

11
AsafSH

Mit pandas und xlsxwriter können Sie Ihre Aufgabe erledigen. Der folgende Code funktioniert perfekt in Python 3.x. Für weitere Informationen zur Arbeit mit XlsxWriter mit pandas kann dieser Link hilfreich sein https://xlsxwriter.readthedocs.io/working_with_pandas.html

import pandas as pd
writer = pd.ExcelWriter(Excel_file_path, engine='xlsxwriter')
df.to_Excel(writer, sheet_name="Summary")
workbook = writer.book
worksheet = writer.sheets["Summary"]
#set the column width as per your requirement
worksheet.set_column('A:A', 25)
writer.save()
2
Ashu007

Ich fand, dass es sinnvoller ist, die Spalte basierend auf der Spaltenüberschrift anzupassen, als den Spalteninhalt.

Mit df.columns.values.tolist() erstelle ich eine Liste der Spaltenüberschriften und bestimme anhand der Länge dieser Überschriften die Breite der Spalten.

Siehe den vollständigen Code unten:

import pandas as pd
import xlsxwriter

writer = pd.ExcelWriter(filename, engine='xlsxwriter')
df.to_Excel(writer, index=False, sheet_name=sheetname)

workbook = writer.book # Access the workbook
worksheet= writer.sheets[sheetname] # Access the Worksheet

header_list = df.columns.values.tolist() # Generate list of headers
for i in range(0, len(header_list)):
    worksheet.set_column(i, i, len(header_list[i])) # Set column widths based on len(header)

writer.save() # Save the Excel file
1
jack1536

Die einfachste Lösung besteht darin, die Spaltenbreite in der set_column-Methode anzugeben. 

    for worksheet in writer.sheets.values():
        worksheet.set_column(0,last_column_value, required_width_constant)
0
Ashish Jith
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
0
Ssubrat Rrudra

Die anderen Antworten und Kommentare kombinieren und auch Multi-Indizes unterstützen:

def autosize_Excel_columns(worksheet, df):
  autosize_Excel_columns_df(worksheet, df.index.to_frame())
  autosize_Excel_columns_df(worksheet, df, offset=df.index.nlevels)

def autosize_Excel_columns_df(worksheet, df, offset=0):
  for idx, col in enumerate(df):
    series = df[col]
    max_len = max((
      series.astype(str).map(len).max(),
      len(str(series.name))
    )) + 1
    worksheet.set_column(idx+offset, idx+offset, max_len)

sheetname=...
df.to_Excel(writer, sheet_name=sheetname, freeze_panes=(df.columns.nlevels, df.index.nlevels))
worksheet = writer.sheets[sheetname]
autosize_Excel_columns(worksheet, df)
writer.save()
0
kgibm