如何将一个文件中的所有PDF与wicked_pdf合并?

问题描述 投票:0回答:3

我现在正在工作的方式是我生成多个pdf文件并一次发送一个以供用户下载,但问题是有时他们最终会得到太多文件。

如何将所有pdf合并到一个文件中,然后再将它们发送给用户?

ruby-on-rails ruby pdf pdf-generation wicked-pdf
3个回答
1
投票

试试qazxsw poi。在我看来,它是用于编辑PDF文件的最佳库,并且有一些宝石包装它以便从Ruby访问。


0
投票

我用PDFtk

要合并PDF文件:

combine_pdf gem

您还可以从内存中解析PDF文件。从内存加载对于导入通过互联网或从不同的创作库(如Prawn)收到的PDF数据特别有效:

pdf = CombinePDF.new
pdf << CombinePDF.load("file1.pdf") # one way to combine, very fast.
pdf << CombinePDF.load("file2.pdf")
pdf.save "combined.pdf"

0
投票

如果你想使用像pdf_data = prawn_pdf_document.render # Import PDF data from Prawn pdf = CombinePDF.parse(pdf_data) PDFTk这样的工具,你需要做的就是通过使用类似的东西来预呈现你的个人PDF:

CombinePDF

要么

pdf1 = render_to_string(pdf: 'pdf1', template: 'pdf1')
pdf2 = render_to_string(pdf: 'pdf2', template: 'pdf2')

如果这些工具不将PDF作为字符串,您可能需要先将它们写入临时文件。

如果您不想引入另一个依赖项来合并内容,pdf1 = WickedPdf.new.pdf_from_string(some_html_string) pdf2 = WickedPdf.new.pdf_from_string(another_html_string) 可以获取多个pdf文件(或url),并使用与此类似的命令将它们全部呈现为一个pdf:

wkhtmltopdf

知道了这一点,你可以预渲染你的模板,包括布局和所有内容,输出到HTML字符串,然后将它们传递给wkhtmltopdf,如下所示:

wkhtmltopdf tmp/tempfile1.html tmp/tempfile2.html tmp/output.pdf

并在你的控制器中调用这样的东西:

# app/models/concerns/multipage_pdf_renderer.rb
require 'open3'
class MultipagePdfRenderer
  def self.combine(documents)
    outfile = WickedPdfTempfile.new('multipage_pdf_renderer.pdf')

    tempfiles = documents.each_with_index.map do |doc, index|
      file = WickedPdfTempfile.new("multipage_pdf_doc_#{index}.html")
      file.binmode
      file.write(doc)
      file.rewind
      file
    end

    filepaths = tempfiles.map{ |tf| tf.path.to_s }

    binary = WickedPdf.new.send(:find_wkhtmltopdf_binary_path)

    command = [binary, '-q']
    filepaths.each { |fp| command << fp }
    command << outfile.path.to_s
    err = Open3.popen3(*command) do |stdin, stdout, stderr|
      stderr.read
    end

    raise "Problem generating multipage pdf: #{err}" if err.present?
    return outfile.read
  ensure
    tempfiles.each(&:close!)
  end
end

但是,这仅涵盖最简单的情况,如果需要,您必须完成呈现页眉和页脚的工作,解析(或添加)您可能需要的任何选项。

这个解决方案最初来自def fancy_report respond_to do |format| format.pdf do doc1 = render_to_string(template: 'pages/_page1') doc2 = render_to_string(template: 'pages/_page2') pdf_file = MultipagePdfRenderer.combine([doc1, doc2]) send_data pdf_file, type: 'application/pdf', disposition: 'inline' end end end ,所以在那里查看有关此策略的更多详细信息可能会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.