実現したいこと
以下のような Excel ファイルを作りたい。1
これは Python で Excel ファイルを扱う定番ライブラリである OpenPyXL では実現できないが、 XlsxWriter で実現できるらしい。詳しくは以下の記事を参照。
この方法では XlsxWriter の API を使うことになり、記述が複雑になる。そこで HTMLテーブル を経由する方法を考えた。
フォーマット付き HTMLテーブル の作成
テーブルの準備
Pandas を使ってテーブルを準備する。ここで文字列中で赤色にしたい部分を _RED_START_
, _END_
で、青色にしたい部分を _BLUE_START_
, _END_
で囲んだ。本当はここに HTML の <font>
タグを書きたいが、この時点で書くと pandas.DataFrame.to_html()
によってエスケープされてしまうので、あとで置換するようにする。
import pandas as pd
dic = {
'国旗': ['日本', 'アメリカ'],
'色': [
'白、_RED_START_紅_END_',
'白、_BLUE_START_青_END_、_RED_START_赤_END_'
]
}
df = pd.DataFrame(dic)
HTMLテーブルに変換
to_html()
で変換する。 to_html()
は引数に output.html
などを指定すると HTML ファイルに出力されるが、指定しない場合は文字列として返す。
html = df.to_html()
文字列 html
は以下のような中身になっている。
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>国旗</th>
<th>色</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>日本</td>
<td>白、_RED_START_紅_END_</td>
</tr>
<tr>
<th>1</th>
<td>アメリカ</td>
<td>白、_BLUE_START_青_END_、_RED_START_赤_END_</td>
</tr>
</tbody>
</table>
font タグを挿入
あとは _RED_START_
などを <font>
タグで置き換える。
html = html.replace('_RED_START_', '<font color="red">').replace('_BLUE_START_', '<font color="blue">').replace('_END_', '</font>')
html
の中身は以下のようになった。
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>国旗</th>
<th>色</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>日本</td>
<td>白、<font color="red">紅</font></td>
</tr>
<tr>
<th>1</th>
<td>アメリカ</td>
<td>白、<font color="blue">青</font>、<font color="red">赤</font></td>
</tr>
</tbody>
</table>
エクセルにコピペ
HTML を表示すると以下のようになっているはずなので、これをコピーして Excel に貼りつけることで欲しかった Excel ファイルが得られる。
Pros & Cons
この方法の利点は HTML タグを使うので新たに XlsxWriter の使い方を覚える必要がないこと、 XlsxWriter で 'A1'
などのわずらわしいセル指定を行う必要がないこと。
一方で欠点はコピペが手動であること、大きいファイルになるとコピペに失敗する可能性があることである。HTML ファイルから Excel ファイルを生成する方法があれば捗るかもしれない。
おわりに
今回行った処理はこの Jupyter Notebook で確認できる。
各国旗の色は以下の記事を参考にしたが、紅色は簡単のため HTML 上では赤色で指定した。
-
ここでは抽象的な例にしているが、具体例としては自然言語処理で生成した要約と人間の要約を横に並べて一致している部分を緑で、異っている部分を赤で表示することなどが考えられる。 (cf. ROUGEを訪ねて三千里:より良い要約の評価を求めて - Qiita)
その場合は difflib.HtmlDiff を使うと捗る。 (cf. Pythonでファイルの差分を抽出し結果をhtmlとして出力する|ゆゆうブログ) ↩