rails: produce pdf and render it as image - ruby-on-rails

I'm trying to produce a pdf and send it as a file, or, better, render it as an image in the browser, using imagemagick and wicked_pdf.
I'm able to send something, but it's not recognized as an image by the OS.
The pdf string is generated correctly, so I suppose the problem is in the image part
this is the code of my controller:
format.jpg do
#format = :pdf
pdfstr = render_to_string 'generated_graphics/tag.erb', :pdf => "tag", :layout => nil, :page_height => '38mm', :page_width => '129mm'
file = Tempfile.new('foo')
file.write pdfstr
file.close
require 'RMagick'
pdf = Magick::ImageList.new(file.path)
send_data pdf.write("myimage.jpg"), :type => 'image/jpg'
end

Take a look at imagemagick and rmagick plugin for ruby. This allows you to do all kinds of image conversions, including PDF to jpeg.
http://rmagick.rubyforge.org/
EDIT:
untested sample code:
require 'RMagick'
pdf = Magick::ImageList.new("doc.pdf")
pdf.write("myimage.jpg")
if doc.pdf has 3 pages, this should output 3 images: myimage.jpg.0 myimage.jpg.1 myimage.jpg.2
take a look at the end of the documentation on this page, which shows
a similar example with a multi-frame gif converted to multiple PNGs

If your goal is to have an image I think you can skip the pdf stuff alltoghether, there's no sense of converting it first to pdf and then to image.
Have a look at IMGKit, it allows to generate an image from an html string.

Related

Invalid/damaged download using send_data with PowerPoint

I am generating a PowerPoint using the powerpoint gem and up until now I was using send_file, but now I want to use send_data. The reason for this is that send_data blocks the application from doing anything else until the call completes, while send_file allows the app to continue executing while the file downloads, which sometimes, due to coincidental timing, leads to the file being deleted before the user tells their browser to start the download and the web server finishes sending the file and thus a blank or incomplete file is downloaded.
This is how I create my PowerPoint:
#Creating the PowerPoint
#deck = Powerpoint::Presentation.new
# Creating an introduction slide:
title = 'PowerPoint'
subtitle = "created by #{username}"
#deck.add_intro title, subtitle
blah blah logic to generate slides
# Saving the pptx file.
pptname = "#{username}_powerpoint.pptx"
#deck.save(Rails.root.join('tmp',pptname))
Now, on to what I have tried. My first instinct was to call as follows:
File.open(Rails.root.join('tmp',"#{pptname}"), 'r') do |f|
send_data f.read, :filename => filename, :type => "application/vnd.ms-powerpoint", :disposition => "attachment"
end
I've also tried sending the #deck directly:
send_data #deck, :filename => pptname, :disposition => "attachment", :type => "application/vnd.ms-powerpoint"
Reading it ends with a larger file than expected and it isn't even able to be opened and sending the #deck results in a PowerPoint with one slide that simply has the title: #Powerpoint::Presentation:0x64f0dd0 (aka the powerpoint object).
Not sure how to get the object or file into binary format that send_data is looking for.
You need to open the file as binary:
path = #deck.save(Rails.root.join('tmp',pptname))
File.open(path, 'r', binmode: true) do |f|
send_data f.read, filename: filename,
type: "application/vnd.ms-powerpoint",
disposition: "attachment"
end
This can also be done by calling the #binmode method on instances of the file class.
send_data #deck, ...
Will not work since it calls to_s on the object. Since Powerpoint::Presentation does not implement a #to_s method you're getting the default Object#to_s.

How to embed an image from Active Storage in Prawn PDF?

I am trying to embed an image from Rails' Active Storage into a Prawn PDF.
This is what I've got in my Prawn PDF class:
path = #view.rails_blob_url(#logo, :host => "localhost:3000", :protocol => "http", :locale => nil)
image(path, :vposition => :center)
When I try to open the PDF, I get this error:
ArgumentError in InvoicesController#show
http://localhost:3000/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBGdz09IiwiZXhwIjxudWxsHCJwdXIiOiJibG9iX2lkIn19--06167c36c283f6d5de63ae306b721310af11f70e/Test-Logo.png
not found
When I copy that exact same URL into my browser, the image shows up as expected. 5 minutes later it expires (?).
What am I missing here?
How can I show the image in my PDF?
Why can the image be rendered in the browser but not in my PDF?
I've spent all day trying to get this to work today, but to no avail.
This is what worked for me:
def initialize_globals
logo_from_object = #organization.logo
#logo = StringIO.open(logo_from_object.download)
..
..
..
end
def print_header
image #logo, scale: 0.10
end
Give this a shot:
image ActiveStorage::Blob.service.send(:path_for, #company.logo_image.key), at: [X, Y], width: DESIRED_WIDTH
Where logo_image is the actual ActiveStorage::Attached::One object.
E.g
class Company
has_one_attached :logo_image
end
Also, I believe as of now, only 2 types are supported: png and jpg.

Opening pdf data as image in rails views

I have used Rails 4,
views
<div>
<%=image_tag(some_method_path), class: 'image-view' %>
</div>
controller method
def some_method
#label_image = Base64_incoded image hex
send_data #label_image, :type => 'application/pdf', :disposition => 'inline'
end
The image is not opening in view but it is opening as pdf if we run the url in window.
How to display the pdf as image in the div ?
Any help appreciated
As far as I understood, what you are trying to do is to render a preview into an image tag of a PDF document. However, this is not an automatic task, and your browser won't magically perform the conversion for you.
You need a library to render the PDF and capture a preview. This is not a Rails problem, it's a generic PDF conversion problem.
Note. This question is very similar to How to have pdf viewer in ruby

When using redirect_to files on s3. How to either display an image or download a file

In Rails 3 AttachmentsController, I have the following:
def show
attachment = Attachment.find_by_id(params[:id])
redirect_to(attachment.authenticated_url())
end
Where authenticated_url is simply a URL to S3 to access the file.
The problem is that the file is always downloaded by the browser. What I would like to have happen is if the file is an image/pdf, something the browser can render, show the file in the browser and only download non-browser friendly files.
Have you seen this before? Any ideas on where to start?
Thanks
send_file can be used for remote url as well
file = open("http://cdn2.example.com/somefile.pdf")
send_file(file, :filename => "example.pdf", :type => "application/pdf" , :disposition => "attachment")
Here example.pdf will be downloaded. If you want open pdf in browser itself use this
file = open("http://cdn2.example.com/somefile.pdf")
send_file(file, :filename => "example.pdf", :type => "application/pdf" , :disposition => "inline")
redirect_to #attachment.url
I'm using Paperclip as well, and this display pictures inside the browser. Do you have to do something different than this?
I think you'll want to look into the rails send_file method.
1) http://apidock.com/rails/ActionController/DataStreaming/send_file
The :disposition option lets you decide whether a file will be downloaded or displayed inline. I used this in my rails app to let users download mp3 files.
Hope this helps.

Saving XML files with Rails

im working on a Rails project that should create XMl files, or to be more specific
use existing XMl templates and put content from the database in it.
So i dont need to create the xml structure, basically just rendering a template with content.
What would be the smartest way to do that?
So far i have a file.xml.erb in my layout folder
and i have a custom route "/renderXML" that does
def renderXML
#reading_question = ReadingQuestion.find(params[:id])
render :file => 'layouts/question.xml'
end
This works, but i also want to save the file, not only show it (actually viewing it is not really needed).
For saving i found this
File.open('fixed.xml','w'){|f| f.write builder.to_xml}
How do i access the rendered file and save it with some method like above?
Perhaps something like:
s = render_to_string :file => 'layouts/question.xml'
File.open('fixed.xml','w'){|f| f.write s}
render :text => s
Another approach :
send_data fixed, :type => 'text/xml; charset=UTF-8;', :disposition =>
"attachment; filename=fixed.xml"

Resources