In our rails 6 project I want to upload excel file into S3 bucket and send file link to email and provide download xls feature from email. Please help me.
I have generated the excel file using the code below, and also set S3 configuration in our project
xlsx = GenerateSpreadsheetService.new(all_data, file_name).call
Now my question is that how to upload the above excel file into S3 bucket and send file link to email and provide download xls feature from email
class ImportCsvDataJob < ApplicationJob
queue_as :default
def perform(file_name, column)
begin
keywords = []
all_data = []
file_path = get_file_path(file_name)
spreadsheet = Roo::Excelx.new(file_path)
(2..spreadsheet.last_row).each do |i|
keywords << {"language_code": "en", "location_code": 2840, "keyword": "allintitle: #{spreadsheet.row(i)}"}
end
response = GetTaskService.new(keywords).call
response["tasks"].map{|task|
keyword = task["data"]["keyword"].gsub('allintitle: ','')
result = GetTaskService.new.get_values(task["id"])
all_data << {keyword: keyword.to_s, value: result["tasks"][0]["result"][0]["se_results_count"]}
}
## Create records
CsvImport.create(all_data)
## Generate excel file
xlsx = GenerateSpreadsheetService.new(all_data, file_name).call
## send email
SendEmailJob.perform_now(xlsx, file_name)
## remove temp storage file after processing
File.delete(Rails.root + "public/spreadsheets/#{file_name}")
rescue Exception => e
Rails.logger.info "--error-----#{e.message}--"
end
end
end
class GenerateSpreadsheetService
def initialize(data = [], file_name)
@data = data
@file_name = file_name
end
def call
ActionController::Base.new().render_to_string(template: "csv_imports/template.xlsx.axlsx", layout: false, formats: [:axlsx], locals: {:data => @data})
end
end
class SendEmailJob < ApplicationJob
queue_as :default
def perform(xlsx, file_name)
SendEmailService.new(xlsx, file_name).call
end
end
class SendEmailService
def initialize(xlsx, file_name)
@xlsx = xlsx
@email = "test@example.com"
@subject = "excel file"
@file_name = file_name
end
def call
KeywordMailer.send_csv(@email, @subject, @xlsx, @file_name).deliver_now!
end
end
time = Time.zone.now.strftime("%Y%m%d%H%M%S")
xlsx = GenerateSpreadsheetService.new(all_data, file_name).call
path = Tempfile.new("data_#{time}.xlsx").path
file = File.open(path,"wb") {|f| f.write(xlsx) }
s3 = Aws::S3::Resource.new(region: APP_CONFIG["s3_region"], credentials: Aws::Credentials.new(APP_CONFIG["s3_access_key"], APP_CONFIG["s3_secret_key"]))
obj = s3.bucket(APP_CONFIG["s3_bucket"]).object("data_#{time}.xlsx")
obj.upload_file(path)
presigned_url = obj.presigned_url(:put, bucket: APP_CONFIG["s3_bucket"], key: "data_#{time}.xlsx", expires_in: 604800)
FileUrl.create(key: "data_#{time}.xlsx", file_public_url: obj.public_url, file_presigned_url: presigned_url) if presigned_url.present?