【Python】Polarsからリンク付きのExcelを出力する
Rustではなく、Pythonの方のPolarsの話です。最近は機会があればPandasではなくPolarsで書いてみようと手を出していますが、なかなか慣れません。
今回は、リンク付きのExcelファイルをいい感じに出力しようとして、調べるのに結構時間がかかってしまいました。
polarsのwrite_excel
メソッドで出力すると、=HYPERLINK("https://example.com", "リンクのサンプル")
の様な文字列がそのまま出力されて、クリックできません。一旦xlsxwrite.Workbook
を持ってきて、それをwrite_excle
メソッドに渡して出力すると、求めていた挙動になります。
検証用コード全体
pip install polars xlsxwrite
してからpython3 example.py
すれば動くハズ。
import polars as pl
import xlsxwriter
def gen_hyperlink(query: str) -> str:
"""検索用のURLを生成"""
return f'=HYPERLINK("https://example.com/search?q={query}", "検索用URL")'
def gen_dataframe() -> pl.DataFrame:
"""テスト用DataFrameを生成"""
return pl.DataFrame(
{
"Fluits": ["apple", "banana", "orange"],
},
).with_columns(pl.col("Fluits").map_elements(gen_hyperlink).alias("SearchURL"))
def export_directly() -> None:
"""pl.DataFrameから直接書き出し"""
fluits = gen_dataframe()
fluits.write_excel("test-direct.xlsx", autofit=True)
def export_with_xlsxwriter() -> None:
"""xlsxwriter.Workbookを使用"""
fluits = gen_dataframe()
with xlsxwriter.Workbook("test-xlsxwriter.xlsx") as wb:
fluits.write_excel(wb, autofit=True)
def export_with_format() -> None:
"""xlsxwriter.Workbookを使用してフォーマットを適用"""
fluits = gen_dataframe()
with xlsxwriter.Workbook("test-format.xlsx") as wb:
fluits.write_excel(
wb,
autofit=True,
column_formats={"SearchURL": {"color": "blue", "underline": "TRUE"}},
)
def main() -> None:
export_directly()
export_with_xlsxwriter()
export_with_format()
if __name__ == "__main__":
main()
検証
下記コードはdf
変数にpolars.DataFrame
が入っているものとします。また、URLを格納した列をSearchURL
とします。
polars.DataFrame.write_excel()
失敗例: 普通にやると、HYPERLINK関数がそのまま文字列として表示される。
df.write_excel("test.xlsx")
直接リンクとしてクリックできない
Excel上で編集すると変換される
これじゃない感
xlsxwriter.Workbook
を使用
成功例: 一旦xlsxwriter.Workbook
を取得して、それを利用してwrite_excel
メソッドを使うと、クリックできるリンクとして出力される。
with xlsxwriter.Workbook("test.xlsx") as wb:
df.write_excel(wb)
ちゃんとクリックできる
さらに完璧に: リンクのある列にスタイルを当てる
見た目が他の文字列と同じままだとクリックできるリンクだと分からないので、該当の列に青文字と下線を適用する。
with xlsxwriter.Workbook("test.xlsx") as wb:
df.write_excel(
wb,
column_formats={"SearchURL": {"color": "blue", "underline": "TRUE"}},
)
求めていたもの
どうしてこうなるのか
原因は、write_excel
関数にWorkbookではなくファイル名などが与えられた場合、_xl_setup_workbook
関数内の ここで Workbookをインスタンス化する時に"strings_to_formulas": False
を設定しているため。
自分でインスタンス化する際はこのオプションを指定していないため、デフォルト値の True
が使用されます。False
になっているのにはセキュリティ上の理由等があるんでしょうか。ご存知の方がいたら教えてください。
まとめ
Polarsの情報量はかなり増えてきましたが、Pandasにはまだまだ遠く及びません。未だに急ぎの時や迷った時はPandasに逃げてしまうときもあります。
パフォーマンスももちろんですが、書き方についてもpl.col
で書けるのがPandasに比べてかなりスマートで気に入っているので、今後も機会があればどんどん使っていきたいです。
参考
Discussion