excel-esv 3.1.0 → 3.3.0

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: bb907e9f6b481001f01561df298d6052f3efb37f4ae3f57191b2bb807699203e
4
- data.tar.gz: ea18830fa510acd5fe6d204714fbfc75114c0e167d08bd3fa969b61406893bf2
3
+ metadata.gz: d46877da5cc1642f15c16ed055a62a15656ff495eb5d3854a606134668f988df
4
+ data.tar.gz: 46c7e0920178b82d593a6a1d1dfef31d929a914ef22ed4ea23efd5a675526eba
5
5
  SHA512:
6
- metadata.gz: 745103dd2cbf9eda28e2d2947f4785b6a3f95372be9c3044265029cb4ac2e01c16d943923cb6e3f677387b2dfc6b5cbaba6bfddab001c0e775c97a92e967870b
7
- data.tar.gz: e22bb76f26d291021847496fd679f6f982c4ecd14f0e9978674f08607f90d848b9539d5931d0a1ae038af8c22a8254814e69198af1802f755960e2fc0394ece4
6
+ metadata.gz: 7dcd7941790d2a1082105f03eb7813b62a91dce96a5624fb124b0819431f7c6261e8e848a78fffd0ac03759bd3bbc8697d32fd05bba9463842fff2e07c445a27
7
+ data.tar.gz: a279ac0df840b36fbb719c3e210696bf6c261e80e80970d9d2accdfa0fea4b5e592542da1cbbb86dbf4d1531266c18294c1726f99c16da872b575edf41c5f399
@@ -22,7 +22,7 @@ jobs:
22
22
  ruby-version: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
23
23
 
24
24
  steps:
25
- - uses: actions/checkout@v5
25
+ - uses: actions/checkout@v7
26
26
  - name: Set up Ruby ${{ matrix.ruby-version }}
27
27
  uses: ruby/setup-ruby@v1
28
28
  with:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.3.0 (Aug 28, 2026)
4
+
5
+ * Fix Numbers.app misrendering by formatting date cells as ISO 8601 ("2026-08-28") and time cells as ISO-like ("2026-08-28 13:45").
6
+
7
+ ## 3.2.0 (Nov 12, 2025)
8
+
9
+ * Support `worksheet_index:` in `.parse_file`, too.
10
+
3
11
  ## 3.1.0 (Nov 12, 2025)
4
12
 
5
13
  * Support specifying worksheet index when there are multiple: `ESV.parse(data, worksheet_index: 0)`.
data/README.md CHANGED
@@ -80,9 +80,7 @@ output = ESV.parse_file("/tmp/test.xls")
80
80
  # => [ [ "Name", "Dogs", … ], … ]
81
81
  ```
82
82
 
83
- This assumes a file with a single worksheet and will raise otherwise.
84
-
85
- Also supports `header_converters:`.
83
+ This is a thin wrapper around `ESV.parse` and takes the same arguments.
86
84
 
87
85
  ### Generate in Ruby on Rails
88
86
 
data/excel-esv.gemspec CHANGED
@@ -12,10 +12,11 @@ Gem::Specification.new do |spec|
12
12
  spec.homepage = "https://github.com/barsoom/excel-esv"
13
13
  spec.license = "MIT"
14
14
  spec.metadata = { "rubygems_mfa_required" => "true" }
15
+ spec.required_ruby_version = ">= 3.1.0"
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.require_paths = [ "lib" ]
18
19
 
19
- spec.add_runtime_dependency "spreadsheet"
20
20
  spec.add_runtime_dependency "logger"
21
+ spec.add_runtime_dependency "spreadsheet"
21
22
  end
data/lib/esv/generator.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  class ESV::Generator
2
+ # The spreadsheet gem otherwise formats date and time cells as "DD.MM.YYYY".
3
+ # Excel reads that case-insensitively, but Numbers.app only recognises the "MM", so it renders e.g. "DD.06.YYYY". Lowercase "dd" and "yyyy" work in both.
4
+ # "hh" is confirmed to render as 24-hour time in Numbers.app.
5
+ DATE_FORMAT = "yyyy-MM-dd"
6
+ DATE_TIME_FORMAT = "yyyy-MM-dd hh:mm:ss"
7
+
2
8
  def initialize
3
9
  @data_rows = []
4
10
  end
@@ -14,6 +20,7 @@ class ESV::Generator
14
20
  @data_rows.each_with_index do |data_row, index|
15
21
  row = sheet.row(index)
16
22
  row.push(*data_row)
23
+ format_dates_and_times(row, data_row)
17
24
  end
18
25
 
19
26
  content = ""
@@ -21,4 +28,23 @@ class ESV::Generator
21
28
  book.write(fake_file)
22
29
  content
23
30
  end
31
+
32
+ private
33
+
34
+ def format_dates_and_times(row, data_row)
35
+ data_row.each_with_index do |value, index|
36
+ format =
37
+ case value
38
+ # DateTime is a Date, so it has to be matched first.
39
+ # Rails' `ActiveSupport::TimeWithZone` is matched by `when Time` since ActiveSupport patches `Time.===`.
40
+ when DateTime, Time then date_time_format
41
+ when Date then date_format
42
+ end
43
+
44
+ row.set_format(index, format) if format
45
+ end
46
+ end
47
+
48
+ def date_format = @date_format ||= Spreadsheet::Format.new(number_format: DATE_FORMAT)
49
+ def date_time_format = @date_time_format ||= Spreadsheet::Format.new(number_format: DATE_TIME_FORMAT)
24
50
  end
@@ -10,7 +10,7 @@ module ESV
10
10
  data,
11
11
  type: ESV::CONTENT_TYPE,
12
12
  disposition: "attachment",
13
- filename: filename,
13
+ filename:,
14
14
  )
15
15
  end
16
16
  end
data/lib/esv/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ESV
2
- VERSION = "3.1.0"
2
+ VERSION = "3.3.0"
3
3
  end
data/lib/esv.rb CHANGED
@@ -87,7 +87,7 @@ module ESV
87
87
  }
88
88
  end
89
89
 
90
- def self.parse_file(path, header_converters: nil)
91
- parse(File.read(path), header_converters: header_converters)
90
+ def self.parse_file(path, header_converters: nil, worksheet_index: nil)
91
+ parse(File.read(path), header_converters:, worksheet_index:)
92
92
  end
93
93
  end
data/spec/esv_spec.rb CHANGED
@@ -15,6 +15,44 @@ RSpec.describe ESV do
15
15
  [ 1, 2 ],
16
16
  ]
17
17
  end
18
+
19
+ it "keeps date and time cells readable as such, rather than as text" do
20
+ data = ESV.generate do |esv|
21
+ esv << [ Date.new(2026, 6, 24), DateTime.new(2026, 6, 24, 13, 30, 5) ]
22
+ end
23
+
24
+ expect(ESV.parse(data)).to eq([ [ Date.new(2026, 6, 24), DateTime.new(2026, 6, 24, 13, 30, 5) ] ])
25
+ end
26
+
27
+ it "reads a Time back as a DateTime" do
28
+ data = ESV.generate { |esv| esv << [ Time.utc(2026, 6, 24, 13, 30, 5) ] }
29
+
30
+ expect(ESV.parse(data)).to eq([ [ DateTime.new(2026, 6, 24, 13, 30, 5) ] ])
31
+ end
32
+ end
33
+
34
+ describe ".generate" do
35
+ it "formats date and time cells so that both Excel and Numbers.app render them" do
36
+ data = ESV.generate do |esv|
37
+ esv << [ Date.new(2026, 6, 24), Time.utc(2026, 6, 24, 13, 30), DateTime.new(2026, 6, 24, 13, 30), "Dogs", 1 ]
38
+ end
39
+
40
+ expect(number_formats_in(data)).to eq([
41
+ "yyyy-MM-dd",
42
+ "yyyy-MM-dd hh:mm:ss",
43
+ "yyyy-MM-dd hh:mm:ss",
44
+ "GENERAL",
45
+ "GENERAL",
46
+ ])
47
+ end
48
+
49
+ private
50
+
51
+ def number_formats_in(data)
52
+ row = Spreadsheet.open(StringIO.new(data)).worksheet(0).row(0)
53
+
54
+ row.each_with_index.map { |_value, index| row.format(index).number_format }
55
+ end
18
56
  end
19
57
 
20
58
  describe "::HEADER_CONVERTERS" do
@@ -77,10 +115,10 @@ RSpec.describe ESV do
77
115
 
78
116
  it "allows specifying a worksheet index" do
79
117
  output = ESV.parse(excel_file_with_two_worksheets, worksheet_index: 0)
80
- expect(output).to eq [[ "I am worksheet 0" ]]
118
+ expect(output).to eq [ [ "I am worksheet 0" ] ]
81
119
 
82
120
  output = ESV.parse(excel_file_with_two_worksheets, worksheet_index: 1)
83
- expect(output).to eq [[ "I am worksheet 1" ]]
121
+ expect(output).to eq [ [ "I am worksheet 1" ] ]
84
122
  end
85
123
  end
86
124
  end
@@ -208,7 +246,7 @@ RSpec.describe ESV do
208
246
  esv << [ 1, 2 ]
209
247
  end
210
248
 
211
- output = ESV.parse_file(path)
249
+ output = ESV.parse_file(path, worksheet_index: 0)
212
250
 
213
251
  expect(output).to eq [
214
252
  [ "Dogs", "Cats" ],
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: excel-esv
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrik Nyh
@@ -10,7 +10,7 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: spreadsheet
13
+ name: logger
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
@@ -24,7 +24,7 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
26
  - !ruby/object:Gem::Dependency
27
- name: logger
27
+ name: spreadsheet
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
@@ -73,14 +73,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '0'
76
+ version: 3.1.0
77
77
  required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  requirements: []
83
- rubygems_version: 3.6.9
83
+ rubygems_version: 4.0.9
84
84
  specification_version: 4
85
85
  summary: Excel parsing and generation with the ease of CSV.
86
86
  test_files: []