axlsx_report 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45c3786fefc932fcf9f891788cfb0c3fcf4d885d
4
+ data.tar.gz: 681f81d9bb9042f0da7200688d80229e368574d1
5
+ SHA512:
6
+ metadata.gz: 9b7f8e17f841fce40e7d0fdf4f687e9b3ffbd8583a3846eb0ce456ef1e8929ddf2ae536a45ba768cf87bce7f0df5174dd20e1a06677c5b36b28cfdf55e9fe837
7
+ data.tar.gz: 7f973dd5e6d1a139e46274c2570c8ac89990f6255c45067d146689e3fda510a9d34a6d4584c3e8ed64254687ae39384abf55e9e87834bef64e3fb67d47fa05de
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /*.xlsx
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in axlsx_report.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Alexey Volochnev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,55 @@
1
+ # AxlsxReport
2
+
3
+ Declarative excel reports based on [axlsx](https://github.com/randym/axlsx).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'axlsx_report'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install axlsx_report
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'axlsx_report'
25
+
26
+ class BaseReport < AxlsxReport::Base
27
+ column 'Number' do |i|
28
+ i
29
+ end
30
+
31
+ column 'Square' do |i|
32
+ i * i
33
+ end
34
+ end
35
+
36
+ report = BaseReport.new
37
+
38
+ (1..10).each do |i|
39
+ report << i
40
+ end
41
+
42
+ report.save('base_report.xlsx')
43
+ ```
44
+
45
+ Find more examples in examples folder.
46
+
47
+ ## Contributing
48
+
49
+ Bug reports and pull requests are welcome on GitHub at https://github.com/avolochnev/axlsx_report.
50
+
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
55
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
Binary file
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'axlsx_report/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "axlsx_report"
8
+ spec.version = AxlsxReport::VERSION
9
+ spec.authors = ["Alexey Volochnev"]
10
+ spec.email = ["alexey.volochnev@gmail.com"]
11
+
12
+ spec.summary = %q{Declarative excel reports based on axlsx.}
13
+ spec.homepage = "https://github.com/avolochnev/axlsx_report"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency 'axlsx', '~> 2.0', '>= 2.0.1'
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency 'roo', '~> 1.13', '>= 1.13.2'
24
+ end
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+
3
+ require 'axlsx_report'
4
+
5
+ class BaseReport < AxlsxReport::Base
6
+ column 'Integer' do |i|
7
+ i
8
+ end
9
+
10
+ column 'Square' do |i|
11
+ i * i
12
+ end
13
+ end
14
+
15
+ if __FILE__ == $0
16
+ report = BaseReport.new
17
+ (1..10).each { |i| report << i }
18
+ report.save('base_report.xlsx')
19
+ end
20
+
21
+
@@ -0,0 +1,28 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+
3
+ require 'axlsx_report'
4
+
5
+ class GroupReport < AxlsxReport::Base
6
+ column 'Integer' do |i|
7
+ i
8
+ end
9
+
10
+ # Define group of columns with merged group header
11
+ group 'Calculations' do
12
+ column 'Square' do |i|
13
+ i * i
14
+ end
15
+
16
+ column 'Sqrt' do |i|
17
+ Math.sqrt(i)
18
+ end
19
+ end
20
+ end
21
+
22
+ if __FILE__ == $0
23
+ report = GroupReport.new
24
+ (1..10).each { |i| report << i }
25
+ report.save('group_report.xlsx')
26
+ end
27
+
28
+
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+
3
+ require 'axlsx_report'
4
+
5
+ class LambdaReport < AxlsxReport::Base
6
+ # proc without params called in context of given object
7
+ column 'Integer', -> { self }
8
+ column 'Odd?', -> { odd? }, width: 7
9
+ column 'Even?', -> { even? }, width: 7
10
+ end
11
+
12
+ if __FILE__ == $0
13
+ report = LambdaReport.new
14
+ (1..10).each { |i| report << i }
15
+ report.save('lambda_report.xlsx')
16
+ end
17
+
18
+
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+
3
+ require 'axlsx_report'
4
+
5
+ class WidthReport < AxlsxReport::Base
6
+ column 'Integer', width: 20 do |i|
7
+ i
8
+ end
9
+
10
+ column 'Square', width: 20 do |i|
11
+ i * i
12
+ end
13
+ end
14
+
15
+ if __FILE__ == $0
16
+ report = WidthReport.new
17
+ (1..10).each { |i| report << i }
18
+ report.save('width_report.xlsx')
19
+ end
20
+
21
+
@@ -0,0 +1,5 @@
1
+ require 'axlsx_report/version'
2
+ require 'axlsx_report/base'
3
+
4
+ module AxlsxReport
5
+ end
@@ -0,0 +1,355 @@
1
+ require 'axlsx'
2
+ require_relative 'column_name_conv'
3
+ require_relative 'group'
4
+ require_relative 'column'
5
+
6
+ module AxlsxReport
7
+ class Base
8
+ include ColumnNameConv
9
+
10
+ # Creates new report.
11
+ # By default creates own Axlsx::Package.
12
+ # @param [Axlsx::Package] package - provide existing package to add report sheet to combined document.
13
+ def initialize(package = nil)
14
+ @package = package || Axlsx::Package.new
15
+ end
16
+
17
+ # Define report column.
18
+ #
19
+ # Usage:
20
+ # Human = Struct.new(:first_name, :last_name, :birthday)
21
+ # class Report < AxlsxReport::Base
22
+ # # calculate column value with block:
23
+ # column 'First Name', width: 10 do |human|
24
+ # human.first_name
25
+ # end
26
+ # # or lambda in context of given object
27
+ # column 'Last Name', -> { last_name }, width: 15
28
+ # # or chagne context using with:
29
+ # column 'Age', -> { Date.today.year - year }, with: :birthday
30
+ # end
31
+ #
32
+ # @see Column#initialize for options description
33
+ #
34
+ # @param [String] name - column header
35
+ # @param [Proc] callable - use proc or lambda instead of block to get cell value. Optional.
36
+ # @param [Hash] options - last param,
37
+ # @param block
38
+ # args: callable = nil, options = {}
39
+ def self.column(col_name, *args, &block)
40
+ @columns ||= []
41
+ options =
42
+ if args.last.is_a? Hash
43
+ args.pop
44
+ else
45
+ {}
46
+ end
47
+ options[:group] = @current_group if @current_group
48
+ callable = args.first || block
49
+ @columns << Column.new(col_name, callable, options)
50
+ end
51
+
52
+ # Define group of columns
53
+ #
54
+ # Usage:
55
+ # Human = Struct.new(:first_name, :last_name, :birthday)
56
+ # class Report < AxlsxReport::Base
57
+ # group 'Name' do
58
+ # column 'First', &:first_name
59
+ # column 'Last', &:last_name
60
+ # end
61
+ # column 'Birthday', &:birthday
62
+ # end
63
+ #
64
+ # @param [String] name group name
65
+ def self.group(name, &block)
66
+ @columns ||= []
67
+ unless @groups
68
+ @groups = []
69
+ define_method :groups do
70
+ self.class.instance_eval { @groups }
71
+ end
72
+ end
73
+ raise 'Nested groups are not implemented yet' if @current_group
74
+ @current_group = Group.new(name, @columns.length)
75
+ @groups << @current_group
76
+ instance_exec(&block)
77
+ @current_group.end_index = @columns.length - 1
78
+ @current_group = nil
79
+ end
80
+
81
+ # Define group row height.
82
+ # Used if any groups are defiend. Autoheight is used by default
83
+ # @param [Integer] num group row height
84
+ def self.group_height(num)
85
+ define_method(:group_height) { num }
86
+ end
87
+
88
+ # Define head row height.
89
+ # Autoheight is used by default
90
+ # @param [Integer] num head row height
91
+ def self.head_height(num)
92
+ define_method(:head_height) { num }
93
+ end
94
+
95
+ # Add 1,2,3...N row below head row
96
+ def self.numerate_columns
97
+ define_method(:numerate_columns) { true }
98
+ end
99
+
100
+ # Define sheet name.
101
+ #
102
+ # @param [String] name (nil) static sheet name.
103
+ # @param block dinamic sheet name (if given)
104
+ def self.sheet_name(name = nil, &block)
105
+ if block_given?
106
+ define_method(:sheet_name, &block)
107
+ else
108
+ define_method(:sheet_name) { name }
109
+ end
110
+ end
111
+
112
+ # Add row to the report.
113
+ # @param [Any] obj object providing the data for columns
114
+ def <<(obj)
115
+ row = columns.map { |column| column.value(self, obj) }
116
+ add_totals row
117
+ sheet.add_row row, row_options
118
+ end
119
+
120
+ # Returns sheet name.
121
+ #
122
+ # May be overriden to provide custom sheet name
123
+ # @see Base.sheet_name
124
+ def sheet_name
125
+ 'Sheet1'
126
+ end
127
+
128
+ # def run(file = nil, enum = nil)
129
+ # file = file_name unless file
130
+ # enum = enumerator if enum.nil? && !block_given?
131
+ # if enum
132
+ # enum.each do |obj|
133
+ # self << obj
134
+ # end
135
+ # elsif block_given?
136
+ # yield self
137
+ # else
138
+ # raise 'No block or enum given. Use #new -> << -> #save for generating report later'
139
+ # end
140
+ # save(file)
141
+ # end
142
+
143
+ # def self.[](*args)
144
+ # new.run(*args)
145
+ # end
146
+
147
+ # Save xlsx file with provided data
148
+ # @param [String] file File name the data to be serialized
149
+ def save(file)
150
+ done
151
+ begin
152
+ @package.serialize(file)
153
+ rescue Errno::EACCES => e
154
+ puts "#{file} is protected!"
155
+ file = file + ".tmp"
156
+ @package.serialize(file)
157
+ end
158
+ end
159
+
160
+ # Finalize document formatting after data collecting and before saving.
161
+ # @note Called during #save.
162
+ # @note Don't call twice. Don't call before all data provided.
163
+ def done
164
+ apply_width(sheet)
165
+ merge_same(sheet)
166
+ sheet.add_row(@totals) if @totals
167
+ end
168
+
169
+ # Axlsx sheet.
170
+ # @return [Axlsx::Worksheet]
171
+ def sheet
172
+ @sheet ||= init_sheet(sheet_name)
173
+ end
174
+
175
+ private
176
+
177
+ def columns
178
+ self.class.instance_eval { @columns }
179
+ end
180
+
181
+ def init_sheet(name = 'Sheet1')
182
+ sheet = @package.workbook.add_worksheet(:name => sheetify_name(name))
183
+ if self.respond_to? :title
184
+ if title.is_a? Array
185
+ title.each do |t|
186
+ sheet.add_row [t]
187
+ end
188
+ else
189
+ sheet.add_row [title]
190
+ end
191
+ end
192
+ if defined? groups
193
+ add_group_head sheet
194
+ else
195
+ add_head sheet, *columns.map{ |col| eval_name(col.name) }
196
+ sheet.rows.last.height = head_height if defined? head_height
197
+ end
198
+ if defined? numerate_columns
199
+ add_frozen_head sheet, *(1..(columns.length)).to_a
200
+ else
201
+ froze(sheet, sheet.rows.count)
202
+ auto_filter(sheet)
203
+ end
204
+ @header_rows = sheet.rows.count
205
+ sheet
206
+ end
207
+
208
+ def auto_filter(sheet)
209
+ sheet.auto_filter = Axlsx::cell_range(sheet.rows.last.cells, false)
210
+ end
211
+
212
+ def apply_width(sheet)
213
+ sheet.column_widths *columns.map(&:width).map { |width| width || default_column_width }
214
+ end
215
+
216
+ def merge_same(sheet)
217
+ columns.map(&:options).each_with_index do |ops, col_num|
218
+ next unless ops[:merge_same]
219
+ merged_style ||= sheet.styles.add_style(:alignment => { :vertical => :center })
220
+ col_char = column_num_to_name(col_num + 1)
221
+ last, start_row = nil, 0
222
+ sheet.rows.dup.each_with_index do |row, row_num|
223
+ next if row_num < @header_rows
224
+ col_value = row.cells[col_num].value
225
+ if last && last != col_value && (row_num - start_row) > 1
226
+ range = "#{col_char}#{start_row + 1}:#{col_char}#{row_num}"
227
+ sheet.merge_cells(range)
228
+ sheet[range].each { |c| c.style = merged_style }
229
+ end
230
+ if last != col_value
231
+ last = col_value
232
+ start_row = row_num
233
+ end
234
+ end
235
+ if last && (sheet.rows.length - start_row) > 1
236
+ range = "#{col_char}#{start_row + 1}:#{col_char}#{sheet.rows.length}"
237
+ sheet.merge_cells(range)
238
+ sheet[range].each { |c| c.style = merged_style }
239
+ end
240
+ end
241
+ end
242
+
243
+ def default_column_width
244
+ 16
245
+ end
246
+
247
+ def add_group_head(sheet)
248
+ head_row = *columns.map{ |col| eval_name(col.name) }
249
+ groups.each { |g| head_row[g.start_index] = g.name }
250
+ add_head sheet, *head_row
251
+ group_row = sheet.rows.length
252
+ groups.map { |g| "#{column_num_to_name(g.start_index + 1)}#{group_row}:#{column_num_to_name(g.end_index + 1)}#{group_row}" }
253
+ .each { |rng| sheet.merge_cells(rng) }
254
+ sheet.rows.last.height = group_height if defined? group_height
255
+ add_head sheet, *columns.map{ |col| eval_name(col.name) }
256
+ sheet.rows.last.height = head_height if defined? head_height
257
+ names_row = sheet.rows.length
258
+ units = *columns.map(&:units)
259
+ has_units = !units.all?(&:nil?)
260
+ if has_units
261
+ add_head sheet, *units
262
+ end
263
+ units_row = sheet.rows.length
264
+ columns.map(&:options).each_with_index do |ops, index|
265
+ row_name = column_num_to_name(index + 1)
266
+ case
267
+ when ops[:units] && ops[:group]
268
+ nil
269
+ when ops[:group]
270
+ sheet.merge_cells("#{row_name}#{names_row}:#{row_name}#{units_row}") if has_units
271
+ when ops[:units]
272
+ sheet.merge_cells("#{row_name}#{group_row}:#{row_name}#{names_row}")
273
+ else
274
+ sheet.merge_cells("#{row_name}#{group_row}:#{row_name}#{units_row}")
275
+ end
276
+ end
277
+ end
278
+
279
+ def add_totals(row)
280
+ return unless total_actions
281
+ @totals ||= [nil] * columns.length
282
+ total_actions.each_with_index do |action, index|
283
+ case action
284
+ when String
285
+ @totals[index] = action
286
+ when :sum
287
+ if row[index]
288
+ @totals[index] ||= 0.0
289
+ @totals[index] += row[index]
290
+ end
291
+ when :count
292
+ if row[index]
293
+ @totals[index] ||= 0
294
+ @totals[index] += 1
295
+ end
296
+ when Proc
297
+ @totals[index] = action[row]
298
+ end
299
+ end
300
+ end
301
+
302
+ def total_actions
303
+ @total_actions ||=
304
+ columns.map(&:options).each do |ops|
305
+ ops[:total]
306
+ end
307
+ end
308
+
309
+ def eval_name(name)
310
+ name.is_a?(Proc) ? instance_exec(&name) : name
311
+ end
312
+
313
+ def sheetify_name(name)
314
+ name.gsub('/', '_')[0..30]
315
+ end
316
+
317
+ def add_head(sheet, *header)
318
+ row = nil
319
+ sheet.workbook.styles do |s|
320
+ head_style = s.add_style :border => { :style => :thin, :color => "00" },
321
+ :alignment => { :horizontal => :center,
322
+ :vertical => :center ,
323
+ :wrap_text => true}
324
+ row = sheet.add_row header, style: head_style
325
+ end
326
+ row
327
+ end
328
+
329
+ def add_frozen_head(sheet, *header)
330
+ row = add_head(sheet, *header)
331
+ froze(sheet, sheet.rows.count)
332
+ sheet.auto_filter = Axlsx::cell_range(row.cells, false)
333
+ end
334
+
335
+ def separate_sheet(sheet, sheet_name = 'Sheet2', &block)
336
+ sheet.workbook.add_worksheet(name: sheet_name) { |sheet| yield sheet }
337
+ end
338
+
339
+ def froze(sheet, num_rows = 2)
340
+ sheet.sheet_view do |vs|
341
+ vs.pane do |pane|
342
+ pane.state = :frozen
343
+ pane.y_split = num_rows
344
+ end
345
+ end
346
+ end
347
+
348
+ def row_options
349
+ options = {}
350
+ types = columns.map { |c| c.options[:type] }
351
+ options[:types] = types unless types.all?(&:nil?)
352
+ options
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,55 @@
1
+ module AxlsxReport
2
+ # Report's column representation
3
+ class Column
4
+ attr_reader :name, :callable, :options
5
+
6
+ # Creates new column
7
+ #
8
+ # @param [String] name Column name
9
+ # @param [Proc] callable Proc to calculate column value form given object
10
+ # @param [Hash] options ({}) Column parameters
11
+ # @option options [Integer] width: (16) column width
12
+ # @option options [Symbol] transform: report object method to be called after value calculation
13
+ # @option options [Symbol] with: method name of given object to be used to base for cell value calculation
14
+ # @option options [String] units: Units text to be added to the header in the column
15
+ # @option options [Symbol] type: axlsx type to be used in this column. One of Axlsx::Cell::CELL_TYPES
16
+ def initialize(name, callable, options = {})
17
+ @name, @callable, @options = name, callable, options
18
+ end
19
+
20
+ # Quick access to options
21
+ %i{width units}.each do |option|
22
+ define_method(option) do
23
+ @options[option]
24
+ end
25
+ end
26
+
27
+ # Calculates column value for given object
28
+ #
29
+ # @param [AxlsxReport::Base] report Report the value is calculated for
30
+ # @param [Any] obj Source object for column value
31
+ # @return Column value for given object.
32
+ def value(report, obj)
33
+ source = extract_source(obj)
34
+ return nil if source.nil?
35
+ value =
36
+ if callable.arity.zero?
37
+ source.instance_exec &callable
38
+ else
39
+ report.instance_exec source, &callable
40
+ end
41
+ transform = options[:transform]
42
+ value = report.send transform, value if transform
43
+ value
44
+ end
45
+
46
+ private
47
+
48
+ def extract_source(obj)
49
+ with = options[:with]
50
+ return obj unless with
51
+ return nil unless obj.respond_to?(with)
52
+ obj.send(with)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,32 @@
1
+ module AxlsxReport
2
+ module ColumnNameConv
3
+ extend self
4
+
5
+ # 'Z' => 25
6
+ # 'AA' => 26
7
+ def column_name_to_num(name)
8
+ num = 0
9
+ name.upcase.each_char do |c|
10
+ num *= 26 if num > 0
11
+ add = c.ord - "A".ord + 1
12
+ raise "Invalid symbol in Excel column name: '#{c}'" if add < 1 || add > 26
13
+ num += add
14
+ end
15
+ num - 1
16
+ end
17
+
18
+ # 1 => 'А'
19
+ # 26 => 'Z'
20
+ # 27 => 'AA'
21
+ # 28 => 'АB'
22
+ def column_num_to_name(num)
23
+ name = ""
24
+ while num > 0
25
+ nm = (num - 1) % 26
26
+ num = (num - 1) / 26
27
+ name << ("A".ord + nm).chr
28
+ end
29
+ name.reverse
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ module AxlsxReport
2
+ class Group
3
+ attr_reader :name, :start_index
4
+ attr_accessor :end_index
5
+
6
+ def initialize(name, start_index)
7
+ @name = name
8
+ @start_index = start_index
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module AxlsxReport
2
+ VERSION = "0.1.1"
3
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: axlsx_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexey Volochnev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: axlsx
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.11'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.11'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: roo
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.13'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 1.13.2
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.13'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 1.13.2
95
+ description:
96
+ email:
97
+ - alexey.volochnev@gmail.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - ".gitignore"
103
+ - ".rspec"
104
+ - Gemfile
105
+ - LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - axlsx_report-0.1.0.gem
109
+ - axlsx_report.gemspec
110
+ - examples/base_report.rb
111
+ - examples/group_report.rb
112
+ - examples/lambda_report.rb
113
+ - examples/width_report.rb
114
+ - lib/axlsx_report.rb
115
+ - lib/axlsx_report/base.rb
116
+ - lib/axlsx_report/column.rb
117
+ - lib/axlsx_report/column_name_conv.rb
118
+ - lib/axlsx_report/group.rb
119
+ - lib/axlsx_report/version.rb
120
+ homepage: https://github.com/avolochnev/axlsx_report
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.2.5
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Declarative excel reports based on axlsx.
144
+ test_files: []