excel_utils 1.2.0 → 1.3.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 +4 -4
- data/.github/workflows/ci.yml +26 -0
- data/README.md +1 -1
- data/lib/excel_utils/version.rb +2 -2
- data/lib/excel_utils/writer.rb +15 -8
- data/lib/excel_utils.rb +1 -1
- data/spec/minitest_helper.rb +13 -0
- data/spec/write_spec.rb +89 -27
- metadata +3 -3
- data/.travis.yml +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0507cda2a3420f5c69d57f6ef3ba09410385a39444d1d8944532cd564db9bc8
|
4
|
+
data.tar.gz: 93f97d7e6e2577a7fb5d98b474c35b50d3914c503a2adde0f012c82f812cc349
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a335fa0c35aae34f171ea9fe533618e4145f3316883bb7bf27156a78456e342b0dfc99b8706d2dc8eca9de8c1d6707a9d1808ce3e9ad0788c8065bb60dd0b8d7
|
7
|
+
data.tar.gz: b698d64e528206b7e7319c343042f2b0dea677256412ae257f3d6e24c83032cf8dc0ce8128757e6ac96a57c305b0752a1cf53b7cceaf7468732128f57272ba1a
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ '**' ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ '**' ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
name: Tests
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby-version: ['2.3', '2.4', '2.5', '2.6', '2.7', 'jruby-9.2.9.0']
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- name: Set up Ruby
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# ExcelUtils
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/excel_utils)
|
4
|
-
[](https://github.com/gabynaiman/excel_utils/actions/workflows/ci.yml)
|
5
5
|
[](https://coveralls.io/github/gabynaiman/excel_utils?branch=master)
|
6
6
|
[](https://codeclimate.com/github/gabynaiman/excel_utils)
|
7
7
|
|
data/lib/excel_utils/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module ExcelUtils
|
2
|
-
VERSION = '1.
|
3
|
-
end
|
2
|
+
VERSION = '1.3.1'
|
3
|
+
end
|
data/lib/excel_utils/writer.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
module ExcelUtils
|
2
2
|
class Writer
|
3
3
|
|
4
|
-
|
4
|
+
DEFAULT_SHEET_NAME = 'Sheet1'.freeze
|
5
|
+
|
6
|
+
TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'.freeze
|
5
7
|
|
6
8
|
EXCEL_FORMATS = {
|
7
9
|
date: 'yyyy-mm-dd',
|
8
10
|
date_time: 'yyyy-mm-dd hh:mm:ss'
|
9
|
-
}
|
11
|
+
}.freeze
|
10
12
|
|
11
13
|
class << self
|
12
|
-
|
14
|
+
|
13
15
|
def write(filename, data)
|
14
16
|
workbook = WriteXLSX.new filename, strings_to_urls: false
|
15
17
|
|
16
18
|
formats = add_formats workbook
|
17
19
|
|
20
|
+
data = {DEFAULT_SHEET_NAME => data} if data.is_a? Array
|
21
|
+
|
18
22
|
data.each do |sheet_name, sheet_data|
|
19
23
|
add_sheet workbook, sheet_name, sheet_data, formats
|
20
24
|
end
|
@@ -40,15 +44,18 @@ module ExcelUtils
|
|
40
44
|
sheet_data.each_with_index do |row, r|
|
41
45
|
row_index = r + 1
|
42
46
|
header.each_with_index do |column, col_index|
|
43
|
-
|
44
|
-
if row[column].is_a?
|
47
|
+
unless row[column].nil?
|
48
|
+
if row[column].is_a?(String) || row[column].is_a?(Array)
|
45
49
|
sheet.write_string row_index, col_index, row[column]
|
46
|
-
|
50
|
+
|
51
|
+
elsif [true, false].include?(row[column])
|
52
|
+
sheet.write_string row_index, col_index, row[column].to_s
|
53
|
+
|
47
54
|
elsif row[column].respond_to? :to_time
|
48
55
|
time = row[column].to_time
|
49
56
|
type = date?(time) ? :date : :date_time
|
50
57
|
sheet.write_date_time row_index, col_index, time.to_time.strftime(TIME_FORMAT), formats[type]
|
51
|
-
|
58
|
+
|
52
59
|
else
|
53
60
|
sheet.write row_index, col_index, row[column]
|
54
61
|
end
|
@@ -65,4 +72,4 @@ module ExcelUtils
|
|
65
72
|
end
|
66
73
|
|
67
74
|
end
|
68
|
-
end
|
75
|
+
end
|
data/lib/excel_utils.rb
CHANGED
data/spec/minitest_helper.rb
CHANGED
@@ -7,10 +7,23 @@ require 'excel_utils'
|
|
7
7
|
|
8
8
|
RESOURCES_PATH = File.expand_path '../resources', __FILE__
|
9
9
|
|
10
|
+
TMP_PATH = File.expand_path '../../tmp', __FILE__
|
11
|
+
FileUtils.mkpath TMP_PATH unless Dir.exists? TMP_PATH
|
12
|
+
|
10
13
|
class Minitest::Test
|
11
14
|
|
12
15
|
def resource_path(relative_path)
|
13
16
|
File.join RESOURCES_PATH, relative_path
|
14
17
|
end
|
15
18
|
|
19
|
+
def tmp_path(relative_path)
|
20
|
+
File.join TMP_PATH, relative_path
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
Minitest.after_run do
|
26
|
+
Dir.glob(File.join(TMP_PATH, '*')).each do |filename|
|
27
|
+
FileUtils.remove_file filename
|
28
|
+
end
|
16
29
|
end
|
data/spec/write_spec.rb
CHANGED
@@ -2,42 +2,104 @@ require 'minitest_helper'
|
|
2
2
|
|
3
3
|
describe ExcelUtils do
|
4
4
|
|
5
|
-
|
5
|
+
def assert_wrote(data, expected=data)
|
6
|
+
filename = tmp_path "#{SecureRandom.uuid}.xlsx"
|
6
7
|
|
7
|
-
|
8
|
+
ExcelUtils.write filename, data
|
9
|
+
|
10
|
+
workbook = ExcelUtils.read filename
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
expected = {'Sheet1' => expected} if expected.is_a?(Array)
|
13
|
+
|
14
|
+
workbook.to_h.must_equal expected
|
12
15
|
end
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
describe 'Single sheet' do
|
18
|
+
|
19
|
+
it 'Basic data' do
|
20
|
+
rows = [
|
21
|
+
{'column_a' => '1', 'column_b' => 'text 1'},
|
22
|
+
{'column_a' => '2.5', 'column_b' => nil, 'column_c' => 'text 2'},
|
23
|
+
]
|
24
|
+
|
25
|
+
assert_wrote rows, rows.map { |r| {'column_c' => nil}.merge r }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'Symbolized column names' do
|
29
|
+
rows = [
|
30
|
+
{column_a: 'text 1'},
|
31
|
+
{column_a: 'text 2'},
|
32
|
+
]
|
33
|
+
|
34
|
+
assert_wrote rows, rows.map { |r| {'column_a' => r[:column_a]} }
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'Long values' do
|
38
|
+
long_url = 'https://external.xx.fbcdn.net/safe_image.php?d=AQCY1f77h1RtuFfa&w=720&h=720&url=https%3A%2F%2Fwww.mercadolibre.com%2Fjms%2Fmla%2Flgz%2Fbackground%2Fsession%2Farmor.c27f26204365785956aaf9b30c289d0d4b0a201b4b01dfc3d83162b82608973be9a82ac85c2097c3f23b522681adca38b143f5e1a10fda251b430051a1592bf19caba204c07179120c48d47a1ceb5a45.774f4b8036d4b909101bab92870d262a%3Fbackground%3Darmor.c27f26204365785956aaf9b30c289d0d4b0a201b4b01dfc3d83162b82608973be9a82ac85c2097c3f23b522681adca38b143f5e1a10fda251b430051a1592bf19caba204c07179120c48d47a1ceb5a45.774f4b8036d4b909101bab92870d262a%26message%3DeyJqc190eXBlIjoianNfY29va2llIiwidmFsdWUiOiJ4In0&cfs=1&_nc_hash=AQB9Sf1HyWCwCVhF'
|
39
|
+
long_text = 'AQCY1f77h1RtuFfa&w=720&h=720&url=https%3A%2F%2Fwww.mercadolibre.com%2Fjms%2Fmla%2Flgz%2Fbackground%2Fsession%2Farmor.c27f26204365785956aaf9b30c289d0d4b0a201b4b01dfc3d83162b82608973be9a82ac85c2097c3f23b522681adca38b143f5e1a10fda251b430051a1592bf19caba204c07179120c48d47a1ceb5a45.774f4b8036d4b909101bab92870d262a%3Fbackground%3Darmor.c27f26204365785956aaf9b30c289d0d4b0a201b4b01dfc3d83162b82608973be9a82ac85c2097c3f23b522681adca38b143f5e1a10fda251b430051a1592bf19caba204c07179120c48d47a1ceb5a45.774f4b8036d4b909101bab92870d262a%26message%3DeyJqc190eXBlIjoianNfY29va2llIiwidmFsdWUiOiJ4In0&cfs=1&_nc_hash=AQB9Sf1HyWCwCVhF'
|
40
|
+
|
41
|
+
rows = [
|
42
|
+
{'column_a' => long_url},
|
43
|
+
{'column_a' => long_text},
|
44
|
+
]
|
45
|
+
|
46
|
+
assert_wrote rows
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'Numbers' do
|
50
|
+
rows = [
|
51
|
+
{'column_a' => 1},
|
52
|
+
{'column_a' => 2.5},
|
53
|
+
]
|
54
|
+
|
55
|
+
assert_wrote rows
|
56
|
+
end
|
17
57
|
|
58
|
+
it 'Date and DateTime' do
|
59
|
+
rows = [
|
60
|
+
{'column_a' => DateTime.parse('2019-05-25T16:30:00')},
|
61
|
+
{'column_a' => Date.parse('2019-07-09')},
|
62
|
+
]
|
63
|
+
|
64
|
+
assert_wrote rows
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'Objects' do
|
68
|
+
rows = [
|
69
|
+
{'column_a' => ['text', 1]},
|
70
|
+
{'column_a' => {key: 123}},
|
71
|
+
{'column_a' => Set.new(['text', 1])}
|
72
|
+
]
|
73
|
+
|
74
|
+
assert_wrote rows, rows.map { |r| {'column_a' => r['column_a'].to_s} }
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'Booleans' do
|
78
|
+
rows = [
|
79
|
+
{'column_a' => true, 'column_b' => 'text 1'},
|
80
|
+
{'column_a' => false, 'column_b' => 'text 2'}
|
81
|
+
]
|
82
|
+
|
83
|
+
assert_wrote rows, [{'column_a' => 'true', 'column_b' => 'text 1'}, {'column_a' => 'false', 'column_b' => 'text 2'}]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'Multiple sheets' do
|
18
89
|
data = {
|
19
|
-
'
|
20
|
-
{'column_a' =>
|
21
|
-
{'
|
90
|
+
'strings' => [
|
91
|
+
{'column_a' => 'text 1', 'column_b' => 'text 2'},
|
92
|
+
{'column_a' => 'text 3', 'column_b' => 'text 4'}
|
22
93
|
],
|
23
|
-
'
|
24
|
-
{'
|
94
|
+
'numbers' => [
|
95
|
+
{'x' => 1, 'y' => 2},
|
96
|
+
{'x' => 3, 'y' => 4},
|
97
|
+
{'x' => 5, 'y' => 6}
|
25
98
|
],
|
26
|
-
'
|
99
|
+
'empty' => [],
|
27
100
|
}
|
28
101
|
|
29
|
-
|
30
|
-
|
31
|
-
workbook = ExcelUtils.read filename
|
32
|
-
|
33
|
-
workbook.sheets.each do |sheet|
|
34
|
-
sheet.each_with_index do |row, i|
|
35
|
-
columns = row.keys | data[sheet.name][i].keys
|
36
|
-
columns.each do |column|
|
37
|
-
row[column].must_equal data[sheet.name][i][column]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
102
|
+
assert_wrote data
|
41
103
|
end
|
42
104
|
|
43
|
-
end
|
105
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excel_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inflecto
|
@@ -192,10 +192,10 @@ extensions: []
|
|
192
192
|
extra_rdoc_files: []
|
193
193
|
files:
|
194
194
|
- ".coveralls.yml"
|
195
|
+
- ".github/workflows/ci.yml"
|
195
196
|
- ".gitignore"
|
196
197
|
- ".ruby-gemset"
|
197
198
|
- ".ruby-version"
|
198
|
-
- ".travis.yml"
|
199
199
|
- Gemfile
|
200
200
|
- LICENSE.txt
|
201
201
|
- README.md
|
data/.travis.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 2.0
|
5
|
-
- 2.1
|
6
|
-
- 2.2
|
7
|
-
- 2.3
|
8
|
-
- 2.4
|
9
|
-
- 2.5
|
10
|
-
- 2.6
|
11
|
-
- 2.7
|
12
|
-
- jruby-9.1.16.0
|
13
|
-
- jruby-9.2.9.0
|
14
|
-
- ruby-head
|
15
|
-
- jruby-head
|
16
|
-
|
17
|
-
matrix:
|
18
|
-
fast_finish: true
|
19
|
-
allow_failures:
|
20
|
-
- rvm: ruby-head
|
21
|
-
- rvm: jruby-head
|