web-dev-qa-db-ja.com

pandas.ExcelWriterでExcelの列幅を自動調整する方法はありますか?

Excelレポートを生成するよう求められています。現在、データにpandasをかなり使用しているため、当然、pandas.ExcelWriterメソッドを使用してこれらのレポートを生成したいと思います。ただし、固定列幅は問題です。

私がこれまでに持っているコードは十分に単純です。 「df」というデータフレームがあるとします。

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

私はpandasコードを見ていましたが、列幅を設定するオプションは実際には表示されません。列が自動調整されるようにする宇宙のトリックはありますかまたは、列幅を調整するためにxlsxファイルに事実の後にできることはありますか?

(私はOpenPyXLライブラリを使用し、.xlsxファイルを生成しています-それが違いを生む場合)

ありがとうございました。

58
badideas

ser6178746's answer に触発されて、次のものがあります。

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

おそらく今すぐ自動で行う方法はおそらくないでしょうが、openpyxlを使用すると、次の行(ユーザー Bufke on 手動で行う方法 )正しい値を(文字幅で)指定できます:

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

私がこれを投稿しているのは、同じ問題に遭遇したばかりで、Xlsxwriterとpandasの公式ドキュメントにはまだこの機能がサポートされていないと記載されていることがわかったからです。基本的に各列を反復処理し、worksheet.set_columnを使用して列幅==その列のコンテンツの最大長を設定します。

ただし、重要な注意事項が1つあります。このソリューションは、列ヘッダーではなく、単に列の値に適合します。ただし、代わりにヘッダーを合わせる必要がある場合は、簡単に変更できます。これが誰かを助けることを願っています:)

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

StyleFrameという最近使用した素敵なパッケージがあります。

dataFrameを取得し、非常に簡単にスタイル設定できます...

デフォルトでは、列の幅は自動調整されます。

例えば:

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

列幅を変更することもできます。

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


[〜#〜] update [〜#〜]

バージョン1.4では、best_fit引数がStyleFrame.to_Excelに追加されました。 ドキュメント を参照してください。

13
AsafSH

pandasとxlsxwriterを使用すると、タスクを実行できます。以下のコードはPython 3.xで完全に機能します。 pandasでXlsxWriterを使用する方法の詳細については、このリンクが役立つ場合があります 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

列の内容ではなく列ヘッダーに基づいて列を調整する方が便利であることがわかりました。

df.columns.values.tolist()を使用して、列ヘッダーのリストを生成し、これらのヘッダーの長さを使用して列の幅を決定します。

以下の完全なコードを参照してください。

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

最も簡単な解決策は、set_columnメソッドで列の幅を指定することです。

    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

他の回答とコメントを組み合わせて、マルチインデックスもサポートします。

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