Excel業務(無駄)を自動化したい　part5 表作り(応用編)

# はじめに
このサイトでは、社会人なりたての私が無駄を省くための戦いをまとめています。
今回のテーマは、pythonのライブラリを用いて、Excelをいじっていきます。
ライブラリ名は、openpyxlです。

# 実行環境
Windows10
Python 3.10.5

# openpyxlとは？
openpyxlはExcelファイル(`.xlsx`)を読み書きできるツールです。
公式ドキュメント　[openpyxl/openpyxl-Bitbucket](https://bitbucket.org/openpyxl/openpyxl/src/master/)
詳しくは[こちら！](https://note.nkmk.me/python-openpyxl-usage/)
**今回はExcelファイル内のデータを読み込んで、分析するのではなく、
代入したいだけなので、pandasではなくopenpyxlを使用しています！**

# 特殊な形の表の作成
今回作りたいのは、[セルの結合と結合解除（公式）](https://support.microsoft.com/ja-jp/office/%E3%82%BB%E3%83%AB%E3%81%AE%E7%B5%90%E5%90%88%E3%81%A8%E7%B5%90%E5%90%88%E8%A7%A3%E9%99%A4-5cbd15d5-9375-4540-907f-c673a93fcedf#OfficeVersion=Web)に記載されている表をopenpyxlを使用して作っていきます。
前回までの知識＋セルの結合を使います。
セルの結合は、`WorkSheet`オブジェクト内のmerge_cell関数を使用します。
書き方は2通りあります。
```python:セルの結合に使用する関数    
ws.merge_cells("A1:A3") #開始のセル:終了のセル

ws.merge_cells( start_row=1,   #開始の行番号 
                start_column=1,#開始の列番号
                end_row=1,     #終了の行番号 
                end_column=3)  #終了の列番号 
```
（どちらの方法でも使えますが、Excelをx,y軸で考えられるので後者がおすすめです。）
このセルの結合の方法で、表を作っていきます。

## 実践
```python:importリスト
import openpyxl
from openpyxl.styles.fills import PatternFill
```

```python:表作成
xlsx_path = "Excelファイルのパス"
wb = openpyxl.load_workbook(xlsx_path)
ws = wb.worksheets[0]

tableList = [["月間売上","",""],
            ["1月","2月","3月"],
            ["￥194,372.56","￥169,906.14","￥72,234.89"],
            ["￥200,203.73","￥175,003.33","￥73,679.59"]]

blue = PatternFill(patternType='solid',fgColor='89cff0')
for x in range(1,5):
    for y in range(1,4):
        ws.cell(row=x,column=y).value = tableList[x-1][y-1]
        if x==2:
            ws.cell(row=x,column=y).fill = blue
ws.merge_cells("A1:C1")

wb.save(xlsx_path)
```
上記のコードの実行結果はこちらです。
![スクリーンショット 2022-10-25 192600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433191/d2e3446d-fd5d-6512-4d4e-97bfd9d7ec18.png)
あれ？結合したのに文字が真ん中に来ていない！
セル結合する上で、文字の位置をコード指定しないといけません。
文字の位置を操作する関数はAlignment関数です。
```python:文字の位置を操作する関数
alignment = Alignment(  horizontal="center", #水平方向での位置を指定
            vertical="center")   #垂直方向での位置を指定
```
上記のAlignment関数を追記して完成させたいと思います。
※個人的感想ですが、セル結合前にAlignment関数使った方が見やすいです。

```python:表作成　追記箇所
for x in range(1,5):
    for y in range(1,4):
        ws.cell(row=x,column=y).value = tableList[x-1][y-1]
        if x==2:
            ws.cell(row=x,column=y).fill = blue
ws.cell(row=1,column=1).alignment = Alignment(horizontal="center",vertical="center")
ws.merge_cells("A1:C1")
```
追記した上で、実行した結果がこちらです。
![スクリーンショット 2022-10-25 194403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433191/e3fd9494-3c83-7ee5-283e-8d6cd7990e04.png)
参考した表から大分数値の部分を削りましたが、指定の表を作成することができました。

# おまけ
Alignment関数には、何個かトラップが仕掛けられているので紹介したいと思います。
## Alignment関数と改行コード
Alignment関数を使っていると改行コードを代入しても改行されない問題があります。
原因としてはAlignment関数の引数の一つに`wrapText`があります。
この引数で、セル内で改行するか決めており、こいつの立ち悪いことは、デフォルトがfalseになっていることです。なので、Alignment関数を使うときは、`wrapText`をtrueにして使ってください。

## Alignment関数とセル結合
Excelでは、セル結合したときは、セル結合を始めたセルのデータが基準になります。
openpyxlでpython使っても一緒で、セル結合を始めたセルのデータを操作しないと、反映されないので、忘れずに。なので、セル結合する前に、セルのデータの操作を終わらせときましょう。

# 終わりに
ここまでである程度のExcelの業務は代替できるのでは？と内心思っていますが、はたしてこれに需要があるかは不明ですね。書いてる本人が疑っているので。ということでpythonでExcelの操作する話のネタが尽きてきたのでもう少しopenpyxlの仕様の部分を書いていきたいと思います。