@kyanny's blog

My life. Opinions are my own.

はしごだか・たつさき等の機種依存文字を含む Microsoft Excel ファイルを CSV として保存するとき気をつけること

TL;DR LibreOffice を使え


「髙(はしごだか)」や「﨑(たつさき)」のような、いわゆる機種依存文字*1を含む Microsoft Excel ファイルのデータを UTF-8 に変換して扱おうとして、 Excel の「Save As…」から CSV 形式で保存したところ、それらの文字が全て「_ (アンダースコア)」に変換されてしまう、というトラブルに見舞われた。

この記事と同じ現象。

www.nowhere.co.jp

.xlsx ファイル -> Excel で CSV 形式で保存 -> iconv(1) で cp932 から utf-8 へ文字コードを変換 -> プログラムで処理、という手順を踏んだが、まさか Excel で CSV に保存する時点で壊れているとは思わず、 iconv を疑ってみたりと時間を無駄にした。

検索してみるとより詳しい調査をしたブログ記事が見つかった。

donatstudios.com

Microsoft Excel (特に Mac 版)で CSV を扱うのにはいろいろと問題があるようだ。曰く、

As of this writing, there exists a single usable CSV format that Microsoft Excel can both read and write safely across platforms. Tab delimited UTF-16LE with leading Byte Order Mark.

とのことだが、相手方に高い IT リテラシーを期待できないからわざわざ .xlsx 形式のファイルでデータをやりとりしているわけで、「BOM つき UTF-16LE で保存したファイルをくれ」といって通じるくらいなら最初から「UTF-8 の CSV ファイルをくれ」と言うほうが楽だ。

ともかく Microsoft Excel は避けるべきだが、ではいくつか考えうる代替案のうちどれが良いのか?気になったので調べてみた。

Google Spreadsheet 形式に変換してエクスポート

Google Drive に .xlsx ファイルをアップロードし、 Google Spreadsheet で開くと Google Spreadsheet 形式に変換してくれる。変換後も機種依存文字が _ に置換されることはないし、 CSV または TSV でエクスポートした場合も問題ない。さらに、エクスポートしたファイルは UTF-8 にも変換済み。 Google Drive を利用できるのであれば、これが最も良い方法だと思う。バックアップにもなるし。

OpenOffice で開いて CSV で保存

OpenOffice で .xlsx ファイルを開いて、 CSV で保存しなおす。保存時に文字コードを選べるので、 UTF-8 にしておけば手間が減る。

LibreOffice で開いて CSV で保存

同上。なんだかんだいって、これが一番手っ取り早いかもしれない(なんとなくイマドキは OpenOffice よりも LibreOffice のほうが良いみたいだし)。

Microsoft Excel で CSV UTF-8 (Comma delimited) (.csv) 形式で保存

Microsoft Excel で CSV 形式で保存するとき、 Comma Separated Values (.csv) と CSV UTF-8 (Comma delimited) (.csv) という二種類から選べる。保存されるファイルの文字コードが違う(前者は Shift_JIS (CP932) 後者は UTF-8)。それ以外にも、 UTF-8 のほうは BOM がつく、という違いもある(U+FEFF)。 UTF-8 のほうの CSV ファイルでは機種依存文字が _ に変換されないようだが、プログラムで処理する際に BOM を削除する必要が(おそらく)あったりするし、そもそも Excel あんまり信用しないほうがいい、という話なのでお勧めしない。

参考資料

実験に使ったファイル置き場

髙﨑とExcelとCSV - Google ドライブ

各種 CSV ファイルの中身

f:id:a666666:20170822035717p:plain

Google Spreadsheet

f:id:a666666:20170822035824p:plain

*1:IBM拡張文字・NEC選定IBM拡張文字などと呼ぶほうが正確なのかもしれない