culturecode-roo 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://img.shields.io/travis/roo-rb/roo.svg?style=flat-square)](https://travis-ci.org/roo-rb/roo) [![Code Climate](https://img.shields.io/codeclimate/github/roo-rb/roo.svg?style=flat-square)](https://codeclimate.com/github/roo-rb/roo) [![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:
|
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
|