excel_templating 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.hound.yml +261 -0
  6. data/.rubocop.ph.yml +44 -0
  7. data/.rubocop.yml +3 -0
  8. data/.yardopts +1 -0
  9. data/ChangeLog.md +8 -0
  10. data/Gemfile +10 -0
  11. data/LICENSE.txt +3 -0
  12. data/README.md +133 -0
  13. data/Rakefile +43 -0
  14. data/excel_templating.gemspec +32 -0
  15. data/lib/excel_templating/document/data_source_registry/registry_list.rb +48 -0
  16. data/lib/excel_templating/document/data_source_registry/registry_renderer.rb +74 -0
  17. data/lib/excel_templating/document/data_source_registry.rb +64 -0
  18. data/lib/excel_templating/document/sheet/repeated_row.rb +39 -0
  19. data/lib/excel_templating/document/sheet.rb +133 -0
  20. data/lib/excel_templating/document.rb +71 -0
  21. data/lib/excel_templating/document_dsl.rb +85 -0
  22. data/lib/excel_templating/excel_abstraction/active_cell_reference.rb +59 -0
  23. data/lib/excel_templating/excel_abstraction/cell.rb +23 -0
  24. data/lib/excel_templating/excel_abstraction/cell_range.rb +26 -0
  25. data/lib/excel_templating/excel_abstraction/cell_reference.rb +39 -0
  26. data/lib/excel_templating/excel_abstraction/date.rb +36 -0
  27. data/lib/excel_templating/excel_abstraction/row.rb +29 -0
  28. data/lib/excel_templating/excel_abstraction/sheet.rb +102 -0
  29. data/lib/excel_templating/excel_abstraction/spread_sheet.rb +28 -0
  30. data/lib/excel_templating/excel_abstraction/time.rb +42 -0
  31. data/lib/excel_templating/excel_abstraction/work_book.rb +47 -0
  32. data/lib/excel_templating/excel_abstraction.rb +16 -0
  33. data/lib/excel_templating/render_helper.rb +14 -0
  34. data/lib/excel_templating/renderer.rb +251 -0
  35. data/lib/excel_templating/rspec_excel_matcher.rb +129 -0
  36. data/lib/excel_templating/version.rb +4 -0
  37. data/lib/excel_templating.rb +4 -0
  38. data/spec/assets/alphalist_7_4.mustache.xlsx +0 -0
  39. data/spec/assets/alphalist_seven_four_expected.xlsx +0 -0
  40. data/spec/assets/valid_cell.mustache.xlsx +0 -0
  41. data/spec/assets/valid_cell_expected.xlsx +0 -0
  42. data/spec/assets/valid_cell_expected_inline.xlsx +0 -0
  43. data/spec/assets/valid_column_expected.xlsx +0 -0
  44. data/spec/cell_validation_spec.rb +114 -0
  45. data/spec/column_validation_spec.rb +47 -0
  46. data/spec/excel_abstraction/active_cell_reference_spec.rb +73 -0
  47. data/spec/excel_abstraction/cell_range_spec.rb +36 -0
  48. data/spec/excel_abstraction/cell_reference_spec.rb +69 -0
  49. data/spec/excel_abstraction/cell_spec.rb +54 -0
  50. data/spec/excel_abstraction/date_spec.rb +27 -0
  51. data/spec/excel_abstraction/row_spec.rb +42 -0
  52. data/spec/excel_abstraction/sheet_spec.rb +83 -0
  53. data/spec/excel_abstraction/spread_sheet_spec.rb +35 -0
  54. data/spec/excel_abstraction/time_spec.rb +27 -0
  55. data/spec/excel_abstraction/work_book_spec.rb +22 -0
  56. data/spec/excel_helper.rb +16 -0
  57. data/spec/excel_templating_spec.rb +141 -0
  58. data/spec/spec_helper.rb +13 -0
  59. metadata +281 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5456436639ebbd5a99cc15d6b20cd329ebf65dc3e72a0f478bf435ae8691f58c
4
+ data.tar.gz: 1e255a1c7d76652157b28fa1c5c40cf7a04b2b81e395f8b81268625531891c5e
5
+ SHA512:
6
+ metadata.gz: d5d583cc68348314463f974f37cbfec702bde8e2e51756717dc8f5fe439cce2ef592d865655d8e325826c48322b7f181156dcd66ac8cc77576c1f0b1e0ee35b1
7
+ data.tar.gz: 2027fbc895ec3f659a39a48aaa5775cdf39b6709132d52413abe4d2b737ece0703fc2a806e48165dad0b6c7b372f19d01b05a4d53aab154cc95d18678d92640e
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.md
3
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ doc/
3
+ pkg/
4
+ vendor/cache/*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1,261 @@
1
+ # this is the default from hound's github, do not modify
2
+ AllCops:
3
+ Exclude:
4
+ - db/schema.rb
5
+
6
+ AccessorMethodName:
7
+ Enabled: false
8
+
9
+ ActionFilter:
10
+ Enabled: false
11
+
12
+ Alias:
13
+ Enabled: false
14
+
15
+ ArrayJoin:
16
+ Enabled: false
17
+
18
+ AsciiComments:
19
+ Enabled: false
20
+
21
+ AsciiIdentifiers:
22
+ Enabled: false
23
+
24
+ Attr:
25
+ Enabled: false
26
+
27
+ BlockNesting:
28
+ Enabled: false
29
+
30
+ CaseEquality:
31
+ Enabled: false
32
+
33
+ CharacterLiteral:
34
+ Enabled: false
35
+
36
+ ClassAndModuleChildren:
37
+ Enabled: false
38
+
39
+ ClassLength:
40
+ Enabled: false
41
+
42
+ ClassVars:
43
+ Enabled: false
44
+
45
+ CollectionMethods:
46
+ PreferredMethods:
47
+ find: detect
48
+ reduce: inject
49
+ collect: map
50
+ find_all: select
51
+
52
+ ColonMethodCall:
53
+ Enabled: false
54
+
55
+ CommentAnnotation:
56
+ Enabled: false
57
+
58
+ CyclomaticComplexity:
59
+ Enabled: false
60
+
61
+ Delegate:
62
+ Enabled: false
63
+
64
+ DeprecatedHashMethods:
65
+ Enabled: false
66
+
67
+ Documentation:
68
+ Enabled: false
69
+
70
+ DotPosition:
71
+ EnforcedStyle: trailing
72
+
73
+ DoubleNegation:
74
+ Enabled: false
75
+
76
+ EachWithObject:
77
+ Enabled: false
78
+
79
+ EmptyLiteral:
80
+ Enabled: false
81
+
82
+ Encoding:
83
+ Enabled: false
84
+
85
+ EvenOdd:
86
+ Enabled: false
87
+
88
+ FileName:
89
+ Enabled: false
90
+
91
+ FlipFlop:
92
+ Enabled: false
93
+
94
+ FormatString:
95
+ Enabled: false
96
+
97
+ GlobalVars:
98
+ Enabled: false
99
+
100
+ GuardClause:
101
+ Enabled: false
102
+
103
+ IfUnlessModifier:
104
+ Enabled: false
105
+
106
+ IfWithSemicolon:
107
+ Enabled: false
108
+
109
+ InlineComment:
110
+ Enabled: false
111
+
112
+ Lambda:
113
+ Enabled: false
114
+
115
+ LambdaCall:
116
+ Enabled: false
117
+
118
+ LineEndConcatenation:
119
+ Enabled: false
120
+
121
+ LineLength:
122
+ Max: 120
123
+ AllowURI: true
124
+
125
+ MethodLength:
126
+ Enabled: false
127
+
128
+ ModuleFunction:
129
+ Enabled: false
130
+
131
+ NegatedIf:
132
+ Enabled: false
133
+
134
+ NegatedWhile:
135
+ Enabled: false
136
+
137
+ Next:
138
+ Enabled: false
139
+
140
+ NilComparison:
141
+ Enabled: false
142
+
143
+ Not:
144
+ Enabled: false
145
+
146
+ NumericLiterals:
147
+ Enabled: false
148
+
149
+ OneLineConditional:
150
+ Enabled: false
151
+
152
+ OpMethod:
153
+ Enabled: false
154
+
155
+ ParameterLists:
156
+ Enabled: false
157
+
158
+ PercentLiteralDelimiters:
159
+ Enabled: false
160
+
161
+ PerlBackrefs:
162
+ Enabled: false
163
+
164
+ PredicateName:
165
+ NamePrefixBlacklist:
166
+ - is_
167
+
168
+ Proc:
169
+ Enabled: false
170
+
171
+ RaiseArgs:
172
+ Enabled: false
173
+
174
+ RegexpLiteral:
175
+ Enabled: false
176
+
177
+ SelfAssignment:
178
+ Enabled: false
179
+
180
+ SingleLineBlockParams:
181
+ Enabled: false
182
+
183
+ SingleLineMethods:
184
+ Enabled: false
185
+
186
+ SignalException:
187
+ Enabled: false
188
+
189
+ SpecialGlobalVars:
190
+ Enabled: false
191
+
192
+ StringLiterals:
193
+ EnforcedStyle: double_quotes
194
+
195
+ VariableInterpolation:
196
+ Enabled: false
197
+
198
+ TrailingComma:
199
+ Enabled: false
200
+
201
+ TrivialAccessors:
202
+ Enabled: false
203
+
204
+ VariableInterpolation:
205
+ Enabled: false
206
+
207
+ WhenThen:
208
+ Enabled: false
209
+
210
+ WhileUntilModifier:
211
+ Enabled: false
212
+
213
+ WordArray:
214
+ Enabled: false
215
+
216
+ # Lint
217
+
218
+ AmbiguousOperator:
219
+ Enabled: false
220
+
221
+ AmbiguousRegexpLiteral:
222
+ Enabled: false
223
+
224
+ AssignmentInCondition:
225
+ Enabled: false
226
+
227
+ ConditionPosition:
228
+ Enabled: false
229
+
230
+ DeprecatedClassMethods:
231
+ Enabled: false
232
+
233
+ ElseLayout:
234
+ Enabled: false
235
+
236
+ HandleExceptions:
237
+ Enabled: false
238
+
239
+ InvalidCharacterLiteral:
240
+ Enabled: false
241
+
242
+ LiteralInCondition:
243
+ Enabled: false
244
+
245
+ LiteralInInterpolation:
246
+ Enabled: false
247
+
248
+ Loop:
249
+ Enabled: false
250
+
251
+ ParenthesesAsGroupedExpression:
252
+ Enabled: false
253
+
254
+ RequireParentheses:
255
+ Enabled: false
256
+
257
+ UnderscorePrefixedVariableName:
258
+ Enabled: false
259
+
260
+ Void:
261
+ Enabled: false
data/.rubocop.ph.yml ADDED
@@ -0,0 +1,44 @@
1
+ # Older version
2
+ Style/EmptyLinesAroundBody:
3
+ Enabled: false
4
+
5
+ # Newer version (3 for the 1 above)
6
+ Style/EmptyLinesAroundClassBody:
7
+ Enabled: false
8
+
9
+ Style/EmptyLinesAroundModuleBody:
10
+ Enabled: false
11
+
12
+ Style/EmptyLinesAroundMethodBody:
13
+ Enabled: false
14
+
15
+ # Other
16
+
17
+ Style/StringLiterals:
18
+ Enabled: false
19
+
20
+ Style/FileName:
21
+ Enabled: false
22
+
23
+ Style/RedundantException:
24
+ Enabled: false
25
+
26
+ Style/SignalException:
27
+ Enabled: false
28
+
29
+ # PH Coding Rules
30
+ Style/Blocks:
31
+ Enabled: false
32
+
33
+ Style/CollectionMethods:
34
+ PreferredMethods:
35
+ detect: find
36
+
37
+ # Github's PR width is 120 characters
38
+ Metrics/LineLength:
39
+ Max: 120
40
+ AllowURI: true
41
+
42
+ # Align with the style guide, we don't prefer anything
43
+ Style/CollectionMethods:
44
+ Enabled: false
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_from:
2
+ - .rubocop.hound.yml
3
+ - .rubocop.ph.yml
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "excel_templating Documentation" --protected
data/ChangeLog.md ADDED
@@ -0,0 +1,8 @@
1
+ ### 0.3.0 / 2015-07-21
2
+
3
+ * Adding feature to be able to lock specific row and/or column in the Excel document.
4
+
5
+ ### 0.1 / 2015-03-09
6
+
7
+ * Initial release:
8
+
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'kramdown'
7
+ gem 'rubocop'
8
+ gem 'byebug'
9
+ gem 'gemfury'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2015 payrollhero
2
+
3
+ CLOSED LICENSE
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # excel_templating
2
+
3
+ * [Homepage](https://github.com/payrollhero/excel_templating)
4
+ * [Documentation](http://rubydoc.info/gems/excel_templating/frames)
5
+ * [Email](mailto:bramski at gmail.com)
6
+
7
+ ## Description
8
+
9
+ A library that does excel templating using mustaching.
10
+
11
+ ## Features
12
+
13
+ ## Examples
14
+ ```ruby
15
+ require 'excel_templating'
16
+
17
+ class MyTemplate < ExcelTemplating::Document
18
+ template "my_template.mustache.xlsx")
19
+ title "My fancy report {{year}}"
20
+ organization "{{organization_name}}"
21
+ default_styling(
22
+ text_wrap: 0,
23
+ font: "Calibri",
24
+ size: 10,
25
+ align: :left,
26
+ )
27
+ sheet 1 do
28
+ repeat_row 17, with: :repeating_data
29
+
30
+ style_columns(
31
+ default: {
32
+ width: inches(1.98)
33
+ },
34
+ columns: {
35
+ 3 => { width: inches(1.98) },
36
+ 4 => { width: inches(1.98) },
37
+ 5 => { width: inches(0.39) }
38
+ }
39
+ )
40
+ end
41
+ end
42
+ ```
43
+
44
+ ## Cell Validation
45
+ You may validate that cells belong to a particular set of values 'dropdown'
46
+ this is done by specifying data sources for your sheet and then referencing
47
+ them in your template.
48
+ ``` ruby
49
+ class MyTemplate < ExcelTemplating::Document
50
+ template 'my_template.mustache.xlsx'
51
+
52
+ list_source :valid_foos, title: "Foos", list: ["foo", "bar"]
53
+ sheet 1 do
54
+ validate_cell row: 5, column: 1, with: :valid_foos
55
+ repeat_row 17, with :repeating_data do
56
+ validate_column 1, with: :valid_foos
57
+ end
58
+ end
59
+ end
60
+ ```
61
+
62
+ The 'list' item may be an Array or :from_data, if it says :from_data, the list
63
+ will be sourced from the same key in the 'all_sheets' data portion.
64
+
65
+ The excel templater will add an additional sheet to your generated xls
66
+ file called 'Data Sources' and 'foo' and 'bar' will be written to that sheet.
67
+ If you don't want a sheet to be created, use inline: true to write the validation
68
+ directly to the cell, NOTE there are limits on the size of the list
69
+ you may write inline.
70
+
71
+ ## Protecting document
72
+ You can specify locking for any row or column. By default all cells are marked as locked.
73
+ Locking is applied when you call `protect_document` method.
74
+ ``` ruby
75
+ class MyTemplate < ExcelTemplating::Document
76
+ template 'my_template.mustache.xlsx'
77
+ default_styling locked: 0 # default set to not locked
78
+
79
+ list_source :valid_foos, title: "Foos", list: ["foo", "bar"]
80
+ sheet 1 do
81
+ validate_cell row: 5, column: 1, with: :valid_foos
82
+ repeat_row 17, with :repeating_data do
83
+ validate_column 1, with: :valid_foos
84
+ end
85
+
86
+ # Lets lock the first row
87
+ style_rows(
88
+ default: { },
89
+ rows: {
90
+ 1 => { format: { locked: 1 } }
91
+ }
92
+ )
93
+ end
94
+
95
+ # add call `protect_document` to lock specified row
96
+ protect_document
97
+ end
98
+ ```
99
+
100
+ ## Rspec Excel Matching
101
+ The library also adds an excel rspec matcher.
102
+ ```ruby
103
+ require 'excel_templating/rspec_excel_matcher'
104
+
105
+ describe MyTemplate do
106
+ subject { described_class.new }
107
+ it do
108
+ expect do
109
+ subject.render do |path|
110
+ expect(path).to match_excel_content('my_expected_file.xlsx')
111
+ end
112
+ end.not_to raise_error
113
+ end
114
+ end
115
+ ```
116
+
117
+ ## Deploying
118
+
119
+ 1. Update lib/excel_templating/version.rb
120
+ 2. Update ChangeLog.md
121
+ 3. Commit the 2 changed files with the version number
122
+ 5. Push this to git
123
+ 6. Run `rake release`
124
+
125
+ ## Install
126
+
127
+ $ gem install excel_templating
128
+
129
+ ## Copyright
130
+
131
+ Copyright (c) 2015 payrollhero
132
+
133
+ See {file:LICENSE.txt} for details.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+ require 'gemfury/tasks'
23
+
24
+ require 'rubygems/tasks'
25
+ Gem::Tasks.new(release: false)
26
+
27
+ require 'rspec/core/rake_task'
28
+ RSpec::Core::RakeTask.new
29
+
30
+ task test: :spec
31
+ task default: :spec
32
+
33
+ require 'yard'
34
+ YARD::Rake::YardocTask.new
35
+ task doc: :yard
36
+
37
+ task :release do
38
+ Rake::Task['fury:release'].invoke(nil, 'payrollhero')
39
+ Dir['*.gem'].each do |fn|
40
+ puts "Removing: #{fn}"
41
+ File.unlink(fn)
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/excel_templating/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "excel_templating"
7
+ gem.version = ExcelTemplating::VERSION
8
+ gem.summary = "A library which allows you to slam data into excel files using mustaching."
9
+ gem.description = "."
10
+ gem.license = "MIT"
11
+ gem.authors = ["bramski", "Mykola Kyryk"]
12
+ gem.email = "bramski@gmail.com"
13
+ gem.homepage = "https://github.com/payrollhero/excel_templating"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "mustache"
21
+ gem.add_dependency "roo", ">= 2.0.0beta1", "< 3"
22
+ gem.add_dependency "roo-xls"
23
+ gem.add_dependency "write_xlsx"
24
+ gem.add_dependency "writeexcel"
25
+
26
+ gem.add_development_dependency 'bundler', '~> 1.0'
27
+ gem.add_development_dependency 'rake', '~> 0.8'
28
+ gem.add_development_dependency 'rspec', '~> 3.3'
29
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
30
+ gem.add_development_dependency 'yard', '~> 0.8'
31
+ gem.add_development_dependency 'rspec-its'
32
+ end
@@ -0,0 +1,48 @@
1
+ module ExcelTemplating
2
+ # Represents a data source list used for validation of cell information
3
+ class Document::DataSourceRegistry::RegistryList
4
+ # @param [Integer] order
5
+ # @param [Symbol] symbol
6
+ # @param [String] title
7
+ # @param [Array<String>|Symbol] list
8
+ # @param [TrueClass|FalseClass] inline
9
+ def initialize(order, symbol, title, list, inline)
10
+ @title = title
11
+ @list = list
12
+ @inline = inline
13
+ @order = order
14
+ @symbol = symbol
15
+ pre_validate!
16
+ end
17
+
18
+ attr_reader :title, :order, :symbol, :list
19
+
20
+ # @return [Boolean] Is this to be rendered inline?
21
+ def inline?
22
+ @inline
23
+ end
24
+
25
+ # @return [Boolean] Is this to be rendered on the data sheet?
26
+ def data_sheet?
27
+ !inline?
28
+ end
29
+
30
+ # @param [Hash] data The data object from which the document is being rendered
31
+ # @return [Array<String>] The validation objects
32
+ def items(data)
33
+ if list == :from_data
34
+ data[symbol]
35
+ else
36
+ list
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def pre_validate!
43
+ unless list.is_a?(Array) || list == :from_data
44
+ raise ArgumentError, "List must be an array or :from_data"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,74 @@
1
+ module ExcelTemplating
2
+ # In charge of rendering the data source registry to the excel document
3
+ class Document::DataSourceRegistry::RegistryRenderer
4
+ def initialize(registry, data)
5
+ @registry = registry
6
+ @data = data
7
+ end
8
+
9
+ # @param [Symbol] source_symbol
10
+ # @return [Hash] Gives back a hash of options which adds the validation options for the symbol
11
+ def absolute_reference_for(source_symbol)
12
+ unless registry.has_registry?(source_symbol)
13
+ raise ArgumentError, "#{source_symbol} is not a defined data_source. Defined data sources are " +
14
+ "#{registry.supported_registries}"
15
+ end
16
+ registry_info = registry[source_symbol]
17
+ validation_options_for(registry_info)
18
+ end
19
+
20
+ # Wrote this registry to the specified workbook. Uses the sheet name 'DataSource'
21
+ # @param [ExcelAbstraction::Workbook] workbook
22
+ def write_sheet(workbook)
23
+ return unless registry.any_data_sheet_symbols?
24
+
25
+ data_sheet = workbook.add_worksheet(sheet_name)
26
+ registry.each do |registry_info|
27
+ write_data_source_to_sheet(data_sheet, registry_info)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :data, :registry
34
+
35
+ def write_data_source_to_sheet(data_sheet, registry_info)
36
+ column_letter = RenderHelper.letter_for(registry_info.order)
37
+ data_sheet.write "#{column_letter}1", registry_info.title
38
+ registry_info.items(data).each_with_index do |item, item_index|
39
+ row_offset = item_index + 2
40
+ data_sheet.write("#{column_letter}#{row_offset}", item)
41
+ end
42
+ end
43
+
44
+ def validation_options_for(registry_info)
45
+ if registry_info.inline?
46
+ inline_validation_options(registry_info)
47
+ else
48
+ data_sheet_validation_options(registry_info)
49
+ end
50
+ end
51
+
52
+ def data_sheet_validation_options(registry_info)
53
+ row_letter = RenderHelper.letter_for(registry_info.order)
54
+ start_column = 2
55
+ end_column = registry_info.items(data).length + 1
56
+ list_validation(source: "#{sheet_name}!$#{row_letter}$#{start_column}:$#{row_letter}$#{end_column}")
57
+ end
58
+
59
+ def inline_validation_options(registry_info)
60
+ list_validation(source: registry_info.items(data).map(&:to_s))
61
+ end
62
+
63
+ def list_validation(source:)
64
+ {
65
+ validate: 'list',
66
+ source: source
67
+ }
68
+ end
69
+
70
+ def sheet_name
71
+ "DataSource"
72
+ end
73
+ end
74
+ end