使用特定路径

时间:2015-07-21 10:20:59

标签: ruby-on-rails

我想保存我创建的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') %>

我该怎么做?

1 个答案:

答案 0 :(得分:3)

rendersend_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

获取的docx渲染器代码
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