@@ -8,7 +8,9 @@ class Creek::Book
88 attr_reader :files ,
99 :sheets ,
1010 :shared_strings ,
11- :with_headers
11+ :with_headers ,
12+ :workbook_rels_by_type ,
13+ :workbook_rels_by_id
1214
1315 DATE_1900 = Date . new ( 1899 , 12 , 30 ) . freeze
1416 DATE_1904 = Date . new ( 1904 , 1 , 1 ) . freeze
@@ -21,12 +23,14 @@ def initialize path, options = {}
2123 end
2224 path = download_file ( path ) if options [ :remote ]
2325 @files = Zip ::File . open ( path )
26+ parse_workbook_path
27+ parse_workbook_rels
2428 @shared_strings = SharedStrings . new ( self )
2529 @with_headers = options . fetch ( :with_headers , false )
2630 end
2731
2832 def sheets
29- doc = @files . file . open "xl/workbook.xml"
33+ doc = @files . file . open @workbook_path
3034 xml = Nokogiri ::XML ::Document . parse doc
3135 namespaces = xml . namespaces
3236
@@ -37,10 +41,8 @@ def sheets
3741 end
3842 end
3943
40- rels_doc = @files . file . open "xl/_rels/workbook.xml.rels"
41- rels = Nokogiri ::XML ::Document . parse ( rels_doc ) . css ( "Relationship" )
4244 @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" ) ]
4446 sheet = Sheet . new (
4547 self ,
4648 sheet . attr ( "name" ) ,
@@ -71,7 +73,7 @@ def base_date
7173 # http://msdn.microsoft.com/en-us/library/ff530155(v=office.12).aspx
7274 result = DATE_1900 # default
7375
74- doc = @files . file . open "xl/workbook.xml"
76+ doc = @files . file . open @workbook_path
7577 xml = Nokogiri ::XML ::Document . parse doc
7678 xml . css ( 'workbookPr[date1904]' ) . each do |workbookPr |
7779 if workbookPr [ 'date1904' ] =~ /true|1/i
@@ -98,5 +100,24 @@ def download_file(url)
98100 downloaded . path
99101 end
100102 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 = "#{ workbook_dirname } #{ slash } #{ rel . attr ( 'Target' ) } "
118+ @workbook_rels_by_id [ rel . attr ( 'Id' ) ] = target
119+ @workbook_rels_by_type [ rel . attr ( 'Type' ) ] = target
120+ end
121+ end
101122 end
102123end
0 commit comments