spreadsheet_architect 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -16
  3. data/README.md +22 -25
  4. data/lib/spreadsheet_architect/class_methods/ods.rb +18 -8
  5. data/lib/spreadsheet_architect/class_methods/xlsx.rb +76 -32
  6. data/lib/spreadsheet_architect/exceptions.rb +30 -13
  7. data/lib/spreadsheet_architect/utils/ods.rb +66 -0
  8. data/lib/spreadsheet_architect/utils/xlsx.rb +61 -32
  9. data/lib/spreadsheet_architect/utils.rb +29 -51
  10. data/lib/spreadsheet_architect/version.rb +1 -1
  11. data/lib/spreadsheet_architect.rb +3 -2
  12. data/test/dummy_app/app/controllers/spreadsheets_controller.rb +6 -3
  13. data/test/dummy_app/config/application.rb +4 -12
  14. data/test/dummy_app/config/environments/test.rb +1 -1
  15. data/test/dummy_app/config/routes.rb +1 -1
  16. data/test/dummy_app/db/migrate/20170103234524_add_posts.rb +1 -1
  17. data/test/dummy_app/db/test.sqlite3 +0 -0
  18. data/test/dummy_app/log/test.log +82177 -58559
  19. data/test/dummy_app/tmp/2.0.1/integration/alt_xlsx.xlsx +0 -0
  20. data/test/dummy_app/tmp/2.0.1/integration/csv.csv +6 -0
  21. data/test/dummy_app/tmp/2.0.1/integration/ods.ods +0 -0
  22. data/test/dummy_app/tmp/2.0.1/integration/xlsx.xlsx +0 -0
  23. data/test/dummy_app/tmp/2.0.1/kitchen_sink.ods +0 -0
  24. data/test/dummy_app/tmp/2.0.1/kitchen_sink.xlsx +0 -0
  25. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.csv +3 -0
  26. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.ods +0 -0
  27. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/data.xlsx +0 -0
  28. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.csv +1 -0
  29. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.ods +0 -0
  30. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/empty.xlsx +0 -0
  31. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.csv +6 -0
  32. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.ods +0 -0
  33. data/test/dummy_app/tmp/2.0.1/models/ActiveModelObject/instances.xlsx +0 -0
  34. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.csv +3 -0
  35. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.ods +0 -0
  36. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/data.xlsx +0 -0
  37. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.csv +0 -0
  38. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.ods +0 -0
  39. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/empty.xlsx +0 -0
  40. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.csv +6 -0
  41. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.ods +0 -0
  42. data/test/dummy_app/tmp/2.0.1/models/CustomColumnsMethodPost/instances.xlsx +0 -0
  43. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.csv +3 -0
  44. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.ods +0 -0
  45. data/test/dummy_app/tmp/2.0.1/models/CustomPost/data.xlsx +0 -0
  46. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.csv +1 -0
  47. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.ods +0 -0
  48. data/test/dummy_app/tmp/2.0.1/models/CustomPost/empty.xlsx +0 -0
  49. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.csv +6 -0
  50. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.ods +0 -0
  51. data/test/dummy_app/tmp/2.0.1/models/CustomPost/instances.xlsx +0 -0
  52. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.csv +3 -0
  53. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.ods +0 -0
  54. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/data.xlsx +0 -0
  55. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.csv +1 -0
  56. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.ods +0 -0
  57. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  58. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.csv +6 -0
  59. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.ods +0 -0
  60. data/test/dummy_app/tmp/2.0.1/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  61. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.csv +3 -0
  62. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.ods +0 -0
  63. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/data.xlsx +0 -0
  64. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.csv +1 -0
  65. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.ods +0 -0
  66. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/empty.xlsx +0 -0
  67. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.csv +6 -0
  68. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.ods +0 -0
  69. data/test/dummy_app/tmp/2.0.1/models/PlainRubyObject/instances.xlsx +0 -0
  70. data/test/dummy_app/tmp/2.0.1/models/Post/data.csv +3 -0
  71. data/test/dummy_app/tmp/2.0.1/models/Post/data.ods +0 -0
  72. data/test/dummy_app/tmp/2.0.1/models/Post/data.xlsx +0 -0
  73. data/test/dummy_app/tmp/2.0.1/models/Post/empty.csv +0 -0
  74. data/test/dummy_app/tmp/2.0.1/models/Post/empty.ods +0 -0
  75. data/test/dummy_app/tmp/2.0.1/models/Post/empty.xlsx +0 -0
  76. data/test/dummy_app/tmp/2.0.1/models/Post/instances.csv +6 -0
  77. data/test/dummy_app/tmp/2.0.1/models/Post/instances.ods +0 -0
  78. data/test/dummy_app/tmp/2.0.1/models/Post/instances.xlsx +0 -0
  79. data/test/dummy_app/tmp/2.0.1/multi_sheet.ods +0 -0
  80. data/test/dummy_app/tmp/2.0.1/multi_sheet.xlsx +0 -0
  81. data/test/dummy_app/tmp/3.0.0.pre/integration/alt_xlsx.xlsx +0 -0
  82. data/test/dummy_app/tmp/3.0.0.pre/integration/csv.csv +5 -5
  83. data/test/dummy_app/tmp/3.0.0.pre/integration/ods.ods +0 -0
  84. data/test/dummy_app/tmp/3.0.0.pre/integration/xlsx.xlsx +0 -0
  85. data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.ods +0 -0
  86. data/test/dummy_app/tmp/3.0.0.pre/kitchen_sink.xlsx +0 -0
  87. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.csv +1 -1
  88. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.ods +0 -0
  89. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/data.xlsx +0 -0
  90. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.ods +0 -0
  91. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/empty.xlsx +0 -0
  92. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.csv +5 -5
  93. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.ods +0 -0
  94. data/test/dummy_app/tmp/3.0.0.pre/models/ActiveModelObject/instances.xlsx +0 -0
  95. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.csv +1 -1
  96. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.ods +0 -0
  97. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/data.xlsx +0 -0
  98. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/empty.ods +0 -0
  99. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/empty.xlsx +0 -0
  100. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.csv +5 -5
  101. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.ods +0 -0
  102. data/test/dummy_app/tmp/3.0.0.pre/models/CustomColumnsMethodPost/instances.xlsx +0 -0
  103. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.csv +1 -1
  104. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.ods +0 -0
  105. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/data.xlsx +0 -0
  106. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.ods +0 -0
  107. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/empty.xlsx +0 -0
  108. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.csv +5 -5
  109. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.ods +0 -0
  110. data/test/dummy_app/tmp/3.0.0.pre/models/CustomPost/instances.xlsx +0 -0
  111. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.csv +1 -1
  112. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.ods +0 -0
  113. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/data.xlsx +0 -0
  114. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.ods +0 -0
  115. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  116. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.csv +5 -5
  117. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.ods +0 -0
  118. data/test/dummy_app/tmp/3.0.0.pre/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  119. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.csv +1 -1
  120. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.ods +0 -0
  121. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/data.xlsx +0 -0
  122. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.csv +0 -1
  123. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.ods +0 -0
  124. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/empty.xlsx +0 -0
  125. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.csv +5 -5
  126. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.ods +0 -0
  127. data/test/dummy_app/tmp/3.0.0.pre/models/PlainRubyObject/instances.xlsx +0 -0
  128. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.csv +1 -1
  129. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.ods +0 -0
  130. data/test/dummy_app/tmp/3.0.0.pre/models/Post/data.xlsx +0 -0
  131. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.csv +1 -0
  132. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.ods +0 -0
  133. data/test/dummy_app/tmp/3.0.0.pre/models/Post/empty.xlsx +0 -0
  134. data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.csv +5 -5
  135. data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.ods +0 -0
  136. data/test/dummy_app/tmp/3.0.0.pre/models/Post/instances.xlsx +0 -0
  137. data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.ods +0 -0
  138. data/test/dummy_app/tmp/3.0.0.pre/multi_sheet.xlsx +0 -0
  139. data/test/dummy_app/tmp/axlsx-master/integration/alt_xlsx.xlsx +0 -0
  140. data/test/dummy_app/tmp/axlsx-master/integration/csv.csv +6 -0
  141. data/test/dummy_app/tmp/axlsx-master/integration/ods.ods +0 -0
  142. data/test/dummy_app/tmp/axlsx-master/integration/xlsx.xlsx +0 -0
  143. data/test/dummy_app/tmp/axlsx-master/kitchen_sink.ods +0 -0
  144. data/test/dummy_app/tmp/axlsx-master/kitchen_sink.xlsx +0 -0
  145. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.csv +4 -0
  146. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.ods +0 -0
  147. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/data.xlsx +0 -0
  148. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.csv +1 -0
  149. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.ods +0 -0
  150. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/empty.xlsx +0 -0
  151. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.csv +6 -0
  152. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.ods +0 -0
  153. data/test/dummy_app/tmp/axlsx-master/models/ActiveModelObject/instances.xlsx +0 -0
  154. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.csv +4 -0
  155. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.ods +0 -0
  156. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/data.xlsx +0 -0
  157. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.csv +1 -0
  158. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.ods +0 -0
  159. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/empty.xlsx +0 -0
  160. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.csv +6 -0
  161. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.ods +0 -0
  162. data/test/dummy_app/tmp/axlsx-master/models/CustomColumnsMethodPost/instances.xlsx +0 -0
  163. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.csv +4 -0
  164. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.ods +0 -0
  165. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/data.xlsx +0 -0
  166. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.csv +1 -0
  167. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.ods +0 -0
  168. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/empty.xlsx +0 -0
  169. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.csv +6 -0
  170. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.ods +0 -0
  171. data/test/dummy_app/tmp/axlsx-master/models/CustomPost/instances.xlsx +0 -0
  172. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.csv +4 -0
  173. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.ods +0 -0
  174. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/data.xlsx +0 -0
  175. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.csv +1 -0
  176. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.ods +0 -0
  177. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/empty.xlsx +0 -0
  178. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.csv +6 -0
  179. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.ods +0 -0
  180. data/test/dummy_app/tmp/axlsx-master/models/LegacyPlainRubyObject/instances.xlsx +0 -0
  181. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.csv +4 -0
  182. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.ods +0 -0
  183. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/data.xlsx +0 -0
  184. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.csv +1 -0
  185. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.ods +0 -0
  186. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/empty.xlsx +0 -0
  187. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.csv +6 -0
  188. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.ods +0 -0
  189. data/test/dummy_app/tmp/axlsx-master/models/PlainRubyObject/instances.xlsx +0 -0
  190. data/test/dummy_app/tmp/axlsx-master/models/Post/data.csv +4 -0
  191. data/test/dummy_app/tmp/axlsx-master/models/Post/data.ods +0 -0
  192. data/test/dummy_app/tmp/axlsx-master/models/Post/data.xlsx +0 -0
  193. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.csv +1 -0
  194. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.ods +0 -0
  195. data/test/dummy_app/tmp/axlsx-master/models/Post/empty.xlsx +0 -0
  196. data/test/dummy_app/tmp/axlsx-master/models/Post/instances.csv +6 -0
  197. data/test/dummy_app/tmp/axlsx-master/models/Post/instances.ods +0 -0
  198. data/test/dummy_app/tmp/axlsx-master/models/Post/instances.xlsx +0 -0
  199. data/test/dummy_app/tmp/axlsx-master/multi_sheet.ods +0 -0
  200. data/test/dummy_app/tmp/axlsx-master/multi_sheet.xlsx +0 -0
  201. data/test/integration/application_test.rb +8 -16
  202. data/test/models/all_models_test.rb +15 -19
  203. data/test/test_helper.rb +48 -9
  204. data/test/unit/ods/general_test.rb +121 -0
  205. data/test/unit/{formats_test.rb → rails/formats_test.rb} +1 -1
  206. data/test/unit/{exceptions_test.rb → spreadsheet_architect/exceptions_test.rb} +19 -15
  207. data/test/unit/{general_test.rb → spreadsheet_architect/spreadsheet_architect_test.rb} +3 -3
  208. data/test/unit/spreadsheet_architect/utils/ods_test.rb +58 -0
  209. data/test/unit/{xlsx_utils_test.rb → spreadsheet_architect/utils/xlsx_test.rb} +13 -21
  210. data/test/unit/{utils_test.rb → spreadsheet_architect/utils_test.rb} +15 -31
  211. data/test/unit/xlsx/freeze_test.rb +79 -0
  212. data/test/unit/xlsx/general_test.rb +199 -0
  213. metadata +395 -128
  214. data/test/dummy_app/config/environments/development.rb +0 -30
  215. data/test/dummy_app/config/environments/production.rb +0 -60
  216. data/test/unit/kitchen_sink_test.rb +0 -110
  217. data/test/unit/multi_sheet_test.rb +0 -29
  218. data/test/unit/regressions_test.rb +0 -11
  219. data/test/unit/xlsx_freeze_test.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0e103cc275bf05dabe10a86cb7f74dcc4a412daa2328e607ca70d7af22ea40b
4
- data.tar.gz: 5799934cf9f9e177ca49ed33d749d01e535143cc18bf6990082b834fe6d9a6d5
3
+ metadata.gz: c88ecaffa3abed6ef127dc13d42c612ebf224c6d8552590d68ae544af2713f93
4
+ data.tar.gz: d0e864c2f50e99040f932da595b7270dd0e9c0161fc1189e6d99cb43126f6b5a
5
5
  SHA512:
6
- metadata.gz: cee7b3f8dfc727d63c1f84f06f94c1bf3eaf46283b15b698724a5d0f57d3ef39728838b5295376df6e112bbb3141579c6ebc4189e8af85bd82558abe0cbd2546
7
- data.tar.gz: 13c7e7db2193bb37be8911592e5eab725700e047dc8437c455adcad0ae8574f3187ac2d40412b82e706e90a286ec38b15be248c013b0fc5ed9db1d0c0b943e98
6
+ metadata.gz: dfc0caea596d57bd5aa88cd3b5ff3cebfca8b1299d1660e9995ca93837746d21420a90e0f427df9b3f8e73c13914a24b137572c005ee16fafdeeb6ddaf18b95d
7
+ data.tar.gz: c31f408e271453d46454e4f85ad2437a2539e39973186a8889c917a338f9e5f57f9ef3f3f28797955d61f8daa6a7100ffb46624ab3974c4bfd9273cc5cacba29
data/CHANGELOG.md CHANGED
@@ -1,14 +1,34 @@
1
1
  CHANGELOG
2
2
  ---------
3
3
 
4
- - **Unreleased**
4
+ - **Unreleased** - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v5.0.0...master)
5
5
  - Nothing yet
6
- - **4.1.0**
6
+
7
+ - **5.0.0** - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v4.2.0...v5.0.0)
8
+ - [#52](https://github.com/westonganger/spreadsheet_architect/pull/52) - Update to caxlsx v3.3.0+ which now contains the axlsx_styler code, so we drop the dependency on axlsx_styler
9
+ - [#38](https://github.com/westonganger/spreadsheet_architect/pull/38) - **Breaking Change** - Add `escape_formulas` option for xlsx spreadsheets. This is a breaking change because we default to `escape_formulas: true` whereas before there was no formula escaping at all. The reasoning for this breaking change is that creating spreadsheets where many of the fields contain direct user input are a large majority compared to use cases that involve formulas.
10
+ - [#39](https://github.com/westonganger/spreadsheet_architect/pull/39) - Add option `use_zero_based_row_index: true` (Default `false`) which allows you to use zero-based row indexes instead of the default 1-based row indexes. Recomended to set this option for the whole project. The original reason it was designed to be 1-based is because spreadsheet row numbers literally start with 1. However this tends to be unituitive for the developer because columns use zero based indexes because they use letter-based notation instead.
11
+ - [#40](https://github.com/westonganger/spreadsheet_architect/pull/40) - Improve argument handling for freeze option and add support for all Axlsx supported options for panes using the `:freeze` hash. See test case for example (./test/unit/xlsx_freeze_test.rb)
12
+ - [#42](https://github.com/westonganger/spreadsheet_architect/pull/42) - Improve exceptions and messages regarding invalid ranges
13
+ - [#45](https://github.com/westonganger/spreadsheet_architect/pull/45) - For `to_xlsx`, dont add empty header row when `header: true`
14
+ - [#44](https://github.com/westonganger/spreadsheet_architect/pull/44) - Add support for hyperlinks in XLSX and ODS
15
+ - [#49](https://github.com/westonganger/spreadsheet_architect/pulls/49) - Extracted some ODS methods from `SpreadsheetArchitect::Utils` to `SpreadsheetArchitect::Utils::ODS`
16
+ - [#51](https://github.com/westonganger/spreadsheet_architect/pulls/51) - Add Proc support to `:column_types`
17
+
18
+ - **4.2.0** - May 27, 2021 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v4.1.0...v4.2.0)
19
+ - Add option `:skip_defaults` which removes the defaults and default styles. Particularily useful for heavily customized spreadsheets where the default styles get in the way.
20
+ - Fix bug where styles werent being un-applied when using the `false` value.
21
+ - Add style aliases for `:valign` and `:wrap_text`
22
+ - Fix error with `headers: false`, previously had to use `headers: []`
23
+
24
+ - **4.1.0** - Nov 20, 2020 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v4.0.1...v4.1.0)
7
25
  - Raise ArgumentError when invalid option names are given
8
- - **4.0.1**
26
+
27
+ - **4.0.1** - Nov 20, 2020 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v4.0.0...v4.0.1)
9
28
  - Fix bug with `headers: false` where a blank header row is still added
10
29
  - Fix Bug for older version of `caxlsx` v2.0.2
11
- - **4.0.0**
30
+
31
+ - **4.0.0** - Mar 3, 2020 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.3.1...v4.0.0)
12
32
  - Switch to the `caxlsx` gem (Community Axlsx) from the legacy unmaintained `axlsx` gem. Axlsx has had a long history of being poorly maintained so this community gem improves the situation.
13
33
  - Require Ruby 2.3+
14
34
  - Ensure all options using Hash are automatically converted to symbol only hashes
@@ -16,29 +36,35 @@ CHANGELOG
16
36
  - Add XLSX option `:freeze_headers` to freeze the headers of your spreadsheet
17
37
  - Remove old Axlsx patch for column width
18
38
  - Backport new code for `string_width` calculations to Axlsx 3.0.1 and below.
19
- - **3.3.1**
39
+
40
+ - **3.3.1** - Dec 2, 2019 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.3.0...v3.3.1)
20
41
  - [Issue #30](https://github.com/westonganger/spreadsheet_architect/issues/30) - Fix duplicate constant warning for XLSX_COLUMN_TYPES
21
- - **3.3.0**
42
+
43
+ - **3.3.0** - Nov 28, 2019 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.2.1...v3.3.0)
22
44
  - Fix `:borders` option, was broken in v3.2.1
23
45
  - Fix bug when passing `false` to `:headers` option
24
46
  - Raise error when unsupported column type is passed
25
47
  - Remove claimed support for `:currency` and `:percent` for ODS spreadsheets as they were not working. PR Wanted.
26
- - **3.2.1** - April 10, 2019
48
+
49
+ - **3.2.1** - April 10, 2019 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.2.0...v3.2.1)
27
50
  - Fix bug when using `column_style` option with `include_header: true` & letter based column numbering
28
- - **3.2.0** - September 14, 2018
51
+
52
+ - **3.2.0** - September 14, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.1.0...v3.2.0)
29
53
  - Change implementation of `:column_styles` option to utilize `axlsx_styler` instead of the built-in axlsx `col_style` method. The reason for the switch is that `col_style` would overwrite all previously set styles. `axlsx_styler` already has the ability to add onto existing styles and is what is currently utilized by `range_styles`.
30
54
  - Date / Time formatting is now set per cell instead of on the entire column.
31
55
  - Default Date formatting for `xlsx` changed from `m/d/yyyy` to `yyyy-mm-dd`
32
56
  - Default Time/DateTime formatting for `xlsx` changed from `yyyy/m/d h:mm AM/PM` to `yyyy-mm-dd h:mm AM/PM`
33
57
  - Fix bug where the ActionController::Renderer `:filename` option was ignored when an AR::Relation passed directly to the renderer without first calling `to_#{format}`
34
- - **3.1.0** - August 19, 2018
58
+
59
+ - **3.1.0** - August 19, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v3.0.0...v3.1.0)
35
60
  - Add new option `:conditional_row_styles` to `to_xlsx`.
36
61
  - Add ability to pass an alternative method name as a Symbol/String to the `:spreadsheet_columns` option.
37
62
  - Replace all usage of the legacy method `instance_eval` with the proper method `send`.
38
63
  - [#23](https://github.com/westonganger/spreadsheet_architect/issues/23#issuecomment-412803761) - Fix bug where custom `columns_widths` in xlsx spreadsheets might not get set correctly.
39
64
  - All exceptions now inherit from the appropriate ruby core exception classes
40
65
  - `SpreadsheetArchitect::Exceptions::InvalidOptionError` renamed to `SpreadsheetArchitect::Exceptions::OptionTypeError`
41
- - **3.0.0** - July 6, 2018
66
+
67
+ - **3.0.0** - July 6, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.1.2...v3.0.0)
42
68
  - [#16](https://github.com/westonganger/spreadsheet_architect/issues/16) - Add ability to pass :instances option to SpreadsheetArchitect class methods
43
69
  - [#16](https://github.com/westonganger/spreadsheet_architect/issues/16) - Remove Plain Ruby syntax `Post.to_xlsx(instances: posts_array)` in favor of `SpreadsheetArchitect.to_xlsx(instance: posts_array)`. However, it may still work at this time if configured correctly.
44
70
  - Fix project-wide and model-level defaults before only `header_style`, `row_style`, & `sheet_name` were being utilized.
@@ -53,12 +79,15 @@ CHANGELOG
53
79
  - Remove all Rails generators `spreadsheet_architect:add_default_options`. No need since its just as easy to copy from the README
54
80
  - Major overhaul of test suite, add a ton more tests, for DRYness use resursion for tests when appropriate
55
81
  - Use appraisal to test various `axlsx` versions
56
- - **2.1.2** - July 6, 2018
82
+
83
+ - **2.1.2** - July 6, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.1.1...v2.1.2)
57
84
  - Fix bug where everything was underlined by default in Excel (LibreOffice was working correctly). For some reason, `false` in `:u` or `:underline` was incorrectly being treated as `true` but only within Excel. Now anytime `false` is encountered for either `:u` or `:underline` it is now converted to `nil`
58
85
  - Fix bug where empty xlsx spreadsheets were corrupt when trying to open with Excel (LibreOffice was working correctly). This only occured when containing no headers and empty `:data` option which resulted in a package with no sheets.
59
- - **2.1.1** - July 4, 2018
86
+
87
+ - **2.1.1** - July 4, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.1.0...v2.1.1)
60
88
  - [#18](https://github.com/westonganger/spreadsheet_architect/pull/18) - Fix controller bug when using an non-ActiveRecord ORM only within Rails
61
- - **2.1.0** - June 20, 2018
89
+
90
+ - **2.1.0** - June 20, 2018 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.0.2...v2.1.0)
62
91
  - [#15](https://github.com/westonganger/spreadsheet_architect/pull/15) - Improved the method symbolize_keys. This method did not work properly for nested objects.
63
92
  - [PR #15](https://github.com/westonganger/spreadsheet_architect/pull/15) - Added the ability to pass `:text_wrap` option within the `:alignment` style
64
93
  - Make axlsx styles higher precendence over Spreadsheet Architect style aliases
@@ -66,14 +95,17 @@ CHANGELOG
66
95
  - Due to [RODF bug](https://github.com/thiagoarrais/rodf/issues/19) convert all Date and Time cells to String in ODS spreadsheets
67
96
  - Improve test suite
68
97
  - Dont test against Ruby versions that Rails no longer supports. Gem code should remain compatible with Ruby 1.9.3.
69
- - **2.0.2** - July 14 2017
98
+
99
+ - **2.0.2** - July 14 2017 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.0.1...v2.0.2)
70
100
  - Fix bug with range styles rows option not counting headers
71
101
  - Fix bug with range styles rows :all option
72
- - **2.0.1** - February 16 2017
102
+
103
+ - **2.0.1** - February 16 2017 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v2.0.0...v2.0.1)
73
104
  - Fix bug where `SpreadsheetArchitect.default_options` and `SPREADSHEET_OPTIONS` were being overwritten
74
105
  - Fix bug where col_styles ignored previous styles on header when using `include_header` option
75
106
  - Errors now try to provide which value is the cause
76
- - **2.0.0** - January 28 2017
107
+
108
+ - **2.0.0** - January 28 2017 - [View Diff](https://github.com/westonganger/spreadsheet_architect/compare/v1.4.8...v2.0.0)
77
109
  - Add to xlsx: `merges`, `column_styles`, `range_styles`, `borders`, `column_widths` multi-row headers, date/time default format_code
78
110
  - Add `column_types` option for xlsx and ods
79
111
  - Add ability to make multi-sheet spreadsheets in XLSX & ODS
@@ -81,52 +113,74 @@ CHANGELOG
81
113
  - Add Examples
82
114
  - Add Axlsx Style Reference
83
115
  - Refractor into smaller files
116
+
84
117
  - **1.4.8** - December 6 2016
85
118
  - Lock `rodf` gem to v0.3.7 for last v1 version of this gem
119
+
86
120
  - **1.4.7** - November 7 2016
87
121
  - Fix method arguments for `to_rodf_spreadsheet` method
122
+
88
123
  - **1.4.6** - May 16 2016
89
124
  - Fix hash syntax for support of ruby v2.1 and below
125
+
90
126
  - **1.4.5** - May 4 2016
91
127
  - Bug fixes
128
+
92
129
  - **1.4.4** - May 3 2016
93
130
  - Add Ability to add format_code to all numbers body rows
131
+
94
132
  - **1.4.3** - May 3 2016
95
133
  - Bug fixes
134
+
96
135
  - **1.4.2** - May 3 2016
97
136
  - Add to_axlsx_package, to_rodf_spreadsheet methods for the item to be further manipulated. Ex. axlsx_styler
137
+
98
138
  - **1.4.1** - May 2 2016
99
139
  - Add rails generator for project defaults initializer
140
+
100
141
  - **1.4.0** - April 29 2016
101
142
  - Add to_xlsx, to_ods, & to_csv to SpreadsheetArchitect model for direct calling by passing in cell data
143
+
102
144
  - **1.3.0** - April 21 2016
103
145
  - Add ability to create class/model and project option defaults
146
+
104
147
  - **1.2.5** - March 25 2016
105
148
  - Fix each_with_index bug
149
+
106
150
  - **1.2.4** - March 24 2016
107
151
  - Fix cell type logic for symbol methods
152
+
108
153
  - **1.2.3** - March 20 2016
109
154
  - Fix cell type logic
155
+
110
156
  - **1.2.2** - March 19 2016
111
157
  - Make cell type numeric if value is numeric
158
+
112
159
  - **1.2.1** - March 13 2016
113
160
  - Better error reporting
114
161
  - Fix for Plain ruby models
162
+
115
163
  - **1.2.0** - March 10 2016
116
164
  - Fix Bug: first row data repeated for all records on custom values
165
+
117
166
  - **1.1.0** - March 3 2016
118
167
  - Breaking Change - Move spreadsheet_columns method from the class to the instance
119
168
  - Fix Bug: remove default underline on cells
169
+
120
170
  - **1.0.4** - March 1 2016
121
171
  - Extract helper methods to seperate module
122
172
  - Improve readme
173
+
123
174
  - **1.0.3** - March 1 2016
124
175
  - Fix/Improve renderers
125
176
  - Fix header default background color
126
177
  - Fix default columns
178
+
127
179
  - **1.0.2** - February 26 2016
128
180
  - Enhance Style options
181
+
129
182
  - **1.0.1** - February 26 2016
130
183
  - Fix bug in renderers
184
+
131
185
  - **1.0.0** - February 26 2016
132
186
  - Gem Initial Release
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # Spreadsheet Architect
2
2
 
3
3
  <a href="https://badge.fury.io/rb/spreadsheet_architect" target="_blank"><img height="21" style='border:0px;height:21px;' border='0' src="https://badge.fury.io/rb/spreadsheet_architect.svg" alt="Gem Version"></a>
4
- <a href='https://travis-ci.com/westonganger/spreadsheet_architect' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://api.travis-ci.org/westonganger/spreadsheet_architect.svg?branch=master' border='0' alt='Build Status' /></a>
4
+ <a href='https://github.com/westonganger/spreadsheet_architect/actions' target='_blank'><img src="https://github.com/westonganger/spreadsheet_architect/workflows/Tests/badge.svg" style="max-width:100%;" height='21' style='border:0px;height:21px;' border='0' alt="CI Status"></a>
5
5
  <a href='https://rubygems.org/gems/spreadsheet_architect' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://ruby-gem-downloads-badge.herokuapp.com/spreadsheet_architect?label=rubygems&type=total&total_label=downloads&color=brightgreen' border='0' alt='RubyGems Downloads' /></a>
6
- <a href='https://ko-fi.com/A5071NK' target='_blank'><img height='22' style='border:0px;height:22px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
7
6
 
8
7
  Spreadsheet Architect is a library that allows you to create XLSX, ODS, or CSV spreadsheets super easily from ActiveRecord relations, plain Ruby objects, or tabular data.
9
8
 
@@ -92,7 +91,7 @@ If you want to use a different method name then `spreadsheet_columns` you can pa
92
91
  Post.to_xlsx(instances: posts, spreadsheet_columns: :my_special_method)
93
92
  ```
94
93
 
95
- Alternatively, you can pass a Proc/lambda to the `spreadsheet_columns` option. For those purists that really dont want to define any extra `spreadsheet_columns` instance method on your model, this option can help you work with that methodology.
94
+ Alternatively, you can pass a Proc to the `spreadsheet_columns` option. For those purists that really dont want to define any extra `spreadsheet_columns` instance method on your model, this option can help you work with that methodology.
96
95
 
97
96
  ```ruby
98
97
  Post.to_xlsx(instances: posts, spreadsheet_columns: Proc.new{|instance|
@@ -104,7 +103,8 @@ Post.to_xlsx(instances: posts, spreadsheet_columns: Proc.new{|instance|
104
103
  :published_at, # uses the method name as header title Einstance. 'Published At'
105
104
  ['# of Views', :number_of_views, :float],
106
105
  ['Rating', :rating],
107
- ['Category/Tags', "#{instance.category.name} - #{instance.tags.collect(&:name).join(', ')}"]
106
+ ['Category/Tags', "#{instance.category.name} - #{instance.tags.collect(&:name).join(', ')}"],
107
+ ['URL', :url, (val.start_with?("http") ? :hyperlink : :string)],
108
108
  ]
109
109
  })
110
110
  ```
@@ -190,20 +190,16 @@ File.open('path/to/multi_sheet_file.xlsx', 'w+b') do |f|
190
190
  end
191
191
  ```
192
192
 
193
- See this file for more details: https://github.com/westonganger/spreadsheet_architect/blob/master/test/spreadsheet_architect/multi_sheet_test.rb
194
-
195
193
  ### ODS
196
194
  ```ruby
197
195
  ods_spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet({headers: headers, data: data})
198
196
  ods_spreadsheet = SpreadsheetArchitect.to_rodf_spreadsheet({headers: headers, data: data}, ods_spreadsheet)
199
197
 
200
198
  File.open('path/to/multi_sheet_file.ods', 'w+b') do |f|
201
- f.write ods_spreadsheet
199
+ f.write ods_spreadsheet.bytes
202
200
  end
203
201
  ```
204
202
 
205
- See this file for more details: https://github.com/westonganger/spreadsheet_architect/blob/master/test/spreadsheet_architect/multi_sheet_test.rb
206
-
207
203
  # Methods
208
204
 
209
205
  ## `to_xlsx(options={})`
@@ -215,17 +211,20 @@ See this file for more details: https://github.com/westonganger/spreadsheet_arch
215
211
  |**spreadsheet_columns**<br>*Proc/Symbol/String*| Use this option to override or define the spreadsheet columns. Normally, if this option is not specified and are using the instances option/ActiveRecord relation, it uses the classes custom `spreadsheet_columns` method or any custom defaults defined.<br>If neither of those and is an ActiveRecord model, then it will falls back to the models `self.column_names` | Cannot be used with the `:data` option.<br><br>If a Proc value is passed it will be evaluated on the instance object.<br><br>If a Symbol or String value is passed then it will search the instance for a method name that matches and call it. |
216
212
  |**headers**<br>*Array / 2D Array*| |Data for the header row cells. If using on a class/relation, this defaults to the ones provided via `spreadsheet_columns`. Pass `false` to skip the header row. |
217
213
  |**sheet_name**<br>*String*|`Sheet1`||
218
- |**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_style_reference.md)|
219
- |**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_style_reference.md)|
220
- |**column_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb)|
221
- |**range_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb)|
222
- |**conditional_row_styles**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb). The if/unless proc will called with the following args: `row_index`, `row_data`|
223
- |**merges**<br>*Array*||Merge cells. [See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb). Warning merges cannot overlap eachother, if you attempt to do so Excel will claim your spreadsheet is corrupt and refuse to open your spreadsheet.|
224
- |**borders**<br>*Array*||[See this example for usage](https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb)|
225
- |**column_types**<br>*Array*||Valid types for XLSX are :string, :integer, :float, :date, :time, :boolean, nil = auto determine.|
214
+ |**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](./docs/axlsx_style_reference.md)|
215
+ |**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](./docs/axlsx_style_reference.md)|
216
+ |**column_styles**<br>*Array*||[See this example for usage](./test/unit/kitchen_sink_test.rb)|
217
+ |**range_styles**<br>*Array*||[See this example for usage](./test/unit/kitchen_sink_test.rb)|
218
+ |**conditional_row_styles**<br>*Array*||[See this example for usage](./test/unit/kitchen_sink_test.rb). The if/unless proc will called with the following args: `row_index`, `row_data`|
219
+ |**merges**<br>*Array*||Merge cells. [See this example for usage](./test/unit/kitchen_sink_test.rb). Warning merges cannot overlap eachother, if you attempt to do so Excel will claim your spreadsheet is corrupt and refuse to open your spreadsheet.|
220
+ |**borders**<br>*Array*||[See this example for usage](./test/unit/kitchen_sink_test.rb)|
221
+ |**column_types**<br>*Array*||Valid types for XLSX are :string, :integer, :float, :date, :time, :boolean, :hyperlink, nil = auto determine. You may also pass a Proc which evaluates to any of the valid types, for example `->(cell_val){ cell_val.start_with?('http') ? :hyperlink : :string }`|
226
222
  |**column_widths**<br>*Array*||Sometimes you may want explicit column widths. Use nil if you want a column to autofit again.|
227
223
  |**freeze_headers**<br>*Boolean*||Make all header rows frozen/fixed so they do not scroll.|
228
- |**freeze**<br>* Hash*|`{rows: (1..4), columns: :all}`|Make all specified rows and columns frozen/fixed so they do not scroll.|
224
+ |**freeze**<br>*Hash*||Make all specified row and/or column frozen/fixed so they do not scroll. See [example usage](./test/unit/xlsx_freeze_test.rb)|
225
+ |**skip_defaults**<br>*Boolean*|`false`|Removes defaults and default styles. Particularily useful for heavily customized spreadsheets where the default styles get in the way.|
226
+ |**escape_formulas**<br>*Boolean* or *Array*|`true`|Pass a single boolean to apply to all cells, or an array of booleans to control column-by-column. Advisable to be set true when involved with untrusted user input. See [an example of the underlying functionality](https://github.com/caxlsx/caxlsx/blob/master/examples/escape_formula_example.md). NOTE: Header row cells are not escaped. |
227
+ |**use_zero_based_row_index**<br>*Boolean*|`false`|Allows you to use zero-based row indexes when defining `range_styles`, `merges`, etc. Recomended to set this option for the whole project rather than per call. The original reason it was designed to be 1-based is because spreadsheet row numbers actually start with 1.|
229
228
 
230
229
  ## `to_axlsx_spreadsheet(options={}, axlsx_package_to_join=nil)`
231
230
  Same options as `to_xlsx`
@@ -241,7 +240,8 @@ Same options as `to_xlsx`
241
240
  |**sheet_name**<br>*String*|`Sheet1`||
242
241
  |**header_style**<br>*Hash*|`{background_color: "AAAAAA", color: "FFFFFF", align: :center, font_size: 10, bold: true}`|Note: Currently ODS only supports these options|
243
242
  |**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|
244
- |**column_types**<br>*Array*||Valid types for ODS are :string, :float, :date, :time, :boolean, nil = auto determine. Due to [RODF Issue #19](https://github.com/thiagoarrais/rodf/issues/19), :date/:time will be converted to :string |
243
+ |**column_types**<br>*Array*||Valid types for ODS are :string, :float, :date, :time, :boolean, :hyperlink, nil = auto determine. Due to [RODF Issue #19](https://github.com/thiagoarrais/rodf/issues/19), :date/:time will be converted to :string. You may also pass a Proc which evaluates to any of the valid types, for example `->(cell_val){ cell_val.start_with?('http') ? :hyperlink : :string }` |
244
+ |**skip_defaults**<br>*Boolean*|`false`|Skip defaults and default styles. Particularily useful for heavily customized spreadsheets where the default styles get in the way.|
245
245
 
246
246
  ## `to_rodf_spreadsheet(options={}, spreadsheet_to_join=nil)`
247
247
  Same options as `to_ods`
@@ -302,15 +302,16 @@ SpreadsheetArchitect.default_options = {
302
302
  merges: [],
303
303
  borders: [],
304
304
  column_types: [],
305
+ use_zero_based_row_index: false,
305
306
  }
306
307
  ```
307
308
 
308
309
  # Kitchen Sink Examples with Styling for XLSX and ODS
309
- See this example: https://github.com/westonganger/spreadsheet_architect/blob/master/test/unit/kitchen_sink_test.rb
310
+ See this example: [test/unit/kitchen_sink_test.rb](./test/unit/kitchen_sink_test.rb)
310
311
 
311
312
  # Axlsx Style Reference
312
313
 
313
- I have compiled a list of all available style options for axlsx here: https://github.com/westonganger/spreadsheet_architect/blob/master/docs/axlsx_style_reference.md
314
+ I have compiled a list of all available style options for axlsx here: [docs/axlsx_style_reference.md](./docs/axlsx_style_reference.md)
314
315
 
315
316
  # Testing / Validating your Spreadsheets
316
317
 
@@ -328,7 +329,3 @@ At this time the spreadsheets generated by the test suite are manually inspected
328
329
  # Credits
329
330
 
330
331
  Created & Maintained by [Weston Ganger](https://westonganger.com) - [@westonganger](https://github.com/westonganger)
331
-
332
- For any consulting or contract work please contact me via my company website: [Solid Foundation Web Development](https://solidfoundationwebdev.com)
333
-
334
- [![Solid Foundation Web Development Logo](https://solidfoundationwebdev.com/logo-sm.png)](https://solidfoundationwebdev.com)
@@ -11,7 +11,7 @@ module SpreadsheetArchitect
11
11
  opts = SpreadsheetArchitect::Utils.get_options(opts, self)
12
12
  options = SpreadsheetArchitect::Utils.get_cell_data(opts, self)
13
13
 
14
- if options[:column_types] && !(options[:column_types].compact.collect(&:to_sym) - SpreadsheetArchitect::ODS_COLUMN_TYPES).empty?
14
+ if options[:column_types] && !(options[:column_types].compact.reject{|x| x.is_a?(Proc) }.collect(&:to_sym) - SpreadsheetArchitect::ODS_COLUMN_TYPES).empty?
15
15
  raise SpreadsheetArchitect::Exceptions::ArgumentError.new("Invalid column type. Valid ODS values are #{SpreadsheetArchitect::ODS_COLUMN_TYPES}")
16
16
  end
17
17
 
@@ -21,7 +21,7 @@ module SpreadsheetArchitect
21
21
 
22
22
  spreadsheet.office_style :header_style, family: :cell do
23
23
  if options[:header_style]
24
- SpreadsheetArchitect::Utils.convert_styles_to_ods(options[:header_style]).each do |prop, styles|
24
+ SpreadsheetArchitect::Utils::ODS.convert_styles(options[:header_style]).each do |prop, styles|
25
25
  styles.each do |k,v|
26
26
  property prop.to_sym, k => v
27
27
  end
@@ -31,7 +31,7 @@ module SpreadsheetArchitect
31
31
 
32
32
  spreadsheet.office_style :row_style, family: :cell do
33
33
  if options[:row_style]
34
- SpreadsheetArchitect::Utils.convert_styles_to_ods(options[:row_style]).each do |prop, styles|
34
+ SpreadsheetArchitect::Utils::ODS.convert_styles(options[:row_style]).each do |prop, styles|
35
35
  styles.each do |k,v|
36
36
  property prop.to_sym, k => v
37
37
  end
@@ -54,15 +54,25 @@ module SpreadsheetArchitect
54
54
  row do
55
55
  row_data.each_with_index do |val, i|
56
56
  if options[:column_types]
57
- type = options[:column_types][i]
57
+ provided_column_type = options[:column_types][i]
58
+
59
+ if provided_column_type.is_a?(Proc)
60
+ provided_column_type = provided_column_type.call(val)
61
+ end
58
62
  end
59
63
 
60
- if (type && [:date, :time].include?(type)) || val.respond_to?(:strftime)
61
- type = :string
62
- val = val.to_s
64
+ type = SpreadsheetArchitect::Utils::ODS.get_cell_type(val, provided_column_type)
65
+
66
+ cell_opts = {
67
+ style: :row_style,
68
+ type: type,
69
+ }
70
+
71
+ if provided_column_type == :hyperlink
72
+ cell_opts[:url] = val
63
73
  end
64
74
 
65
- cell val, style: :row_style, type: type
75
+ cell(val, **cell_opts)
66
76
  end
67
77
  end
68
78
  end
@@ -1,5 +1,4 @@
1
1
  require 'axlsx'
2
- require 'axlsx_styler'
3
2
 
4
3
  require 'spreadsheet_architect/axlsx_string_width_patch'
5
4
 
@@ -14,7 +13,7 @@ module SpreadsheetArchitect
14
13
  opts = SpreadsheetArchitect::Utils.get_options(opts, self)
15
14
  options = SpreadsheetArchitect::Utils.get_cell_data(opts, self)
16
15
 
17
- if options[:column_types] && !(options[:column_types].compact.collect(&:to_sym) - SpreadsheetArchitect::XLSX_COLUMN_TYPES).empty?
16
+ if options[:column_types] && !(options[:column_types].compact.reject{|x| x.is_a?(Proc) }.collect(&:to_sym) - SpreadsheetArchitect::XLSX_COLUMN_TYPES).empty?
18
17
  raise SpreadsheetArchitect::Exceptions::ArgumentError.new("Invalid column type. Valid XLSX values are #{SpreadsheetArchitect::XLSX_COLUMN_TYPES}")
19
18
  end
20
19
 
@@ -79,16 +78,27 @@ module SpreadsheetArchitect
79
78
 
80
79
  types = []
81
80
  styles = []
82
- row_data.each_with_index do |x,i|
83
- if (x.respond_to?(:empty) ? x.empty? : x.nil?)
81
+ hyperlink_cell_indexes = []
82
+
83
+ row_data.each_with_index do |val,i|
84
+ if (val.respond_to?(:empty) ? val.empty? : val.nil?)
84
85
  types[i] = nil
85
86
  styles[i] = row_style_index
86
87
  else
87
88
  if options[:column_types]
88
- types[i] = options[:column_types][i]
89
+ provided_column_type = options[:column_types][i]
90
+
91
+ if provided_column_type.is_a?(Proc)
92
+ provided_column_type = provided_column_type.call(val)
93
+ end
89
94
  end
90
95
 
91
- types[i] ||= SpreadsheetArchitect::Utils::XLSX.get_type(x)
96
+ if provided_column_type == :hyperlink
97
+ hyperlink_cell_indexes << i
98
+ row_data[i] = val.to_s
99
+ end
100
+
101
+ types[i] = SpreadsheetArchitect::Utils::XLSX.get_type(val, provided_column_type)
92
102
 
93
103
  if [:date, :time].include?(types[i])
94
104
  if types[i] == :date
@@ -104,7 +114,12 @@ module SpreadsheetArchitect
104
114
  end
105
115
  end
106
116
 
107
- sheet.add_row row_data, style: styles, types: types
117
+ sheet.add_row row_data, style: styles, types: types, escape_formulas: options[:escape_formulas]
118
+
119
+ hyperlink_cell_indexes.each do |cell_index|
120
+ cell_ref = "#{SpreadsheetArchitect::Utils::XLSX::COL_NAMES[cell_index]}#{row_index+1}"
121
+ sheet.add_hyperlink location: row_data[cell_index], ref: cell_ref
122
+ end
108
123
 
109
124
  if options[:conditional_row_styles]
110
125
  options[:conditional_row_styles] = SpreadsheetArchitect::Utils.hash_array_symbolize_keys(options[:conditional_row_styles])
@@ -133,12 +148,12 @@ module SpreadsheetArchitect
133
148
 
134
149
  options[:borders].each do |x|
135
150
  if x[:range].is_a?(Hash)
136
- x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows)
151
+ x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows, use_zero_based_row_index: options[:use_zero_based_row_index])
137
152
  else
138
153
  SpreadsheetArchitect::Utils::XLSX.verify_range(x[:range], num_rows)
139
154
  end
140
155
 
141
- sheet.add_border x[:range], (x[:border_styles] || x[:styles])
156
+ sheet.add_border x[:range], (x[:border_styles] || x[:styles] || Axlsx::Border::EDGES)
142
157
  end
143
158
  end
144
159
 
@@ -182,7 +197,7 @@ module SpreadsheetArchitect
182
197
  styles = SpreadsheetArchitect::Utils::XLSX.convert_styles_to_axlsx(x[:styles])
183
198
 
184
199
  if x[:range].is_a?(Hash)
185
- x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows)
200
+ x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows, use_zero_based_row_index: options[:use_zero_based_row_index])
186
201
  else
187
202
  SpreadsheetArchitect::Utils::XLSX.verify_range(x[:range], num_rows)
188
203
  end
@@ -196,7 +211,7 @@ module SpreadsheetArchitect
196
211
 
197
212
  options[:merges].each do |x|
198
213
  if x[:range].is_a?(Hash)
199
- x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows)
214
+ x[:range] = SpreadsheetArchitect::Utils::XLSX.range_hash_to_str(x[:range], max_row_length, num_rows, use_zero_based_row_index: options[:use_zero_based_row_index])
200
215
  else
201
216
  SpreadsheetArchitect::Utils::XLSX.verify_range(x[:range], num_rows)
202
217
  end
@@ -212,33 +227,62 @@ module SpreadsheetArchitect
212
227
  end
213
228
 
214
229
  elsif options[:freeze]
215
- options[:freeze] = SpreadsheetArchitect::Utils.symbolize_keys(options[:freeze])
230
+ case options[:freeze][:type].to_s
231
+ when "split_panes"
232
+ options[:freeze][:state] == "split"
233
+ when "frozen", "freeze"
234
+ options[:freeze][:state] == "frozen"
235
+ end
236
+
237
+ if options[:freeze][:rows]
238
+ options[:freeze][:row] ||= options[:freeze][:rows]
239
+ end
240
+
241
+ if options[:freeze][:columns]
242
+ options[:freeze][:column] ||= options[:freeze][:columns]
243
+ end
244
+
245
+ if options[:freeze][:row] == :all
246
+ options[:freeze][:row] = nil
247
+ elsif options[:freeze][:row].is_a?(Range)
248
+ options[:freeze][:row] = options[:freeze][:row].last
249
+ end
250
+
251
+ if options[:freeze][:column] == :all
252
+ options[:freeze][:column] = nil
253
+ elsif options[:freeze][:column].is_a?(Range)
254
+ options[:freeze][:column] = options[:freeze][:column].last
255
+ end
256
+
257
+ if !options[:freeze][:row] && !options[:freeze][:column]
258
+ raise SpreadsheetArchitect::Exceptions::ArgumentError.new("Missing required :row or :column value in the :freeze option hash")
259
+ elsif options[:freeze][:row] && !options[:freeze][:row].is_a?(Integer)
260
+ raise SpreadsheetArchitect::Exceptions::ArgumentError.new("Invalid :row value provided for in :freeze option hash, must be an Integer")
261
+ elsif options[:freeze][:column] && !options[:freeze][:column].is_a?(Integer)
262
+ raise SpreadsheetArchitect::Exceptions::ArgumentError.new("Invalid :column value provided for in :freeze option hash, must be an Integer")
263
+ end
216
264
 
217
265
  sheet.sheet_view.pane do |pane|
218
- pane.state = :frozen
266
+ pane.state = (options[:freeze][:state] || :frozen).to_sym ### Other options are :split and :frozen_split
219
267
 
220
- ### Currently not working
221
- #if options[:freeze][:active_pane]
222
- # Axlsx.validate_pane_type(options[:freeze][:active_pane])
223
- # pane.active_pane = options[:freeze][:active_pane]
224
- #else
225
- # pane.active_pane = :bottom_right
226
- #end
227
-
228
- if !options[:freeze][:rows]
229
- raise SpreadsheetArchitect::Exceptions::ArgumentError.new("The :rows key must be specified in the :freeze option hash")
230
- elsif options[:freeze][:rows].is_a?(Range)
231
- pane.y_split = options[:freeze][:rows].count
232
- else
233
- pane.y_split = 1
268
+ if options[:freeze][:active_pane]
269
+ pane.active_pane = options[:freeze][:active_pane].to_sym
234
270
  end
235
271
 
236
- if options[:freeze][:columns] && options[:freeze][:columns] != :all
237
- if options[:freeze][:columns].is_a?(Range)
238
- pane.x_split = options[:freeze][:columns].count
239
- else
240
- pane.x_split = 1
272
+ if options[:freeze][:top_left_cell]
273
+ pane.top_left_cell = options[:freeze][:top_left_cell]
274
+ end
275
+
276
+ if options[:freeze][:row]
277
+ if options[:use_zero_based_row_index]
278
+ options[:freeze][:row] += 1
241
279
  end
280
+
281
+ pane.y_split = options[:freeze][:row]
282
+ end
283
+
284
+ if options[:freeze][:column]
285
+ pane.x_split = options[:freeze][:column]
242
286
  end
243
287
  end
244
288
  end
@@ -14,17 +14,27 @@ module SpreadsheetArchitect
14
14
  end
15
15
 
16
16
  class InvalidRangeError < ArgumentError
17
- def initialize(type, range)
18
- case type
19
- when :columns, :rows
20
- super("Invalid range `#{range}` passed. Some of the #{type} specified were greater than the total number of #{type}")
21
- when :format
22
- super("Invalid range `#{range}` passed. Format must be as follows: A1:D4")
23
- when :type
24
- super("Invalid range type `#{range}`. Valid types are String and Hash")
25
- else
26
- super("Invalid range `#{range}` passed.")
17
+ def initialize(type, range, message: nil)
18
+ default_msg = "Invalid range `#{range}` passed"
19
+
20
+ if message.nil?
21
+ case type
22
+ when :missing_range_keys
23
+ message = "Missing :rows or :columns key"
24
+ when :format
25
+ message = "Format must be as follows: A1:D4"
26
+ when :type
27
+ message = "Valid types are Hash and String"
28
+ end
27
29
  end
30
+
31
+ super([default_msg, message].compact.join(". "))
32
+ end
33
+ end
34
+
35
+ class InvalidRangeValue < ArgumentError
36
+ def initialize(type, range)
37
+ super("Invalid range `#{range}` passed. Some of the :#{type} specified are either an invalid value or are greater than the total number of #{type}")
28
38
  end
29
39
  end
30
40
 
@@ -34,9 +44,16 @@ module SpreadsheetArchitect
34
44
  end
35
45
  end
36
46
 
37
- class InvalidRangeStylesOptionError < ArgumentError
38
- def initialize(type, opt)
39
- super("Invalid or missing :#{type} option for `#{opt}`. :#{type} can be an integer, range, or :all")
47
+ class InvalidRangeOptionError < ArgumentError
48
+ def initialize(key, opt)
49
+ default_msg = "Invalid :#{key} option for `#{opt}`"
50
+
51
+ case key
52
+ when :columns, :rows
53
+ message = ":#{key} can be an integer, range, or :all"
54
+ end
55
+
56
+ super([default_msg, message].compact.join(". "))
40
57
  end
41
58
  end
42
59