Repeat HTML in every page generated with Wicked PDF and Rails - ruby-on-rails

I'm generating PDF with the Wicked PDF gem on Ruby on Rails, but have to repeat some HTML content on every page.
What I'm trying is to use just part of the page to my main content, and use HTML to add stuff around it, in every page.
Something like this image (Check)
I tried playing with header, but I wasn't able to put the content in front of the HTML (even using z-index), and was only able to position the main content with margin and spacing vertically (didn't find any options to do it horizontally).
Any ideas? Thanks!

Since no one answered, I will post my solution here. It is not beautiful nor brilliant, it is so so so far from these - but since no one answered, maybe we can start a discussion from it.
I was able to generate a PDF with only the text (but with the correct margins), with no background, using Wicked PDF. Like this image. I used it to just save the file.
This was the code for it:
# Save PDF with only the text (with correct margins)
render :pdf => "text#{id}",
:margin => {:top => "1.6in", :left => "4.1in", :right => "1.2in", :bottom => "2.5in"},
:page_size => "Letter",
:template => "careers/job_pdf_text.pdf.erb",
:save_to_file => Rails.root.join('public/job_pdf_tempfiles', "text#{id}.pdf"),
:save_only => true,
:no_background => true
Then I used RMagick to create images from this saved PDF. The important here is that I saved GIFs with transparent background, and Magick creates one image for each page on the PDF. This was the code to save the images:
# Save images from the only-text PDF
#text_images = []
text_images_magick = Magick::Image.read(Rails.root.join('public/job_pdf_tempfiles', "text#{id}.pdf"))
text_images_magick.each_with_index do |image, index|
file_name = Rails.root.join('app/assets/images/careers_pdf', "text#{id}-#{index}.gif")
image.write(file_name)
#text_images << file_name
end
Ok, so at this moment I have images of the text, like this. Now what I did was put those in an HTML page, in the correct place and then used Wicked PDF again to render the final PDF. I rendered the PDF with margin 0, and for each #text_images I created a container, from which I positioned everything else (including the image itself) to achieve what I wanted in the beggining.
Does anyone have a better idea to share?

Related

render dynamic HTML with wicked pdf

I have a DSL that renders HTML. If I manually generate HTML in the console, and save it as a view (as an experiment, there's no reason to do this), so that it lives in app/views/manifests as show.pdf.erb, and then I simply render the PDF using Wicked's/Rails built in rendering, everything works great and looks great. Now, because this is dynamic HTML, meaning it can change based on the data, what I have to do is generate the HTML as a string, and then use Wicked's pdf_from_string:
html = HtmlGenerator.parse_node node, "root", #manifest
pdf = WickedPdf.new.pdf_from_string(html) # note, this is the same HTML that looks great as a view
and then send it to the browser
send_data(pdf,
:filename => "my_pdf_name.pdf",
:disposition => 'inline')
Now, everything is screwed up. It appears like the fonts are 15% bigger, all of my rows are screwed up. Does the rendering routine in WickedPDF use a different formatting that pdf_from_string?
Thanks for any help,
Kevin

How to create fixed footer/header with PDFKit in rails?

I'm using https://github.com/pdfkit/pdfkit in rails to generate a PDF.
kit = PDFKit.new(html)
kit.stylesheets << 'app/assets/stylesheets/pdf.css'
kit.to_pdf
The PDF renders properly based on the HTML. I'm just curious how to introduce a fixed footer/header. For instance, if I like to add a page number fixed at the bottom of the page along with a logo on every single page.
Thanks in advance.
I just dug into the gem more and saw the :header_center option.
Looks like I'll be able to pass in value (probably a template as well) when creating the PDF like so.
kit = PDFKit.new(html, :header_center => "foo", :footer_center => "bar")

Repeater in Prawn PDF rendering contents twice

I have a pdf being generated by prawn, it contains a header, a table and a footer. Both header and footer are repeatable, with :dynamic => true, the table is not.
The problem I'm having is that all content on the header and footer is displaying as if it's being rendered twice in the same place, and this seems to mess with the anti aliasing function so the text appears to be choppy and bold (see image below). However, when I zoom in or print it, it looks right.
Here's some code of the specific part where I start the repeater blocks:
pdf = Prawn::Document.new :page_size => "A4", :margin => [28, 20, 7, 20]
(...)
pdf.repeat :all, :dynamic => true do
pdf.bounding_box([0, 803], :width => 555, :height => 60) do
pdf.stroke_bounds
(...)
end
end
(...)
pdf.render
# End of file
As far as I know, this is the default way to declare a repeater block, I almost mirrorred it from the manual.
Here's the image: the top container is the header, inside the repeater, it looks like everything is bold, but it's the exact same font and line width as the section below, which is from the table, and looks fine. Sorry I can't post a larger part of the pdf, it's for confidentiality reasons.
If I remove the repeater, the header will look correct, as it should, but when I add it again it looks like this.
Has anyone else encountered this issue before? How do I fix it?
EDIT: Added some more code above. Also added the code below, which is inside a Rails template file, "historico.pdf.prawn", and this is how I call it on the controller to render the PDF and return it to the user:
rendered_pdf = render_to_string :template => "reports/historico.pdf"
send_data rendered_pdf, :filename => "Historico.pdf", :type => "application/pdf"
When you use pdf.repeat :all the pdf is 'reopened' after the document is already created and the data within the repeat block is added. This can cause a myriad of odd behavior, I believe this is what is causing your issue.
There is a related issue with a solution that utilizes Prawn's canvas method. If you adapt this solution to your problem (use canvas to generate your header and footer, rather than repeat :all) , you should no longer have these text-on-top-of-text problems.
Note:
It may be important for you to know that Prawn has officially stated that they are, "not in a good position to support templating features (I bring this up because you appear to be creating a template), " so similar workarounds may be needed if you continue to use this tool for these types of needs. Depending on your dependance on these types of templating features, you may want to look into using a different tool.

Multiline graph in PDF file using ruby on rails

I want to give export option in my application that will export PDF file and it should consist multi-line graph. How can i do this in ruby on rails.
It depends on your situation, and what content you already have (if any) which you want to render your PDF based on. Some existing options are:
PDFKit, which can create PDFs based on your existing HTML documents
Prawn, which is a lightweight Ruby API for creating PDFs
Some options (like PDFKit above, and also Wicked PDF) will rely on an external tool like wkhtmltopdf to render existing HTML pages as PDFs, whereas other options (like Prawn) are more Ruby native, so it really depends on your situation which path your should take in your application.
As for the graph you mentioned, if you already have it being rendered as an image file, it might be easiest to use one of the HTML-to-PDF generation options, but if you're wanting to render the graph custom in the PDF context and don't already have it as a standalone image, something like Prawn may be best.
In my application, i am using Highcharts.
I have found great success in rendering charts to pdf using a combination of 2 gems:
wicked_pdf - https://github.com/mileszs/wicked_pdf
and
wkhtmltopdf-binary - https://github.com/zakird/wkhtmltopdf_binary_gem
The second is the binary dependency for wicked_pdf.
It can render your rails view in pdf format.
Edit:
I have used PDFkit as well, code is given below from my controller method:
Onclick of "Download PDF" button:
if params[:commit]=="Download PDF"
html = render_to_string(:layout => false , :action => "controller_name/pdf_chart_erb_file.html.erb")
kit = PDFKit.new(html)
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/application.css"
send_data(kit.to_pdf, :filename => "my_chart.pdf", :type => 'application/pdf', :disposition => 'inline')
file = kit.to_file("#{Rails.root}/app/exe.pdf")
end
You can use or render your graphs in pdf_chart_erb_file.html.erb, it simply converts all your html file to PDF file as per code given above.

Can prawn generate PDFs with links?

I need to embed a link into a generated pdf in a ruby on rails app. Is there a way to do this with prawn?
Reading about this it turns out that prawn-format was the answer for awhile, but 0.7.x broke this.
prawn-format uses the link_annotate(rect, options={}) function to create links. What options need to be passed into this to get it to create a link in the PDF?
edit:
I would like to see a code example of this being done if anyone has one.
I know this is an old question, but for those still stumbling upon it, in current versions of Prawn, you can use inline format like this:
pdf.text "Website: <link href='http://www.stackoverflow.com'>stackoverflow</link>", :inline_format => true
If you are attempting to create a link to an external page (http://google.com), for instance you could use the following, to place a link that is 100x100 and placed at 5, 5 from the bottom left of the page, with a 1px border:
pdf.link_annotation([100, 100, 5, 5], :Border => [0,0,1], :A => { :Type => :Action, :S => :URI, :URI => Prawn::LiteralString.new("http://google.com") } )
Prawn Format would parse the text passed to the pdf.text method and find html a tags. It would then use regular expressions to parse out the target and link text and finally create a link like the one above with a bounding box (the first param) that would fit around the text that was within the tags. I'm not sure how you could achieve this without Prawn Format. But that is how you can create a link using link_annotation.
As of Prawn 0.7, prawn-format is
completely unsupported, and will not
work with versions of Prawn 0.7+. Feel
free to fork and fix, of course
- prawn-format's homepage on github
The other option is to use prawn's built in low-level annotation support:
http://prawn.majesticseacreature.com/docs/prawn-core/classes/Prawn/Document/Annotations.html#M000158
Heres the method:
link_annotation(rect, options={})
A convenience method for creating Link
annotations. rect must be an array of
four numbers, describing the bounds of
the annotation. The options hash
should include either :Dest
(describing the target destination,
usually as a string that has been
recorded in the document‘s Dests
tree), or :A (describing an action to
perform on clicking the link), or :PA
(for describing a URL to link to).
I recently did it like this - works great:
formatted_text_box([{:text=>"Google", :link=>"https://google.com", :color=>"0000ee"}])

Resources