poormans_export 0.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0512d8f5b14c154addca9d079e50f10ed70ff42be9f298d16be0e43303fb9513
4
+ data.tar.gz: ba9db716689c2666e67d44720f27f76d46335db2bcb090f3bc9e7bc0722aef86
5
+ SHA512:
6
+ metadata.gz: 9c82d6e3676b9b1e01c9d678bbc98a088f107f1859ea433b2c3f1ac5fb029ae52baac922ee5bf8f6f99adfbb3f9397404d2a187064c97c4059e5a634091ce0b0
7
+ data.tar.gz: eebb11a1e9a02174092893a57db84a717fd30691c37ffda89ab0c6b209dc551d8cdfe8e9168a052a4af71312c653a906f044edeb4259edbe7451ebf404f4087f
@@ -0,0 +1,20 @@
1
+ Copyright 2019 Usabi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ # Poorman's Export
2
+ Poorman's Export is a simple but powerful CSV and XLS exporter.
3
+
4
+ ## Usage
5
+ Poorman's Export transforms a collection of objects into a CSV or a XLS file that can be sent to the browser just like this:
6
+ ```ruby
7
+ def index
8
+ @collection = Article.all
9
+ fields_to_export = %i[id title body created_at published_at]
10
+
11
+ respond_to do |format|
12
+ format.html
13
+ format.csv do
14
+ send_data(
15
+ PoormansExport::Exporter.new(@collection, fields_to_export).csv_string,
16
+ type: 'text/csv; charset=utf-16le; header=present',
17
+ disposition: 'attachment',
18
+ filename: 'articles.csv'
19
+ )
20
+ end
21
+ format.xls do
22
+ send_data(
23
+ PoormansExport::Exporter.new(@collection, fields_to_export).xls_string,
24
+ type: 'application/xls',
25
+ disposition: 'attachment',
26
+ filename: 'articles.xls'
27
+ )
28
+ end
29
+ end
30
+ end
31
+ ```
32
+
33
+ Poorman's Export will process the collection and convert its fields into something readable by a human, automatically processing dates, times, booleans and even relations, by using the `to_s` method of the related object.
34
+
35
+ ## Installation
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'poormans_export'
40
+ ```
41
+
42
+ And then execute:
43
+ ```bash
44
+ $ bundle
45
+ ```
46
+
47
+ Or install it yourself as:
48
+ ```bash
49
+ $ gem install poormans_export
50
+ ```
51
+
52
+ After installing the gem, register the CSV and XLS MIME types in your application by adding these lines to your `config/initializers/mime_types.rb` file:
53
+ ```ruby
54
+ Mime::Type.register 'text/csv; charset=utf-16le; header=present', :csv
55
+ Mime::Type.register 'application/xls', :xls
56
+ ```
57
+
58
+ And you're good to go!
59
+
60
+ ## Contributing
61
+ Contribution directions go here.
62
+
63
+ ## License
64
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'PoormansExport'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ require 'bundler/gem_tasks'
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'test'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = false
27
+ end
28
+
29
+ task default: :test
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'poormans_export/exporter'
4
+
5
+ module PoormansExport
6
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'csv'
4
+ require 'spreadsheet'
5
+
6
+ module PoormansExport
7
+ class Exporter
8
+ def initialize(collection, fields, headers = [])
9
+ @collection = collection
10
+ @head = []
11
+ @fields = []
12
+ @types = []
13
+ fields.each do |f|
14
+ if f.is_a?(Symbol) || f.is_a?(String)
15
+ @head << f.to_s
16
+ @fields << f
17
+ elsif f.is_a?(Hash)
18
+ @head << f.keys.first
19
+ @fields << f.values.first
20
+ @types << f[:type]
21
+ end
22
+ end
23
+ @headers = headers
24
+ end
25
+
26
+ def csv_string(params = {})
27
+ options = { col_sep: ',' }
28
+ options.merge! params
29
+ csv_string = CSV.generate(options) do |csv|
30
+ if @collection.first.class.nil?
31
+ class_name = @collection
32
+ elsif @collection.first.class != NilClass
33
+ class_name = @collection.first.class
34
+ end
35
+
36
+ header = []
37
+ @head.each do |header_field|
38
+ header <<
39
+ if class_name
40
+ class_name.human_attribute_name(header_field.gsub(/_ids?/, ''))
41
+ else
42
+ header_field
43
+ end
44
+ end
45
+ csv << header
46
+
47
+ @collection.each do |item|
48
+ row_array = []
49
+ @fields.each do |field|
50
+ row_array << Exporter.field_value(item, field)
51
+ end
52
+ csv << row_array
53
+ end
54
+ end
55
+ csv_string
56
+ end
57
+
58
+ def xls_string(params = {})
59
+ template_path = params[:template]
60
+ start_on_row = params[:start_on_row] || 0
61
+ formats = params[:formats] || { 0 => { weight: :bold } }
62
+ formats[@headers.size + 1] = { weight: :bold } unless @headers.empty?
63
+ workbook = params[:workbook]
64
+ workbook ||=
65
+ if template_path.present?
66
+ ::Spreadsheet.open(template_path)
67
+ else
68
+ ::Spreadsheet::Workbook.new
69
+ end
70
+ sheet = template_path ? workbook.worksheet(0) : workbook.create_worksheet
71
+ sheet.name = params[:sheet_name] if params[:sheet_name]
72
+ current_row = start_on_row
73
+
74
+ if @collection.first.class.nil?
75
+ class_name = @collection
76
+ elsif @collection.first.class != NilClass
77
+ class_name = @collection.first.class
78
+ end
79
+
80
+ unless @headers.empty?
81
+ if @headers[0]
82
+ sheet.row(current_row).concat [@headers[0]]
83
+ current_row += 1
84
+ end
85
+ sheet.row(current_row).concat [I18n.l(Time.zone.now, format: :compact)]
86
+ current_row += 1
87
+ if @headers[1]
88
+ sheet.row(current_row).concat [@headers[1]]
89
+ current_row += 1
90
+ end
91
+ end
92
+
93
+ header = []
94
+ @head.each do |header_field|
95
+ header <<
96
+ if class_name
97
+ class_name.human_attribute_name(header_field.gsub(/_ids?/, ''))
98
+ else
99
+ header_field
100
+ end
101
+ end
102
+ sheet.row(current_row).concat header
103
+ current_row += 1
104
+
105
+ @collection.each do |item|
106
+ row_array = []
107
+ @fields.each do |field|
108
+ row_array << Exporter.field_value(item, field)
109
+ end
110
+ sheet.row(current_row).replace row_array
111
+ @types.each_with_index do |type, idx|
112
+ case type
113
+ when Date
114
+ cell_format = 'DD-MM-YYYY'
115
+ when Time
116
+ cell_format = 'DD-MM-YYYY HH:MM:SS'
117
+ end
118
+ next unless cell_format
119
+
120
+ sheet.row(current_row).set_format(
121
+ idx,
122
+ Spreadsheet::Format.new(number_format: cell_format)
123
+ )
124
+ end
125
+ current_row += 1
126
+ end
127
+
128
+ formats.each do |k, v|
129
+ format = Spreadsheet::Format.new(v)
130
+ if k.respond_to?(:each)
131
+ k.each do |sub_k|
132
+ sheet.row(sub_k).default_format = format
133
+ end
134
+ else
135
+ sheet.row(k).default_format = format
136
+ end
137
+ end
138
+
139
+ if params[:format] == :object
140
+ workbook
141
+ else
142
+ output = StringIO.new
143
+ workbook.write(output)
144
+ output.string
145
+ end
146
+ end
147
+
148
+ def self.field_value(item, field)
149
+ if item && field.is_a?(Proc)
150
+ Exporter.format field.call(item)
151
+ elsif field =~ /(.+)_id$/
152
+ Exporter.format item.send(Regexp.last_match(1))
153
+ elsif field =~ /(.+)_ids$/
154
+ item.send(Regexp.last_match(1)).map do |f|
155
+ Exporter.format f
156
+ end.join('; ')
157
+ elsif field.in? %w[status state]
158
+ I18n.t(item.send(field), scope: field.to_sym)
159
+ elsif item.is_a?(Hash)
160
+ Exporter.format item[field]
161
+ else
162
+ Exporter.format item.send(field)
163
+ end
164
+ end
165
+
166
+ def self.format(val)
167
+ val = Time.zone.parse(val) if val.is_a?(String) && val =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/
168
+
169
+ if val.is_a?(ActiveRecord::Base)
170
+ val.try(:to_s)
171
+ elsif val.is_a? Time
172
+ I18n.l(val, format: :compact)
173
+ elsif val.is_a? Date
174
+ I18n.l(val, format: :default)
175
+ elsif val.is_a? BigDecimal
176
+ val.to_f
177
+ elsif val.is_a?(FalseClass) || val.is_a?(TrueClass)
178
+ I18n.t(val ? 'yes' : 'no')
179
+ elsif val.nil?
180
+ '-'
181
+ else
182
+ val
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PoormansExport
4
+ VERSION = '0.1.0.1'
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # desc "Explaining what the task does"
3
+ # task :poormans_export do
4
+ # # Task goes here
5
+ # end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poormans_export
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Imobach González Sosa
8
+ - Ignacio Aliende García
9
+ - Adán Alonso Salvador
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2020-07-29 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 4.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 4.2.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: spreadsheet
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '1.0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.0'
43
+ description: Poorman's Export is a simple but powerful CSV and XLS exporter
44
+ email:
45
+ - imobachgs@banot.net
46
+ - ialiendeg@gmail.com
47
+ - adan.alonso.s@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - MIT-LICENSE
53
+ - README.md
54
+ - Rakefile
55
+ - lib/poormans_export.rb
56
+ - lib/poormans_export/exporter.rb
57
+ - lib/poormans_export/version.rb
58
+ - lib/tasks/poormans_export_tasks.rake
59
+ homepage: https://github.com/Usabi/poormans_export
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.1.2
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A simple but powerful exporter
82
+ test_files: []