我想保存我创建的docx。我使用了宝石htmltoword
。
渲染是我认为的宝石中的一个功能。
在我的控制器中(但不起作用):
respond_to do |format|
format.html
format.docx do
@filepath = "#{Rails.root}/app/template/#{@cvmodif.nom}.docx"
render docx: 'show', filename: 'show.docx'
send_file(@filepath, :type => 'application/docx', :disposition => 'attachment')
end
end
我有一个链接。当我点击它时,docx下载corexly。但我想在自定义路径中保存它。
<%= link_to 'WORD', cv_path(@cvmodif, :format => 'docx') %>
我该怎么做?
答案 0 :(得分:3)
render
和send_file
都做同样的事情:生成文档并将其作为附件发送。
如果要保存文档,则必须在发送之前手动执行:
respond_to do |format|
format.docx do
# Generate the document
my_html = '<html><head></head><body><p>Hello</p></body></html>'
file_path = "test-#{Time.now.sec}.docx"
document = Htmltoword::Document.create(my_html)
# Save it in the custom file
File.open(file_path, "wb") do |out|
out << document
end
# Send the custom file
send_file(file_path, :type => 'application/docx', :disposition => 'attachment')
end
end
P.S。根据版本0.4.4中的Htmltodoc源代码,有一个函数create_and_save
,但在当前分布的gem中,此函数缺失。如果您的应用程序经常使用此方案,我建议您为此目的创建一个通用方法。
<强>更新强>
然后没有直接的解决方案,因为在这种情况下,发送文件是渲染过程的一部分,这是页面加载的最后一步,并在Htmltoword
内深入运行。
最正确的解决方案是使其成为Htmltoword的功能。 (创建功能请求,甚至自己实现)。
但目前您可以从库中获取* .docx文件的渲染器并添加最少的更改以实现您的目标。
创建文件RailsApp/config/initializers/application_controller.rb
。
添加从github
ActionController::Renderers.add :docx do |filename, options|
formats[0] = :docx unless formats.include?(:docx) || Rails.version < '3.2'
# This is ugly and should be solved with regular file utils
if options[:template] == action_name
if filename =~ %r{^([^\/]+)/(.+)$}
options[:prefixes] ||= []
options[:prefixes].unshift $1
options[:template] = $2
else
options[:template] = filename
end
end
# disposition / filename
disposition = options.delete(:disposition) || 'attachment'
if file_name = options.delete(:filename)
file_name += '.docx' unless file_name =~ /\.docx$/
else
file_name = "#{filename.gsub(/^.*\//, '')}.docx"
end
# other properties
save_to = options.delete(:save_to)
word_template = options.delete(:word_template) || nil
extras = options.delete(:extras) || false
# content will come from property content unless not specified
# then it will look for a template.
content = options.delete(:content) || render_to_string(options)
document = Htmltoword::Document.create(content, word_template, extras)
File.open(save_to, "wb") { |out| out << document } if save_to
send_data document, filename: file_name, type: Mime::DOCX, disposition: disposition
end
如果您将此文件与源文件进行比较,您会发现我添加了save_to
选项,并且在设置此选项后,渲染器会将文档保存到给定位置。
控制器中的用法:
format.docx do
render docx: 'my_view', filename: 'my_file.docx', save_to: "test-#{Time.now.sec}.docx"
end