On Github pimpin / introducing-AXLSX
Présentation de Pierre Merlin, le 7 janvier 2012, au Paris.rb
Pierre Merlin, développeur freelance. e-mail: pierre at apido.org
Agiliste webdev dispo heureux rugby.Grâce à la librairie CSV de Ruby 1.9, vous pouvez exporter des données.
Modifiez votre contrôleur,
##/app/controllers/products_controller.rb class ProductsController < ApplicationController def index @products = Product.order(:name) respond_to do |format| format.html format.csv { render text: @products.to_csv } end end endsend_data pour downloader le fichier au lieu d'avoir un rendu en ligne cf http://apidock.com/rails/ActionController/Streaming/send_data format.csv { send_data @products.to_csv } format.xls { send_data @products.to_csv(col_sep: "\t") }
Equipez votre modèle,
##/app/models/product.rb class Product < ActiveRecord::Base attr_accessible :name, :price, :released_on def self.to_csv CSV.generate do |csv| csv << column_names all.each do |product| csv << product.attributes.values_at(*column_names) end end end end
Et voila !
On déclare le nouveau type,
##/config/initializers/mime_types.rb Mime::Type.register "application/xls", :xls
on adapte son contrôleur,
##/app/controllers/products_controller.rb class ProductsController < ApplicationController def index @products = Product.order(:name) respond_to do |format| format.html format.csv { send_data @products.to_csv } format.xls { send_data @products.to_csv(col_sep: "\t") } end end endWe’ll need to modify our controller now so that it responds to this type. The data needs to be tab-separated to open up properly in Excel; fortunately the csv library supports a column separator option that we can pass a tab character to to do this.
Soit. Développons une mise ne forme plus poussée à l'aide d'un template.
Instead of rendering the data in the controller we’ll create a template file for rendering the xls file. First we’ll remove the block from the xls’s format in the controller.On allège le contrôleur (bonne pratique)
##app/controllers/products.rb class ProductsController < ApplicationController def index @products = Product.order(:name) respond_to do |format| format.html format.csv { send_data @products.to_csv } format.xls end end end
Et on crée un template
/app/views/products/index.xls.erb
<table border="1"> <tr> <th>ID</th> <th>Name</th> <th>Release Date</th> <th>Price</th> </tr> <% @products.each do |product| %> <tr> <td><%= product.id %></td> <td><%= product.name %></td> <td><%= product.released_on %></td> <td><%= product.price %></td> </tr> <% end %> </table>'
Construire des fichiers EXCEL "à la mano", Ce n'est pas compliqué : RTFM.
Et voila un template "minimaliste".
/app/views/products/index.xls.erb '<?xml version="1.0"?>' <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40"> <Worksheet ss:Name="Sheet1"> <Table> <Row> <Cell><Data ss:Type="String">ID</Data></Cell> <Cell><Data ss:Type="String">Name</Data></Cell> <Cell><Data ss:Type="String">Release Date</Data></Cell> <Cell><Data ss:Type="String">Price</Data></Cell> </Row> <% @products.each do |product| %> <Row> <Cell><Data ss:Type="Number"><%= product.id %></Data></Cell> <Cell><Data ss:Type="String"><%= product.name %></Data></Cell> <Cell><Data ss:Type="String"><%= product.released_on %></Data></Cell> <Cell><Data ss:Type="Number"><%= product.price %></Data></Cell> </Row> <% end %> </Table> </Worksheet> </Workbook>
Attention la doc.
Instead of rendering the data in the controller we’ll create a template file for rendering the xls file. First we’ll remove the block from the xls’s format in the controller.prise en charge des données formatées en UTF-8
formatage les pourcentage en tant que chiffres, des dates en tant que date etc.
intégration des formules de calcul dans le fichier Excel
création de fichiers avec plusieurs feuilles
édition de graph en battons, camemberts, histogrammes....
insertion d'images
gestion des styles
protection par mot de passe
gestion de la mise en forme pour impression
...
La base :
p = Axlsx::Package.new wb = p.workbook wb.add_worksheet(:name => "Ventes") do |sheet| sheet.add_row Product.attribute_name @products.each do |product| sheet.add_row product.attributes.values end end p.serialize('ventes.xlsx')
ajoutons du style
p = Axlsx::Package.new wb = p.workbook wb.styles do |s| black_cell = s.add_style :bg_color => "00", :fg_color => "FF", :sz => 14, :alignment => { :horizontal=> :center } blue_cell = s.add_style :bg_color => "0000FF", :fg_color => "FF", :sz => 20, :alignment => { :horizontal=> :center } end wb.add_worksheet(:name => "Ventes") do |sheet| sheet.add_row Product.attribute_name @products.each do |product| sheet.add_row product.attributes.values, :style => [black_cell, blue_cell, black_cell] end end p.serialize('ventes.xlsx')
Vous prendrez bien du camembert ?
wb.add_worksheet(:name => "statistiques") do |sheet| sheet.add_row ["catégorie"] + sells_by_categorie.map(&:category) sheet.add_row ["Volume de vente"] + sells_by_categorie.map(&:amount) sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,5], :end_at => [10, 20], :title => "Répartition des ventes par catégorie") do |chart| chart.add_series :data => sheet["B2:B6"], :labels => sheet["A2:A6"], :colors => ['FF0000', '00FF00', '0000FF'] end end
Et enfin...
distribué sous licence MIT
trés bonne couverture
documenté
support actif
intégration continue sur Travis CI
utilisez, contribuez, participez.