ooxl 0.0.1.5.1 → 0.0.1.5.6

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
- SHA1:
3
- metadata.gz: b4f14b323fab2a3362235d62a449584a6b980482
4
- data.tar.gz: 696182e5392827ccc8754300c8e9e9df49fc020b
2
+ SHA256:
3
+ metadata.gz: 6f5c08486fcbbb5d3df21da5ca0a08dc0e121de0da7232af5795a46144611238
4
+ data.tar.gz: fbb52109d99ed095afbc98655d4f234c06d3652357cdfd924fc66e8ae95dca56
5
5
  SHA512:
6
- metadata.gz: 7c4a10ad5b476b807649a94541ce6c7a516a8efbebbd527eceab608a01eb1c0e80edbf1fd535511b521a92725c969b6196cf79b8437391a115fcf04529e853ad
7
- data.tar.gz: c1b0926146a8b4cdf68bb55ea1b0307dd4cae502dd11a4fd7fba4b137b16fcc56931b806e651bf2a12e2d2df43c953f0b7c16232b5d5b1e7b59e56b64bade18f
6
+ metadata.gz: e06f441373a787cef916246cca3fafb8ed88c5e9bbc350956252cdc946e43b924c6ff786645fa10d0106fd97f50a21165a5037066469870bafb9d00a7fe5c573
7
+ data.tar.gz: 6287c0dc02be92d01e49f0c8fcb934c857219dbf596cf3a3d6c0636cb2cd46160f19193b456608fcd07ddebb046bbe4ca18ba1c4a6d07d41ecfa3e8bc7d794af
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "ooxml_excel"
4
+ require "./lib/ooxl"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "ooxml_excel"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
14
- IRB.start
13
+ require "pry"
14
+ Pry.start
data/lib/ooxl/ooxl.rb CHANGED
@@ -3,20 +3,33 @@ class OOXL
3
3
  include ListHelper
4
4
  attr_reader :filename
5
5
 
6
- def initialize(spreadsheet_filepath, options={})
6
+ def initialize(filepath = nil, contents: nil, **options)
7
7
  @workbook = nil
8
8
  @sheets = {}
9
9
  @styles = []
10
10
  @comments = {}
11
- @relationships = {}
11
+ @workbook_relationships = nil
12
+ @sheet_relationships = {}
12
13
  @options = options
13
14
  @tables = []
14
- @filename = File.basename(spreadsheet_filepath)
15
- parse_spreadsheet_contents(spreadsheet_filepath)
15
+
16
+ @filename = filepath && File.basename(filepath)
17
+ if contents.present?
18
+ parse_spreadsheet_contents(contents)
19
+ elsif filepath.present?
20
+ parse_spreadsheet_file(filepath)
21
+ else
22
+ raise 'no file path or contents were provided'
23
+ end
16
24
  end
17
25
 
18
26
  def self.open(spreadsheet_filepath, options={})
19
- new(spreadsheet_filepath, options)
27
+ new(spreadsheet_filepath, **options)
28
+ end
29
+
30
+ def self.parse(spreadsheet_contents, options={})
31
+ spreadsheet_contents.force_encoding('ASCII-8BIT') if spreadsheet_contents.respond_to?(:force_encoding)
32
+ new(nil, contents: spreadsheet_contents, **options)
20
33
  end
21
34
 
22
35
  def sheets(skip_hidden: false)
@@ -33,9 +46,11 @@ class OOXL
33
46
  end
34
47
 
35
48
  def sheet(sheet_name)
36
- sheet_index = @workbook.sheets.index { |sheet| sheet[:name] == sheet_name}
37
- raise "No #{sheet_name} in workbook." if sheet_index.nil?
38
- sheet = @sheets.fetch((sheet_index+1).to_s)
49
+ sheet_meta = @workbook.sheets.find { |sheet| sheet[:name] == sheet_name }
50
+ raise "No #{sheet_name} in workbook." if sheet_meta.nil?
51
+
52
+ sheet_index = @workbook_relationships[sheet_meta[:relationship_id]].scan(/\d+/).first
53
+ sheet = @sheets.fetch(sheet_index)
39
54
 
40
55
  # shared variables
41
56
  sheet.name = sheet_name
@@ -73,38 +88,46 @@ class OOXL
73
88
  end
74
89
 
75
90
  def fetch_comments(sheet_index)
76
- final_sheet_index = sheet_index+1
77
- relationship = @relationships[final_sheet_index.to_s]
91
+ relationship = @sheet_relationships[sheet_index]
78
92
  @comments[relationship.comment_id] if relationship.present?
79
93
  end
80
94
 
81
- def parse_spreadsheet_contents(spreadsheet)
95
+ def parse_spreadsheet_file(file_path)
96
+ Zip::File.open(file_path) { |zip| parse_zip(zip) }
97
+ end
98
+
99
+ def parse_spreadsheet_contents(file_contents)
100
+ # open_buffer works for strings and IO streams
101
+ Zip::File.open_buffer(file_contents) { |zip| parse_zip(zip) }
102
+ end
103
+
104
+ def parse_zip(spreadsheet_zip)
82
105
  shared_strings = []
83
- Zip::File.open(spreadsheet) do |spreadsheet_zip|
84
- spreadsheet_zip.each do |entry|
85
- case entry.name
86
- when /xl\/worksheets\/sheet(\d+)?\.xml/
87
- sheet_id = entry.name.scan(/xl\/worksheets\/sheet(\d+)?\.xml/).flatten.first
88
- @sheets[sheet_id] = OOXL::Sheet.new(entry.get_input_stream.read, shared_strings, @options)
89
- when /xl\/styles\.xml/
90
- @styles = OOXL::Styles.load_from_stream(entry.get_input_stream.read)
91
- when /xl\/comments(\d+)?\.xml/
92
- comment_id = entry.name.scan(/xl\/comments(\d+)\.xml/).flatten.first
93
- @comments[comment_id] = OOXL::Comments.load_from_stream(entry.get_input_stream.read)
94
- when "xl/sharedStrings.xml"
95
- Nokogiri.XML(entry.get_input_stream.read).remove_namespaces!.xpath('sst/si').each do |shared_string_node|
96
- shared_strings << shared_string_node.xpath('r/t|t').map { |value_node| value_node.text}.join('')
97
- end
98
- when /xl\/tables\/.*?/i
99
- @tables << OOXL::Table.new(entry.get_input_stream.read)
100
- when "xl/workbook.xml"
101
- @workbook = OOXL::Workbook.load_from_stream(entry.get_input_stream.read)
102
- when /xl\/worksheets\/_rels\/sheet\d+\.xml\.rels/
103
- sheet_id = entry.name.scan(/sheet(\d+)/).flatten.first
104
- @relationships[sheet_id] = Relationships.new(entry.get_input_stream.read)
105
- else
106
- # unsupported for now..
106
+ spreadsheet_zip.each do |entry|
107
+ case entry.name
108
+ when /xl\/worksheets\/sheet(\d+)?\.xml/
109
+ sheet_id = entry.name.scan(/xl\/worksheets\/sheet(\d+)?\.xml/).flatten.first
110
+ @sheets[sheet_id] = OOXL::Sheet.new(entry.get_input_stream.read, shared_strings, @options)
111
+ when /xl\/styles\.xml/
112
+ @styles = OOXL::Styles.load_from_stream(entry.get_input_stream.read)
113
+ when /xl\/comments(\d+)?\.xml/
114
+ comment_id = entry.name.scan(/xl\/comments(\d+)\.xml/).flatten.first
115
+ @comments[comment_id] = OOXL::Comments.load_from_stream(entry.get_input_stream.read)
116
+ when "xl/sharedStrings.xml"
117
+ Nokogiri.XML(entry.get_input_stream.read).remove_namespaces!.xpath('sst/si').each do |shared_string_node|
118
+ shared_strings << shared_string_node.xpath('r/t|t').map { |value_node| value_node.text}.join('')
107
119
  end
120
+ when /xl\/tables\/.*?/i
121
+ @tables << OOXL::Table.new(entry.get_input_stream.read)
122
+ when "xl/workbook.xml"
123
+ @workbook = OOXL::Workbook.load_from_stream(entry.get_input_stream.read)
124
+ when /xl\/worksheets\/_rels\/sheet\d+\.xml\.rels/
125
+ sheet_id = entry.name.scan(/sheet(\d+)/).flatten.first
126
+ @sheet_relationships[sheet_id] = Relationships.new(entry.get_input_stream.read)
127
+ when /xl\/_rels\/workbook\.xml\.rels/
128
+ @workbook_relationships = Relationships.new(entry.get_input_stream.read)
129
+ else
130
+ # unsupported for now..
108
131
  end
109
132
  end
110
133
  end
data/lib/ooxl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class OOXL
2
- VERSION = "0.0.1.5.1"
2
+ VERSION = "0.0.1.5.6"
3
3
  end
@@ -14,7 +14,7 @@ class OOXL
14
14
  comment_xml =Nokogiri.XML(comment_xml).remove_namespaces!
15
15
 
16
16
  comments = comment_xml.xpath("//comments/commentList/comment").map do |comment_node|
17
- comment_text_node = comment_node.xpath('./text/r/t')
17
+ comment_text_node = comment_node.xpath('./text/r/t').presence || comment_node.xpath('./text/t')
18
18
 
19
19
  value = if comment_text_node.is_a?(Array)
20
20
  comment_text_node.map { |comment_text_node| comment_text_node.text }.join('')
@@ -1,29 +1,41 @@
1
1
  class OOXL
2
2
  class Relationships
3
3
  SUPPORTED_TYPES = ['http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments']
4
+
4
5
  def initialize(relationships_node)
5
- @types = {}
6
+ @relationships = []
6
7
  parse_relationships(relationships_node)
7
8
  end
8
9
 
9
10
  def comment_id
10
- @types['comments']
11
+ comment_target = by_type('comments').first
12
+ comment_target && extract_file_reference(comment_target)
13
+ end
14
+
15
+ def [](id)
16
+ @relationships.find { |rel| rel.id == id }&.target
17
+ end
18
+
19
+ def by_type(type)
20
+ @relationships.select { |rel| rel.type == type }.map(&:target)
11
21
  end
12
22
 
13
23
  private
24
+
14
25
  def parse_relationships(relationships_node)
15
26
  relationships_node = Nokogiri.XML(relationships_node).remove_namespaces!
16
27
  relationships_node.xpath('//Relationship').each do |relationship_node|
17
28
  relationship_type = relationship_node.attributes["Type"].value
18
29
  target = relationship_node.attributes["Target"].value
19
- if supported_type?(relationship_type)
20
- @types[extract_type(relationship_type)] = extract_file_reference(target)
21
- end
30
+ id = extract_number(relationship_node.attributes["Id"].value)
31
+ type = extract_type(relationship_type)
32
+ target = relationship_node.attributes["Target"].value
33
+ @relationships << Relationship.new(id, type, target)
22
34
  end
23
35
  end
24
36
 
25
- def supported_type?(type)
26
- SUPPORTED_TYPES.include?(type)
37
+ def extract_number(str)
38
+ str.scan(/(\d+)/).flatten.first
27
39
  end
28
40
 
29
41
  def extract_type(type)
@@ -34,6 +46,7 @@ class OOXL
34
46
  file.scan(/(\d+)\.[\w]/).flatten.first
35
47
  end
36
48
 
49
+ Relationship = Struct.new(:id, :type, :target)
37
50
  end
38
51
  end
39
52
 
@@ -117,7 +117,7 @@ class OOXL
117
117
  end
118
118
 
119
119
  def row_nodes
120
- @row_nodes ||= @sheet_xml.xpath('//sheetData/row')
120
+ @row_nodes ||= @sheet_xml.xpath('//sheetData/row')&.to_a
121
121
  end
122
122
 
123
123
  def parse_row(row_node)
data/ooxml_excel.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.require_paths = ["lib"]
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'nokogiri', '~> 1'
29
- spec.add_dependency 'rubyzip', '~> 1.0', '< 2.0.0'
29
+ spec.add_dependency 'rubyzip', '~> 1.3.0', '< 2.0.0'
30
30
 
31
31
  spec.add_development_dependency "bundler"
32
32
  spec.add_development_dependency "pry-byebug"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ooxl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.5.1
4
+ version: 0.0.1.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Mones
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-19 00:00:00.000000000 Z
11
+ date: 2022-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -44,7 +44,7 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.0'
47
+ version: 1.3.0
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
50
  version: 2.0.0
@@ -54,7 +54,7 @@ dependencies:
54
54
  requirements:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: '1.0'
57
+ version: 1.3.0
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 2.0.0
@@ -153,7 +153,7 @@ files:
153
153
  homepage: https://github.com/halcjames/ooxl
154
154
  licenses: []
155
155
  metadata: {}
156
- post_install_message:
156
+ post_install_message:
157
157
  rdoc_options: []
158
158
  require_paths:
159
159
  - lib
@@ -168,9 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
170
  requirements: []
171
- rubyforge_project:
172
- rubygems_version: 2.6.12
173
- signing_key:
171
+ rubygems_version: 3.0.9
172
+ signing_key:
174
173
  specification_version: 4
175
174
  summary: OOXL Excel - Parse Excel Spreadsheets (xlsx, xlsm).
176
175
  test_files: []