From 724ce6ff60c5e269725afc9c38bec63561b85f23 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 8 May 2014 12:42:50 +0200 Subject: [PATCH] make csv export more compatible with Microsoft Excel --- lib/order_csv.rb | 51 +++++++++++++++++++---------------------------- lib/render_csv.rb | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 lib/render_csv.rb diff --git a/lib/order_csv.rb b/lib/order_csv.rb index 22057ec0..4a3114bb 100644 --- a/lib/order_csv.rb +++ b/lib/order_csv.rb @@ -1,39 +1,28 @@ require 'csv' -class OrderCsv - include ActionView::Helpers::NumberHelper +class OrderCsv < RenderCSV - def initialize(order, options={}) - @order = order + def header + [ + OrderArticle.human_attribute_name(:units_to_order), + Article.human_attribute_name(:order_number), + Article.human_attribute_name(:name), + Article.human_attribute_name(:unit), + ArticlePrice.human_attribute_name(:price), + OrderArticle.human_attribute_name(:total_price) + ] end - def to_csv - CSV.generate do |csv| - # header - csv << [ - OrderArticle.human_attribute_name(:units_to_order), - Article.human_attribute_name(:order_number), - Article.human_attribute_name(:name), - Article.human_attribute_name(:unit), - ArticlePrice.human_attribute_name(:price), - OrderArticle.human_attribute_name(:total_price) - ] - # data - @order.order_articles.ordered.includes([:article, :article_price]).all.map do |oa| - csv << [ - oa.units_to_order, - oa.article.order_number, - oa.article.name, - oa.article.unit + (oa.price.unit_quantity > 1 ? " × #{oa.price.unit_quantity}" : ''), - number_to_currency(oa.article_price.price * oa.article_price.unit_quantity), - number_to_currency(oa.total_price) - ] - end + def data + @object.order_articles.ordered.includes([:article, :article_price]).all.map do |oa| + yield [ + oa.units_to_order, + oa.article.order_number, + oa.article.name, + oa.article.unit + (oa.price.unit_quantity > 1 ? " × #{oa.price.unit_quantity}" : ''), + number_to_currency(oa.article_price.price * oa.article_price.unit_quantity), + number_to_currency(oa.total_price) + ] end end - - # Helper method to test pdf via rails console: OrderCsv.new(order).save_tmp - def save_tmp - File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.csv", 'w') {|f| f.write(to_csv.force_encoding("UTF-8")) } - end end diff --git a/lib/render_csv.rb b/lib/render_csv.rb new file mode 100644 index 00000000..c8742d41 --- /dev/null +++ b/lib/render_csv.rb @@ -0,0 +1,42 @@ +require 'csv' + +class RenderCSV + include ActionView::Helpers::NumberHelper + + def initialize(object, options={}) + @object = object + @options = options + # defaults to please Microsoft Excel ... + @options[:col_sep] ||= FoodsoftConfig[:csv_col_sep] || ';' + @options[:row_sep] ||= FoodsoftConfig[:csv_row_sep] if FoodsoftConfig[:csv_row_sep] + @options[:encoding] ||= FoodsoftConfig[:csv_encoding] || 'ISO-8859-15' + end + + def to_csv + CSV.generate @options do |csv| + if h = header + csv << h + end + data {|d| csv << d} + end + end + + def header + nil + end + + def data + yield [] + end + + # Helper method to test pdf via rails console: OrderCsv.new(order).save_tmp + def save_tmp + encoding = @options[:encoding] || 'UTF-8' + File.open("#{Rails.root}/tmp/#{self.class.to_s.underscore}.csv", 'w') {|f| f.write(to_csv.force_encoding(encoding)) } + end + + # XXX avoid encoding confusion when using unicode whitespace + def number_to_currency(number, options={}) + super(number, options).gsub("\u202f", ' ') + end +end