pandasでExcel書込み時に幅/高さ,中央揃え,折り返しをStyleFrameで変更する

- Python -
2020.08.27
Python[パイソン]

pandas.DataFrame.to_excel()でエクセルに書き込みと同時に、

  • 列幅や行の高さを変えたい
  • セル内の文字を中央揃え/左揃え/右揃えにしたい
  • 長文すぎて折り返し表示されているのを、折り返しせず表示したい
  • セル背景の色を変えたい

などなど、セルの状態を細かく変更するところまで自動化したかったんですが、pandasのデータフレームではどう頑張ってもできませんでした。

調べてみると、 StyleFrame というセルの状態をあれこれ細かく設定できるライブラリがあるようで、実際に使ってみた結果とても分かりやすく便利だったので忘れぬようメモを残します。

例として、以下のpandasのデータフレームを使って説明していきます。

test.pyimport pandas as pd

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

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

# エクセルへ書き込み
with pd.ExcelWriter('test.xlsx') as writer:
    df.to_excel(writer, index=False, sheet_name='会員一覧')

test $ python test.py
  姓     名   年齢  職業
0 鈴木  太郎  25  会社員
1 佐藤  一郎  30  公務員
2 田中  三郎  28  無職
test $

pandasでエクセル書き込み

ここから列・高さ幅や左/中央揃え、折り返しなどセルの表示設定を細かく変えたいとき、StyleFrameを使ってどう変えるかを例示していきます。

参考StyleFrame公式:Basic Usage Examples

pandas DataFrameをエクセル書き込み時に幅/高さ/折り返し等をStyleFrameで変更する

StyleFrameのインストール・準備

まず、pip install styleframeでStyleFrameをインストールします。

インストール完了後、そのままPythonインタープリタでStyleFrameが動作するかテストを実行。

from styleframe import tests

tests.run()を実行し、全てOKになれば準備は完了です。

test $ python
Python 3.7.4 (default, Aug 13 2019, 15:17:50)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from styleframe import tests
>>> tests.run()
...................
----------------------------------------------------------------------
Ran 19 tests in 0.003s

OK
......................................
----------------------------------------------------------------------
Ran 38 tests in 2.188s

OK
..
----------------------------------------------------------------------
Ran 2 tests in 0.090s

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

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

OK
>>>

つぎにpandas.DataFrame.to_excelではなく、StyleFrame.to_excelでエクセルへ書き込むようにコードを書き換える。

test.py(書き換え後)import pandas as pd
# ① インポートする
from styleframe import StyleFrame

member = [
    ...省略...
]

df = pd.DataFrame(member)

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

これでDataFrame.to_excel()のときのようにエクセルへ書き込みができれば準備が完了。

styleframeでエクセル書き込み

StyleFrameで書き込むと、中央揃えがデフォルト

StyleFrameでエクセルへ書き込むと、上記のように全て「中央揃え」で表示されます(DataFrameだと数字以外左揃えで書き込まれる)。

ここから、ようやくセルの状態を細かく設定できるようになります。

列幅を変える

pandasでエクセルのセル幅を変える

「名」列の横幅を変えたいとします。

12, 13行目のset_column_width(columns, width)がポイント。

test.pyimport pandas as pd
from styleframe import StyleFrame

member = [
    ...省略...
]

df = pd.DataFrame(member)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_column_width(columns='名', width=20)
    # sf.set_column_width(columns=2, width=20) ...これでも同じ
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

columnsのキーワード引数には、「列名」か「インデックス」で幅を変えたい列を指定可。※14行目でindex=Falseにしているため、インデックス"1"が左端になっています

複数列を同じ幅を変えたい時は、以下のようにcolumns引数にリストで指定するだけです。

test.pydf = pd.DataFrame(member)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_column_width(columns=['名', '職業'], width=20)
    # sf.set_column_width(columns=[2, 4], width=20) ...これでも同じ
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

これで、複数列の幅が変わりました。

pandasでエクセルのセル幅を変える

行の高さを変える

pandasでエクセルのセル幅を変える

2行目の高さを変えたいとします。

以下12行目のset_row_height(rows, height)がポイント。

test.pyimport pandas as pd
from styleframe import StyleFrame

member = [
    ...省略...
]

df = pd.DataFrame(member)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_row_height(rows=2, height=50)
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

rowsのキーワード引数には、行の「インデックス」で幅を変えたい列を指定可。"1"がそのまま1行目という意味です。0スタートではないので注意。

複数行を同じ高さに変えたい時は、rows引数にリストで指定するだけです。以下、1行目を除いた全ての行に適用する例。

test.pydf = pd.DataFrame(member)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.set_row_height(rows=list(range(2, len(member)+2)), height=50)
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

これで全ての行の高さが変更されました。

pandasでエクセルのセル幅を変える

左揃え/右揃え/中央揃えにする

pandasでエクセルのセル幅を変える

「姓」「名」の2列を左揃えにしたいとします。

Stylerutilsをインポートし、11行目で左揃えのスタイル定義をするのがポイント。

test.pyimport pandas as pd
# ① Styler, utilsをインポート
from styleframe import StyleFrame, Styler, utils

member = [
    ...省略...
]

df = pd.DataFrame(member)
# ② 左揃えのスタイルを定義
style = Styler(horizontal_alignment=utils.horizontal_alignments.left)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    # ③ 列に適用
    sf.apply_column_style(cols_to_style=['姓', '名'], styler_obj=style)
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

16行目で適用したい列名と定義したスタイルを指定するだけです。

Stylerhorizontal_alignmentには右揃え(right)、中央揃え(center)など指定できるオプションが他にもあります。

以下ドキュメントに全て書いてあるので参考にどうぞ。

参考StyleFrame公式ドキュメント:utils.horizontal_alignments

テキストの折り返し

pandasでエクセルのセル幅を変える

StyleFrameでエクセル書き込みをすると、デフォルトでは「テキストを折り返す」となっているので縦長になってしまいます。

テキストを折り返さず、1行で表示されるように変更したいとき。12行目のwrap_textがポイント。

text.pyimport pandas as pd
# ① Styler, utilsをインポート
from styleframe import StyleFrame, Styler, utils

member = [
    ...省略...
]

df = pd.DataFrame(member)
# ② 左揃え・折り返しなし のスタイルを定義
style = Styler(
    horizontal_alignment=utils.horizontal_alignments.left, wrap_text=False)

with StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    # ③ 列に適用
    sf.apply_column_style(cols_to_style=['プロフィール'], styler_obj=style)
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

wrap_textがTrueデフォルトなので、これをFalse(折り返ししない)にするだけです。

styleframe8

これだと1行目だけまだ折り返し表示されていますね(プロフィール)。

もし1行目にも適用したい場合はstyle_header引数をTrueにします。

test.pywith StyleFrame.ExcelWriter('test.xlsx') as writer:
    sf = StyleFrame(df)
    sf.apply_column_style(
        cols_to_style=['プロフィール'], styler_obj=style, style_header=True)
    sf.to_excel(writer, index=False, sheet_name='会員一覧')

これで、1行目(ヘッダー)にもStylerで定義したスタイルが適用され、折り返さずに表示されました。

pandasでエクセルのセル幅を変える

セル背景の色を変える

背景色を変えたい場合は、Stylerbg_color引数を放り込みます。

test.py...省略...

style = Styler(bg_color=utils.colors.grey)

...省略...

↓結果

pandasでセルの背景色を変える

色の指定はなんでもOKというわけではないので、以下StyleFrame公式ドキュメントをご覧ください。

参考StyleFrame公式ドキュメント:utils.colors

その他、Stylerの引数によって色々変更できる

他にもたくさんあって書ききれないのですが、エクセルでよく操作しがちなセルの設定はこれまで見てきたようにStylerの引数に放り込めば実現できます。

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

詳しくは、StyleFrameの公式ドキュメントを参考にしてください。

参考StyleFrame公式:API Document

↑TOP