roo 1.13.2 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +17 -0
  3. data/.github/issue_template.md +16 -0
  4. data/.github/pull_request_template.md +14 -0
  5. data/.github/workflows/pull-request.yml +15 -0
  6. data/.github/workflows/ruby.yml +34 -0
  7. data/.gitignore +11 -0
  8. data/.rubocop.yml +186 -0
  9. data/.simplecov +4 -0
  10. data/CHANGELOG.md +702 -0
  11. data/Gemfile +18 -12
  12. data/Guardfile +23 -0
  13. data/LICENSE +5 -1
  14. data/README.md +328 -0
  15. data/Rakefile +23 -23
  16. data/examples/roo_soap_client.rb +28 -31
  17. data/examples/roo_soap_server.rb +4 -6
  18. data/examples/write_me.rb +9 -10
  19. data/lib/roo/base.rb +317 -504
  20. data/lib/roo/constants.rb +7 -0
  21. data/lib/roo/csv.rb +141 -113
  22. data/lib/roo/errors.rb +11 -0
  23. data/lib/roo/excelx/cell/base.rb +108 -0
  24. data/lib/roo/excelx/cell/boolean.rb +30 -0
  25. data/lib/roo/excelx/cell/date.rb +28 -0
  26. data/lib/roo/excelx/cell/datetime.rb +107 -0
  27. data/lib/roo/excelx/cell/empty.rb +20 -0
  28. data/lib/roo/excelx/cell/number.rb +99 -0
  29. data/lib/roo/excelx/cell/string.rb +19 -0
  30. data/lib/roo/excelx/cell/time.rb +44 -0
  31. data/lib/roo/excelx/cell.rb +110 -0
  32. data/lib/roo/excelx/comments.rb +55 -0
  33. data/lib/roo/excelx/coordinate.rb +19 -0
  34. data/lib/roo/excelx/extractor.rb +39 -0
  35. data/lib/roo/excelx/format.rb +71 -0
  36. data/lib/roo/excelx/images.rb +26 -0
  37. data/lib/roo/excelx/relationships.rb +33 -0
  38. data/lib/roo/excelx/shared.rb +39 -0
  39. data/lib/roo/excelx/shared_strings.rb +151 -0
  40. data/lib/roo/excelx/sheet.rb +151 -0
  41. data/lib/roo/excelx/sheet_doc.rb +257 -0
  42. data/lib/roo/excelx/styles.rb +64 -0
  43. data/lib/roo/excelx/workbook.rb +64 -0
  44. data/lib/roo/excelx.rb +407 -601
  45. data/lib/roo/font.rb +17 -0
  46. data/lib/roo/formatters/base.rb +15 -0
  47. data/lib/roo/formatters/csv.rb +84 -0
  48. data/lib/roo/formatters/matrix.rb +23 -0
  49. data/lib/roo/formatters/xml.rb +31 -0
  50. data/lib/roo/formatters/yaml.rb +40 -0
  51. data/lib/roo/helpers/default_attr_reader.rb +20 -0
  52. data/lib/roo/helpers/weak_instance_cache.rb +41 -0
  53. data/lib/roo/libre_office.rb +4 -0
  54. data/lib/roo/link.rb +34 -0
  55. data/lib/roo/open_office.rb +631 -0
  56. data/lib/roo/spreadsheet.rb +28 -23
  57. data/lib/roo/tempdir.rb +24 -0
  58. data/lib/roo/utils.rb +128 -0
  59. data/lib/roo/version.rb +3 -0
  60. data/lib/roo.rb +26 -24
  61. data/roo.gemspec +29 -203
  62. data/spec/helpers.rb +5 -0
  63. data/spec/lib/roo/base_spec.rb +291 -3
  64. data/spec/lib/roo/csv_spec.rb +38 -11
  65. data/spec/lib/roo/excelx/cell/time_spec.rb +15 -0
  66. data/spec/lib/roo/excelx/format_spec.rb +7 -6
  67. data/spec/lib/roo/excelx/relationships_spec.rb +43 -0
  68. data/spec/lib/roo/excelx/sheet_doc_spec.rb +11 -0
  69. data/spec/lib/roo/excelx_spec.rb +672 -11
  70. data/spec/lib/roo/libreoffice_spec.rb +16 -6
  71. data/spec/lib/roo/openoffice_spec.rb +30 -8
  72. data/spec/lib/roo/spreadsheet_spec.rb +60 -12
  73. data/spec/lib/roo/strict_spec.rb +43 -0
  74. data/spec/lib/roo/utils_spec.rb +119 -0
  75. data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
  76. data/spec/lib/roo_spec.rb +0 -0
  77. data/spec/spec_helper.rb +7 -6
  78. data/test/all_ss.rb +12 -11
  79. data/test/excelx/cell/test_attr_reader_default.rb +72 -0
  80. data/test/excelx/cell/test_base.rb +68 -0
  81. data/test/excelx/cell/test_boolean.rb +36 -0
  82. data/test/excelx/cell/test_date.rb +38 -0
  83. data/test/excelx/cell/test_datetime.rb +45 -0
  84. data/test/excelx/cell/test_empty.rb +18 -0
  85. data/test/excelx/cell/test_number.rb +90 -0
  86. data/test/excelx/cell/test_string.rb +48 -0
  87. data/test/excelx/cell/test_time.rb +30 -0
  88. data/test/excelx/test_coordinate.rb +51 -0
  89. data/test/formatters/test_csv.rb +136 -0
  90. data/test/formatters/test_matrix.rb +76 -0
  91. data/test/formatters/test_xml.rb +78 -0
  92. data/test/formatters/test_yaml.rb +20 -0
  93. data/test/helpers/test_accessing_files.rb +81 -0
  94. data/test/helpers/test_comments.rb +43 -0
  95. data/test/helpers/test_formulas.rb +9 -0
  96. data/test/helpers/test_labels.rb +103 -0
  97. data/test/helpers/test_sheets.rb +55 -0
  98. data/test/helpers/test_styles.rb +62 -0
  99. data/test/roo/test_base.rb +182 -0
  100. data/test/roo/test_csv.rb +88 -0
  101. data/test/roo/test_excelx.rb +360 -0
  102. data/test/roo/test_libre_office.rb +9 -0
  103. data/test/roo/test_open_office.rb +289 -0
  104. data/test/test_helper.rb +123 -59
  105. data/test/test_roo.rb +392 -2292
  106. metadata +153 -298
  107. data/CHANGELOG +0 -417
  108. data/Gemfile.lock +0 -78
  109. data/README.markdown +0 -126
  110. data/VERSION +0 -1
  111. data/lib/roo/excel.rb +0 -355
  112. data/lib/roo/excel2003xml.rb +0 -300
  113. data/lib/roo/google.rb +0 -292
  114. data/lib/roo/openoffice.rb +0 -496
  115. data/lib/roo/roo_rails_helper.rb +0 -83
  116. data/lib/roo/worksheet.rb +0 -18
  117. data/scripts/txt2html +0 -67
  118. data/spec/lib/roo/excel2003xml_spec.rb +0 -15
  119. data/spec/lib/roo/excel_spec.rb +0 -17
  120. data/spec/lib/roo/google_spec.rb +0 -64
  121. data/test/files/1900_base.xls +0 -0
  122. data/test/files/1900_base.xlsx +0 -0
  123. data/test/files/1904_base.xls +0 -0
  124. data/test/files/1904_base.xlsx +0 -0
  125. data/test/files/Bibelbund.csv +0 -3741
  126. data/test/files/Bibelbund.ods +0 -0
  127. data/test/files/Bibelbund.xls +0 -0
  128. data/test/files/Bibelbund.xlsx +0 -0
  129. data/test/files/Bibelbund.xml +0 -62518
  130. data/test/files/Bibelbund1.ods +0 -0
  131. data/test/files/Pfand_from_windows_phone.xlsx +0 -0
  132. data/test/files/bad_excel_date.xls +0 -0
  133. data/test/files/bbu.ods +0 -0
  134. data/test/files/bbu.xls +0 -0
  135. data/test/files/bbu.xlsx +0 -0
  136. data/test/files/bbu.xml +0 -152
  137. data/test/files/bode-v1.ods.zip +0 -0
  138. data/test/files/bode-v1.xls.zip +0 -0
  139. data/test/files/boolean.csv +0 -2
  140. data/test/files/boolean.ods +0 -0
  141. data/test/files/boolean.xls +0 -0
  142. data/test/files/boolean.xlsx +0 -0
  143. data/test/files/boolean.xml +0 -112
  144. data/test/files/borders.ods +0 -0
  145. data/test/files/borders.xls +0 -0
  146. data/test/files/borders.xlsx +0 -0
  147. data/test/files/borders.xml +0 -144
  148. data/test/files/bug-numbered-sheet-names.xlsx +0 -0
  149. data/test/files/bug-row-column-fixnum-float.xls +0 -0
  150. data/test/files/bug-row-column-fixnum-float.xml +0 -127
  151. data/test/files/comments.ods +0 -0
  152. data/test/files/comments.xls +0 -0
  153. data/test/files/comments.xlsx +0 -0
  154. data/test/files/csvtypes.csv +0 -1
  155. data/test/files/datetime.ods +0 -0
  156. data/test/files/datetime.xls +0 -0
  157. data/test/files/datetime.xlsx +0 -0
  158. data/test/files/datetime.xml +0 -142
  159. data/test/files/datetime_floatconv.xls +0 -0
  160. data/test/files/datetime_floatconv.xml +0 -148
  161. data/test/files/dreimalvier.ods +0 -0
  162. data/test/files/emptysheets.ods +0 -0
  163. data/test/files/emptysheets.xls +0 -0
  164. data/test/files/emptysheets.xlsx +0 -0
  165. data/test/files/emptysheets.xml +0 -105
  166. data/test/files/excel2003.xml +0 -21140
  167. data/test/files/false_encoding.xls +0 -0
  168. data/test/files/false_encoding.xml +0 -132
  169. data/test/files/file_item_error.xlsx +0 -0
  170. data/test/files/formula.ods +0 -0
  171. data/test/files/formula.xls +0 -0
  172. data/test/files/formula.xlsx +0 -0
  173. data/test/files/formula.xml +0 -134
  174. data/test/files/formula_parse_error.xls +0 -0
  175. data/test/files/formula_parse_error.xml +0 -1833
  176. data/test/files/formula_string_error.xlsx +0 -0
  177. data/test/files/html-escape.ods +0 -0
  178. data/test/files/link.xls +0 -0
  179. data/test/files/link.xlsx +0 -0
  180. data/test/files/matrix.ods +0 -0
  181. data/test/files/matrix.xls +0 -0
  182. data/test/files/named_cells.ods +0 -0
  183. data/test/files/named_cells.xls +0 -0
  184. data/test/files/named_cells.xlsx +0 -0
  185. data/test/files/no_spreadsheet_file.txt +0 -1
  186. data/test/files/numbers1.csv +0 -18
  187. data/test/files/numbers1.ods +0 -0
  188. data/test/files/numbers1.xls +0 -0
  189. data/test/files/numbers1.xlsx +0 -0
  190. data/test/files/numbers1.xml +0 -312
  191. data/test/files/numeric-link.xlsx +0 -0
  192. data/test/files/only_one_sheet.ods +0 -0
  193. data/test/files/only_one_sheet.xls +0 -0
  194. data/test/files/only_one_sheet.xlsx +0 -0
  195. data/test/files/only_one_sheet.xml +0 -67
  196. data/test/files/paragraph.ods +0 -0
  197. data/test/files/paragraph.xls +0 -0
  198. data/test/files/paragraph.xlsx +0 -0
  199. data/test/files/paragraph.xml +0 -127
  200. data/test/files/prova.xls +0 -0
  201. data/test/files/ric.ods +0 -0
  202. data/test/files/simple_spreadsheet.ods +0 -0
  203. data/test/files/simple_spreadsheet.xls +0 -0
  204. data/test/files/simple_spreadsheet.xlsx +0 -0
  205. data/test/files/simple_spreadsheet.xml +0 -225
  206. data/test/files/simple_spreadsheet_from_italo.ods +0 -0
  207. data/test/files/simple_spreadsheet_from_italo.xls +0 -0
  208. data/test/files/simple_spreadsheet_from_italo.xml +0 -242
  209. data/test/files/so_datetime.csv +0 -7
  210. data/test/files/style.ods +0 -0
  211. data/test/files/style.xls +0 -0
  212. data/test/files/style.xlsx +0 -0
  213. data/test/files/style.xml +0 -154
  214. data/test/files/time-test.csv +0 -2
  215. data/test/files/time-test.ods +0 -0
  216. data/test/files/time-test.xls +0 -0
  217. data/test/files/time-test.xlsx +0 -0
  218. data/test/files/time-test.xml +0 -131
  219. data/test/files/type_excel.ods +0 -0
  220. data/test/files/type_excel.xlsx +0 -0
  221. data/test/files/type_excelx.ods +0 -0
  222. data/test/files/type_excelx.xls +0 -0
  223. data/test/files/type_openoffice.xls +0 -0
  224. data/test/files/type_openoffice.xlsx +0 -0
  225. data/test/files/whitespace.ods +0 -0
  226. data/test/files/whitespace.xls +0 -0
  227. data/test/files/whitespace.xlsx +0 -0
  228. data/test/files/whitespace.xml +0 -184
  229. data/test/rm_sub_test.rb +0 -12
  230. data/test/rm_test.rb +0 -7
  231. data/test/test_generic_spreadsheet.rb +0 -259
  232. data/website/index.html +0 -385
  233. data/website/index.txt +0 -423
  234. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  235. data/website/stylesheets/screen.css +0 -130
  236. data/website/template.rhtml +0 -48
data/Gemfile CHANGED
@@ -1,18 +1,24 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
- gem 'spreadsheet', '> 0.6.4'
4
- gem 'nokogiri'
5
- gem 'rubyzip'
6
-
7
- group :development do
8
- gem 'google_drive'
9
- gem 'jeweler'
10
- end
3
+ gemspec
11
4
 
12
5
  group :test do
13
6
  # additional testing libs
14
- gem 'webmock'
15
7
  gem 'shoulda'
16
- gem 'rspec'
17
- gem 'vcr'
8
+ gem 'activesupport', '< 5.1'
9
+ gem 'rspec', '>= 3.0.0'
10
+ gem 'simplecov', '>= 0.9.0', require: false
11
+ gem 'coveralls', require: false
12
+ gem "minitest-reporters"
13
+ gem 'webrick' if RUBY_VERSION >= '3.0.0'
14
+ end
15
+
16
+ group :local_development do
17
+ gem 'terminal-notifier-guard', require: false if RUBY_PLATFORM.downcase.include?('darwin')
18
+ gem 'guard-rspec', '>= 4.3.1', require: false
19
+ gem 'guard-minitest', require: false
20
+ gem 'guard-bundler', require: false
21
+ gem 'guard-rubocop', require: false
22
+ gem "rb-readline"
23
+ gem 'pry'
18
24
  end
data/Guardfile ADDED
@@ -0,0 +1,23 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :minitest, test_folders: ['test'] do
5
+ watch(%r{^test/(.*)\/?test_(.*)\.rb$})
6
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1].to_s.sub('roo/', '')}test_#{m[2]}.rb" }
7
+ watch(%r{^test/test_helper\.rb$}) { 'test' }
8
+ end
9
+
10
+ # Note: The cmd option is now required due to the increasing number of ways
11
+ # rspec may be run, below are examples of the most common uses.
12
+ # * bundler: 'bundle exec rspec'
13
+ # * bundler binstubs: 'bin/rspec'
14
+ # * spring: 'bin/rsspec' (This will use spring if running and you have
15
+ # installed the spring binstubs per the docs)
16
+ # * zeus: 'zeus rspec' (requires the server to be started separetly)
17
+ # * 'just' rspec: 'rspec'
18
+ guard :rspec, cmd: 'bundle exec rspec' do
19
+ watch(%r{^spec/.+_spec\.rb$})
20
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
21
+ watch('spec/spec_helper.rb') { "spec" }
22
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
23
+ end
data/LICENSE CHANGED
@@ -1,4 +1,8 @@
1
- Copyright (c) 2008-2013 Thomas Preymesser, Ben Woosley
1
+ Copyright (c) 2008-2014 Thomas Preymesser, Ben Woosley
2
+ Copyright (c) 2014-2017 Ben Woosley
3
+ Copyright (c) 2015-2017 Oleksandr Simonov, Steven Daniels
4
+
5
+ MIT License
2
6
 
3
7
  Permission is hereby granted, free of charge, to any person obtaining
4
8
  a copy of this software and associated documentation files (the
data/README.md ADDED
@@ -0,0 +1,328 @@
1
+ # Roo
2
+
3
+ [![Build Status](https://img.shields.io/travis/roo-rb/roo.svg?style=flat-square)](https://travis-ci.org/roo-rb/roo) [![Maintainability](https://api.codeclimate.com/v1/badges/be8d7bf34e2aeaf67c62/maintainability)](https://codeclimate.com/github/roo-rb/roo/maintainability) [![Coverage Status](https://img.shields.io/coveralls/roo-rb/roo.svg?style=flat-square)](https://coveralls.io/r/roo-rb/roo) [![Gem Version](https://img.shields.io/gem/v/roo.svg?style=flat-square)](https://rubygems.org/gems/roo)
4
+
5
+ Roo implements read access for all common spreadsheet types. It can handle:
6
+ * Excel 2007 - 2013 formats (xlsx, xlsm)
7
+ * LibreOffice / OpenOffice.org formats (ods)
8
+ * CSV
9
+ * Excel 97, Excel 2002 XML, and Excel 2003 XML formats when using the [roo-xls](https://github.com/roo-rb/roo-xls) gem (xls, xml)
10
+ * Google spreadsheets with read/write access when using [roo-google](https://github.com/roo-rb/roo-google)
11
+
12
+ ## Installation
13
+
14
+ Install as a gem
15
+
16
+ $ gem install roo
17
+
18
+ Or add it to your Gemfile
19
+
20
+ ```ruby
21
+ gem "roo", "~> 2.10.0"
22
+ ```
23
+ ## Usage
24
+
25
+ ### Opening a spreadsheet
26
+
27
+ You can use the `Roo::Spreadsheet` class so `roo` automatically detects which [parser class](https://github.com/roo-rb/roo/blob/master/lib/roo.rb#L17) to use for you.
28
+ ```ruby
29
+ require 'roo'
30
+
31
+ file_name = './new_prices.xlsx'
32
+ xlsx = Roo::Spreadsheet.open(file_name)
33
+ xlsx.info
34
+ # => Returns basic info about the spreadsheet file
35
+ ```
36
+
37
+ ``Roo::Spreadsheet.open`` can accept both string paths and ``File`` instances. Also, you can provide the extension of the file as an option:
38
+
39
+ ```ruby
40
+ require 'roo'
41
+
42
+ file_name = './rails_temp_upload'
43
+ xlsx = Roo::Spreadsheet.open(file_name, extension: :xlsx)
44
+ xlsx.info
45
+ # => Returns basic info about the spreadsheet file
46
+ ```
47
+
48
+ On the other hand, if you know what the file extension is, you can use the specific parser class instead:
49
+ ```ruby
50
+ require 'roo'
51
+
52
+ xlsx = Roo::Excelx.new("./new_prices.xlsx")
53
+ xlsx.info
54
+ # => Returns basic info about the spreadsheet file
55
+ ```
56
+
57
+ ### Working with sheets
58
+
59
+ ```ruby
60
+ ods.sheets
61
+ # => ['Info', 'Sheet 2', 'Sheet 3'] # an Array of sheet names in the workbook
62
+
63
+ ods.sheet('Info').row(1)
64
+ ods.sheet(0).row(1)
65
+
66
+ # Set the last sheet as the default sheet.
67
+ ods.default_sheet = ods.sheets.last
68
+ ods.default_sheet = ods.sheets[2]
69
+ ods.default_sheet = 'Sheet 3'
70
+
71
+ # Iterate through each sheet
72
+ ods.each_with_pagename do |name, sheet|
73
+ p sheet.row(1)
74
+ end
75
+ ```
76
+
77
+ ### Accessing rows and columns
78
+
79
+ Roo uses Excel's numbering for rows, columns and cells, so `1` is the first index, not `0` as it is in an ``Array``
80
+
81
+ ```ruby
82
+ sheet.row(1)
83
+ # returns the first row of the spreadsheet.
84
+
85
+ sheet.column(1)
86
+ # returns the first column of the spreadsheet.
87
+ ```
88
+
89
+ Almost all methods have an optional argument `sheet`. If this parameter is omitted, the default_sheet will be used.
90
+
91
+ ```ruby
92
+ sheet.first_row(sheet.sheets[0])
93
+ # => 1 # the number of the first row
94
+ sheet.last_row
95
+ # => 42 # the number of the last row
96
+ sheet.first_column
97
+ # => 1 # the number of the first column
98
+ sheet.last_column
99
+ # => 10 # the number of the last column
100
+ ```
101
+
102
+ #### Accessing cells
103
+
104
+ You can access the top-left cell in the following ways
105
+
106
+ ```ruby
107
+ sheet.cell(1,1)
108
+ sheet.cell('A',1)
109
+ sheet.cell(1,'A')
110
+ sheet.a1
111
+
112
+ # Access the second sheet's top-left cell.
113
+ sheet.cell(1,'A',sheet.sheets[1])
114
+ ```
115
+
116
+ #### Querying a spreadsheet
117
+ Use ``each`` to iterate over each row.
118
+
119
+ If each is given a hash with the names of some columns, then each will generate a hash with the columns supplied for each row.
120
+
121
+ ```ruby
122
+ sheet.each(id: 'ID', name: 'FULL_NAME') do |hash|
123
+ puts hash.inspect
124
+ # => { id: 1, name: 'John Smith' }
125
+ end
126
+ ```
127
+
128
+ Use ``sheet.parse`` to return an array of rows. Column names can be a ``String`` or a ``Regexp``.
129
+
130
+ ```ruby
131
+ sheet.parse(id: /UPC|SKU/, qty: /ATS*\sATP\s*QTY\z/)
132
+ # => [{:id => 727880013358, :qty => 12}, ...]
133
+ ```
134
+
135
+ Use the ``:headers`` option to include the header row in the parsed content.
136
+
137
+ ```ruby
138
+ sheet.parse(headers: true)
139
+ ```
140
+
141
+ Use the ``:header_search`` option to locate the header row and assign the header names.
142
+
143
+ ```ruby
144
+ sheet.parse(header_search: [/UPC*SKU/,/ATS*\sATP\s*QTY\z/])
145
+ ```
146
+
147
+ Use the ``:clean`` option to strip out control characters and surrounding white space.
148
+
149
+ ```ruby
150
+ sheet.parse(clean: true)
151
+ ```
152
+
153
+ #### Options
154
+
155
+ When opening the file you can add a hash of options.
156
+
157
+ ##### expand_merged_ranges
158
+ If you open a document with merged cells and do not want to end up with nil values for the rows after the first one.
159
+ ```ruby
160
+ xlsx = Roo::Excelx.new('./roo_error.xlsx', {:expand_merged_ranges => true})
161
+ ```
162
+
163
+ ### Exporting spreadsheets
164
+ Roo has the ability to export sheets using the following formats. It
165
+ will only export the ``default_sheet``.
166
+
167
+ ```ruby
168
+ sheet.to_csv
169
+ sheet.to_matrix
170
+ sheet.to_xml
171
+ sheet.to_yaml
172
+ ```
173
+
174
+ ### Excel (xlsx and xlsm) Support
175
+
176
+ Stream rows from an Excelx spreadsheet.
177
+
178
+ ```ruby
179
+ xlsx = Roo::Excelx.new("./test_data/test_small.xlsx")
180
+ xlsx.each_row_streaming do |row|
181
+ puts row.inspect # Array of Excelx::Cell objects
182
+ end
183
+ ```
184
+
185
+ By default blank cells will be excluded from the array. To keep them, use the option pad_cells = true. (They will be set to nil in the array)
186
+ ```ruby
187
+ xlsx.each_row_streaming(pad_cells: true) do |row|
188
+ puts row.inspect # Array of Excelx::Cell objects
189
+ end
190
+ ```
191
+
192
+ To stream only some of the rows, you can use the ```max_rows``` and ```offset```options.
193
+ ```ruby
194
+ xlsx.each_row_streaming(offset: 1) do |row| # Will exclude first (inevitably header) row
195
+ puts row.inspect # Array of Excelx::Cell objects
196
+ end
197
+ ```
198
+
199
+ ```ruby
200
+ xlsx.each_row_streaming(max_rows: 3) do |row| # Will yield 4 rows (it's automatically incremented by 1) after the supplied offset.
201
+ puts row.inspect # Array of Excelx::Cell objects
202
+ end
203
+ ```
204
+
205
+ Iterate over each row
206
+
207
+ ```ruby
208
+ xlsx.each_row do |row|
209
+ ...
210
+ end
211
+ ```
212
+
213
+ ``Roo::Excelx`` also provides these helpful methods.
214
+
215
+ ```ruby
216
+ xlsx.excelx_type(3, 'C')
217
+ # => :numeric_or_formula
218
+
219
+ xlsx.cell(3, 'C')
220
+ # => 600000383.0
221
+
222
+ xlsx.excelx_value(row,col)
223
+ # => '600000383'
224
+
225
+ xlsx.formatted_value(row,col)
226
+ # => '0600000383'
227
+ ```
228
+
229
+ ``Roo::Excelx`` can access celltype, comments, font information, formulas, hyperlinks and labels.
230
+
231
+ ```ruby
232
+ xlsx.comment(1,1, ods.sheets[-1])
233
+ xlsx.font(1,1).bold?
234
+ xlsx.formula('A', 2)
235
+ ```
236
+
237
+ ### OpenOffice / LibreOffice Support
238
+
239
+ Roo::OpenOffice has support for encrypted OpenOffice spreadsheets.
240
+
241
+ ```ruby
242
+ # Load an encrypted OpenOffice Spreadsheet
243
+ ods = Roo::OpenOffice.new("myspreadsheet.ods", password: "password")
244
+ ```
245
+
246
+ ``Roo::OpenOffice`` can access celltype, comments, font information, formulas and labels.
247
+
248
+ ```ruby
249
+ ods.celltype
250
+ # => :percentage
251
+
252
+ ods.comment(1,1, ods.sheets[-1])
253
+
254
+ ods.font(1,1).italic?
255
+ # => false
256
+
257
+ ods.formula('A', 2)
258
+ ```
259
+
260
+ ### CSV Support
261
+
262
+ ```ruby
263
+ # Load a CSV file
264
+ csv = Roo::CSV.new("mycsv.csv")
265
+ ```
266
+
267
+ Because Roo uses the standard CSV library, you can use options available to that library to parse csv files. You can pass options using the ``csv_options`` key.
268
+
269
+ For instance, you can load tab-delimited files (``.tsv``), and you can use a particular encoding when opening the file.
270
+
271
+
272
+ ```ruby
273
+ # Load a tab-delimited csv
274
+ csv = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})
275
+
276
+ # Load a csv with an explicit encoding
277
+ csv = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})
278
+ ```
279
+
280
+ You can also open csv files through the Roo::Spreadsheet class (useful if you accept both CSV and Excel types from a user file upload, for example).
281
+
282
+ ```ruby
283
+ # Load a spreadsheet from a file path
284
+ # Roo figures out the right parser based on file extension
285
+ spreadsheet = Roo::Spreadsheet.open(csv_or_xlsx_file)
286
+
287
+ # Load a csv and auto-strip the BOM (byte order mark)
288
+ # csv files saved from MS Excel typically have the BOM marker at the beginning of the file
289
+ spreadsheet = Roo::Spreadsheet.open("mycsv.csv", { csv_options: { encoding: 'bom|utf-8' } })
290
+ ```
291
+
292
+ ## Upgrading from Roo 1.13.x
293
+ If you use ``.xls`` or Google spreadsheets, you will need to install ``roo-xls`` or ``roo-google`` to continue using that functionality.
294
+
295
+ Roo's public methods have stayed relatively consistent between 1.13.x and 2.0.0, but please check the [Changelog](https://github.com/roo-rb/roo/blob/master/CHANGELOG.md) to better understand the changes made since 1.13.x.
296
+
297
+
298
+
299
+ ## Contributing
300
+ ### Features
301
+ 1. Fork it ( https://github.com/roo-rb/roo/fork )
302
+ 2. Install it (`bundle install --with local_development`)
303
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
304
+ 4. Commit your changes (`git commit -am 'My new feature'`)
305
+ 5. Push to the branch (`git push origin my-new-feature`)
306
+ 6. Create a new Pull Request
307
+
308
+ ### Testing
309
+ Roo uses Minitest and RSpec. The best of both worlds! Run `bundle exec rake` to
310
+ run the tests/examples.
311
+
312
+ You can run the tests/examples with Rspec like reporters by running
313
+ `USE_REPORTERS=true bundle exec rake`
314
+
315
+ Roo also has a few tests that take a long time (5+ seconds). To run these, use
316
+ `LONG_RUN=true bundle exec rake`
317
+
318
+ ### Issues
319
+
320
+ If you find an issue, please create a gist and refer to it in an issue ([sample gist](https://gist.github.com/stevendaniels/98a05849036e99bb8b3c)). Here are some instructions for creating such a gist.
321
+
322
+ 1. [Create a gist](https://gist.github.com) with code that creates the error.
323
+ 2. Clone the gist repo locally, add a stripped down version of the offending spreadsheet to the gist repo, and push the gist's changes master.
324
+ 3. Paste the gist url here.
325
+
326
+
327
+ ## License
328
+ [Roo uses an MIT License](https://github.com/roo-rb/roo/blob/master/LICENSE)
data/Rakefile CHANGED
@@ -1,23 +1,23 @@
1
- require 'jeweler'
2
-
3
- Jeweler::Tasks.new do |gem|
4
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
5
- gem.name = "roo"
6
- gem.summary = "Roo can access the contents of various spreadsheet files."
7
- gem.description = "Roo can access the contents of various spreadsheet files. It can handle\n* OpenOffice\n* Excel\n* Google spreadsheets\n* Excelx\n* LibreOffice\n* CSV"
8
- gem.email = "ruby.ruby.ruby.roo@gmail.com"
9
- gem.homepage = "http://github.com/Empact/roo"
10
- gem.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley']
11
-
12
- gem.license = 'MIT'
13
- gem.required_ruby_version = '>= 1.9.0'
14
-
15
- gem.test_files = FileList["{spec,test}/**/*.*"]
16
- end
17
-
18
- require 'rake/testtask'
19
- Rake::TestTask.new do |t|
20
- t.libs << "test"
21
- t.test_files = FileList['test/test*.rb']
22
- t.verbose = true
23
- end
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+ require 'rspec/core/rake_task'
5
+ require 'coveralls/rake/task'
6
+
7
+ # Test unit
8
+ Rake::TestTask.new do |t|
9
+ t.libs << 'test'
10
+ t.test_files = FileList['test/**/test*.rb']
11
+ t.verbose = true
12
+ end
13
+
14
+ # RSpec
15
+ RSpec::Core::RakeTask.new(:spec)
16
+
17
+ # Coveralls
18
+ Coveralls::RakeTask.new
19
+
20
+ default_task = [:test, :spec]
21
+ default_task << 'coveralls:push' if ENV['TRAVIS']
22
+
23
+ task default: default_task
@@ -1,38 +1,38 @@
1
1
  require 'soap/rpc/driver'
2
2
 
3
- def ferien_fuer_region(proxy, region, year=nil)
4
- proxy.first_row.upto(proxy.last_row) { |row|
5
- if proxy.cell(row, 2) == region
6
- jahr = proxy.cell(row,1).to_i
7
- if year == nil || jahr == year
8
- bis_datum = proxy.cell(row,5)
9
- if DateTime.now > bis_datum
10
- print '('
11
- end
12
- print jahr.to_s+" "
13
- print proxy.cell(row,2)+" "
14
- print proxy.cell(row,3)+" "
15
- print proxy.cell(row,4).to_s+" "
16
- print bis_datum.to_s+" "
17
- print (proxy.cell(row,6) || '')+" "
18
- if DateTime.now > bis_datum
19
- print ')'
20
- end
21
- puts
3
+ def ferien_fuer_region(proxy, region, year = nil)
4
+ proxy.first_row.upto(proxy.last_row) do |row|
5
+ if proxy.cell(row, 2) == region
6
+ jahr = proxy.cell(row, 1).to_i
7
+ if year.nil? || jahr == year
8
+ bis_datum = proxy.cell(row, 5)
9
+ if DateTime.now > bis_datum
10
+ print '('
22
11
  end
23
- end
24
- }
12
+ print jahr.to_s + ' '
13
+ print proxy.cell(row, 2) + ' '
14
+ print proxy.cell(row, 3) + ' '
15
+ print proxy.cell(row, 4).to_s + ' '
16
+ print bis_datum.to_s + ' '
17
+ print (proxy.cell(row, 6) || '') + ' '
18
+ if DateTime.now > bis_datum
19
+ print ')'
20
+ end
21
+ puts
22
+ end
23
+ end
25
24
  end
25
+ end
26
26
 
27
- proxy = SOAP::RPC::Driver.new("http://localhost:12321","spreadsheetserver")
28
- proxy.add_method('cell','row','col')
27
+ proxy = SOAP::RPC::Driver.new('http://localhost:12321', 'spreadsheetserver')
28
+ proxy.add_method('cell', 'row', 'col')
29
29
  proxy.add_method('officeversion')
30
30
  proxy.add_method('last_row')
31
31
  proxy.add_method('last_column')
32
32
  proxy.add_method('first_row')
33
33
  proxy.add_method('first_column')
34
34
  proxy.add_method('sheets')
35
- proxy.add_method('set_default_sheet','s')
35
+ proxy.add_method('set_default_sheet', 's')
36
36
  proxy.add_method('ferien_fuer_region', 'region')
37
37
 
38
38
  sheets = proxy.sheets
@@ -42,12 +42,9 @@ puts "first row: #{proxy.first_row}"
42
42
  puts "first column: #{proxy.first_column}"
43
43
  puts "last row: #{proxy.last_row}"
44
44
  puts "last column: #{proxy.last_column}"
45
- puts "cell: #{proxy.cell('C',8)}"
46
- puts "cell: #{proxy.cell('F',12)}"
45
+ puts "cell: #{proxy.cell('C', 8)}"
46
+ puts "cell: #{proxy.cell('F', 12)}"
47
47
  puts "officeversion: #{proxy.officeversion}"
48
- puts "Berlin:"
49
-
50
- ferien_fuer_region(proxy, "Berlin")
51
-
52
-
48
+ puts 'Berlin:'
53
49
 
50
+ ferien_fuer_region(proxy, 'Berlin')
@@ -1,11 +1,10 @@
1
1
  require 'roo'
2
2
  require 'soap/rpc/standaloneServer'
3
3
 
4
- NS = "spreadsheetserver" # name of your service = namespace
4
+ NS = 'spreadsheetserver' # name of your service = namespace
5
5
  class Server2 < SOAP::RPC::StandaloneServer
6
-
7
6
  def on_init
8
- spreadsheet = OpenOffice.new("./Ferien-de.ods")
7
+ spreadsheet = OpenOffice.new('./Ferien-de.ods')
9
8
  add_method(spreadsheet, 'cell', 'row', 'col')
10
9
  add_method(spreadsheet, 'officeversion')
11
10
  add_method(spreadsheet, 'first_row')
@@ -13,14 +12,13 @@ class Server2 < SOAP::RPC::StandaloneServer
13
12
  add_method(spreadsheet, 'first_column')
14
13
  add_method(spreadsheet, 'last_column')
15
14
  add_method(spreadsheet, 'sheets')
16
- #add_method(spreadsheet, 'default_sheet=', 's')
15
+ # add_method(spreadsheet, 'default_sheet=', 's')
17
16
  # method with '...=' did not work? alias method 'set_default_sheet' created
18
17
  add_method(spreadsheet, 'set_default_sheet', 's')
19
18
  end
20
-
21
19
  end
22
20
 
23
- PORT = 12321
21
+ PORT = 12_321
24
22
  puts "serving at port #{PORT}"
25
23
  svr = Server2.new('Roo', NS, '0.0.0.0', PORT)
26
24
 
data/examples/write_me.rb CHANGED
@@ -5,28 +5,27 @@ require 'roo'
5
5
  MAXTRIES = 1000
6
6
  print "what's your name? "
7
7
  my_name = gets.chomp
8
- print "where do you live? "
8
+ print 'where do you live? '
9
9
  my_location = gets.chomp
10
- print "your message? (if left blank, only your name and location will be inserted) "
10
+ print 'your message? (if left blank, only your name and location will be inserted) '
11
11
  my_message = gets.chomp
12
12
  spreadsheet = Google.new('ptu6bbahNZpY0N0RrxQbWdw')
13
13
  spreadsheet.default_sheet = 'Sheet1'
14
14
  success = false
15
15
  MAXTRIES.times do
16
- col = rand(10)+1
17
- row = rand(10)+1
18
- if spreadsheet.empty?(row,col)
16
+ col = rand(10) + 1
17
+ row = rand(10) + 1
18
+ if spreadsheet.empty?(row, col)
19
19
  if my_message.empty?
20
- text = Time.now.to_s+" "+"Greetings from #{my_name} (#{my_location})"
20
+ text = Time.now.to_s + ' ' + "Greetings from #{my_name} (#{my_location})"
21
21
  else
22
- text = Time.now.to_s+" "+"#{my_message} from #{my_name} (#{my_location})"
22
+ text = Time.now.to_s + ' ' + "#{my_message} from #{my_name} (#{my_location})"
23
23
  end
24
- spreadsheet.set_value(row,col,text)
24
+ spreadsheet.set_value(row, col, text)
25
25
  puts "message written to row #{row}, column #{col}"
26
26
  success = true
27
27
  break
28
28
  end
29
29
  puts "Row #{row}, column #{col} already occupied, trying again..."
30
30
  end
31
- puts "no empty cell found within #{MAXTRIES} tries" if !success
32
-
31
+ puts "no empty cell found within #{MAXTRIES} tries" unless success