Permitir que administradores de sistemas de dados exportem dados para planilhas permite que eles os manipulem, tornem-nos bonitos, gerem relatórios e os repassem à sua própria maneira, sem que o desenvolvedor tenha que usar toda essa funcionalidade para o aplicativo. Pronto para usar Rails pode fazer dump em XML e JSON, mas isso não é tão amigável. O despejo em CSV está mais perto, mas é muito fácil ter problemas com o encerramento de campo e cotação de valor, além disso, você não tem chance de estilizar a saída. Um pouco pode ir longe.
Digite a gema axlsx . Ele permite que você crie planilhas em Rails de forma rápida e fácil, exportando para o formato .xlsx que pode ser lido pelo Excel, OpenOffice e Google Docs. Cobertura sólida. Quando você combina isso com a gema axlsx-rails, você pode gerar planilhas tão facilmente quanto gera HTML com um modelo ERB.
No momento em que este livro foi escrito, você deseja a versão 2.1.0.pre do axlsx, então adicione-o ao seu Gemfile
:
# Export data to spreadsheets
gem 'axlsx', '2.1.0.pre'
gem 'axlsx_rails'
Em seguida, crie um arquivo de visualização exatamente como faria para HTML. Aqui está um index.xlsx.axlsx
modelo de visualização genérico para descartar os atributos de um registro:
# app/views/base_controller/index.xlsx.axlsx
# Hook into the xlsx package provided by the axlsx-rails gem
wb = xlsx_package.workbook
# Create a style we can use for record headers
styles = xlsx_package.workbook.styles
header_style = styles.add_style bg_color: "00",
fg_color: "FF",
bold: true,
alignment: { horizontal: :center }
# Get a list of associations. We want to export the association value rather than ID
# e.x. Get Post#user rather than Post#user_id
assocs = resource_class.reflect_on_all_associations(:belongs_to).map{|a| [a.foreign_key.to_sym, a.name]}.to_h
# Create a worksheet. Name it after the resource we're exporting
wb.add_worksheet(name: @resource.model_name.plural.titleize) do |sheet|
# Get list of attributes to export
attrs = policy(@resources.first).permitted_export_attributes
# Add a header row using the header style we defined
sheet.add_row attrs.map { |n| @resources.first.class.human_attribute_name(n) }, style: header_style
# Add each row to our sheet
@resources.each do |row|
sheet.add_row attrs.map { |a| row.send(assocs[a] || a) }
end
end
Uma coisa digna de nota é a policy(@resource_value.first).permitted_export_attributes
linha. Isso nos permite definir um método nas políticas do Pundit que retorna uma lista de campos permitidos para exportação. Em application_policy.rb
um pode adicionar algo como:
# app/policies/application_policy.rb
def permitted_export_attributes
# don't export friendly_id slug, or legacy data mapping fields.
record.class.attribute_names.map(&:to_sym) - %i(slug legacy_id data_source)
end
Uma última coisa que eu achei útil foi para definir o Content-Disposition
que attachment
e definir meu próprio nome do arquivo de exportação. Isso dispara o download do arquivo (em vez de o usuário clicar com o botão direito do mouse, salvar como) e nos permite definir um nome de arquivo adequado.
# app/controllers/people_controller.rb
def index
respond_to do |format|
format.html
format.xlsx { set_attachment_name "sites #{Time.now.utc.strftime('%Y%M%d%H%M%S')}.xlsx" }
end
end
# app/controllers/base_controller.rb
protected
def set_attachment_name(name)
escaped = URI.encode(name)
response.headers['Content-Disposition'] = "attachment; filename*=UTF-8''#{escaped}"
end
E aqui vamos nós! sites 20172419062423.xlsx