Image not rendered in prawn pdf using AngularJs
Asked Answered
K

1

8

I have a ReportPdf inherited from Prawn::Document.
When I test it from Rails console, The embedded png image in pdf rendered correctly.

ReportPdf.new(param1,param2).render_file('/Users/ZZ/Desktop/test.pdf')

However, when it is requested from controller:

def generate_pdf
  pdf = ReportPdf.new(param1, param2)
  send_data pdf.render, filename: 'report.pdf', type: 'application/pdf'
end

the image was not rendered, other contents rendered without any problems.

I've tried using local image and image from Amazon S3. Both works fine in console but not from controller.

The generate_pdf method in controller also gives a correct pdf. The PDF was correctly rendered if I request it directly. I tested it with Postman.

However, the image in PDF was not rendered only when it is requested from an export button in Angular. The following are implementations:

Backend:

class ReportPdf < Prawn::Document
  def initialize(param1, param2)
    super()
    @param1 = param1
    @date = Time.zone.parse(param2) || Time.zone.now
    header
  end

  def header
    img = open('https://s3-ap-southeast2.amazonaws.com/bucket/folder/logo.png')
    # use local image
    # img = "#{Rails.root}/app/assets/images/logo.png"
    data = [[{ image: img, image_width: 150, vposition: :center },
           "#{@param1.name} - #{@param2.suburb}"]]
    table(data, cell_style: { borders: {}, 
                            valign: :center, align: :right, size: 25, width:
                          270 })
  end
end

Frontend:

  $scope.exportToPdf = function() {
    var tmpDate = moment(new Date($scope.date)).format('DD-MM-YYYY');
    $http({
      method: 'GET',
      url: '/resourceA/' + $stateParams.resourceAId + '/resourceB/daily_pdf?day=' + tmpDate
    }).
    success(function(data, status, headers, config) {
      var anchor = angular.element('<a/>');
      anchor.attr({
        href: 'data:application/pdf;charset=utf-8,' + encodeURI(data),
        target: '_blank',
        download: 'daily_report.pdf'
      })[0].click();
    }).
    error(function(data, status, headers, config) {
      // something here.
    });
  };

I guess the problem is encoding, image binary data was corrupted during encoding. Where is the mistake?

Knightly answered 24/8, 2015 at 3:3 Comment(5)
Where is your view template? i.e report.pdf.erbUnmeet
I'm using similar method introduced here (idyllic-software.com/blog/…). I'm not converting html to pdf, there is no view template.Knightly
1. you're passing either the image raw data or the path, depending if it's local or remote - that seems off; also... 2. try printing out the img object's data or class to review the returned value from open(img_url)... I'm wondering if that line isn't where something goes sideways...Uncork
@ZhongZheng did you ever find a solution for this?Kazak
@Kazak Unfortunately, I did not get an solution, so I left this question open.Knightly
D
0

Hard to tell where the mistake is when we can't see the code that is trying to add the image to the PDF. How is ReportPdf accessing the image?

Maybe there's a hint in here for your situation. In my code, when generating a pdf for a gallery, the gallery creates the pdf, and has each of its photos add themselves to the pdf with a call like:

photo = Photo.find(photo_id)
photo.add_to_pdf(pdf, h_pos, v_pos, h_size, v_size)

The photo class method uses (layout calcs removed):

def add_to_pdf(pdf, h_pos, v_pos, h_size, v_size)
  pdf.image self.image.path(:full),
            :position => pos_sym,
            :vposition => vpos_sym,
            :fit => [size,vsize]
end

Prawn for pdf generation, paperclip for image attachments (photo has_attached_file :image)

Denationalize answered 24/8, 2015 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.