How to convert Base64 string to pdf file using prawn gem
Asked Answered
B

1

9

I want to generate pdf file from DB record. Encode it to Base64 string and store it to DB. Which works fine. Now I want reverse action, How can I decode Base64 string and generate pdf file again?

here is what I tried so far.

def data_pdf_base64
  begin
    # Create Prawn Object
    my_pdf = Prawn::Document.new
    # write text to pdf
    my_pdf.text("Hello Gagan, How are you?")
    # Save at tmp folder as pdf file
    my_pdf.render_file("#{Rails.root}/tmp/pdf/gagan.pdf")
    # Read pdf file and encode to Base64
    encoded_string = Base64.encode64(File.open("#{Rails.root}/tmp/pdf/gagan.pdf"){|i| i.read})
    # Delete generated pdf file from tmp folder
    File.delete("#{Rails.root}/tmp/pdf/gagan.pdf") if File.exist?("#{Rails.root}/tmp/pdf/gagan.pdf")
    # Now converting Base64 to pdf again
    pdf = Prawn::Document.new
    # I have used ttf font because it was giving me below error
    # Your document includes text that's not compatible with the Windows-1252 character set. If you need full UTF-8 support, use TTF fonts instead of PDF's built-in fonts.
    pdf.font Rails.root.join("app/assets/fonts/fontawesome-webfont.ttf")
    pdf.text Base64.decode64 encoded_string
    pdf.render_file("#{Rails.root}/tmp/pdf/gagan2.pdf")
  rescue => e
    return render :text => "Error: #{e}"
  end
end

Now I am getting below error:

Encoding ASCII-8BIT can not be transparently converted to UTF-8. Please ensure the encoding of the string you are attempting to use is set correctly

I have tried How to convert base64 string to PNG using Prawn without saving on server in Rails but it gives me error:

"\xFF" from ASCII-8BIT to UTF-8

Can anyone point me what I am missing?

Buerger answered 13/9, 2017 at 11:50 Comment(14)
@Med : ok let me try will update you soonBuerger
@Med : getting this error : invalid byte sequence in UTF-8Buerger
Your question is unclear. First you say that you store a PDF file in the DB. Then you ask how you can generate a PDF file from the data in the DB. But you just said that the data is a PDF file! So, which is it?Ambert
@JörgWMittag : I am generating pdf file, convert it to Base64 encoded string, store encoded string to DB, now from DB (Base64 encoded string) I want to generate pdf file again, I hope now it's clearBuerger
But you already have generated the PDF file! Why do you want to generate it again, when you can just retrieve it from the database?Ambert
@JörgWMittag : yes I have generated pdf file and can send it to user, but for security reason I can not store pdf file to db, instead i store encoded string, now in some method I need to generate pdf file from stored encoded stringBuerger
But why do you have to re-generate the PDF? Why don't you just get the PDF file that you stored in the database?Ambert
forget about generated pdf, it is generated to convert in Base64, once i get encoded string, it will be deleted, my problem is "How can I convert Base64 encoded string to pdf ?"Buerger
@JörgWMittag: here is encoded string codepaste.net/8hyb1r now if I paste this to base64decode.org it generate pdf file, but I am not aware how can I generate this in Ruby using prawn gemBuerger
I still don't understand what this has to do with Prawn. Prawn is for generating PDFs. You already have a PDF. Why do you need Prawn? Why do you need to generate a PDF, when you already have a PDF in your DB?Ambert
@JörgWMittag : I have pdf in db as encoded string. now I want to decode it and get back as original pdf fileBuerger
Yes, then you decode it, but why do you want to generate it, and what do you need Prawn for?Ambert
Let us continue this discussion in chat.Buerger
@JörgWMittag : I got the solution bro.Buerger
A
12

The answer is to decode the Base64 encoded string and either send it directly or save it directly to disk (naming it as a PDF file, but without using prawn).

The decoded string is a binary representation of the PDF file data, so there's no need to use Prawn or to re-calculate the content of the PDF data.

i.e.

 raw_pdf_str = Base64.decode64 encoded_string
 render :text, raw_pdf_str # <= this isn't the correct rendering pattern, but it's good enough as an example.

EDIT

To clarify some of the information given in the comments:

  1. It's possible to send the string as an attachment without saving it to disk, either using render text: raw_pdf_str or the #send_data method (these are 4.x API versions, I don't remember the 5.x API style).

  2. It's possible to encode the string (from the Prawn object) without saving the rendered PDF data to a file (save it to a String object instead). i.e.:

    encoded_string = Base64.encode64(my_pdf.render)
    
  3. The String data could be used directly as an email attachment, similarly to the pattern provided here only using the String directly instead of reading any data from a file. i.e.:

    # inside a method in the Mailer class
    attachments['my_pdf.pdf'] = { :mime_type => 'application/pdf',
                                  :content => raw_pdf_str } 
    
Ambary answered 21/9, 2017 at 13:0 Comment(8)
thank you for the answer, can I send as attachment without saving as physical file in my system?Buerger
@GaganGami - Yap, you can send the string as an attachment without saving it to disk. I don't remember the "Rails way" off the cuff. You can also render the Prawn data to a string (before encoding it) instead of rendering it to a file (use #render instead of #render_file). No need for temporary files.Ambary
render worked fine, I have converted encoded string to physical pdf file, but I don't want to save that file anywhere, instead want some file object which I can attached to the mail without saving to the disk as temporary fileBuerger
@GaganGami , I'm not sure I understand your requirements... the String object is (as far as email attachments are concerned) an object you can attach to the email (as if it were a PDF file) without saving anything to the disk.Ambary
no worry bro, thanks for your help regarding, render it helps me, I have attached file without saving as physical, reference #5146370Buerger
will post my full answer so it can help in future to anyone elseBuerger
@GaganGami - I added more information to my answer, I hope this helps.Ambary
Thanks for your kind help, really helps me a lotBuerger

© 2022 - 2024 — McMap. All rights reserved.