Excelレポートを生成するよう求められています。現在、データにpandasをかなり使用しているため、当然、pandas.ExcelWriterメソッドを使用してこれらのレポートを生成したいと思います。ただし、固定列幅は問題です。
私がこれまでに持っているコードは十分に単純です。 「df」というデータフレームがあるとします。
writer = pd.ExcelWriter(Excel_file_path)
df.to_Excel(writer, sheet_name="Summary")
私はpandasコードを見ていましたが、列幅を設定するオプションは実際には表示されません。列が自動調整されるようにする宇宙のトリックはありますかまたは、列幅を調整するためにxlsxファイルに事実の後にできることはありますか?
(私はOpenPyXLライブラリを使用し、.xlsxファイルを生成しています-それが違いを生む場合)
ありがとうございました。
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()
私がこれを投稿しているのは、同じ問題に遭遇したばかりで、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()
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
に追加されました。 ドキュメント を参照してください。
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()
列の内容ではなく列ヘッダーに基づいて列を調整する方が便利であることがわかりました。
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
最も簡単な解決策は、set_columnメソッドで列の幅を指定することです。
for worksheet in writer.sheets.values():
worksheet.set_column(0,last_column_value, required_width_constant)
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
他の回答とコメントを組み合わせて、マルチインデックスもサポートします。
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()