Help us understand the problem. What is going on with this article?

Excelファイルの中でjinja2テンプレートを使う

More than 3 years have passed since last update.

背景

システム開発をやっていると、Excelで書かれたドキュメントを書かせていただく機会がしばしばあります。
場合によっては、下記のようにほとんど同じ内容のファイルを大量に作らなければならないケースも、稀によくあります。

八百屋買い物手順書.xlsx
yaoya.png

魚屋買い物手順書.xlsx
sakanaya.png

上記の2つは、買いに行く店と、買う物を除いてまったく同じ内容です。

このような場合、「八百屋買い物手順書を作成してから、文字列置換によって魚屋バージョンを作成する」という方法がありますが、Excelの貧弱な置換機能では実現できない場合もあり、泣く泣く手動による置換(いわゆる手sed)を敢行する場合も多いのではないかと思います。

そこで、Pythonからxlsxファイルを読み書きするopenpyxlと、Pythonの代表的なテンプレートエンジンjinja2を使って、Excelファイル内のテキストをテンプレートで生成することを試してみました。

https://gist.github.com/kokumura/c44970102e1f33685152

pyxl.py [jinjaテンプレートを含むxlsxファイル名] [出力ファイル名] [テンプレート変数(YAML)]

このように実行することで、元のxlsxファイルに含まれる全シートの全セルを走査し、jinja2テンプレートが含まれていれば展開し、結果を別のファイルに出力します。

使い方

まず、Excelを使って下記のようなテンプレートファイルを用意します。
文法はjinja2そのものです。

template.xlsx
template.png

テンプレートで使う変数をYAMLで記述します。

yasai.yml
---
place: 八百屋
targets:
  - name: みかん
    num:  3
  - name: りんご
    num:  2
  - name: にんじん
    num:  1

sakana.yml
---
place: 魚屋
targets:
  - name: さんま
    num:  2
  - name: いか
    num:  1
  - name: たこ
    num:  1

下記のように実行することで、template.xlsxとYAMLファイルから、「八百屋買い物手順書.xlsx」「魚屋買い物手順書.xlsx」が生成されます。
めでたしめでたし。

python xljj.py template.xlsx 八百屋買い物手順書.xlsx yasai.yml
python xljj.py template.xlsx 魚屋買い物手順書.xlsx sakana.yml

おまけ

openpyxlは案外多機能で、頑張ればスタイルなども変更することができます。
ただし、ドキュメントがあまり充実していないので、ドキュメントに明記されていない機能や、プライベートメソッドを呼ぶ覚悟も時には求められます。

下記は、「Excelファイルを開き、すべてのシートの"A1"セルを選択し、最初のシートに切り替えてから保存する」というこれまたよくある作業を自動的に行う関数です。

from openpyxl import load_workbook
import openpyxl.worksheet.views

def select_a1(workbook_path):
    wb = load_workbook(workbook_path)
    wb._active_sheet_index = 0
    for ws in wb.worksheets:
        ws.sheet_view.selection = (openpyxl.worksheet.views.Selection(),)
    wb.save(workbook_path)

kokumura
空気の読める機械を目指して。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away