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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83f4fd8fec5396120145aefdaa76246f93310b40a6a80d9d799223546e8de9d2
4
- data.tar.gz: 45cce54a288cd0e462f60341d0fc4f8884eea4c640db9f92850a50f35e1f32bf
3
+ metadata.gz: e0507cda2a3420f5c69d57f6ef3ba09410385a39444d1d8944532cd564db9bc8
4
+ data.tar.gz: 93f97d7e6e2577a7fb5d98b474c35b50d3914c503a2adde0f012c82f812cc349
5
5
  SHA512:
6
- metadata.gz: 20d1dfdf88228997f8c999348541dd269ef2bd9510bb5480663a3aa9c1cef9528ffe1287c198355b55347299d0d89ba6e6946e4950bf11b9b398d66f59ecebdc
7
- data.tar.gz: 7e0d52d3569e343780230ba2efff28c69f449502de5dab3931d1caa426e3748c4131d72cabe003b28d4eac70602ed5be1c031470028069dcc8d0c6ddffe11544
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
  [![Gem Version](https://badge.fury.io/rb/excel_utils.svg)](https://rubygems.org/gems/excel_utils)
4
- [![Build Status](https://travis-ci.org/gabynaiman/excel_utils.svg?branch=master)](https://travis-ci.org/gabynaiman/excel_utils)
4
+ [![CI](https://github.com/gabynaiman/excel_utils/actions/workflows/ci.yml/badge.svg)](https://github.com/gabynaiman/excel_utils/actions/workflows/ci.yml)
5
5
  [![Coverage Status](https://coveralls.io/repos/github/gabynaiman/excel_utils/badge.svg?branch=master)](https://coveralls.io/github/gabynaiman/excel_utils?branch=master)
6
6
  [![Code Climate](https://codeclimate.com/github/gabynaiman/excel_utils.svg)](https://codeclimate.com/github/gabynaiman/excel_utils)
7
7
 
@@ -1,3 +1,3 @@
1
1
  module ExcelUtils
2
- VERSION = '1.2.0'
3
- end
2
+ VERSION = '1.3.1'
3
+ end
@@ -1,20 +1,24 @@
1
1
  module ExcelUtils
2
2
  class Writer
3
3
 
4
- TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
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
- if row[column]
44
- if row[column].is_a? String
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
@@ -30,4 +30,4 @@ module ExcelUtils
30
30
  Writer.write filename, data
31
31
  end
32
32
 
33
- end
33
+ end
@@ -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
- let(:tmp_path) { File.expand_path '../../tmp', __FILE__ }
5
+ def assert_wrote(data, expected=data)
6
+ filename = tmp_path "#{SecureRandom.uuid}.xlsx"
6
7
 
7
- let(:filename) { File.join tmp_path, "#{SecureRandom.uuid}.xlsx" }
8
+ ExcelUtils.write filename, data
9
+
10
+ workbook = ExcelUtils.read filename
8
11
 
9
- before do
10
- FileUtils.rm_rf tmp_path
11
- FileUtils.mkpath tmp_path
12
+ expected = {'Sheet1' => expected} if expected.is_a?(Array)
13
+
14
+ workbook.to_h.must_equal expected
12
15
  end
13
16
 
14
- it 'Write' do
15
- 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'
16
- 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'
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
- 'Sheet 1' => [
20
- {'column_a' => 1.5, 'column_b' => 'text 1', 'column_c' => DateTime.parse('2019-05-25T16:30:00')},
21
- {'column_b' => 'text 2', 'column_c' => Date.parse('2019-07-09'), 'column_a' => 2, 'column_d' => '0123'},
90
+ 'strings' => [
91
+ {'column_a' => 'text 1', 'column_b' => 'text 2'},
92
+ {'column_a' => 'text 3', 'column_b' => 'text 4'}
22
93
  ],
23
- 'Sheet 2' => [
24
- {'Column A' => long_url, 'Column B' => long_text}
94
+ 'numbers' => [
95
+ {'x' => 1, 'y' => 2},
96
+ {'x' => 3, 'y' => 4},
97
+ {'x' => 5, 'y' => 6}
25
98
  ],
26
- 'Sheet 3' => []
99
+ 'empty' => [],
27
100
  }
28
101
 
29
- ExcelUtils.write filename, data
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.2.0
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: 2020-12-16 00:00:00.000000000 Z
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