Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Base64 string to pdf file using prawn gem

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?

like image 682
Gagan Gami Avatar asked Sep 13 '17 11:09

Gagan Gami


People also ask

How do I decrypt a Base64 string?

To decode with base64 you need to use the --decode flag. With encoded string, you can pipe an echo command into base64 as you did to encode it. Using the example encoding shown above, let's decode it back into its original form. Provided your encoding was not corrupted the output should be your original string.

How do I get files from Base64?

How to convert Base64 to file. Paste your string in the “Base64” field. Press the “Decode Base64 to File” button. Click on the filename link to download the file.


1 Answers

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 } 
    
like image 129
Myst Avatar answered Oct 08 '22 18:10

Myst