summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/workbook
diff options
context:
space:
mode:
authorStefan Daschek <[email protected]>2013-07-05 04:22:35 +0200
committerStefan Daschek <[email protected]>2013-07-08 14:15:59 +0200
commit92b73ffb1e5cdfb001da684c463856f79aff6e11 (patch)
tree69c6de36e9ee3eb7a4bb241d65f4ccdf1d604d3a /lib/axlsx/workbook
parentb7e14c242c0d9fc3af7b7ad969ec25df21475547 (diff)
downloadcaxlsx-92b73ffb1e5cdfb001da684c463856f79aff6e11.tar.gz
caxlsx-92b73ffb1e5cdfb001da684c463856f79aff6e11.zip
Make relationship ids more reliable.
Relationship instances now keep track of their own id – this should be much more reliable than the old way of more or less “guessing” the relationship id based on the position of some object in some array. Fixes https://github.com/randym/axlsx/issues/212, especially. Each relationship now has its own, unique id – except for the cases when it doesn’t: Some relationships need to share the same id, see `Relation#should_use_same_id_as?` for the gory details. All tests pass, and the full example.xlsx is generated without errors and looks fine in Excel for Mac 2011. The pivot table example still has the problems mentioned in https://github.com/randym/axlsx/issues/168 – but as far as I can tell I didn’t make it worse (Excel is still be able to “repair” the file, and the repaired file then contains the pivot table).
Diffstat (limited to 'lib/axlsx/workbook')
-rw-r--r--lib/axlsx/workbook/workbook.rb13
-rw-r--r--lib/axlsx/workbook/worksheet/comments.rb6
-rw-r--r--lib/axlsx/workbook/worksheet/pivot_table.rb10
-rw-r--r--lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb5
-rw-r--r--lib/axlsx/workbook/worksheet/pivot_tables.rb2
-rw-r--r--lib/axlsx/workbook/worksheet/table.rb5
-rw-r--r--lib/axlsx/workbook/worksheet/tables.rb2
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet.rb13
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet_comments.rb11
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet_drawing.rb12
-rw-r--r--lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb15
11 files changed, 36 insertions, 58 deletions
diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb
index 1397552a..d122f253 100644
--- a/lib/axlsx/workbook/workbook.rb
+++ b/lib/axlsx/workbook/workbook.rb
@@ -270,14 +270,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
def relationships
r = Relationships.new
@worksheets.each do |sheet|
- r << Relationship.new(WORKSHEET_R, WORKSHEET_PN % (r.size+1))
+ r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size+1))
end
pivot_tables.each_with_index do |pivot_table, index|
- r << Relationship.new(PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
+ r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
end
- r << Relationship.new(STYLES_R, STYLES_PN)
+ r << Relationship.new(self, STYLES_R, STYLES_PN)
if use_shared_strings
- r << Relationship.new(SHARED_STRINGS_R, SHARED_STRINGS_PN)
+ r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
end
r
end
@@ -336,9 +336,8 @@ require 'axlsx/workbook/worksheet/selection.rb'
defined_names.to_xml_string(str)
unless pivot_tables.empty?
str << '<pivotCaches>'
- pivot_tables.each_with_index do |pivot_table, index|
- rId = "rId#{@worksheets.size + index + 1 }"
- str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << rId << '"/>'
+ pivot_tables.each do |pivot_table|
+ str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
end
str << '</pivotCaches>'
end
diff --git a/lib/axlsx/workbook/worksheet/comments.rb b/lib/axlsx/workbook/worksheet/comments.rb
index 25da9de2..03cce339 100644
--- a/lib/axlsx/workbook/worksheet/comments.rb
+++ b/lib/axlsx/workbook/worksheet/comments.rb
@@ -56,9 +56,9 @@ module Axlsx
# The relationships required by this object
# @return [Array]
def relationships
- [Relationship.new(VML_DRAWING_R, "../#{vml_drawing.pn}"),
- Relationship.new(COMMENT_R, "../#{pn}"),
- Relationship.new(COMMENT_R_NULL, "NULL")]
+ [Relationship.new(self, VML_DRAWING_R, "../#{vml_drawing.pn}"),
+ Relationship.new(self, COMMENT_R, "../#{pn}"),
+ Relationship.new(self, COMMENT_R_NULL, "NULL")]
end
# serialize the object
diff --git a/lib/axlsx/workbook/worksheet/pivot_table.rb b/lib/axlsx/workbook/worksheet/pivot_table.rb
index da87162d..632765f9 100644
--- a/lib/axlsx/workbook/worksheet/pivot_table.rb
+++ b/lib/axlsx/workbook/worksheet/pivot_table.rb
@@ -135,20 +135,14 @@ module Axlsx
@cache_definition ||= PivotTableCacheDefinition.new(self)
end
- # The worksheet relationships. This is managed automatically by the worksheet
+ # The relationships for this pivot table.
# @return [Relationships]
def relationships
r = Relationships.new
- r << Relationship.new(PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
+ r << Relationship.new(cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, "../#{cache_definition.pn}")
r
end
- # The relation reference id for this table
- # @return [String]
- def rId
- "rId#{index+1}"
- end
-
# Serializes the object
# @param [String] str
# @return [String]
diff --git a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb
index c1683520..340b94ff 100644
--- a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb
+++ b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb
@@ -35,10 +35,11 @@ module Axlsx
index + 1
end
- # The relation reference id for this table
+ # The relationship id for this pivot table cache definition.
+ # @see Relationship#Id
# @return [String]
def rId
- "rId#{index + 1}"
+ pivot_table.relationships.for(self).Id
end
# Serializes the object
diff --git a/lib/axlsx/workbook/worksheet/pivot_tables.rb b/lib/axlsx/workbook/worksheet/pivot_tables.rb
index f5625fc0..912d9f41 100644
--- a/lib/axlsx/workbook/worksheet/pivot_tables.rb
+++ b/lib/axlsx/workbook/worksheet/pivot_tables.rb
@@ -17,7 +17,7 @@ module Axlsx
# returns the relationships required by this collection
def relationships
return [] if empty?
- map{ |pivot_table| Relationship.new(PIVOT_TABLE_R, "../#{pivot_table.pn}") }
+ map{ |pivot_table| Relationship.new(pivot_table, PIVOT_TABLE_R, "../#{pivot_table.pn}") }
end
end
diff --git a/lib/axlsx/workbook/worksheet/table.rb b/lib/axlsx/workbook/worksheet/table.rb
index dce1a40e..94474c57 100644
--- a/lib/axlsx/workbook/worksheet/table.rb
+++ b/lib/axlsx/workbook/worksheet/table.rb
@@ -47,10 +47,11 @@ module Axlsx
"#{TABLE_PN % (index+1)}"
end
- # The relation reference id for this table
+ # The relationship id for this table.
+ # @see Relationship#Id
# @return [String]
def rId
- "rId#{index+1}"
+ @sheet.relationships.for(self).Id
end
# The name of the Table.
diff --git a/lib/axlsx/workbook/worksheet/tables.rb b/lib/axlsx/workbook/worksheet/tables.rb
index 2d9a1f3c..814f995f 100644
--- a/lib/axlsx/workbook/worksheet/tables.rb
+++ b/lib/axlsx/workbook/worksheet/tables.rb
@@ -17,7 +17,7 @@ module Axlsx
# returns the relationships required by this collection
def relationships
return [] if empty?
- map{ |table| Relationship.new(TABLE_R, "../#{table.pn}") }
+ map{ |table| Relationship.new(table, TABLE_R, "../#{table.pn}") }
end
def to_xml_string(str = "")
diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb
index 7324181a..ecba9254 100644
--- a/lib/axlsx/workbook/worksheet/worksheet.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet.rb
@@ -348,10 +348,11 @@ module Axlsx
"#{WORKSHEET_RELS_PN % (index+1)}"
end
- # The relationship Id of thiw worksheet
+ # The relationship id of this worksheet.
# @return [String]
+ # @see Relationship#Id
def rId
- "rId#{index+1}"
+ @workbook.relationships.for(self).Id
end
# The index of this worksheet in the owning Workbook's worksheets list.
@@ -574,14 +575,6 @@ module Axlsx
r
end
- # identifies the index of an object withing the collections used in generating relationships for the worksheet
- # @param [Any] object the object to search for
- # @return [Integer] The index of the object
- def relationships_index_of(object)
- objects = [tables.to_a, worksheet_comments.comments.to_a, hyperlinks.to_a, worksheet_drawing.drawing].flatten.compact || []
- objects.index(object)
- end
-
# Returns the cell or cells defined using excel style A1:B3 references.
# @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber
# @return [Cell, Array]
diff --git a/lib/axlsx/workbook/worksheet/worksheet_comments.rb b/lib/axlsx/workbook/worksheet/worksheet_comments.rb
index 8c700aa0..f9e4c8cd 100644
--- a/lib/axlsx/workbook/worksheet/worksheet_comments.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet_comments.rb
@@ -40,10 +40,11 @@ module Axlsx
!comments.empty?
end
- # The index in the worksheet's relationships for the VML drawing that will render the comments
- # @return [Integer]
- def index
- worksheet.relationships.index { |r| r.Type == VML_DRAWING_R } + 1
+ # The relationship id of the VML drawing that will render the comments.
+ # @see Relationship#Id
+ # @return [String]
+ def drawing_rId
+ comments.relationships.find{ |r| r.Type == VML_DRAWING_R }.Id
end
# Seraalize the object
@@ -51,7 +52,7 @@ module Axlsx
# @return [String]
def to_xml_string(str = '')
return unless has_comments?
- str << "<legacyDrawing r:id='rId#{index}' />"
+ str << "<legacyDrawing r:id='#{drawing_rId}' />"
end
end
end
diff --git a/lib/axlsx/workbook/worksheet/worksheet_drawing.rb b/lib/axlsx/workbook/worksheet/worksheet_drawing.rb
index 9deeeec3..08cad1f7 100644
--- a/lib/axlsx/workbook/worksheet/worksheet_drawing.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet_drawing.rb
@@ -41,24 +41,18 @@ module Axlsx
@drawing.is_a? Drawing
end
- # The relationship required by this object
+ # The relationship instance for this drawing.
# @return [Relationship]
def relationship
return unless has_drawing?
- Relationship.new(DRAWING_R, "../#{drawing.pn}")
- end
-
- # returns the index of the worksheet releationship that defines this drawing.
- # @return [Integer]
- def index
- worksheet.relationships.index{ |r| r.Type == DRAWING_R } +1
+ Relationship.new(self, DRAWING_R, "../#{drawing.pn}")
end
# Serialize the drawing for the worksheet
# @param [String] str
def to_xml_string(str = '')
return unless has_drawing?
- str << "<drawing r:id='rId#{index}'/>"
+ str << "<drawing r:id='#{relationship.Id}'/>"
end
end
end
diff --git a/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb b/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb
index d352ec90..2a241287 100644
--- a/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb
+++ b/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb
@@ -45,18 +45,13 @@ module Axlsx
@ref = cell_reference
end
- # The relationship required by this hyperlink when the taget is :external
+ # The relationship instance for this hyperlink.
+ # A relationship is only required if `@target` is `:external`. If not, this method will simply return `nil`.
+ # @see #target=
# @return [Relationship]
def relationship
return unless @target == :external
- Relationship.new HYPERLINK_R, location, :target_mode => :External
- end
-
- # The id of the relationship for this object
- # @return [String]
- def id
- return unless @target == :external
- "rId#{(@worksheet.relationships_index_of(self)+1)}"
+ Relationship.new(self, HYPERLINK_R, location, :target_mode => :External)
end
# Seralize the object
@@ -73,7 +68,7 @@ module Axlsx
# r:id should only be specified for external targets.
# @return [Hash]
def location_or_id
- @target == :external ? { :"r:id" => id } : { :location => Axlsx::coder.encode(location) }
+ @target == :external ? { :"r:id" => relationship.Id } : { :location => Axlsx::coder.encode(location) }
end
end
end