雲のメモ帳

猫とクラウドと旅行が好きなインフラエンジニアです。 日々の調べたことや興味が持ったことをこのブログにアウトプットします。

Streamlit上でExcelで文字化けしないCSVのダウンロードリンクを生成する

これはなに?

Streamlit上で生成したデータフレームをCSVとして出力し、Excelで読み込むと日本語が文字化けして困ったので、Excelで文字化けしないCSVのダウンロードファイルリンクの生成方法をメモとして残します。

1. Excelでの文字化けの原因

pandasを利用してDFをCSVにして出力すると文字コードはUTF-8で出力されるのですが、EXCELが標準としてCSVをShift-JISで読み込んでしまうらしく、文字コードが一致せず文字化けが発生していました。

f:id:ykoomaru:20211120220001p:plain

文字化けするダウンロードリンク サンプル

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

2. 対処方法

対処方法としては、Byte Order Mark(BOM) 付きのutf-8でCSVを出力してあげれば、Excelがutf-8としてファイルを開くようになるため、文字化けせずにCSVファイルを読み込むことができます。

文字化けしないダウンロードリンク サンプル

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)

ポイントとしては、csvをエンコードする際に、'utf-8-sig' を指定するところです。
このリンクで生成されたCSVファイルをExcelで読み込むと文字化けせずに読み込めます。

f:id:ykoomaru:20211120220956p:plain

メモ帳で開いてみるとBOM付きになっていることがわかります。

f:id:ykoomaru:20211120221810p:plain

3. サンプル

簡単なサンプルですが、日本語で記述されているDataframeをutf-8とutf-8(BOM)で出力するダウンロードできるサンプルコードを書いてみました。
2種類のCSVを開いてみて、文字化けの有無を確認してもらえればと思います。

f:id:ykoomaru:20211120220513p:plain

gist79f52912a1ab84b7bf1633c07a085905