Action Mailerでエクセルを添付する方法
環境
rails3のaction mailerでメールを送る際にエクセルを添付したいケースがあると思う。
Rails Guideにならって書くとこうなる。
# -*- coding: utf-8 -*- class TestMailer < ActionMailer::Base default from: "hakutoitoi@example.com" def test_email attachments['test.xls'] = File.read('/tmp/test.xls') mail(:to => "hakutoitoi@example.com", :subject => "a mail with excel") end end
実行してみると、下記のようなエラーで失敗した。
$ rails console [1] pry(main)> mail = TestMailer.test_email ArgumentError: invalid byte sequence in UTF-8from /Users/hakutoitoi/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.2.8/lib/active_support/core_ext/object/blank.rb:105:in `=~'
普通エクセルはSHIFT-JISで作成されるがaction_mailerはattachmentsにUTF-8を期待している感じ。 色々調査した結果、下記のようにバイナリ指定をすることでマルチバイトを含んだエクセルを添付できました。
# -*- coding: utf-8 -*- class TestMailer < ActionMailer::Base default from: "hakutoitoi@example.com" def test_email attachments['test.xls'] = { :content => File.read('/tmp/test.xls', :mode => 'rb'), :transfer_encoding => :binary } mail(:to => "hakutoitoi@example.com", :subject => "a mail with excel") end end
再度実行してみると...
[1] pry(main)> mail = TestMailer.test_email => #<Mail::Message:70296836491860, Multipart: true, Headers: <From: hakutoitoi@example.com>, <To: hakutoitoi@example.com>, <Subject: a mail with excel>, <Mime-Version: 1.0>, <Content-Type: multipart/mixed; boundary="--==_mimepart_5093785b42888_1ae43fef40834cd410818"; charset=UTF-8>> [2] pry(main)> mail.deliver => #<Mail::Message:70296836491860, Multipart: true, Headers: <Date: Fri, 02 Nov 2012 16:38:12 +0900>, <From: hakutoitoi@example.com>, <To: hakutoitoi@example.com>, <Message-ID: <5093786488979_1ae43fef40834cd411095@hakutoitoi.co.jp.mail>>, <Subject: a mail with excel>, <Mime-Version: 1.0>, <Content-Type: multipart/mixed; boundary="--==_mimepart_5093785b42888_1ae43fef40834cd410818"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>
成功した。
まとめ
- File.readでファイルを読む時にバイナリモードを指定する
- attachmentsメソッドのオプションとして :transer_encoding => :binary を指定する