2015-09-07 31 views
0

我有一個場景,我需要生成基於對象數組的多頁pdf。wicked_pdf多頁文件

以下是我的模型:

# Member has_many certificates 

class Member < ActiveRecord::Base 

    has_many :certificates, dependent: :destroy 

    before_save :set_expiry 

    def self.delete_expired 
    where(expire_at: Date.today).destroy_all 
    end 

    private 
    def set_expiry 
     self.expire_at = 15.days.from_now 
    end 
end 

# certificate belongs_to member 
class Certificate < ActiveRecord::Base 
    belongs_to :member 
    belongs_to :certificate_type 
    belongs_to :company 

    def company_name 
    company.name 
    end 

    def page_orientation 
    company_name == 'CompanyA' ? 'Landscape' : 'Portrait' 
    end 

    def page_height 
    company_name == 'CompanyA' ? '10.5in' : '11in' 
    end 

    def page_width 
    company_name == 'CompanyA' ? '7in' : '8.5in' 
    end 
end 

# each type can have many certificates 
class CertificateType < ActiveRecord::Base 
    has_many :certificates 
end 

用戶流量是類似以下內容:

  • 用戶上傳的Excel與會員的記錄文件。系統存儲記錄。
  • 用戶可以爲單個成員生成證書。 (已經在工作)。
  • 用戶可以爲所有上傳的成員批量生成證書。

我有一個自定義表單,我在創建證書對象(複選框選擇),然後提交表單。控制器接收證書對象的散列。我必須逐個遍歷所有對象來爲其關聯成員創建證書。問題是每個證書都有自己的模板和一些自定義頁面佈局設置,如方向,寬度和高度。我想生成一個包含多個頁面的單個PDF文件,其中每個頁面都是一個證書。我被困在哪裏以及如何通過每個單獨證書的頁面佈局設置。我在我的控制器中嘗試了render_to_string,並嘗試在那裏設置頁面佈局選項,但它似乎不起作用。我需要一些建議或指針。

+0

使用外部工具,如'poppler的-utils'一個選項(即你控制服務器)?如果它在Heroku上或其他什麼,它可能不是。如果是這樣,我可以給你一些關於如何在你的場景中使用它的細節。 – fdisk

+0

@fdisk它不是Heroku。我正在使用數字海洋,我想這應該工作。 –

回答

0

由於這是一個選項,我會建議通過您的發行包管理器(yum,apt-get,dnf等)安裝poppler-utils。在此之後,每個證書保存爲Tempfile

require 'shellwords' 

certificates = @member.certificates.map do |certificate| 
    Tempfile.open(["cert", ".pdf"]) { |file| file << WickedPdf.new.pdf_from_string(render_to_string(something, layout: some_layout)) } 
end 

paths = certificates.map { |cert| cert.path.shellescape } 

@final_pdf = Tempfile.new(["cert", ".pdf"]) 
@final_pdf.close 
%x[pdfunite #{paths} #{@final_pdf.path.shellescape}] 

@final_pdf對象應包含合併後的個人證書。我也做了一個簡單的gem來處理這些情況,但它可能有一點額外的開銷,你不想找(它旨在創建嵌套書籤的PDF文件)。

+0

您可以使用[CombinePDF](https://github.com/boazsegev/combine_pdf)等原生Ruby解決方案來做同樣的事情。 – Myst

3

大廈@fdisk的答案,但是使用Ruby的本地combine_pdf gem ......你可以嘗試:

require 'combine_pdf' 

merged_certificates = CombinePDF.new 

@member.certificates.each do |certificate| 
    pdf_data = WickedPdf.new.pdf_from_string(render_to_string(something, layout: some_layout)) 
    merged_certificates << CombinePDF.parse(pdf_data) 
end 

send_data merged_certificates.to_pdf, filename: 'mypdf.pdf' #... 
+1

'merged_certificates << CombinePDF.new.parse(pdf_data)'應該是merged_certificates << CombinePDF.parse(pdf_data)'。你的回答幫了我很多,順便說一句!謝謝! –

+0

@NelsonSenna,感謝您的支持:)並且我很高興這會有所幫助。 – Myst