Rails ActionMailer在附件中发送csv、excel、pdf、zip文件

1.修改Gemfile

# PDF generator
gem 'prawn'
gem 'prawn-table'

# Excel generator
gem 'rubyXL'

bundle install

2.生成附件

export.rb

requere 'csv'
class Export
  def export file_type,data
    file_name = "file_name"
    attachment = case file_type
                  when 'csv'
                      generate_csv(data)
                  when 'zip'
                     generate_zip(data)
                  when 'excel'
                     generate_excel(data)
                  end
    ExportMailer.with_attachment(attachment, file_name).deliver_now
  end 

  def generate_csv data
    file = Tempfile.new ['export', '.csv']
    file.write(csv_data(data))
    file
  end

  def generate_excel data
    file = Tempfile.new ['export', '.xlsx']
    file.write(excel_data(data))
    file
  end

  def generate_zip data
    pdf_files = Hash.new
    data.find_each do |item|
      file = Tempfile.new
      pdf = Prawn::Document.new
      pdf.font('path/to/font') do
        pdf.text "item_data"
      end
      pdf.render_file file
      pdf_files[item] = file
    end
    write_to_zip(pdf_files)
  end

  def csv_data data
    CSV.generate(encoding: 'gbk') do |csv|
      data.each do |record|
        csv << record.to_a
      end
    end
  end

  def excel_data data
    excel = RubyXL::Workbook.new
    sheet = excel.worksheets.first
    sheet.sheet_name = "sheet_1"
    data.each_with_index do |record,m|
      record.each.with_index{|content,n|
        sheet.add_cell(m,n,content)
      }
    end
    excel.stream.read
  end

  def write_to_zip queue
      file = Tempfile.new ['export', '.zip']
      Zip::File.open file.path, Zip::File::CREATE do |zip|
        zip.get_output_stream(".keep") { |os| os.write "keep file" }
        queue.each do |name, pdf|
          pdf.rewind
          zip.get_output_stream("#{name}.pdf"){ |stream| stream.write pdf.read }
        end
      end
      file
  end
   
end

3.发送邮件

export_mailer.rb

class ExportMailer < ApplicationMailer
  def with_attachment attatchment_file, filename
    attatchment_file.rewind
    file_name = "#{filename}#{File.extname(attatchment_file.path)}"
    attachments[file_name] = File.read(attatchment_file.path)
    mail(to: [email protected], subject: '发送附件测试')
  end

end

猜你喜欢

转载自www.cnblogs.com/xiaoff/p/8944827.html