@@ -8,7 +8,9 @@ class Creek::Book
8
8
attr_reader :files ,
9
9
:sheets ,
10
10
:shared_strings ,
11
- :with_headers
11
+ :with_headers ,
12
+ :workbook_rels_by_type ,
13
+ :workbook_rels_by_id
12
14
13
15
DATE_1900 = Date . new ( 1899 , 12 , 30 ) . freeze
14
16
DATE_1904 = Date . new ( 1904 , 1 , 1 ) . freeze
@@ -21,12 +23,14 @@ def initialize path, options = {}
21
23
end
22
24
path = download_file ( path ) if options [ :remote ]
23
25
@files = Zip ::File . open ( path )
26
+ parse_workbook_path
27
+ parse_workbook_rels
24
28
@shared_strings = SharedStrings . new ( self )
25
29
@with_headers = options . fetch ( :with_headers , false )
26
30
end
27
31
28
32
def sheets
29
- doc = @files . file . open "xl/workbook.xml"
33
+ doc = @files . file . open @workbook_path
30
34
xml = Nokogiri ::XML ::Document . parse doc
31
35
namespaces = xml . namespaces
32
36
@@ -37,10 +41,8 @@ def sheets
37
41
end
38
42
end
39
43
40
- rels_doc = @files . file . open "xl/_rels/workbook.xml.rels"
41
- rels = Nokogiri ::XML ::Document . parse ( rels_doc ) . css ( "Relationship" )
42
44
@sheets = xml . css ( cssPrefix +'sheet' ) . map do |sheet |
43
- sheetfile = rels . find { | el | sheet . attr ( "r:id" ) == el . attr ( "Id" ) } . attr ( "Target" )
45
+ sheetfile = @workbook_rels_by_id [ sheet . attr ( "r:id" ) ]
44
46
sheet = Sheet . new (
45
47
self ,
46
48
sheet . attr ( "name" ) ,
@@ -71,7 +73,7 @@ def base_date
71
73
# http://msdn.microsoft.com/en-us/library/ff530155(v=office.12).aspx
72
74
result = DATE_1900 # default
73
75
74
- doc = @files . file . open "xl/workbook.xml"
76
+ doc = @files . file . open @workbook_path
75
77
xml = Nokogiri ::XML ::Document . parse doc
76
78
xml . css ( 'workbookPr[date1904]' ) . each do |workbookPr |
77
79
if workbookPr [ 'date1904' ] =~ /true|1/i
@@ -98,5 +100,25 @@ def download_file(url)
98
100
downloaded . path
99
101
end
100
102
end
103
+
104
+ def parse_workbook_path
105
+ rels_file = @files . file . open '_rels/.rels'
106
+ rels_xml = Nokogiri ::XML ::Document . parse ( rels_file ) . css ( 'Relationship' )
107
+ rel = rels_xml . find { |el | el . attr ( 'Type' ) == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" }
108
+ @workbook_path = rel . attr ( 'Target' )
109
+ end
110
+
111
+ def parse_workbook_rels
112
+ @workbook_rels_by_id = { }
113
+ @workbook_rels_by_type = { }
114
+ workbook_dirname , slash , workbook_basename = @workbook_path . rpartition ( '/' )
115
+ workbook_rels_file = @files . file . open "#{ workbook_dirname } #{ slash } _rels/#{ workbook_basename } .rels"
116
+ Nokogiri ::XML ::Document . parse ( workbook_rels_file ) . css ( 'Relationship' ) . each do |rel |
117
+ target = rel . attr ( 'Target' )
118
+ target = "#{ workbook_dirname } #{ slash } #{ target } " unless target . start_with? ( '/' )
119
+ @workbook_rels_by_id [ rel . attr ( 'Id' ) ] = target
120
+ @workbook_rels_by_type [ rel . attr ( 'Type' ) ] = target
121
+ end
122
+ end
101
123
end
102
124
end
0 commit comments