如何使用Ruby将csv文件的内容写入电子邮件?

时间:2019-01-04 18:23:23

标签: ruby-on-rails ruby

我有一个代码,可以计算一组值并将其写入csv文件。我一直将此csv文件作为附件发送到电子邮件中。

现在,我想实际上将csv文件的内容写在电子邮件正文上,而不是将其作为附件发送。

CSV文件如下所示:

Region,Count
Asia,5
America,3
Europe,4

我一直用于发送电子邮件的代码如下:

require 'mail'
def mailsender
  Mail.defaults do
    delivery_method :smtp,{ address: "smtp.xyz.com",openssl_verify_mode: "none" }
  end

  Mail.deliver do
    from     'abc@xyz.com'
    to       'admins@xyz.com'
    subject  'Status Report'
    body     'Please find attached the status report'
    add_file 'C:\Users\abc\Desktop\Ruby\Summary.csv'
  end
end

因此,我希望邮件正文看起来像这样:

请在下面找到摘要:

亚洲5
美国3
欧洲4

2 个答案:

答案 0 :(得分:2)

您可以使用stdlib的CSV来读取文件:

require 'csv'

contents = CSV.read('file.csv')

这将为您提供一个数组数组,其中第一个值为标头。您还可以传递headers: true来获取哈希值:

> contents = CSV.read('file.csv', headers: true)
> contents.first

 {
  "Region" => "Asia",
  "Count" => "5"
 }

如果您要处理较大的数据集并且需要按名称访问值,则此选项很有用:

> contents.map{|i| "#{i["Region"]} #{i["Count"]}"}

[
    [0] "Asia 5",
    [1] "America 3",
    [2] "Europe 4"
]

然后您可以.join("\n")用它们来获取所需的字符串格式。

请注意CSV#read,因为它将整个文件拖入内存。如果文件很大,则可以使用CSV#foreach逐行对其进行迭代。

答案 1 :(得分:1)

要达到预期结果,将当前主体连接起来就足够了 带有CSV数据:

def formatted_body
  title + data.join("\n")
end

其中title是您当前的正文和用于构建CSV文件的数据值

def title
  "Please find attached the status report:\n"
end

def data
  # code which returns your structure 
  ["Asia 5", "America 3", "Europe 4"]  

  # alternatively reuse existing .csv
  read_csv
end

如果您想重用现有的.csv文件

def read_csv
  content = CSV.read("data.csv")
  content.shift  # to exclude headers
  content.map {|row| row.join(' ') }
end

您可以考虑将其包装到类中:

require 'mail'

class MailSender
  attr_accessor :data

  def initialize(data)
    @data = data
  end

  def mailsender
    Mail.defaults do
      delivery_method :smtp,{ address: "smtp.xyz.com",openssl_verify_mode: "none" }
    end

    Mail.deliver do
      from     'abc@xyz.com'
      to       'admins@xyz.com'
      subject  'Status Report'
      body     formatted_body
      add_file 'C:\Users\abc\Desktop\Ruby\Summary.csv'
    end
  end

  private 
  def formatted_body
    title + data.join("\n")
  end

  def title 
    "Please find attached the status report:\n"
  end

end