spreadsheet_architect 1.4.8 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -2
  3. data/README.md +117 -98
  4. data/Rakefile +8 -1
  5. data/lib/generators/spreadsheet_architect/add_project_defaults_generator.rb +12 -3
  6. data/lib/spreadsheet_architect.rb +19 -330
  7. data/lib/spreadsheet_architect/action_controller_renderers.rb +9 -19
  8. data/lib/spreadsheet_architect/class_methods/csv.rb +22 -0
  9. data/lib/spreadsheet_architect/class_methods/ods.rb +61 -0
  10. data/lib/spreadsheet_architect/class_methods/xlsx.rb +162 -0
  11. data/lib/spreadsheet_architect/exceptions.rb +47 -0
  12. data/lib/spreadsheet_architect/{set_mime_types.rb → mime_types.rb} +0 -2
  13. data/lib/spreadsheet_architect/monkey_patches/axlsx_column_width.rb +23 -0
  14. data/lib/spreadsheet_architect/utils.rb +223 -0
  15. data/lib/spreadsheet_architect/utils/xlsx.rb +126 -0
  16. data/lib/spreadsheet_architect/version.rb +1 -1
  17. data/test/rails_app/Gemfile +17 -0
  18. data/test/rails_app/Gemfile.lock +176 -0
  19. data/test/rails_app/README.md +24 -0
  20. data/test/rails_app/Rakefile +6 -0
  21. data/test/rails_app/app/assets/config/manifest.js +3 -0
  22. data/test/rails_app/app/assets/javascripts/application.js +16 -0
  23. data/test/rails_app/app/assets/javascripts/cable.js +13 -0
  24. data/test/rails_app/app/assets/stylesheets/application.css +15 -0
  25. data/test/rails_app/app/channels/application_cable/channel.rb +4 -0
  26. data/test/rails_app/app/channels/application_cable/connection.rb +4 -0
  27. data/test/rails_app/app/controllers/application_controller.rb +3 -0
  28. data/test/rails_app/app/controllers/spreadsheets_controller.rb +74 -0
  29. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  30. data/test/rails_app/app/jobs/application_job.rb +2 -0
  31. data/test/rails_app/app/mailers/application_mailer.rb +4 -0
  32. data/test/rails_app/app/models/active_model_object.rb +14 -0
  33. data/test/rails_app/app/models/application_record.rb +3 -0
  34. data/test/rails_app/app/models/bad_plain_ruby_object.rb +3 -0
  35. data/test/rails_app/app/models/custom_post.rb +15 -0
  36. data/test/rails_app/app/models/plain_ruby_object.rb +19 -0
  37. data/test/rails_app/app/models/post.rb +3 -0
  38. data/test/rails_app/app/views/layouts/application.html.erb +14 -0
  39. data/test/rails_app/app/views/layouts/mailer.html.erb +13 -0
  40. data/test/rails_app/app/views/layouts/mailer.text.erb +1 -0
  41. data/test/rails_app/bin/bundle +3 -0
  42. data/test/rails_app/bin/rails +9 -0
  43. data/test/rails_app/bin/rake +9 -0
  44. data/test/rails_app/bin/setup +34 -0
  45. data/test/rails_app/bin/spring +16 -0
  46. data/test/rails_app/bin/update +29 -0
  47. data/test/rails_app/config.ru +5 -0
  48. data/test/rails_app/config/application.rb +15 -0
  49. data/test/rails_app/config/boot.rb +3 -0
  50. data/test/rails_app/config/cable.yml +9 -0
  51. data/test/rails_app/config/database.yml +16 -0
  52. data/test/rails_app/config/environment.rb +5 -0
  53. data/test/rails_app/config/environments/development.rb +54 -0
  54. data/test/rails_app/config/environments/production.rb +86 -0
  55. data/test/rails_app/config/environments/test.rb +42 -0
  56. data/test/rails_app/config/initializers/application_controller_renderer.rb +6 -0
  57. data/test/rails_app/config/initializers/assets.rb +11 -0
  58. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  59. data/test/rails_app/config/initializers/cookies_serializer.rb +5 -0
  60. data/test/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  61. data/test/rails_app/config/initializers/inflections.rb +16 -0
  62. data/test/rails_app/config/initializers/mime_types.rb +4 -0
  63. data/test/rails_app/config/initializers/new_framework_defaults.rb +24 -0
  64. data/test/rails_app/config/initializers/session_store.rb +3 -0
  65. data/test/rails_app/config/initializers/wrap_parameters.rb +14 -0
  66. data/test/rails_app/config/locales/en.yml +23 -0
  67. data/test/rails_app/config/routes.rb +7 -0
  68. data/test/rails_app/config/secrets.yml +22 -0
  69. data/test/{spreadsheet_architect.sqlite3.db → rails_app/db/development.sqlite3} +0 -0
  70. data/test/rails_app/db/migrate/20170103234524_add_posts.rb +10 -0
  71. data/test/rails_app/db/schema.rb +23 -0
  72. data/test/rails_app/db/seeds.rb +7 -0
  73. data/test/rails_app/db/test.sqlite3 +0 -0
  74. data/test/rails_app/log/development.log +1195 -0
  75. data/test/rails_app/log/test.log +52766 -0
  76. data/test/rails_app/public/404.html +67 -0
  77. data/test/rails_app/public/422.html +67 -0
  78. data/test/rails_app/public/500.html +66 -0
  79. data/test/rails_app/public/apple-touch-icon-precomposed.png +0 -0
  80. data/test/rails_app/public/apple-touch-icon.png +0 -0
  81. data/test/rails_app/public/favicon.ico +0 -0
  82. data/test/rails_app/public/robots.txt +5 -0
  83. data/test/rails_app/test/controllers/spreadsheets_controller_test.rb +46 -0
  84. data/test/rails_app/test/models/active_model_object_test.rb +54 -0
  85. data/test/rails_app/test/models/bad_plain_ruby_object_test.rb +30 -0
  86. data/test/rails_app/test/models/csv_test.rb +60 -0
  87. data/test/rails_app/test/models/custom_post_test.rb +47 -0
  88. data/test/rails_app/test/models/ods_test.rb +68 -0
  89. data/test/rails_app/test/models/plain_ruby_object_test.rb +54 -0
  90. data/test/rails_app/test/models/post_test.rb +47 -0
  91. data/test/rails_app/test/models/spreadsheet_architect_utils_test.rb +68 -0
  92. data/test/rails_app/test/models/xlsx_test.rb +99 -0
  93. data/test/rails_app/test/test_helper.rb +21 -0
  94. data/test/rails_app/tmp/active_model_object/csv.csv +21 -0
  95. data/test/rails_app/tmp/active_model_object/ods.ods +0 -0
  96. data/test/rails_app/tmp/active_model_object/xlsx.xlsx +0 -0
  97. data/test/rails_app/tmp/controller_tests/alt_xlsx.xlsx +0 -0
  98. data/test/rails_app/tmp/controller_tests/csv.csv +1 -0
  99. data/test/rails_app/tmp/controller_tests/ods.ods +0 -0
  100. data/test/rails_app/tmp/controller_tests/xlsx.xlsx +0 -0
  101. data/test/rails_app/tmp/custom_posts/csv.csv +1 -0
  102. data/test/rails_app/tmp/custom_posts/empty.xlsx +0 -0
  103. data/test/rails_app/tmp/custom_posts/ods.ods +0 -0
  104. data/test/rails_app/tmp/custom_posts/xlsx.xlsx +0 -0
  105. data/test/rails_app/tmp/empty_model.csv +1 -0
  106. data/test/rails_app/tmp/empty_model.xlsx +0 -0
  107. data/test/rails_app/tmp/empty_sa.csv +0 -0
  108. data/test/rails_app/tmp/empty_sa.xlsx +0 -0
  109. data/test/rails_app/tmp/extreme.xlsx +0 -0
  110. data/test/rails_app/tmp/model.csv +1 -0
  111. data/test/rails_app/tmp/model.xlsx +0 -0
  112. data/test/rails_app/tmp/ods/empty_model.ods +0 -0
  113. data/test/rails_app/tmp/ods/empty_sa.ods +0 -0
  114. data/test/rails_app/tmp/ods/model.ods +0 -0
  115. data/test/rails_app/tmp/ods/model_options.ods +0 -0
  116. data/test/rails_app/tmp/ods/sa.ods +0 -0
  117. data/test/rails_app/tmp/options.csv +1 -0
  118. data/test/rails_app/tmp/plain_ruby_object/csv.csv +4 -0
  119. data/test/rails_app/tmp/plain_ruby_object/ods.ods +0 -0
  120. data/test/rails_app/tmp/plain_ruby_object/xlsx.xlsx +0 -0
  121. data/test/rails_app/tmp/posts/csv.csv +1 -0
  122. data/test/rails_app/tmp/posts/empty.xlsx +0 -0
  123. data/test/rails_app/tmp/posts/ods.ods +0 -0
  124. data/test/rails_app/tmp/posts/xlsx.xlsx +0 -0
  125. data/test/rails_app/tmp/sa.csv +4 -0
  126. data/test/rails_app/tmp/sa.xlsx +0 -0
  127. metadata +255 -21
  128. data/lib/spreadsheet_architect/axlsx_column_width_patch.rb +0 -13
  129. data/test/database.yml +0 -3
  130. data/test/helper.rb +0 -52
  131. data/test/tc_spreadsheet_architect.rb +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ba54bf20a206113ae9aaa6f365d6ede5ce5da8e
4
- data.tar.gz: cf706a260a73b220b98516c644fcd03ed71f57a7
3
+ metadata.gz: 4d4000e6f14557a9a68ad0c48c9b0af57e537f50
4
+ data.tar.gz: 8d38d5252918e37378b38d98fac0ec73a85cd396
5
5
  SHA512:
6
- metadata.gz: 899a3edfe864b869c077e651d998be65fd0d7871e95f27c0160a0964312cee173caba47547af58cdbd939a1b26c431b37924589882c556180167aa4b529baecc
7
- data.tar.gz: 4fdff1744122edc359486e77b4e524a293e776f28e23e1708416837e02fa22fb1a224a5ce2d784d8cdc2537ad7d54dd44ce4c43ef93d6772bf523c7fce287605
6
+ metadata.gz: 15cf33b58be7549574d0945fdadd9446bf0be3fb986577767de14147f53e8b3e71c893ce9fa603fce66237cf706ebf2e85c96dd3332462d638715d972ee635ee
7
+ data.tar.gz: 3181178d0ec7a662af3c23cbcaea731607d54de5c1a9c43af45acdb9060e6cc9afdb26f8a14d96e2ebdd491423dfdcd9991f139962ea1254728a2ef6c7c07b6f
data/CHANGELOG.md CHANGED
@@ -1,12 +1,20 @@
1
1
  CHANGELOG
2
2
  ---------
3
3
 
4
+ - **January.28.2017**: 2.0.0
5
+ - Add to xlsx: `merges`, `column_styles`, `range_styles`, `borders`, `column_widths` multi-row headers, date/time default format_code
6
+ - Add `column_types` option for xlsx and ods
7
+ - Add ability to make multi-sheet spreadsheets in XLSX & ODS
8
+ - Adds `axlsx_styler` gem dependency
9
+ - Add Examples
10
+ - Add Axlsx Style Reference
11
+ - Refractor into smaller files
4
12
  - **December.6.2016**: 1.4.8
5
13
  - Lock `rodf` gem to v0.3.7 for last v1 version of this gem
6
14
  - **November.7.2016**: 1.4.7
7
15
  - Fix method arguments for `to_rodf_spreadsheet` method
8
- - **May.12.2016**: 1.4.6
9
- - Fix ruby <= 2.1 hash syntax
16
+ - **May.16.2016**: 1.4.6
17
+ - Fix hash syntax for support of ruby v2.1 and below
10
18
  - **May.4.2016**: 1.4.5
11
19
  - Bug fixes
12
20
  - **May.3.2016**: 1.4.4
data/README.md CHANGED
@@ -1,16 +1,19 @@
1
1
  # Spreadsheet Architect
2
- <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=VKY8YAWAS5XRQ&lc=CA&item_name=Weston%20Ganger&item_number=spreadsheet_architect&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest" target="_blank" title="Buy Me A Coffee"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" alt="Buy Me A Coffee"/></a>
2
+ <a href='https://www.patreon.com/bePatron?u=4956947' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://miraclesfor.me/wp-content/plugins/patron-button-and-widgets-by-codebard/images/patreon-medium-button.png' border='0' alt='Become a Patron' /></a>
3
+ <a href='https://ko-fi.com/A5071NK' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
3
4
 
4
5
  Spreadsheet Architect is a library that allows you to create XLSX, ODS, or CSV spreadsheets easily from ActiveRecord relations, Plain Ruby classes, or predefined data.
5
6
 
6
7
  Key Features:
7
8
 
8
- - Can generate headers & columns from ActiveRecord column_names, or a Class/Model's spreadsheet_columns method, or one creation with 2D array of data
9
- - Plain Ruby support
10
- - Plain from ActiveRecord relations or Ruby Objects from models ActiveRecord, or 2d Array Data
11
- - Easily style headers and rows
12
- - Model/Class or Project specific defaults
13
- - Simple to use ActionController renderers
9
+ - Can generate headers & columns from ActiveRecord column_names or a Class/Model's `spreadsheet_columns` method
10
+ - Dead simple custom spreadsheets with custom data
11
+ - Data Sources: ActiveRecord relations, array of Ruby Objects, or 2D Array Data
12
+ - Easily style and customize spreadsheets
13
+ - Create multi sheet spreadsheets
14
+ - Setting Class/Model or Project specific defaults
15
+ - Simple to use ActionController renderers for Rails
16
+ - Plain Ruby (without Rails) supported
14
17
 
15
18
  Spreadsheet Architect adds the following methods:
16
19
  ```ruby
@@ -30,20 +33,15 @@ data = [[1,2,3], [4,5,6], [7,8,9]]
30
33
  SpreadsheetArchitect.to_xlsx(data: data, headers: headers)
31
34
  SpreadsheetArchitect.to_ods(data: data, headers: headers)
32
35
  SpreadsheetArchitect.to_csv(data: data, header: false)
33
-
34
- # These return a ruby object that can be further manipulated
35
- # These methods may also be used on models/classes
36
- SpreadsheetArchitect.to_axlsx('package', {data: data, headers: headers})
37
- SpreadsheetArchitect.to_axlsx('sheet', {data: data, headers: headers})
38
- SpreadsheetArchitect.to_rodf_spreadsheet(data: data, headers: headers)
39
36
  ```
40
37
 
41
38
  # Install
42
39
  ```ruby
43
- gem install spreadsheet_architect
40
+ # Gemfile
41
+ gem 'spreadsheet_architect'
44
42
  ```
45
43
 
46
- # Class/Model Setup
44
+ # Basic Class/Model Setup
47
45
 
48
46
  ### Model
49
47
  ```ruby
@@ -57,14 +55,14 @@ class Post < ActiveRecord::Base #activerecord not required
57
55
  #optional for activerecord classes, defaults to the models column_names
58
56
  def spreadsheet_columns
59
57
 
60
- #[[Label, Method/Statement to Call on each Instance, Cell Type(optional)]....]
58
+ #[[Label, Method/Statement, Type(optional) to Call on each Instance, Cell Type(optional)]....]
61
59
  [
62
60
  ['Title', :title],
63
61
  ['Content', content],
64
- ['Author', (author.name rescue nil)],
62
+ ['Author', (author.name if author)],
65
63
  ['Published?', (published ? 'Yes' : 'No')],
66
64
  ['Published At', :published_at],
67
- ['# of Views', :number_of_views],
65
+ ['# of Views', :number_of_views, :float],
68
66
  ['Rating', :rating],
69
67
  ['Category/Tags', "#{category.name} - #{tags.collect(&:name).join(', ')}"]
70
68
  ]
@@ -73,11 +71,13 @@ class Post < ActiveRecord::Base #activerecord not required
73
71
  [:title, :content, :published]
74
72
 
75
73
  # OR a Combination of Both ex. "Title", "Content", "Author Name", "Published"
76
- [:title, :content, ['Author Name',(author.name rescue nil)], :published]
74
+ [:title, :content, ['Author Name',(author.name rescue nil)], ['# of Views', :number_of_views, :float], :published]
77
75
  end
78
76
  end
79
77
  ```
80
78
 
79
+ Note: Do not define your labels inside this method if you are going to be using custom headers in the model or project defaults.
80
+
81
81
  # Usage
82
82
 
83
83
  ### Method 1: Controller (for Rails)
@@ -123,7 +123,7 @@ class PostsController < ActionController::Base
123
123
  respond_to do |format|
124
124
  format.html
125
125
  format.xlsx { render xlsx: @posts.to_xlsx(headers: false) }
126
- format.ods { render ods: Post.to_odf(instances: @posts) }
126
+ format.ods { render ods: Post.to_ods(instances: @posts) }
127
127
  format.csv{ render csv: @posts.to_csv(headers: false), file_name: 'articles' }
128
128
  end
129
129
  end
@@ -132,88 +132,102 @@ end
132
132
 
133
133
  ### Method 2: Save to a file manually
134
134
  ```ruby
135
- # Ex. with ActiveRecord realtion
136
- File.open('path/to/file.xlsx') do |f|
135
+ # Ex. with ActiveRecord relation
136
+ File.open('path/to/file.xlsx', 'w+b') do |f|
137
137
  f.write{ Post.order(published_at: :asc).to_xlsx }
138
138
  end
139
- File.open('path/to/file.ods') do |f|
139
+ File.open('path/to/file.ods', 'w+b) do |f|
140
140
  f.write{ Post.order(published_at: :asc).to_ods }
141
141
  end
142
- File.open('path/to/file.csv') do |f|
142
+ File.open('path/to/file.csv', 'w+b') do |f|
143
143
  f.write{ Post.order(published_at: :asc).to_csv }
144
144
  end
145
145
 
146
146
  # Ex. with plain ruby class
147
- File.open('path/to/file.xlsx') do |f|
147
+ File.open('path/to/file.xlsx', 'w+b') do |f|
148
148
  f.write{ Post.to_xlsx(instances: posts_array) }
149
149
  end
150
150
 
151
151
  # Ex. One time Usage
152
- File.open('path/to/file.xlsx') do |f|
152
+ File.open('path/to/file.xlsx', 'w+b') do |f|
153
153
  headers = ['Col 1','Col 2','Col 3']
154
154
  data = [[1,2,3], [4,5,6], [7,8,9]]
155
155
  f.write{ SpreadsheetArchitect::to_xlsx(data: data, headers: headers) }
156
156
  end
157
157
  ```
158
+ <br>
158
159
 
159
- # Method & Options
160
+ # Methods & Options
160
161
 
161
- <br>
162
- #### `.to_xlsx` - (on custom class/model)
163
- |Option|Type|Default|Notes|
164
- |---|---|---|---|
165
- |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method |
166
- |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.|
167
- |**headers**|Boolean|`true`|Pass false to skip the header row.|
168
- |**sheet_name**|String|Class name||
169
- |**header_style**|Hash|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`||
170
- |**row_style**|Hash|`{background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false, number_format_code: nil}`|Styles for non-header rows.|
162
+
163
+ ## SomeClass.to_xlsx
164
+
165
+ |Option|Default|Notes|
166
+ |---|---|---|
167
+ |**spreadsheet_columns**<br>*Array*| This defaults to your models custom `spreadsheet_columns` method or any custom defaults defined.<br>If none of those then falls back to `self.column_names` for ActiveRecord models. | Use this option to override the model instances `spreadsheet_columns` method|
168
+ |**instances**<br>*Array*| |**Required only for Non-ActiveRecord classes** Array of class/model instances.|
169
+ |**headers**<br>*2D Array*|This defaults to your models custom spreadsheet_columns method or `self.column_names.collect(&:titleize)`|Pass `false` to skip the header row.|
170
+ |**sheet_name**<br>*String*|The class name||
171
+ |**header_style**<br>*Hash*|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|See all available style options [here](https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_styles_reference.md)|
172
+ |**row_style**<br>*Hash*|`{background_color: nil, color: "000000", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false, format_code: nil}`|Styles for non-header rows. See all available style options [here](https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_styles_reference.md)|
173
+ |**column_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
174
+ |**range_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
175
+ |**merges**<br>*Array*||Merge cells. [See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
176
+ |**borders**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
177
+ |**column_widths**<br>*Array*||Sometimes you may want explicit column widths. Use nil if you want a column to autofit again.|
171
178
 
172
179
  <br>
173
- #### `.to_ods` - (on custom class/model)
174
- |Option|Type|Default|Notes|
175
- |---|---|---|---|
176
- |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method |
177
- |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.|
178
- |**headers**|Boolean|`true`|Pass false to skip the header row.|
179
- |**sheet_name**|String|Class name||
180
- |**header_style**|Hash|`{color: "000000", align: :center, font_size: 10, bold: true}`|Note: Currently only supports these options (values can be changed though)|
181
- |**row_style**|Hash|`{color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently only supports these options (values can be changed though)|
180
+ ## SomeClass.to_ods
181
+ |Option|Default|Notes|
182
+ |---|---|---|
183
+ |**spreadsheet_columns**<br>*Array*| This defaults to your models custom `spreadsheet_columns` method or any custom defaults defined.<br>If none of those then falls back to `self.column_names` for ActiveRecord models. | Use this option to override the model instances `spreadsheet_columns` method|
184
+ |**instances**<br>*Array*| |**Required only for Non-ActiveRecord models** Array of class/model instances.|
185
+ |**headers**<br>*2D Array*|`self.column_names.collect(&:titleize)`|Pass `false` to skip the header row.|
186
+ |**sheet_name**<br>*String*|The class name||
187
+ |**header_style**<br>*Hash*|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_size: 10, bold: true}`|Note: Currently ODS only supports these options (values can be changed though)|
188
+ |**row_style**<br>*Hash*|`{background_color: nil, color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently ODS only supports these options|
182
189
 
183
190
  <br>
184
- #### `.to_csv` - (on custom class/model)
185
- |Option|Type|Default|Notes|
186
- |---|---|---|---|
187
- |**spreadsheet_columns**|Array| AR Model column_names | Required if `spreadsheet_columns` not defined on class except with ActiveRecord models which default to the `column_names` method. Will override models `spreadsheet_columns` method |
188
- |**instances**|Array| |**Required for Non-ActiveRecord classes** Array of class/model instances.|
189
- |**headers**|Boolean|`true`|Pass false to skip the header row.|
191
+ ## SomeClass.to_csv
192
+ |Option|Default|Notes|
193
+ |---|---|---|
194
+ |**spreadsheet_columns**<br>*Array*| This defaults to your models custom `spreadsheet_columns` method or any custom defaults defined.<br>If none of those then falls back to `self.column_names` for ActiveRecord models. | Use this to option override the model instances `spreadsheet_columns` method|
195
+ |**instances**<br>*Array*| |**Required only for Non-ActiveRecord classes** Array of class/model instances.|
196
+ |**headers**<br>*2D Array*|`self.column_names.collect(&:titleize)`| Data for the header rows cells. Pass `false` to skip the header row.|
190
197
 
191
198
  <br>
192
- #### `SpreadsheetArchitect.to_xlsx`
193
- |Option|Type|Default|Notes|
194
- |---|---|---|---|
195
- |**data**|Array| |**Required** 2D Array of data for the non-header row cells. |
196
- |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.|
197
- |**sheet_name**|String|`SpreadsheetArchitect`||
198
- |**header_style**|Hash|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`||
199
- |**row_style**|Hash|`{background_color: nil, color: "FFFFFF", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false, number_format_code: nil}`|Styles for non-header rows.|
199
+ ## SpreadsheetArchitect.to_xlsx
200
+ |Option|Default|Notes|
201
+ |---|---|---|
202
+ |**data**<br>*Array*| |Data for the non-header row cells. |
203
+ |**headers**<br>*2D Array*|`false`|Data for the header row cells. Pass `false` to skip the header row.|
204
+ |**sheet_name**<br>*String*|`Sheet1`||
205
+ |**header_style**<br>*Hash*|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false}`|See all available style options [here](https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_styles_reference.md)|
206
+ |**row_style**<br>*Hash*|`{background_color: nil, color: "000000", align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false, format_code: nil}`|Styles for non-header rows. See all available style options [here](https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_styles_reference.md)|
207
+ |**column_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
208
+ |**range_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
209
+ |**merges**<br>*Array*||Merge cells. [See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
210
+ |**borders**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)|
211
+ |**column_types**<br>*Array*||Valid types for XLSX are :string, :integer, :float, :date, :time, :boolean, nil = auto determine|
212
+ |**column_widths**<br>*Array*||Sometimes you may want explicit column widths. Use nil if you want a column to autofit again.|
200
213
 
201
214
  <br>
202
- #### `SpreadsheetArchitect.to_ods`
203
- |Option|Type|Default|Notes|
204
- |---|---|---|---|
205
- |**data**|Array| |**Required** 2D Array of data for the non-header row cells.|
206
- |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.|
207
- |**sheet_name**|String|`SpreadsheetArchitect`||
208
- |**header_style**|Hash|`{color: "000000", align: :center, font_size: 10, bold: true}`|Note: Currently only supports these options (values can be changed though)|
209
- |**row_style**|Hash|`{color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently only supports these options (values can be changed though)|
215
+ ## SpreadsheetArchitect.to_ods
216
+ |Option|Default|Notes|
217
+ |---|---|---|
218
+ |**data**<br>*2D Array*| |Data for the non-header row cells.|
219
+ |**headers**<br>*2D Array*|`false`|Data for the header rows cells. Pass `false` to skip the header row.|
220
+ |**sheet_name**<br>*String*|`Sheet1`||
221
+ |**header_style**<br>*Hash*|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_size: 10, bold: true}`|Note: Currently ODS only supports these options|
222
+ |**row_style**<br>*Hash*|`{background_color: nil, color: "000000", align: :left, font_size: 10, bold: false}`|Styles for non-header rows. Currently ODS only supports these options|
223
+ |**column_types**<br>*Array*||Valid types for ODS are :string, :float, :date, :percent, :currency, nil = auto determine|
210
224
 
211
225
  <br>
212
- #### `SpreadsheetArchitect.to_csv`
213
- |Option|Type|Default|Notes|
214
- |---|---|---|---|
215
- |**data**|Array| |**Required** 2D Array of data for the non-header row cells.|
216
- |**headers**|Array|`false`|2D Array of data for the header rows cells. Pass false to skip the header row.|
226
+ ## SpreadsheetArchitect.to_csv
227
+ |Option|Default|Notes|
228
+ |---|---|---|
229
+ |**data**<br>*2D Array*| |Data for the non-header row cells.|
230
+ |**headers**<br>*2D Array*|`false`|Data for the header rows cells. Pass `false` to skip the header row.|
217
231
 
218
232
 
219
233
  # Change model default method options
@@ -226,10 +240,18 @@ class Post
226
240
  end
227
241
 
228
242
  SPREADSHEET_OPTIONS = {
229
- headers: true,
243
+ headers: [
244
+ ['My Post Report'],
245
+ self.column_names.map{|x| x.titleize}
246
+ ],
230
247
  header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
231
- row_style: {background_color: nil, color: 'FFFFFF', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
232
- sheet_name: self.name
248
+ row_style: {background_color: nil, color: '000000', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
249
+ sheet_name: self.name,
250
+ column_styles: [],
251
+ range_styles: [],
252
+ merges: [],
253
+ borders: [],
254
+ column_types: []
233
255
  }
234
256
  end
235
257
  ```
@@ -238,38 +260,35 @@ end
238
260
  ```ruby
239
261
  # config/initializers/spreadsheet_architect.rb
240
262
 
241
- SpreadsheetArchitect.module_eval do
242
- const_set('SPREADSHEET_OPTIONS', {
243
- headers: true,
244
- header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
245
- row_style: {background_color: nil, color: 'FFFFFF', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
246
- sheet_name: 'My Project Export'
247
- })
248
- end
263
+ SpreadsheetArchitect.default_options = {
264
+ headers: true,
265
+ header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
266
+ row_style: {background_color: nil, color: 'FFFFFF', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
267
+ sheet_name: 'My Project Export',
268
+ column_styles: [],
269
+ range_styles: [],
270
+ merges: [],
271
+ borders: [],
272
+ column_types: []
273
+ }
249
274
  ```
250
275
 
251
- # Format all numbers, money, or currency in xlsx only
276
+ # Complex XLSX Example with Styling
277
+ See this example: (https://github.com/westonganger/spreadsheet_architect/blob/master/examples/complex_xlsx_styling.rb)
252
278
 
253
- Unfortunately so far I have only been successful in applying the format_code to all numbers in the entire spreadsheet.
254
279
 
255
- ```
256
- # Ex. dollar sign, comma's, and minumum two decimal places
257
- Product.to_xlsx(headers: headers, data: data, number_format_code: "$#,##0.00")
258
- ```
280
+ # Multi Sheet XLSX or ODS spreadsheets
281
+ See this example: (https://github.com/westonganger/spreadsheet_architect/blob/master/examples/multi_sheet_spreadsheets.rb)
259
282
 
260
- # TODO
261
283
 
262
- Would love for any help with new features for this projects. Some desired features are:
284
+ # Axlsx Style Reference
285
+ I have compiled a list of all available style options for `axlsx` here: (https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_styles_reference.md)
263
286
 
264
- - More ODS style options
265
- - Apply format codes to only certain columns (xlsx) - this is supposed to be possible with axlsx_styler
266
- - Add Columns styles (xlsx & ods)
267
- - Create multiple sheets (xlsx & ods)
268
287
 
269
288
  # Credits
270
289
  Created by Weston Ganger - @westonganger
271
290
 
272
291
  Heavily influenced by the dead gem `acts_as_xlsx` by @randym but adapted to work for more spreadsheet types and plain ruby models.
273
292
 
274
-
275
- <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=VKY8YAWAS5XRQ&lc=CA&item_name=Weston%20Ganger&item_number=spreadsheet_architect&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest" target="_blank" title="Buy Me A Coffee"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" alt="Buy Me A Coffee"/></a>
293
+ <a href='https://www.patreon.com/bePatron?u=4956947' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://miraclesfor.me/wp-content/plugins/patron-button-and-widgets-by-codebard/images/patreon-medium-button.png' border='0' alt='Become a Patron' /></a>
294
+ <a href='https://ko-fi.com/A5071NK' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
data/Rakefile CHANGED
@@ -5,9 +5,16 @@ task :test do
5
5
  require 'rake/testtask'
6
6
  Rake::TestTask.new do |t|
7
7
  t.libs << 'test'
8
- t.test_files = FileList['test/**/tc_*.rb']
8
+ t.test_files = FileList['test/**/*_test.rb']
9
9
  t.verbose = true
10
10
  end
11
11
  end
12
12
 
13
13
  task default: :test
14
+
15
+ task :console do
16
+ require 'spreadsheet_architect'
17
+
18
+ require 'irb'
19
+ binding.irb
20
+ end
@@ -1,10 +1,19 @@
1
1
  require 'rails/generators'
2
2
 
3
3
  module SpreadsheetArchitect
4
- class AddProjectDefaultsGenerator < Rails::Generators::Base
4
+ class AddDefaultOptionsGenerator < Rails::Generators::Base
5
5
 
6
- def add_project_defaults
7
- create_file "config/initializers/spreadsheet_architect.rb", "SpreadsheetArchitect.module_eval do\n const_set('SPREADSHEET_OPTIONS', {\n headers: true,\n header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},\n row_style: {background_color: nil, color: 'FFFFFF', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},\n sheet_name: 'My Project Export'\n })\nend"
6
+ def add_default_options
7
+ create_file "config/initializers/spreadsheet_architect.rb", <<eos
8
+ SpreadsheetArchitect.default_options = {
9
+ headers: true,
10
+ header_style: {background_color: "AAAAAA", color: "FFFFFF", align: :center, bold: false, font_name: 'Arial', font_size: 10, italic: false, underline: false},
11
+ row_style: {background_color: nil, color: "000000", align: :left, bold: false, font_name: 'Arial', font_size: 10, italic: false, underline: false},
12
+ column_styles: [],
13
+ range_styles: [],
14
+ borders: []
15
+ }
16
+ eos
8
17
  end
9
18
 
10
19
  end
@@ -1,343 +1,32 @@
1
- require 'spreadsheet_architect/set_mime_types'
1
+ require 'spreadsheet_architect/mime_types'
2
2
  require 'spreadsheet_architect/action_controller_renderers'
3
- require 'axlsx'
4
- require 'spreadsheet_architect/axlsx_column_width_patch'
5
- require 'odf/spreadsheet'
6
- require 'csv'
7
3
 
8
- module SpreadsheetArchitect
9
- def self.included(base)
10
- base.send :extend, ClassMethods
11
- end
12
-
13
- class NoDataError < StandardError
14
- def initialize
15
- super("Missing data option or data is empty")
16
- end
17
- end
18
-
19
- class NoInstancesError < StandardError
20
- def initialize
21
- super("Missing instances option or relation is empty.")
22
- end
23
- end
24
-
25
- class SpreadsheetColumnsNotDefined < StandardError
26
- def initialize(klass=nil)
27
- super("The spreadsheet_columns option is not defined on #{klass.name}")
28
- end
29
- end
30
-
31
- module Helpers
32
- def self.str_humanize(str, capitalize = true)
33
- str = str.sub(/\A_+/, '').gsub(/[_\.]/,' ').sub(' rescue nil','')
34
- if capitalize
35
- str = str.gsub(/(\A|\ )\w/){|x| x.upcase}
36
- end
37
- return str
38
- end
39
-
40
- def self.get_type(value, type=nil, last_run=false)
41
- return type if !type.blank?
42
- if value.is_a?(Numeric)
43
- if [:float, :decimal].include?(type)
44
- type = :float
45
- else
46
- type = :integer
47
- end
48
- elsif !last_run && value.is_a?(Symbol)
49
- type = :symbol
50
- else
51
- type = :string
52
- end
53
- return type
54
- end
55
-
56
- def self.get_cell_data(options={}, klass)
57
- if klass.name == 'SpreadsheetArchitect'
58
- if !options[:data] || options[:data].empty?
59
- raise SpreadsheetArchitect::NoDataError
60
- end
61
-
62
- if options[:headers] && !options[:headers].empty?
63
- headers = options[:headers]
64
- else
65
- headers = false
66
- end
67
-
68
- data = options[:data]
69
-
70
- types = []
71
- data.first.each do |x|
72
- types.push self.get_type(x, nil)
73
- end
74
- else
75
- has_custom_columns = options[:spreadsheet_columns] || klass.instance_methods.include?(:spreadsheet_columns)
76
-
77
- if !options[:instances] && defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
78
- options[:instances] = klass.where(nil).to_a # triggers the relation call, not sure how this works but it does
79
- end
80
-
81
- if !options[:instances] || options[:instances].empty?
82
- raise SpreadsheetArchitect::NoInstancesError
83
- end
84
-
85
- if has_custom_columns
86
- headers = []
87
- columns = []
88
- types = []
89
- array = options[:spreadsheet_columns] || options[:instances].first.spreadsheet_columns
90
- array.each do |x|
91
- if x.is_a?(Array)
92
- headers.push x[0].to_s
93
- columns.push x[1]
94
- #types.push self.get_type(x[1], x[2])
95
- types.push self.get_type(x[1], nil)
96
- else
97
- headers.push str_humanize(x.to_s)
98
- columns.push x
99
- types.push self.get_type(x, nil)
100
- end
101
- end
102
- elsif !has_custom_columns && defined?(ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
103
- ignored_columns = ["id","created_at","updated_at","deleted_at"]
104
- the_column_names = (klass.column_names - ignored_columns)
105
- headers = the_column_names.map{|x| str_humanize(x)}
106
- columns = the_column_names.map{|x| x.to_sym}
107
- types = klass.columns.keep_if{|x| !ignored_columns.include?(x.name)}.collect(&:type)
108
- types.map!{|type| self.get_type(nil, type)}
109
- else
110
- raise SpreadsheetArchitect::SpreadsheetColumnsNotDefined, klass
111
- end
112
-
113
- if options[:headers].nil?
114
- options[:headers] = klass::SPREADSHEET_OPTIONS[:headers] if defined?(klass::SPREADSHEET_OPTIONS)
115
- options[:headers] = SpreadsheetArchitect::SPREADSHEET_OPTIONS[:headers] if options[:headers].nil?
116
- end
117
- if options[:headers].nil? || options[:headers] == false
118
- headers = false
119
- end
120
-
121
- data = []
122
- options[:instances].each do |instance|
123
- if has_custom_columns && !options[:spreadsheet_columns]
124
- row_data = []
125
- instance.spreadsheet_columns.each do |x|
126
- if x.is_a?(Array)
127
- row_data.push(x[1].is_a?(Symbol) ? instance.instance_eval(x[1].to_s) : x[1])
128
- else
129
- row_data.push(x.is_a?(Symbol) ? instance.instance_eval(x.to_s) : x)
130
- end
131
- end
132
- data.push row_data
133
- else
134
- data.push columns.map{|col| col.is_a?(Symbol) ? instance.instance_eval(col.to_s) : col}
135
- end
136
- end
137
-
138
- # Fixes missing types from symbol methods
139
- if has_custom_columns || options[:spreadsheet_columns]
140
- data.first.each_with_index do |x,i|
141
- if types[i] == :symbol
142
- types[i] = self.get_type(x, nil, true)
143
- end
144
- end
145
- end
146
- end
147
-
148
- return options.merge(headers: headers, data: data, types: types)
149
- end
150
-
151
- def self.get_options(options={}, klass)
152
- if options[:headers]
153
- if defined?(klass::SPREADSHEET_OPTIONS)
154
- header_style = SpreadsheetArchitect::SPREADSHEET_OPTIONS[:header_style].merge(klass::SPREADSHEET_OPTIONS[:header_style] || {})
155
- else
156
- header_style = SpreadsheetArchitect::SPREADSHEET_OPTIONS[:header_style]
157
- end
158
-
159
- if options[:header_style]
160
- header_style.merge!(options[:header_style])
161
- elsif options[:header_style] == false
162
- header_style = false
163
- end
164
- else
165
- header_style = false
166
- end
167
-
168
- if options[:row_style] == false
169
- row_style = false
170
- else
171
- if defined?(klass::SPREADSHEET_OPTIONS)
172
- row_style = SpreadsheetArchitect::SPREADSHEET_OPTIONS[:row_style].merge(klass::SPREADSHEET_OPTIONS[:row_style] || {})
173
- else
174
- row_style = SpreadsheetArchitect::SPREADSHEET_OPTIONS[:row_style]
175
- end
176
-
177
- if options[:row_style]
178
- row_style.merge!(options[:row_style])
179
- end
180
- end
4
+ require 'spreadsheet_architect/exceptions'
5
+ require 'spreadsheet_architect/utils'
6
+ require 'spreadsheet_architect/utils/xlsx'
181
7
 
182
- if defined?(klass::SPREADSHEET_OPTIONS)
183
- sheet_name = options[:sheet_name] || klass::SPREADSHEET_OPTIONS[:sheet_name] || SpreadsheetArchitect::SPREADSHEET_OPTIONS[:sheet_name] || klass.name
184
- else
185
- sheet_name = options[:sheet_name] || SpreadsheetArchitect::SPREADSHEET_OPTIONS[:sheet_name] || klass.name
186
- end
187
-
188
- return {headers: options[:headers], header_style: header_style, row_style: row_style, types: options[:types], sheet_name: sheet_name, data: options[:data]}
189
- end
190
- end
191
-
192
- module ClassMethods
193
- def to_csv(opts={})
194
- opts = SpreadsheetArchitect::Helpers.get_cell_data(opts, self)
195
- options = SpreadsheetArchitect::Helpers.get_options(opts, self)
196
-
197
- CSV.generate do |csv|
198
- csv << options[:headers] if options[:headers]
199
-
200
- options[:data].each do |row_data|
201
- csv << row_data
202
- end
203
- end
204
- end
205
-
206
- def to_rodf_spreadsheet(opts={})
207
- opts = SpreadsheetArchitect::Helpers.get_cell_data(opts, self)
208
- options = SpreadsheetArchitect::Helpers.get_options(opts, self)
209
-
210
- spreadsheet = ODF::Spreadsheet.new
211
-
212
- spreadsheet.office_style :header_style, family: :cell do
213
- if options[:header_style]
214
- unless opts[:header_style] && opts[:header_style][:bold] == false #uses opts, temporary
215
- property :text, 'font-weight' => :bold
216
- end
217
- if options[:header_style][:align]
218
- property :text, align: options[:header_style][:align]
219
- end
220
- if options[:header_style][:size]
221
- property :text, 'font-size' => options[:header_style][:size]
222
- end
223
- if options[:header_style][:color] && opts[:header_style] && opts[:header_style][:color] #temporary
224
- property :text, color: "##{options[:header_style][:color]}"
225
- end
226
- end
227
- end
228
- spreadsheet.office_style :row_style, family: :cell do
229
- if options[:row_style]
230
- if options[:row_style][:bold]
231
- property :text, 'font-weight' => :bold
232
- end
233
- if options[:row_style][:align]
234
- property :text, align: options[:row_style][:align]
235
- end
236
- if options[:row_style][:size]
237
- property :text, 'font-size' => options[:row_style][:size]
238
- end
239
- if opts[:row_style] && opts[:row_style][:color] #uses opts, temporary
240
- property :text, color: "##{options[:row_style][:color]}"
241
- end
242
- end
243
- end
244
-
245
- spreadsheet.table options[:sheet_name] do
246
- if options[:headers]
247
- row do
248
- options[:headers].each do |header|
249
- cell header, style: :header_style
250
- end
251
- end
252
- end
253
- options[:data].each do |row_data|
254
- row do
255
- row_data.each_with_index do |y,i|
256
- cell y, style: :row_style, type: options[:types][i]
257
- end
258
- end
259
- end
260
- end
261
-
262
- return spreadsheet
263
- end
264
-
265
- def to_ods(opts={})
266
- return to_rodf_spreadsheet(opts).bytes
267
- end
268
-
269
- def to_axlsx(which='sheet', opts={})
270
- opts = SpreadsheetArchitect::Helpers.get_cell_data(opts, self)
271
- options = SpreadsheetArchitect::Helpers.get_options(opts, self)
272
-
273
- header_style = {}
274
- if options[:header_style]
275
- header_style[:fg_color] = options[:header_style].delete(:color)
276
- header_style[:bg_color] = options[:header_style].delete(:background_color)
277
- if header_style[:align]
278
- header_style[:alignment] = {}
279
- header_style[:alignment][:horizontal] = options[:header_style].delete(:align)
280
- end
281
- header_style[:b] = options[:header_style].delete(:bold)
282
- header_style[:sz] = options[:header_style].delete(:font_size)
283
- header_style[:i] = options[:header_style].delete(:italic)
284
- if options[:header_style][:underline]
285
- header_style[:u] = options[:header_style].delete(:underline)
286
- end
287
- header_style.delete_if{|x| x.nil?}
288
- end
289
-
290
- row_style = {}
291
- if options[:row_style]
292
- row_style[:fg_color] = options[:row_style].delete(:color)
293
- row_style[:bg_color] = options[:row_style].delete(:background_color)
294
- if row_style[:align]
295
- row_style[:alignment] = {}
296
- row_style[:alignment][:horizontal] = options[:row_style][:align]
297
- end
298
- row_style[:b] = options[:row_style].delete(:bold)
299
- row_style[:sz] = options[:row_style].delete(:font_size)
300
- row_style[:i] = options[:row_style].delete(:italic)
301
- if options[:row_style][:underline]
302
- row_style[:u] = options[:row_style].delete(:underline)
303
- end
304
- row_style.delete_if{|x| x.nil?}
305
- end
306
-
307
- package = Axlsx::Package.new
308
-
309
- return package if options[:data].empty?
310
-
311
- the_sheet = package.workbook.add_worksheet(name: options[:sheet_name]) do |sheet|
312
- if options[:headers]
313
- sheet.add_row options[:headers], style: package.workbook.styles.add_style(header_style)
314
- end
315
-
316
- options[:data].each do |row_data|
317
- row_style.merge!(format_code: opts[:row_style][:number_format_code]) if opts[:row_style] && opts[:row_style][:number_format_code]
318
- sheet.add_row row_data, style: package.workbook.styles.add_style(row_style), types: options[:types]
319
- end
320
- end
321
-
322
- if which.to_sym == :sheet
323
- return the_sheet
324
- else
325
- return package
326
- end
327
- end
328
-
329
- def to_xlsx(opts={})
330
- return to_axlsx('package', opts).to_stream.read
331
- end
8
+ require 'spreadsheet_architect/class_methods/csv'
9
+ require 'spreadsheet_architect/class_methods/ods'
10
+ require 'spreadsheet_architect/class_methods/xlsx'
332
11
 
12
+ module SpreadsheetArchitect
13
+ def self.included(base)
14
+ base.send(:extend, ClassMethods)
333
15
  end
334
16
 
335
17
  extend SpreadsheetArchitect::ClassMethods
336
18
 
337
- SPREADSHEET_OPTIONS = {
19
+ @default_options = {
338
20
  headers: true,
339
- #sheet_name: self.name,
340
21
  header_style: {background_color: "AAAAAA", color: "FFFFFF", align: :center, bold: false, font_name: 'Arial', font_size: 10, italic: false, underline: false},
341
22
  row_style: {background_color: nil, color: "000000", align: :left, bold: false, font_name: 'Arial', font_size: 10, italic: false, underline: false}
342
23
  }
24
+
25
+ def self.default_options=(val)
26
+ @default_options = val
27
+ end
28
+
29
+ def self.default_options
30
+ @default_options
31
+ end
343
32
  end