Haseeb Ahmad
Haseeb Ahmad

Reputation: 8730

How to upload generate pdf file in controller to S3 bucket

I am using wicked_pdf to generate pdf file and want to upload it on s3 bucket because heroku not save in public. But facing issues how to upload there or how to give s3 bucket path in save path.

Here is my controller code:-

pdf = render_to_string :pdf => "user_detail"

# then save to a file
save_path = Rails.root.join('pdfs','filename.pdf')
File.open(save_path, 'wb') do |file|
  file << pdf
end

Upvotes: 2

Views: 3352

Answers (3)

Rohit
Rohit

Reputation: 677

This S3 gem can get you perform this pdf upload. Bucket Name, Access Key ID, Access Key Secret need to be passed.

filename = "invoice.pdf"
# render your pdf file
pdf = render_to_string(:pdf => filename, template: "invoice.html.erb")
# S3 upload Code goes here
service = S3::Service.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
bucket = service.buckets.find(ENV['S3_BUCKET_NAME'])
file = bucket.objects.build("invoices/#{filename}")
file.content = pdf
file.content_type = "application/pdf"
file.acl = :public_read
file.save
# Done, use the URL below as needed
s3url = "http://#{ENV['S3_BUCKET_NAME']}.s3.amazonaws.com/invoices/#{filename}"

Upvotes: 1

Martin
Martin

Reputation: 4222

In addition to Anurag Aryan answer you can use Aws::S3::Object#put. This is useful if the object is a string or an IO object that is not a file on disk:

filename = 'filename.pdf'
pdf = render_to_string :pdf => "user_detail"
s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
obj = s3.bucket('your-s3-bucket-name').object(filename)

# upload pdf data as a string
obj.put(body: pdf)

# or as an IO object
save_path = Rails.root.join('pdfs', filename)
File.open(save_path, 'wb') do |file|
  file << pdf
  obj.put(body: file)
end

Here is an example of file uploading on docs.aws.amazon.com

Upvotes: 3

Anurag Aryan
Anurag Aryan

Reputation: 651

You can use aws-sdk gem.

The gem looks for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION in your environment file so you need to add these. You can create a S3 resource for the region where your bucket exists and create an object with a unique file name and call upload_file as shown below.

require 'aws-sdk'

file_name = 'your-file.pdf'

s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
obj = s3.bucket('your-s3-bucket-name').object(file_name)
puts "Uploading file #{file_name}"
obj.upload_file("/Users/username/path/to/#{file_name}")
puts "Done"

Upvotes: 2

Related Questions