ruh-roo 3.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +677 -0
- data/Gemfile +24 -0
- data/LICENSE +24 -0
- data/README.md +315 -0
- data/lib/roo/base.rb +607 -0
- data/lib/roo/constants.rb +7 -0
- data/lib/roo/csv.rb +141 -0
- data/lib/roo/errors.rb +11 -0
- data/lib/roo/excelx/cell/base.rb +108 -0
- data/lib/roo/excelx/cell/boolean.rb +30 -0
- data/lib/roo/excelx/cell/date.rb +28 -0
- data/lib/roo/excelx/cell/datetime.rb +107 -0
- data/lib/roo/excelx/cell/empty.rb +20 -0
- data/lib/roo/excelx/cell/number.rb +89 -0
- data/lib/roo/excelx/cell/string.rb +19 -0
- data/lib/roo/excelx/cell/time.rb +44 -0
- data/lib/roo/excelx/cell.rb +110 -0
- data/lib/roo/excelx/comments.rb +55 -0
- data/lib/roo/excelx/coordinate.rb +19 -0
- data/lib/roo/excelx/extractor.rb +39 -0
- data/lib/roo/excelx/format.rb +71 -0
- data/lib/roo/excelx/images.rb +26 -0
- data/lib/roo/excelx/relationships.rb +33 -0
- data/lib/roo/excelx/shared.rb +39 -0
- data/lib/roo/excelx/shared_strings.rb +151 -0
- data/lib/roo/excelx/sheet.rb +151 -0
- data/lib/roo/excelx/sheet_doc.rb +248 -0
- data/lib/roo/excelx/styles.rb +64 -0
- data/lib/roo/excelx/workbook.rb +63 -0
- data/lib/roo/excelx.rb +480 -0
- data/lib/roo/font.rb +17 -0
- data/lib/roo/formatters/base.rb +15 -0
- data/lib/roo/formatters/csv.rb +84 -0
- data/lib/roo/formatters/matrix.rb +23 -0
- data/lib/roo/formatters/xml.rb +31 -0
- data/lib/roo/formatters/yaml.rb +40 -0
- data/lib/roo/helpers/default_attr_reader.rb +20 -0
- data/lib/roo/helpers/weak_instance_cache.rb +41 -0
- data/lib/roo/libre_office.rb +4 -0
- data/lib/roo/link.rb +34 -0
- data/lib/roo/open_office.rb +628 -0
- data/lib/roo/spreadsheet.rb +39 -0
- data/lib/roo/tempdir.rb +21 -0
- data/lib/roo/utils.rb +128 -0
- data/lib/roo/version.rb +3 -0
- data/lib/roo.rb +36 -0
- data/roo.gemspec +28 -0
- metadata +189 -0
data/Gemfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
# additional testing libs
|
7
|
+
gem 'shoulda'
|
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'
|
24
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
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
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
a copy of this software and associated documentation files (the
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be
|
16
|
+
included in all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,315 @@
|
|
1
|
+
# Ruh-Roo
|
2
|
+
|
3
|
+
[](https://travis-ci.org/roo-rb/roo) [](https://codeclimate.com/github/roo-rb/roo/maintainability) [](https://coveralls.io/r/roo-rb/roo) [](https://rubygems.org/gems/roo)
|
4
|
+
|
5
|
+
Ruh-roh, it's been a while (2 years at the time of writing) since roo has released a new version of their gem. This fixes that by packaging up the latest master branch and publishing it for release.
|
6
|
+
|
7
|
+
Roo implements read access for all common spreadsheet types. It can handle:
|
8
|
+
* Excel 2007 - 2013 formats (xlsx, xlsm)
|
9
|
+
* LibreOffice / OpenOffice.org formats (ods)
|
10
|
+
* CSV
|
11
|
+
* 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)
|
12
|
+
* Google spreadsheets with read/write access when using [roo-google](https://github.com/roo-rb/roo-google)
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Install as a gem
|
17
|
+
|
18
|
+
$ gem install roo
|
19
|
+
|
20
|
+
Or add it to your Gemfile
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem "ruh-roo", "~> 3.0.0"
|
24
|
+
```
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Opening a spreadsheet
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'roo'
|
31
|
+
|
32
|
+
xlsx = Roo::Spreadsheet.open('./new_prices.xlsx')
|
33
|
+
xlsx = Roo::Excelx.new("./new_prices.xlsx")
|
34
|
+
|
35
|
+
# Use the extension option if the extension is ambiguous.
|
36
|
+
xlsx = Roo::Spreadsheet.open('./rails_temp_upload', extension: :xlsx)
|
37
|
+
|
38
|
+
xlsx.info
|
39
|
+
# => Returns basic info about the spreadsheet file
|
40
|
+
```
|
41
|
+
|
42
|
+
``Roo::Spreadsheet.open`` can accept both paths and ``File`` instances.
|
43
|
+
|
44
|
+
### Working with sheets
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
ods.sheets
|
48
|
+
# => ['Info', 'Sheet 2', 'Sheet 3'] # an Array of sheet names in the workbook
|
49
|
+
|
50
|
+
ods.sheet('Info').row(1)
|
51
|
+
ods.sheet(0).row(1)
|
52
|
+
|
53
|
+
# Set the last sheet as the default sheet.
|
54
|
+
ods.default_sheet = ods.sheets.last
|
55
|
+
ods.default_sheet = ods.sheets[2]
|
56
|
+
ods.default_sheet = 'Sheet 3'
|
57
|
+
|
58
|
+
# Iterate through each sheet
|
59
|
+
ods.each_with_pagename do |name, sheet|
|
60
|
+
p sheet.row(1)
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
### Accessing rows and columns
|
65
|
+
|
66
|
+
Roo uses Excel's numbering for rows, columns and cells, so `1` is the first index, not `0` as it is in an ``Array``
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
sheet.row(1)
|
70
|
+
# returns the first row of the spreadsheet.
|
71
|
+
|
72
|
+
sheet.column(1)
|
73
|
+
# returns the first column of the spreadsheet.
|
74
|
+
```
|
75
|
+
|
76
|
+
Almost all methods have an optional argument `sheet`. If this parameter is omitted, the default_sheet will be used.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
sheet.first_row(sheet.sheets[0])
|
80
|
+
# => 1 # the number of the first row
|
81
|
+
sheet.last_row
|
82
|
+
# => 42 # the number of the last row
|
83
|
+
sheet.first_column
|
84
|
+
# => 1 # the number of the first column
|
85
|
+
sheet.last_column
|
86
|
+
# => 10 # the number of the last column
|
87
|
+
```
|
88
|
+
|
89
|
+
#### Accessing cells
|
90
|
+
|
91
|
+
You can access the top-left cell in the following ways
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
sheet.cell(1,1)
|
95
|
+
sheet.cell('A',1)
|
96
|
+
sheet.cell(1,'A')
|
97
|
+
sheet.a1
|
98
|
+
|
99
|
+
# Access the second sheet's top-left cell.
|
100
|
+
sheet.cell(1,'A',sheet.sheets[1])
|
101
|
+
```
|
102
|
+
|
103
|
+
#### Querying a spreadsheet
|
104
|
+
Use ``each`` to iterate over each row.
|
105
|
+
|
106
|
+
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.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
sheet.each(id: 'ID', name: 'FULL_NAME') do |hash|
|
110
|
+
puts hash.inspect
|
111
|
+
# => { id: 1, name: 'John Smith' }
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
Use ``sheet.parse`` to return an array of rows. Column names can be a ``String`` or a ``Regexp``.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
sheet.parse(id: /UPC|SKU/, qty: /ATS*\sATP\s*QTY\z/)
|
119
|
+
# => [{:id => 727880013358, :qty => 12}, ...]
|
120
|
+
```
|
121
|
+
|
122
|
+
Use the ``:headers`` option to include the header row in the parsed content.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
sheet.parse(headers: true)
|
126
|
+
```
|
127
|
+
|
128
|
+
Use the ``:header_search`` option to locate the header row and assign the header names.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
sheet.parse(header_search: [/UPC*SKU/,/ATS*\sATP\s*QTY\z/])
|
132
|
+
```
|
133
|
+
|
134
|
+
Use the ``:clean`` option to strip out control characters and surrounding white space.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
sheet.parse(clean: true)
|
138
|
+
```
|
139
|
+
|
140
|
+
#### Options
|
141
|
+
|
142
|
+
When opening the file you can add a hash of options.
|
143
|
+
|
144
|
+
##### expand_merged_ranges
|
145
|
+
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.
|
146
|
+
```ruby
|
147
|
+
xlsx = Roo::Excelx.new('./roo_error.xlsx', {:expand_merged_ranges => true})
|
148
|
+
```
|
149
|
+
|
150
|
+
### Exporting spreadsheets
|
151
|
+
Roo has the ability to export sheets using the following formats. It
|
152
|
+
will only export the ``default_sheet``.
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
sheet.to_csv
|
156
|
+
sheet.to_matrix
|
157
|
+
sheet.to_xml
|
158
|
+
sheet.to_yaml
|
159
|
+
```
|
160
|
+
|
161
|
+
### Excel (xlsx and xlsm) Support
|
162
|
+
|
163
|
+
Stream rows from an Excelx spreadsheet.
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
xlsx = Roo::Excelx.new("./test_data/test_small.xlsx")
|
167
|
+
xlsx.each_row_streaming do |row|
|
168
|
+
puts row.inspect # Array of Excelx::Cell objects
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
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)
|
173
|
+
```ruby
|
174
|
+
xlsx.each_row_streaming(pad_cells: true) do |row|
|
175
|
+
puts row.inspect # Array of Excelx::Cell objects
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
To stream only some of the rows, you can use the ```max_rows``` and ```offset```options.
|
180
|
+
```ruby
|
181
|
+
xlsx.each_row_streaming(offset: 1) do |row| # Will exclude first (inevitably header) row
|
182
|
+
puts row.inspect # Array of Excelx::Cell objects
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
xlsx.each_row_streaming(max_rows: 3) do |row| # Will yield 4 rows (it's automatically incremented by 1) after the supplied offset.
|
188
|
+
puts row.inspect # Array of Excelx::Cell objects
|
189
|
+
end
|
190
|
+
```
|
191
|
+
|
192
|
+
Iterate over each row
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
xlsx.each_row do |row|
|
196
|
+
...
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
``Roo::Excelx`` also provides these helpful methods.
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
xlsx.excelx_type(3, 'C')
|
204
|
+
# => :numeric_or_formula
|
205
|
+
|
206
|
+
xlsx.cell(3, 'C')
|
207
|
+
# => 600000383.0
|
208
|
+
|
209
|
+
xlsx.excelx_value(row,col)
|
210
|
+
# => '600000383'
|
211
|
+
|
212
|
+
xlsx.formatted_value(row,col)
|
213
|
+
# => '0600000383'
|
214
|
+
```
|
215
|
+
|
216
|
+
``Roo::Excelx`` can access celltype, comments, font information, formulas, hyperlinks and labels.
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
xlsx.comment(1,1, ods.sheets[-1])
|
220
|
+
xlsx.font(1,1).bold?
|
221
|
+
xlsx.formula('A', 2)
|
222
|
+
```
|
223
|
+
|
224
|
+
### OpenOffice / LibreOffice Support
|
225
|
+
|
226
|
+
Roo::OpenOffice has support for encrypted OpenOffice spreadsheets.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
# Load an encrypted OpenOffice Spreadsheet
|
230
|
+
ods = Roo::OpenOffice.new("myspreadsheet.ods", password: "password")
|
231
|
+
```
|
232
|
+
|
233
|
+
``Roo::OpenOffice`` can access celltype, comments, font information, formulas and labels.
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
ods.celltype
|
237
|
+
# => :percentage
|
238
|
+
|
239
|
+
ods.comment(1,1, ods.sheets[-1])
|
240
|
+
|
241
|
+
ods.font(1,1).italic?
|
242
|
+
# => false
|
243
|
+
|
244
|
+
ods.formula('A', 2)
|
245
|
+
```
|
246
|
+
|
247
|
+
### CSV Support
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
# Load a CSV file
|
251
|
+
csv = Roo::CSV.new("mycsv.csv")
|
252
|
+
```
|
253
|
+
|
254
|
+
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.
|
255
|
+
|
256
|
+
For instance, you can load tab-delimited files (``.tsv``), and you can use a particular encoding when opening the file.
|
257
|
+
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
# Load a tab-delimited csv
|
261
|
+
csv = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})
|
262
|
+
|
263
|
+
# Load a csv with an explicit encoding
|
264
|
+
csv = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})
|
265
|
+
```
|
266
|
+
|
267
|
+
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).
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
# Load a spreadsheet from a file path
|
271
|
+
# Roo figures out the right parser based on file extension
|
272
|
+
spreadsheet = Roo::Spreadsheet.open(csv_or_xlsx_file)
|
273
|
+
|
274
|
+
# Load a csv and auto-strip the BOM (byte order mark)
|
275
|
+
# csv files saved from MS Excel typically have the BOM marker at the beginning of the file
|
276
|
+
spreadsheet = Roo::Spreadsheet.open("mycsv.csv", { csv_options: { encoding: 'bom|utf-8' } })
|
277
|
+
```
|
278
|
+
|
279
|
+
## Upgrading from Roo 1.13.x
|
280
|
+
If you use ``.xls`` or Google spreadsheets, you will need to install ``roo-xls`` or ``roo-google`` to continue using that functionality.
|
281
|
+
|
282
|
+
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.
|
283
|
+
|
284
|
+
|
285
|
+
|
286
|
+
## Contributing
|
287
|
+
### Features
|
288
|
+
1. Fork it ( https://github.com/roo-rb/roo/fork )
|
289
|
+
2. Install it (`bundle install --with local_development`)
|
290
|
+
3. Create your feature branch (`git checkout -b my-new-feature`)
|
291
|
+
4. Commit your changes (`git commit -am 'My new feature'`)
|
292
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
293
|
+
6. Create a new Pull Request
|
294
|
+
|
295
|
+
### Testing
|
296
|
+
Roo uses Minitest and RSpec. The best of both worlds! Run `bundle exec rake` to
|
297
|
+
run the tests/examples.
|
298
|
+
|
299
|
+
You can run the tests/examples with Rspec like reporters by running
|
300
|
+
`USE_REPORTERS=true bundle exec rake`
|
301
|
+
|
302
|
+
Roo also has a few tests that take a long time (5+ seconds). To run these, use
|
303
|
+
`LONG_RUN=true bundle exec rake`
|
304
|
+
|
305
|
+
### Issues
|
306
|
+
|
307
|
+
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.
|
308
|
+
|
309
|
+
1. [Create a gist](https://gist.github.com) with code that creates the error.
|
310
|
+
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.
|
311
|
+
3. Paste the gist url here.
|
312
|
+
|
313
|
+
|
314
|
+
## License
|
315
|
+
[Roo uses an MIT License](https://github.com/roo-rb/roo/blob/master/LICENSE)
|