forked from vidmantas/csv_builder
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
191 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
require 'csv_builder' | ||
|
||
ActionView::Template.register_template_handler 'csvbuilder', ActionView::TemplateHandlers::CsvBuilder | ||
ActionView::Template.register_template_handler 'csvbuilder', CsvBuilder::TemplateHandler::Base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,12 @@ | ||
require 'action_controller' | ||
require 'action_view' | ||
|
||
require 'fastercsv' | ||
require 'iconv' | ||
|
||
module ActionView # :nodoc: | ||
module TemplateHandlers | ||
# Template handler for csv templates | ||
# | ||
# Add rows to your CSV file in the template by pushing arrays of columns into csv | ||
# | ||
# # First row | ||
# csv << [ 'cell 1', 'cell 2' ] | ||
# # Second row | ||
# csv << [ 'another cell value', 'and another' ] | ||
# # etc... | ||
# | ||
# You can set the default filename for that a browser will use for 'save as' by | ||
# setting <tt>@filename</tt> instance variable in your controller's action method | ||
# e.g. | ||
# | ||
# @filename = 'report.csv' | ||
# | ||
# You can also set the input encoding and output encoding by setting | ||
# <tt>@input_encoding</tt> and <tt>@output_encoding</tt> instance variables. | ||
# These default to 'UTF-8' and 'LATIN1' respectively. e.g. | ||
# | ||
# @output_encoding = 'UTF-8' | ||
|
||
class CsvBuilder < TemplateHandler | ||
|
||
include Compilable | ||
|
||
def self.line_offset | ||
9 | ||
end | ||
|
||
def compile(template) | ||
<<-EOV | ||
begin | ||
unless defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) | ||
@filename ||= "\#{controller.action_name}.csv" | ||
controller.response.headers["Content-Type"] ||= 'text/csv' | ||
controller.response.headers['Content-Disposition'] = "attachment; filename=\#{@filename}" | ||
end | ||
result = FasterCSV.generate do |csv| | ||
#{template.source} | ||
end | ||
# Transliterate into the required encoding if necessary | ||
# TODO: make defaults configurable | ||
@input_encoding ||= 'UTF-8' | ||
@output_encoding ||= 'LATIN1' | ||
if @input_encoding == @output_encoding | ||
result | ||
else | ||
# TODO: do some checking to make sure iconv works correctly in | ||
# current environment. See ActiveSupport::Inflector#transliterate | ||
# definition for details | ||
# | ||
# Not using the more standard //IGNORE//TRANLIST because it raises | ||
# Iconv::IllegalSequence for some inputs | ||
c = Iconv.new("\#{@output_encoding}//TRANSLIT//IGNORE", @input_encoding) | ||
c.iconv(result) | ||
end | ||
rescue Exception => e | ||
RAILS_DEFAULT_LOGGER.warn("Exception \#{e} \#{e.message} with class \#{e.class.name} thrown when rendering CSV") | ||
raise e | ||
end | ||
EOV | ||
end | ||
require 'csv_builder/action_controller' | ||
require 'csv_builder/template_handler/base' | ||
|
||
end | ||
end | ||
end | ||
class ActionController::Base | ||
include CsvBuilder::ActionController | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
module CsvBuilder | ||
module ActionController | ||
|
||
DEFAULT_CSV_BUILDER_OPTIONS = { :col_sep => ';' } | ||
|
||
def csv_builder(options) | ||
@csv_builder_options = options | ||
end | ||
|
||
private | ||
|
||
def compute_csv_builder_options | ||
options = DEFAULT_CSV_BUILDER_OPTIONS.dup | ||
options.merge!(@csv_builder_options || {}) | ||
options | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
module CsvBuilder | ||
module TemplateHandler | ||
|
||
# Template handler for csv templates | ||
# | ||
# Add rows to your CSV file in the template by pushing arrays of columns into csv | ||
# | ||
# # First row | ||
# csv << [ 'cell 1', 'cell 2' ] | ||
# # Second row | ||
# csv << [ 'another cell value', 'and another' ] | ||
# # etc... | ||
# | ||
# You can set the default filename for that a browser will use for 'save as' by | ||
# setting <tt>@filename</tt> instance variable in your controller's action method | ||
# e.g. | ||
# | ||
# @filename = 'report.csv' | ||
# | ||
# You can also set the input encoding and output encoding by setting | ||
# <tt>@input_encoding</tt> and <tt>@output_encoding</tt> instance variables. | ||
# These default to 'UTF-8' and 'LATIN1' respectively. e.g. | ||
# | ||
# @output_encoding = 'UTF-8' | ||
|
||
class Base < ActionView::TemplateHandler | ||
|
||
include ActionView::TemplateHandlers::Compilable | ||
|
||
def self.line_offset | ||
9 | ||
end | ||
|
||
def compile(template) | ||
<<-EOV | ||
begin | ||
unless defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) | ||
@filename ||= "\#{controller.action_name}.csv" | ||
controller.response.headers["Content-Type"] ||= 'text/csv' | ||
controller.response.headers['Content-Disposition'] = "attachment; filename=\#{@filename}" | ||
end | ||
result = FasterCSV.generate(controller.send(:compute_csv_builder_options)) do |csv| | ||
#{template.source} | ||
end | ||
# Transliterate into the required encoding if necessary | ||
# TODO: make defaults configurable | ||
@input_encoding ||= 'UTF-8' | ||
@output_encoding ||= 'LATIN1' | ||
if @input_encoding == @output_encoding | ||
result | ||
else | ||
# TODO: do some checking to make sure iconv works correctly in | ||
# current environment. See ActiveSupport::Inflector#transliterate | ||
# definition for details | ||
# | ||
# Not using the more standard //IGNORE//TRANLIST because it raises | ||
# Iconv::IllegalSequence for some inputs | ||
c = Iconv.new("\#{@output_encoding}//TRANSLIT//IGNORE", @input_encoding) | ||
c.iconv(result) | ||
end | ||
rescue Exception => e | ||
RAILS_DEFAULT_LOGGER.warn("Exception \#{e} \#{e.message} with class \#{e.class.name} thrown when rendering CSV") | ||
raise e | ||
end | ||
EOV | ||
end | ||
|
||
|
||
end | ||
end | ||
end | ||
|
||
|
||
module ActionView # :nodoc: | ||
module TemplateHandlers | ||
# Template handler for csv templates | ||
# | ||
# Add rows to your CSV file in the template by pushing arrays of columns into csv | ||
# | ||
# # First row | ||
# csv << [ 'cell 1', 'cell 2' ] | ||
# # Second row | ||
# csv << [ 'another cell value', 'and another' ] | ||
# # etc... | ||
# | ||
# You can set the default filename for that a browser will use for 'save as' by | ||
# setting <tt>@filename</tt> instance variable in your controller's action method | ||
# e.g. | ||
# | ||
# @filename = 'report.csv' | ||
# | ||
# You can also set the input encoding and output encoding by setting | ||
# <tt>@input_encoding</tt> and <tt>@output_encoding</tt> instance variables. | ||
# These default to 'UTF-8' and 'LATIN1' respectively. e.g. | ||
# | ||
# @output_encoding = 'UTF-8' | ||
|
||
class CsvBuilder < TemplateHandler | ||
|
||
include Compilable | ||
|
||
attr_reader :csv_builder_options | ||
|
||
def self.line_offset | ||
9 | ||
end | ||
|
||
def compile(template) | ||
<<-EOV | ||
begin | ||
unless defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) | ||
@filename ||= "\#{controller.action_name}.csv" | ||
controller.response.headers["Content-Type"] ||= 'text/csv' | ||
controller.response.headers['Content-Disposition'] = "attachment; filename=\#{@filename}" | ||
end | ||
result = FasterCSV.generate do |csv| | ||
#{template.source} | ||
end | ||
# Transliterate into the required encoding if necessary | ||
# TODO: make defaults configurable | ||
@input_encoding ||= 'UTF-8' | ||
@output_encoding ||= 'LATIN1' | ||
if @input_encoding == @output_encoding | ||
result | ||
else | ||
# TODO: do some checking to make sure iconv works correctly in | ||
# current environment. See ActiveSupport::Inflector#transliterate | ||
# definition for details | ||
# | ||
# Not using the more standard //IGNORE//TRANLIST because it raises | ||
# Iconv::IllegalSequence for some inputs | ||
c = Iconv.new("\#{@output_encoding}//TRANSLIT//IGNORE", @input_encoding) | ||
c.iconv(result) | ||
end | ||
rescue Exception => e | ||
RAILS_DEFAULT_LOGGER.warn("Exception \#{e} \#{e.message} with class \#{e.class.name} thrown when rendering CSV") | ||
raise e | ||
end | ||
EOV | ||
end | ||
|
||
end | ||
end | ||
end |