我曾经使用wicked_pdf
gem 为我的用户生成 PDF,并编写如下示例代码:
class ThingsController < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render pdf: "file_name" # Excluding ".pdf" extension.
end
end
end
end
然后我会在页面上有一个链接,这样<%= link_to report_pdf_path(@report), "Download PDF", target: "_blank" %>
会导致 PDF 在用户的浏览器中显示为新选项卡。这是我想要的首选行为,但它会暂停所有请求,直到为用户完成 PDF 并且其中一些需要相当长的时间才能生成。
因此,我已经将 PDF 的生成工作交给了 ActiveJob,效果很好,但我不知道如何让 ActiveJob 在新窗口中打开文件。目前,我将其写入服务器,然后更新显示用户请求的文件的部分内容。下面是一个例子。
class GeneratePdfJob < ApplicationJob
queue_as :default
def perform(*args)
params = args.first
generate_pdf_document(params)
end
def generate_pdf_document(params)
html = ApplicationController.new.render_to_string(
template: 'players/board_labels.pdf.erb',
locals: { player_ids: params[:player_ids] }
)
save_to_pdf(html, params[:pdf_title], params[:user_code])
end
def save_to_pdf(html, pdf_title, user_code)
pdf = WickedPdf.new.pdf_from_string(
html,
pdf: "#{pdf_title}",
layout: 'print',
encoding: 'utf-8'
)
pdf_name = "#{pdf_title}.pdf"
pdf_dir = Rails.root.join('public','uploads','reports',"#{user_code}")
pdf_path = Rails.root.join(pdf_dir,pdf_name)
# create the folder if it doesn't exist
FileUtils.mkdir_p(pdf_dir) unless File.directory?(pdf_dir)
# create a new file
File.open(pdf_path,'wb') do |file|
file.binmode
file << pdf.force_encoding("UTF-8")
end
end
end
那么如何创建一个方法来替换该save_to_pdf
方法,而是在新选项卡中为用户打开文件?如果这是不可能的,我可以在启动作为占位符选项卡的 ActiveJob 时打开一个选项卡,然后合并 ActionCable 以在为用户生成文件后以某种方式显示文件吗?