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
end
send_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
end
We’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.