[Ruby] 匯出XLS、CSV轉存編碼問題
前言
前陣子遇到需要匯出CSV問題,想想很簡單嘛,ruby內建的CSV應該手抖一下就寫完了。 後來發現事情不像我想得這麼簡單,照理說只要照預設輸出成UTF-8就萬事OK, 但是在window開起來卻是亂碼,在開頭加了BOM後原以為事情完美落幕, 偏偏廠商就是不吃UTF-8格式,研究半天,轉成Big5還是有問題,後來才發現是ISO-8859-1,接下來就來聽我抱怨。
讓我們研究一下在Windows之下Excel編碼格式
一般中文的話,會是以下兩種編碼
- ANSI(ISO-8859-1) - 實際上中文是從Big5轉過去ISO-8859-1
- UTF-8(含BOM)
實際Rails Console測試狀況
這邊拿了一個中文字”類”來測試 (沒什麼特別原因,就當初文件的第一個字) 可以看到用big5轉碼後
2.3.1 :001 > str_utf8 = "類"
=> "類"
2.3.1 :003 > str_utf8.encode('big5')
=> "\x{C3FE}"
2.3.1 :004 > str_utf8.encode('big5').force_encoding('ISO-8859-1')
=> "\xC3\xFE"
實際寫法
- ANSI(ISO-8859-1) - 這寫法中文是big5,在window的excel開起來正常,在linux openoffice開起來要特別選
YOUR_TITLES = ['標題1','標題2',....]
YOUR_CONTENTS = [{ 標題1: xxx1, 標題2: yyy1,... },{ 標題1: xxx2, 標題2: yyy2,... },....]
csv_data = CSV.generate do |csv|
csv << YOUR_TITLES
csv << YOUR_CONTENTS
end
#轉成Big5再用ISO-8859-1來顯示
csv_data = csv_data.encode('Big5').force_encoding('ISO-8859-1')
#直接存檔(存ISO-8859-1)
File.open("#{Rails.root}/public/xxx.csv", 'wb:ISO-8859-1') { |file| file.write(csv_data) }
#直接下載
respond_to do |format|
format.csv { send_data csv_data, filename: 'xxx.csv' }
end
- UTF-8(BOM) - 開起來Window及Linux都正常顯示,但是有些廠商excel只吃ANSI格式
YOUR_TITLES = ['標題1','標題2',....]
YOUR_CONTENTS = [{ 標題1: xxx1, 標題2: yyy1,... },{ 標題1: xxx2, 標題2: yyy2,... },....]
head = 'EF BB BF'.split(' ').map{|a|a.hex.chr}.join() # 加入BOM,解決excel中文亂碼
csv_data = CSV.generate(csv = head) do |csv|
csv << YOUR_TITLES
csv << YOUR_CONTENTS
end
#直接存檔
File.open("#{Rails.root}/public/xxx.csv", 'wb') { |file| file.write(csv_data) }
#直接下載
respond_to do |format|
format.csv { send_data csv_data, filename: 'xxx.csv' }
end
Reference
留言