見出し画像

pandas_ExcelWriterとstyleframeを使ってエクセルの書式設定をしてから出力 #304日目

データフレームの内容をExcelに出力したい時、to_excel()を使うことができます。今回はそこから更に、どういう書式設定で出力するかを定義する方法についてまとめたいと思います。

こちらのブログを参考にさせていただきました。


結論として、pandasのExcelWriterメソッドと、styleframeライブラリの各メソッドを使用します。


まず下準備としてpandasとstyleframeをpipインストールします。ディレクトリにvenvで仮想環境を作成し、そこにインストールします。

$ python -m venv .venv
$ source .venv/bin/activate
(.venv) $ python -V
Python 3.10.3

(.venv) $ pip install pandas
(.venv) $ pip install styleframe

インターナルが完了したらstyleframeの動作確認を行います。Pythonのインタープリタを起動して以下のコマンドを打ちます。

(.venv) $ python3
>>> from styleframe import tests
>>> tests.run()
 

----------------------------------------------------------------------
Ran 4 tests in 0.095s

OK
...
----------------------------------------------------------------------
Ran 3 tests in 0.066s

OK
.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s

OK

全てOKになれば下準備完了です。

先にデータフレームを定義しておきます。ブログの内容をそのまま使わせていただきました。

import pandas as pd

member = [
    {
        '姓': '鈴木',
        '名': '太郎',
        '年齢': 25,
        '職業': '会社員',
    },
    {
        '姓': '佐藤',
        '名': '一郎',
        '年齢': 30,
        '職業': '公務員',
    },
    {
        '姓': '田中',
        '名': '三郎',
        '年齢': 28,
        '職業': '無職',
    }
]

df = pd.DataFrame(member)
print(df)


ExcelWriterの基本文法は以下です。書式は何も定義していないので、デフォルトの設定でExcelが出力されるだけです。


with pd.ExcelWriter('test.xlsx') as writer:
    df.to_excel(writer, index=False, sheet_name='会員一覧') # index=Falseにしないとindex番号まで出力されてしまう

書式を定義するためにstyleframeと組み合わせます。以下が基本文法です。このStyleFrame()に属する各メソッドで書式設定を行っていきます。

import pandas as pd
from styleframe import StyleFrame

# StyleFrameのエクセルライターを使う
with StyleFrame.ExcelWriter('test.xlsx') as writer:
    # dfをStyleFrameクラスの引数にしてインスタンス生成
    sf = StyleFrame(df)
    # StyleFrameのto_excelメソッドで書き込む
    sf.to_excel(writer, index=False, sheet_name='会員一覧')


書式を色々と定義してみます。Styler()で書式を定義し、apply_column_styleで指定の列に適用します。また、set_column_widthとset_row_heightで行列の長さを定義しています。

styler_num = Styler(horizontal_alignment=utils.horizontal_alignments.right, number_format='0.0')
styler_str = Styler(horizontal_alignment=utils.horizontal_alignments.left, wrap_text=False)  # wrap_textがTrueだとセル内で折り返す(デフォルトがTrue)
styler_str_bg = Styler(horizontal_alignment=utils.horizontal_alignments.left, wrap_text=False, bg_color=utils.colors.grey)
with pd.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_column_width(columns=[2,3], width=20) # columnsは1列目が1,2列目が2、という感じ。列名を直接指定する形でもOK
    sf.set_row_height(rows=list(range(2, len(member) + 2)), height=50) # 1行目を除いて2行目以降の全ての行を対象にしている
    sf.apply_column_style(cols_to_style=['年齢'], styler_obj=styler_num)
    sf.apply_column_style(cols_to_style=['姓', '名'], styler_obj=styler_str) # style_header = Trueとすると1行目にも適用される
    sf.apply_column_style(cols_to_style=['職業'], styler_obj=styler_str_bg)     
    sf.to_excel(writer, index=False, sheet_name='会員一覧')  # index=Falseにしないとindex番号まで出力されてしまう

こうすると以下のようなエクセルが出力されてきます。

test.xlsx


apply_column_styleが何列にもなってしまったので、for文を使えばスマートに定義できます。

excel_colums = [
    ('姓', styler_str),
    ('名', styler_str),
    ('年齢', styler_num),
    ('職業', styler_str_bg)
]
with pd.ExcelWriter('test2.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_column_width(columns=[2,3], width=20) 
    sf.set_row_height(rows=list(range(2, len(member) + 2)), height=50)
    for colum_name, styler in excel_colums:
        sf.apply_column_style(cols_to_style=[colum_name], styler_obj=styler)
    sf.to_excel(writer, index=False, sheet_name='会員一覧') 

出力結果は先ほどと同じです。

test2.xlsx


Stylerで定義できる書式は例えば以下のものがあります。

太字にする:bold=
フォントを変更:font=
フォントサイズを変更:font_size=
フォント色を変更:font_color=
上/下/中央揃え:vertical_alignment=
セルをはみ出して表示:shrink_to_fit=
セルを(数値/日付などに)フォーマット:number_format=
セルを編集不可に:protection=

YUKI.WORLD

詳しくはこちらにまとまっています。


ここまでお読みいただきありがとうございました!


参考


この記事が気に入ったらサポートをしてみませんか?