culturecode-roo 2.0.1 → 2.0.2
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.
- data/.gitignore +1 -0
- data/CHANGELOG.md +513 -0
- data/README.md +206 -73
- data/lib/roo.rb +3 -3
- data/lib/roo/base.rb +49 -33
- data/lib/roo/csv.rb +10 -0
- data/lib/roo/excelx.rb +187 -60
- data/lib/roo/excelx/comments.rb +2 -1
- data/lib/roo/excelx/sheet_doc.rb +30 -3
- data/lib/roo/open_office.rb +250 -221
- data/lib/roo/utils.rb +28 -31
- data/lib/roo/version.rb +1 -1
- data/roo.gemspec +10 -12
- data/spec/lib/roo/csv_spec.rb +14 -0
- data/spec/lib/roo/excelx_spec.rb +90 -2
- data/spec/lib/roo/libreoffice_spec.rb +16 -0
- data/spec/lib/roo/openoffice_spec.rb +11 -0
- data/spec/lib/roo/utils_spec.rb +5 -4
- data/test/test_roo.rb +113 -2
- metadata +29 -180
- data/CHANGELOG +0 -438
- data/scripts/txt2html +0 -67
- data/test/files/1900_base.xlsx +0 -0
- data/test/files/1904_base.xlsx +0 -0
- data/test/files/Bibelbund.csv +0 -3741
- data/test/files/Bibelbund.ods +0 -0
- data/test/files/Bibelbund.xlsx +0 -0
- data/test/files/Bibelbund1.ods +0 -0
- data/test/files/Pfand_from_windows_phone.xlsx +0 -0
- data/test/files/advanced_header.ods +0 -0
- data/test/files/bbu.ods +0 -0
- data/test/files/bbu.xlsx +0 -0
- data/test/files/bode-v1.ods.zip +0 -0
- data/test/files/bode-v1.xls.zip +0 -0
- data/test/files/boolean.csv +0 -2
- data/test/files/boolean.ods +0 -0
- data/test/files/boolean.xlsx +0 -0
- data/test/files/borders.ods +0 -0
- data/test/files/borders.xlsx +0 -0
- data/test/files/bug-numbered-sheet-names.xlsx +0 -0
- data/test/files/comments.ods +0 -0
- data/test/files/comments.xlsx +0 -0
- data/test/files/csvtypes.csv +0 -1
- data/test/files/datetime.ods +0 -0
- data/test/files/datetime.xlsx +0 -0
- data/test/files/dreimalvier.ods +0 -0
- data/test/files/emptysheets.ods +0 -0
- data/test/files/emptysheets.xlsx +0 -0
- data/test/files/encrypted-letmein.ods +0 -0
- data/test/files/file_item_error.xlsx +0 -0
- data/test/files/formula.ods +0 -0
- data/test/files/formula.xlsx +0 -0
- data/test/files/formula_string_error.xlsx +0 -0
- data/test/files/html-escape.ods +0 -0
- data/test/files/link.csv +0 -1
- data/test/files/link.xlsx +0 -0
- data/test/files/matrix.ods +0 -0
- data/test/files/named_cells.ods +0 -0
- data/test/files/named_cells.xlsx +0 -0
- data/test/files/no_spreadsheet_file.txt +0 -1
- data/test/files/numbers-export.xlsx +0 -0
- data/test/files/numbers1.csv +0 -18
- data/test/files/numbers1.ods +0 -0
- data/test/files/numbers1.xlsx +0 -0
- data/test/files/numbers1withnull.xlsx +0 -0
- data/test/files/numeric-link.xlsx +0 -0
- data/test/files/only_one_sheet.ods +0 -0
- data/test/files/only_one_sheet.xlsx +0 -0
- data/test/files/paragraph.ods +0 -0
- data/test/files/paragraph.xlsx +0 -0
- data/test/files/ric.ods +0 -0
- data/test/files/sheet1.xml +0 -109
- data/test/files/simple_spreadsheet.ods +0 -0
- data/test/files/simple_spreadsheet.xlsx +0 -0
- data/test/files/simple_spreadsheet_from_italo.ods +0 -0
- data/test/files/so_datetime.csv +0 -8
- data/test/files/style.ods +0 -0
- data/test/files/style.xlsx +0 -0
- data/test/files/time-test.csv +0 -2
- data/test/files/time-test.ods +0 -0
- data/test/files/time-test.xlsx +0 -0
- data/test/files/type_excel.ods +0 -0
- data/test/files/type_excel.xlsx +0 -0
- data/test/files/type_excelx.ods +0 -0
- data/test/files/type_openoffice.xlsx +0 -0
- data/test/files/whitespace.ods +0 -0
- data/test/files/whitespace.xlsx +0 -0
data/README.md
CHANGED
@@ -1,121 +1,254 @@
|
|
1
|
-
# Roo
|
1
|
+
# Roo
|
2
|
+
|
3
|
+
[](https://travis-ci.org/roo-rb/roo) [](https://codeclimate.com/github/roo-rb/roo) [](https://coveralls.io/r/roo-rb/roo) [](https://rubygems.org/gems/roo)
|
4
|
+
|
5
|
+
Roo implements read access for all common spreadsheet types. It can handle:
|
2
6
|
|
3
|
-
Roo implements read access for all spreadsheet types and read/write access for
|
4
|
-
Google spreadsheets. It can handle
|
5
7
|
* Excelx
|
6
8
|
* OpenOffice / LibreOffice
|
7
9
|
* CSV
|
8
10
|
|
9
|
-
## Additional
|
11
|
+
## Additional Libraries
|
12
|
+
|
13
|
+
In addition, the [roo-xls](https://github.com/roo-rb/roo-xls) and [roo-google](https://github.com/roo-rb/roo-google) gems exist to extend Roo to support reading classic Excel formats (i.e. `.xls` and ``Excel2003XML``) and read/write access for Google spreadsheets.
|
14
|
+
|
15
|
+
# #Installation
|
16
|
+
|
17
|
+
Install as a gem
|
10
18
|
|
11
|
-
|
12
|
-
handling capabilities to roo.
|
19
|
+
$ gem install roo
|
13
20
|
|
14
|
-
|
21
|
+
Or add it to your Gemfile
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'roo', '~> 2.0.0'
|
25
|
+
```
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
Opening a spreadsheet
|
15
29
|
|
16
30
|
```ruby
|
17
31
|
require 'roo'
|
18
32
|
|
19
|
-
|
20
|
-
|
21
|
-
s = Roo::Excelx.new("myspreadsheet.xlsx") # loads an Excel Spreadsheet for Excel .xlsx files
|
22
|
-
s = Roo::CSV.new("mycsv.csv") # loads a CSV file
|
33
|
+
xlsx = Roo::Spreadsheet.open('./new_prices.xlsx')
|
34
|
+
xlsx = Roo::Excelx.new("./new_prices.xlsx")
|
23
35
|
|
24
|
-
#
|
25
|
-
|
26
|
-
s = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"}) # TSV
|
27
|
-
s = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1}) # csv with explicit encoding
|
36
|
+
# Use the extension option if the extension is ambiguous.
|
37
|
+
xlsx = Roo::Spreadsheet.open('./rails_temp_upload', extension: :xlsx)
|
28
38
|
|
29
|
-
|
39
|
+
xlsx.info
|
40
|
+
# => Returns basic info about the spreadsheet file
|
41
|
+
```
|
30
42
|
|
31
|
-
|
32
|
-
# a spreadsheet.
|
33
|
-
# you can also write
|
34
|
-
# s.default_sheet = s.sheets[3] or
|
35
|
-
# s.default_sheet = 'Sheet 3'
|
43
|
+
``Roo::Spreadsheet.open`` can accept both paths and ``File`` instances.
|
36
44
|
|
37
|
-
|
38
|
-
s.cell('A',1) # same cell
|
39
|
-
s.cell(1,'A') # same cell
|
40
|
-
s.cell(1,'A',s.sheets[0]) # same cell
|
45
|
+
### Working with sheets
|
41
46
|
|
42
|
-
|
43
|
-
|
47
|
+
```ruby
|
48
|
+
ods.sheets
|
49
|
+
# => ['Info', 'Sheet 2', 'Sheet 3'] # an Array of sheet names in the workbook
|
44
50
|
|
45
|
-
|
51
|
+
ods.sheet('Info').row(1)
|
52
|
+
ods.sheet(0).row(1)
|
46
53
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
# Set the last sheet as the default sheet.
|
55
|
+
ods.default_sheet = ods.sheets.last
|
56
|
+
ods.default_sheet = s.sheets[3]
|
57
|
+
ods.default_sheet = 'Sheet 3'
|
51
58
|
|
52
|
-
#
|
59
|
+
# Iterate through each sheet
|
60
|
+
ods.each_with_pagename do |name, sheet|
|
61
|
+
p sheet.row(1)
|
62
|
+
end
|
63
|
+
```
|
53
64
|
|
54
|
-
|
55
|
-
s.font(1,1).italic?
|
56
|
-
s.font(1,1).underline?
|
65
|
+
### Accessing rows and columns
|
57
66
|
|
67
|
+
Roo uses Excel's numbering for rows, columns and cells, so `1` is the first index, not `0` as it is in an ``Array``
|
58
68
|
|
59
|
-
|
60
|
-
|
69
|
+
```ruby
|
70
|
+
sheet.row(1)
|
71
|
+
# returns the first row of the spreadsheet.
|
61
72
|
|
62
|
-
|
73
|
+
sheet.column(1)
|
74
|
+
# returns the first column of the spreadsheet.
|
75
|
+
```
|
63
76
|
|
64
|
-
|
77
|
+
Almost all methods have an optional argument `sheet`. If this parameter is omitted, the default_sheet will be used.
|
65
78
|
|
66
|
-
|
67
|
-
|
79
|
+
```ruby
|
80
|
+
sheet.first_row(sheet.sheets[0])
|
81
|
+
# => 1 # the number of the first row
|
82
|
+
sheet.last_row
|
83
|
+
# => 42 # the number of the last row
|
84
|
+
sheet.first_column
|
85
|
+
# => 1 # the number of the first column
|
86
|
+
sheet.last_column
|
87
|
+
# => 10 # the number of the last column
|
88
|
+
```
|
68
89
|
|
69
|
-
|
90
|
+
#### Accessing cells
|
70
91
|
|
71
|
-
|
92
|
+
You can access the top-left cell in the following ways
|
72
93
|
|
73
|
-
|
74
|
-
|
94
|
+
```ruby
|
95
|
+
s.cell(1,1)
|
96
|
+
s.cell('A',1)
|
97
|
+
s.cell(1,'A')
|
98
|
+
s.a1
|
75
99
|
|
76
|
-
#
|
77
|
-
|
100
|
+
# Access the second sheet's top-left cell.
|
101
|
+
s.cell(1,'A',s.sheets[1])
|
102
|
+
```
|
78
103
|
|
79
|
-
|
104
|
+
#### Querying a spreadsheet
|
105
|
+
Use ``each`` with a ``block`` to iterate over each row.
|
80
106
|
|
81
|
-
|
107
|
+
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.
|
82
108
|
|
83
|
-
|
84
|
-
|
109
|
+
```ruby
|
110
|
+
sheet.each(id: 'ID', name: 'FULL_NAME') do |hash|
|
111
|
+
puts hash.inspect
|
112
|
+
# => { id: 1, name: 'John Smith' }
|
85
113
|
end
|
114
|
+
```
|
86
115
|
|
87
|
-
|
116
|
+
Use ``sheet.parse`` to return an array of rows. Column names can be a ``String`` or a ``Regexp``.
|
88
117
|
|
89
|
-
|
90
|
-
|
118
|
+
```ruby
|
119
|
+
sheet.parse(:id => /UPC|SKU/,:qty => /ATS*\sATP\s*QTY\z/)
|
120
|
+
# => [{:upc => 727880013358, :qty => 12}, ...]
|
121
|
+
```
|
91
122
|
|
92
|
-
|
123
|
+
Use the ``:header_search`` option to locate the header row and assign the header names.
|
93
124
|
|
94
|
-
|
125
|
+
```ruby
|
126
|
+
sheet.parse(header_search: [/UPC*SKU/,/ATS*\sATP\s*QTY\z/])
|
127
|
+
```
|
95
128
|
|
96
|
-
|
129
|
+
Use the ``:clean`` option to strip out control characters and surrounding white space.
|
97
130
|
|
98
|
-
|
99
|
-
|
131
|
+
```ruby
|
132
|
+
sheet.parse(:clean => true)
|
133
|
+
```
|
100
134
|
|
101
|
-
|
102
|
-
|
103
|
-
|
135
|
+
### Exporting spreadsheets
|
136
|
+
Roo has the ability to export sheets using the following formats. It
|
137
|
+
will only export the ``default_sheet``.
|
104
138
|
|
105
|
-
|
139
|
+
```ruby
|
140
|
+
sheet.to_csv
|
141
|
+
sheet.to_matrix
|
142
|
+
sheet.to_xml
|
143
|
+
sheet.to_yaml
|
144
|
+
```
|
145
|
+
|
146
|
+
### Excel (xlsx) Support
|
106
147
|
|
107
|
-
|
148
|
+
Stream rows from an Excelx spreadsheet.
|
108
149
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
#
|
150
|
+
```ruby
|
151
|
+
xlsx = Roo::Excelx.new("./test_data/test_small.xlsx")
|
152
|
+
xlsx.each_row_streaming do |row|
|
153
|
+
puts row.inspect # Array of Excelx::Cell objects
|
154
|
+
end
|
155
|
+
```
|
113
156
|
|
114
|
-
|
157
|
+
Iterate over each row
|
115
158
|
|
116
|
-
|
117
|
-
|
118
|
-
|
159
|
+
```ruby
|
160
|
+
xlsx.each_row do |row|
|
161
|
+
...
|
119
162
|
end
|
163
|
+
```
|
164
|
+
|
165
|
+
``Roo::Excelx`` also provides these helpful methods.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
xlsx.excelx_type(3, 'C')
|
169
|
+
# => :numeric_or_formula
|
170
|
+
|
171
|
+
xlsx.cell(3, 'C')
|
172
|
+
# => 600000383.0
|
173
|
+
|
174
|
+
xlsx.excelx_value(row,col)
|
175
|
+
# => '0600000383'
|
176
|
+
```
|
177
|
+
|
178
|
+
``Roo::Excelx`` can access celltype, comments, font information, formulas, hyperlinks and labels.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
xlsx.comment(1,1, ods.sheets[-1])
|
182
|
+
xlsx.font(1,1).bold?
|
183
|
+
xlsx.formula('A', 2)
|
184
|
+
```
|
185
|
+
|
186
|
+
### OpenOffice / LibreOffice Support
|
187
|
+
|
188
|
+
Roo::OpenOffice supports for encrypted OpenOffice spreadsheets.
|
120
189
|
|
190
|
+
```ruby
|
191
|
+
# Load an encrypted OpenOffice Spreadsheet
|
192
|
+
ods = Roo::OpenOffice.new("myspreadsheet.ods", :password => "password")
|
193
|
+
```
|
194
|
+
|
195
|
+
``Roo::OpenOffice`` can access celltype, comments, font information, formulas and labels.
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
ods.celltype
|
199
|
+
# => :percentage
|
200
|
+
|
201
|
+
ods.comment(1,1, ods.sheets[-1])
|
202
|
+
|
203
|
+
ods.font(1,1).italic?
|
204
|
+
# => false
|
205
|
+
|
206
|
+
ods.formula('A', 2)
|
121
207
|
```
|
208
|
+
|
209
|
+
### CSV Support
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# Load a CSV file
|
213
|
+
s = Roo::CSV.new("mycsv.csv")
|
214
|
+
```
|
215
|
+
|
216
|
+
Because Roo uses the [standard CSV library](), and you can use options available to that library to parse csv files. You can pass options using the ``csv_options`` key.
|
217
|
+
|
218
|
+
For instance, you can load tab-delimited files (``.tsv``), and you can use a particular encoding when opening the file.
|
219
|
+
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
# Load a tab-delimited csv
|
223
|
+
s = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})
|
224
|
+
|
225
|
+
# Load a csv with an explicit encoding
|
226
|
+
s = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})
|
227
|
+
```
|
228
|
+
|
229
|
+
## Upgrading from Roo 1.13.x
|
230
|
+
If you use ``.xls`` or Google spreadsheets, you will need to install ``roo-xls`` or ``roo-google`` to continue using that functionality.
|
231
|
+
|
232
|
+
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.
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
## Contributing
|
237
|
+
### Features
|
238
|
+
1. Fork it ( https://github.com/[my-github-username]/roo/fork )
|
239
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
240
|
+
3. Commit your changes (`git commit -am 'My new feature'`)
|
241
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
242
|
+
5. Create a new Pull Request
|
243
|
+
|
244
|
+
### Issues
|
245
|
+
|
246
|
+
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.
|
247
|
+
|
248
|
+
1. [Create a gist](https://gist.github.com) with code that creates the error.
|
249
|
+
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.
|
250
|
+
3. Paste the gist url here.
|
251
|
+
|
252
|
+
|
253
|
+
## License
|
254
|
+
[Roo uses an MIT License](https://github.com/roo-rb/roo/blob/master/LICENSE)
|
data/lib/roo.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
autoload :Base, 'roo/base'
|
1
|
+
require 'roo/spreadsheet'
|
2
|
+
require 'roo/base'
|
4
3
|
|
4
|
+
module Roo
|
5
5
|
autoload :OpenOffice, 'roo/open_office'
|
6
6
|
autoload :LibreOffice, 'roo/libre_office'
|
7
7
|
autoload :Excelx, 'roo/excelx'
|
data/lib/roo/base.rb
CHANGED
@@ -9,7 +9,7 @@ require 'roo/utils'
|
|
9
9
|
class Roo::Base
|
10
10
|
include Enumerable
|
11
11
|
|
12
|
-
TEMP_PREFIX = 'roo_'
|
12
|
+
TEMP_PREFIX = 'roo_'.freeze
|
13
13
|
MAX_ROW_COL = 999_999.freeze
|
14
14
|
MIN_ROW_COL = 0.freeze
|
15
15
|
|
@@ -32,6 +32,15 @@ class Roo::Base
|
|
32
32
|
@last_column = {}
|
33
33
|
|
34
34
|
@header_line = 1
|
35
|
+
rescue => e # clean up any temp files, but only if an error was raised
|
36
|
+
close
|
37
|
+
raise e
|
38
|
+
end
|
39
|
+
|
40
|
+
def close
|
41
|
+
return nil unless @tmpdirs
|
42
|
+
@tmpdirs.each { |dir| ::FileUtils.remove_entry(dir) }
|
43
|
+
nil
|
35
44
|
end
|
36
45
|
|
37
46
|
def default_sheet
|
@@ -160,9 +169,8 @@ class Roo::Base
|
|
160
169
|
end)
|
161
170
|
end
|
162
171
|
|
163
|
-
# call to_s method defined on subclasses
|
164
172
|
def inspect
|
165
|
-
to_s
|
173
|
+
"<##{ self.class }:#{ self.object_id.to_s(8) } #{ self.instance_variables.join(' ') }>"
|
166
174
|
end
|
167
175
|
|
168
176
|
# find a row either by row number or a condition
|
@@ -321,26 +329,6 @@ class Roo::Base
|
|
321
329
|
end
|
322
330
|
end
|
323
331
|
|
324
|
-
|
325
|
-
def clean_sheet_if_need(options)
|
326
|
-
return unless options[:clean]
|
327
|
-
options.delete(:clean)
|
328
|
-
@cleaned ||= {}
|
329
|
-
clean_sheet(default_sheet) unless @cleaned[default_sheet]
|
330
|
-
end
|
331
|
-
|
332
|
-
def search_or_set_header(options)
|
333
|
-
if options[:header_search]
|
334
|
-
@headers = nil
|
335
|
-
@header_line = row_with(options[:header_search])
|
336
|
-
elsif [:first_row, true].include?(options[:headers])
|
337
|
-
@headers = []
|
338
|
-
row(first_row).each_with_index { |x, i| @headers << [x, i + 1] }
|
339
|
-
else
|
340
|
-
set_headers(options)
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
332
|
# by passing in headers as options, this method returns
|
345
333
|
# specific columns from your header assignment
|
346
334
|
# for example:
|
@@ -361,11 +349,13 @@ class Roo::Base
|
|
361
349
|
# * is the wildcard character
|
362
350
|
|
363
351
|
# you can also pass in a :clean => true option to strip the sheet of
|
364
|
-
#
|
352
|
+
# control characters and white spaces around columns
|
365
353
|
|
366
354
|
def each(options = {})
|
367
|
-
if
|
368
|
-
|
355
|
+
if first_row.nil?
|
356
|
+
# Sheet is empty
|
357
|
+
elsif options.empty?
|
358
|
+
first_row.upto(last_row) do |line|
|
369
359
|
yield row(line)
|
370
360
|
end
|
371
361
|
else
|
@@ -450,9 +440,37 @@ class Roo::Base
|
|
450
440
|
"#{arr[0]},#{arr[1]}"
|
451
441
|
end
|
452
442
|
|
443
|
+
def is_stream?(filename_or_stream)
|
444
|
+
filename_or_stream.respond_to?(:seek)
|
445
|
+
end
|
446
|
+
|
453
447
|
private
|
454
448
|
|
449
|
+
def track_tmpdir!(tmpdir)
|
450
|
+
(@tmpdirs ||= []) << tmpdir
|
451
|
+
end
|
452
|
+
|
453
|
+
def clean_sheet_if_need(options)
|
454
|
+
return unless options[:clean]
|
455
|
+
options.delete(:clean)
|
456
|
+
@cleaned ||= {}
|
457
|
+
clean_sheet(default_sheet) unless @cleaned[default_sheet]
|
458
|
+
end
|
459
|
+
|
460
|
+
def search_or_set_header(options)
|
461
|
+
if options[:header_search]
|
462
|
+
@headers = nil
|
463
|
+
@header_line = row_with(options[:header_search])
|
464
|
+
elsif [:first_row, true].include?(options[:headers])
|
465
|
+
@headers = []
|
466
|
+
row(first_row).each_with_index { |x, i| @headers << [x, i + 1] }
|
467
|
+
else
|
468
|
+
set_headers(options)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
455
472
|
def local_filename(filename, tmpdir, packed)
|
473
|
+
return if is_stream?(filename)
|
456
474
|
filename = download_uri(filename, tmpdir) if uri?(filename)
|
457
475
|
filename = unzip(filename, tmpdir) if packed == :zip
|
458
476
|
unless File.file?(filename)
|
@@ -518,21 +536,21 @@ class Roo::Base
|
|
518
536
|
else
|
519
537
|
TEMP_PREFIX
|
520
538
|
end
|
521
|
-
Dir.mktmpdir(prefix, root || ENV['ROO_TMP'], &block)
|
539
|
+
::Dir.mktmpdir(prefix, root || ENV['ROO_TMP'], &block).tap do |result|
|
540
|
+
block_given? || track_tmpdir!(result)
|
541
|
+
end
|
522
542
|
end
|
523
543
|
|
524
544
|
def clean_sheet(sheet)
|
525
545
|
read_cells(sheet)
|
526
546
|
@cell[sheet].each_pair do |coord, value|
|
527
|
-
if value.is_a?(::String)
|
528
|
-
@cell[sheet][coord] = sanitize_value(value)
|
529
|
-
end
|
547
|
+
@cell[sheet][coord] = sanitize_value(value) if value.is_a?(::String)
|
530
548
|
end
|
531
549
|
@cleaned[sheet] = true
|
532
550
|
end
|
533
551
|
|
534
552
|
def sanitize_value(v)
|
535
|
-
v.
|
553
|
+
v.gsub(/[[:cntrl:]]|^[\p{Space}]+|[\p{Space}]+$/, '')
|
536
554
|
end
|
537
555
|
|
538
556
|
def set_headers(hash = {})
|
@@ -703,8 +721,6 @@ class Roo::Base
|
|
703
721
|
end
|
704
722
|
end
|
705
723
|
|
706
|
-
private
|
707
|
-
|
708
724
|
# converts an integer value to a time string like '02:05:06'
|
709
725
|
def integer_to_timestring(content)
|
710
726
|
h = (content / 3600.0).floor
|