Ruby on Rails-压缩和下载pdf文件

时间:2018-09-17 14:43:19

标签: ruby-on-rails ruby pdf download zip

正在执行将同一report_id的两个pdf报告版本压缩的任务。

我需要将2个pdf版本放在.zip文件上并下载,我将2个pdf生成到tmp目录中,然后将zip创建到tmp文件夹中,并下载到相同的文件夹中并下载目录我的电脑。

当再次下载同一报告时,如果存在,我需要删除/ tmp文件夹中的旧.zip文件。

此处是report_controller.rb:

require 'date'
class Web::ReportsController < Web::ApplicationController
  load_and_authorize_resource

  def generate_pdf
    report = Report.find( params[ :id ] ).decorate
    pdf_info = {
      Author:       current_user.decorate.full_name,
      Subject:      report.pdf_filename,
      Creator:      "Altagem Solution",
      CreationDate: Time.current
    }

    if version = params[ :version ]
      pdf_info[ :Title ] =  "#{I18n.t "report.version.internal" }"
    else
      pdf_info[ :Title ] =  "#{I18n.t "report.version.customer" }"
    end

    pdf    = ReportPdf.new current_company, report, [], version , pdf_info


    send_data pdf.generate, filename: report.pdf_filename,
                                type: "application/pdf",
                         disposition: 'inline'
  end

  def zip_it
    report = Report.find( params[ :id ] ).decorate

    report_date      = report.created_at.strftime("%y-%m-%d")
    contract_name    = report.activities()[0].contract.name
    report_reference = report.reference

    pdf_name         = contract_name + "_" + report_date + "_" + report_reference.to_s

    public_pdf    = ReportPdf.new current_company, report, []
    public_pdf.generate_pdf( report, pdf_name )

    internal_pdf    = ReportPdf.new current_company, report, [], "internal"
    internal_pdf.generate_pdf( report, pdf_name + "_internal"  )

    zip_pdf( "#{Rails.root}/tmp/pdf/reports/#{report.reference}" )

    send_file( "#{Rails.root}/tmp/pdf/reports/#{report.reference}.zip"  )

  end

  def zip_pdf( path )
    archive = File.join( File.dirname(path), File.basename(path) )+'.zip'
    Zip::ZipFile.open( archive, 'w' ) do |zipfile|
      Dir["#{path}/**/**"].reject{ |f|f==archive }.each do |file|
        zipfile.add( file.sub( path +'/','' ),file)
      end
    end
  end

end

report_pdf.rb:

require 'fileutils'
require 'open-uri'
require 'prawn'
require 'prawn/table'

class ReportPdf < PdfBuilder
  def initialize( company, report, recipients, version = '', pdf_info = nil )
    phone = company.current_phones.where(label: "work")[0].try :value
    fax   = company.current_phones.where(label: "fax")[0].try  :value
    email = company.current_emails.where(label: "company")[0].try :value

    @version = version
    @company = OpenStruct.new(
      name:      company.name.mb_chars.upcase,
      logopath:  company.logo.url_or_path,
      address:   company.address.try( :entered_by_user ),
      phone:     phone,
      fax:       fax,
      email:     email,
      display_default_avatar: company.display_default_avatar
    )

    @declarant    = format_technician( report.declarant )
    @team_members = report.teammates.map { |teammate| format_technician( teammate ) }

    @report = OpenStruct.new(
      reference:  report.reference,
      date:       report.date,
      type:       report.activity_type,
      site:                 report.site,
      address:              report.intervention_address,
      sheets:               report.sheets,
      fragment_color:       company.report_fragment_color[1..6], # Select 6 first number of hexadecimal color
      activities:           report.activities,
      intervention_type?:   report.intervention_type?
    )


    @pdf = Prawn::Document.new( info: pdf_info )
  end

  def draw()
    ReportPdf::RegisterFont.new( @pdf )

    ReportPdf::Header.new(  @pdf, @company ).draw
    ReportPdf::Content.new( @pdf, @report, @declarant, @team_members, @version, @company ).draw
    ReportPdf::Footer.new(  @pdf ).draw
  end

  def generate
    draw
    @pdf.render
  end

  def generate_file(filename)
    draw
    FileUtils.mkdir_p 'tmp/pdf'
    @pdf.render_file "#{ Rails.root }/tmp/pdf/#{ filename }"
  end

  def generate_pdf(report, version)
    draw
    path = "tmp/pdf/reports/#{report.reference}"
    pdf_filename = report.decorate.attachment_pdf_filename
    # Remove old directory

    FileUtils.mkdir_p( path )  # Create a new directory
    @pdf.render_file "#{ Rails.root }/#{path}/#{ version }"
  end


  def format_technician(technician)
    default_avatar = Rails.root + 'app/assets/images/default_avatar.png'
    OpenStruct.new(
      name:   technician.decorate.format_name,
      avatar: technician.avatar.try( :url_or_path ) || default_avatar
    )
  end
end

1 个答案:

答案 0 :(得分:1)

您可以执行此操作以删除文件(如果存在)

File.delete(path_to_file) if File.exist?(path_to_file)

或使用FileUtils

FileUtils.rm('path_to_file')

File.deleteFileUtils.rm之间的区别在于,File.delete将以文件名作为参数并返回删除的文件数也将引发错误,并且{{1 }}会列出文件名,并且不会引发异常。