3
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

streamlitでexcel形式のファイルをダウンロードする方法

Last updated at Posted at 2023-01-31

はじめに

Pythonのみで記述できるお手軽webフレームワークであるstreamlitはHTMLやCSSの勉強の必要がなくちょっとしたものを作るには非常に便利です。しかしその反面で標準搭載されている機能も少なく、場合によっては自作する必要があります。
今回、結果を出力する際にexcel形式(.xlsx)を利用しようとしたのですが、少々つまずいたので備忘録として残しておきます。

2023/02/15追記
@SaitoTsutomoさんより良い方法を教えていただきました。
記事の下に追記したのでそちらをご参照ください。
ありがとうございます。

内容

from io import BytesIO
import pandas as pd
import streamlit as st

def df_to_xlsx(df):
    byte_xlsx = BytesIO()
    writer_xlsx = pd.ExcelWriter(byte_xlsx, engine="xlsxwriter")
    df.to_excel(writer_xlsx, index=False, sheet_name="Sheet1")
    ##-----必要に応じてexcelのフォーマット等を設定-----##
    workbook = writer_xlsx.book
    worksheet = writer_xlsx.sheets["Sheet1"]
    format1 = workbook.add_format({"num_format": "0.00"})
    worksheet.set_column("A:A", None, format1)
    writer_xlsx.save()
    ##---------------------------------------------##
    workbook = writer_xlsx.book
    out_xlsx = byte_xlsx.getvalue()
    return out_xlsx


df_test = pd.read_excel("test.xlsx")
xlsx_test = df_to_xlsx(df_test)

st.download_button(label="Download", data=xlsx_test, file_name="_test.xlsx")

上記のコードを使うことでDataFrameをcsvではなくxlsxの形式でダウンロードすることが可能になります。
xlsxのエンジンとしてxlsxwriterを利用するのでこちらのライブラリのインストールを忘れないでください。
xlsxを用いる利点としては
・日本語が入っていても文字化けしない
・画像やグラフの挿入ができる
・非プログラマーにとってはcsvより使いやすい
といった点が挙げられます。

特に日本語を含むcsvを扱いたい場合、デフォルトのst.download_buttonでは文字化けしてしまいます。
そのため別途ダウンロードリンクを作成する必要があり厄介です。
ダウンロードリンクの例も示しておきます(こちらから流用)。

csv用のダウンロードリンクの例
import base64
import streamlit as st

csv = df.to_csv(index=False) 
b64 = base64.b64encode(csv.encode('utf-8-sig')).decode()
href = f'<a href="data:application/octet-stream;base64,{b64}" download="result_utf-8-sig.csv">Download Link</a>'
st.markdown(f"CSVファイルのダウンロード(utf-8 BOM):  {href}", unsafe_allow_html=True)

またアプリ画面の見栄えも標準搭載されているst.download_buttonの方が綺麗だと思います(好みですが...)。
image.png

最後に

streamlitでDataFrameをxlsx形式で出力する方法について記しました。
webフレームワークとしてはほかにFastAPIやDjangoなどもあるので、必要に応じて使い分けたいと思います。

2023/02/15追記

@SaitoTsutomoさんに以下の方法を教えていただきました。

from io import BytesIO
import pandas as pd
import streamlit as st

df = pd.DataFrame(["テスト"], columns=["列A"])

df.to_excel(buf := BytesIO(), index=False)
st.download_button(
    "Download",
    buf.getvalue(),
    "sample.xlsx",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)

こちらの方がコンパクトに書けるので良いと思います。

3
16
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?