caxlsx 3.0.0 → 3.1.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 +4 -4
- data/CHANGELOG.md +126 -31
- data/README.md +78 -170
- data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
- data/examples/generate.rb +15 -0
- data/lib/axlsx.rb +2 -3
- data/lib/axlsx/drawing/bar_chart.rb +3 -3
- data/lib/axlsx/drawing/bar_series.rb +3 -5
- data/lib/axlsx/drawing/d_lbls.rb +1 -1
- data/lib/axlsx/drawing/pie_series.rb +1 -1
- data/lib/axlsx/drawing/series_title.rb +3 -1
- data/lib/axlsx/drawing/title.rb +3 -2
- data/lib/axlsx/package.rb +53 -19
- data/lib/axlsx/rels/relationship.rb +26 -25
- data/lib/axlsx/stylesheet/font.rb +10 -2
- data/lib/axlsx/util/constants.rb +2 -1
- data/lib/axlsx/util/mime_type_utils.rb +1 -1
- data/lib/axlsx/util/validators.rb +2 -2
- data/lib/axlsx/util/zip_command.rb +73 -0
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/workbook.rb +0 -9
- data/lib/axlsx/workbook/worksheet/cell.rb +32 -5
- data/lib/axlsx/workbook/worksheet/col.rb +8 -4
- data/lib/axlsx/workbook/worksheet/data_validation.rb +4 -4
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +7 -2
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +1 -1
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +1 -1
- data/lib/axlsx/workbook/worksheet/row.rb +6 -3
- data/lib/axlsx/workbook/worksheet/table.rb +1 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +17 -4
- data/lib/caxlsx.rb +2 -0
- data/test/drawing/tc_drawing.rb +2 -2
- data/test/drawing/tc_hyperlink.rb +1 -1
- data/test/drawing/tc_one_cell_anchor.rb +1 -1
- data/test/drawing/tc_pic.rb +4 -4
- data/test/drawing/tc_pie_series.rb +2 -1
- data/test/drawing/tc_series_title.rb +21 -0
- data/test/drawing/tc_title.rb +16 -0
- data/test/fixtures/image1.gif +0 -0
- data/test/fixtures/image1.jpeg +0 -0
- data/test/fixtures/image1.jpg +0 -0
- data/test/fixtures/image1.png +0 -0
- data/test/fixtures/image1_fake.jpg +0 -0
- data/test/rels/tc_relationship.rb +8 -0
- data/test/stylesheet/tc_font.rb +14 -2
- data/test/stylesheet/tc_styles.rb +27 -1
- data/test/tc_axlsx.rb +6 -0
- data/test/tc_helper.rb +0 -2
- data/test/tc_package.rb +82 -13
- data/test/util/tc_mime_type_utils.rb +1 -1
- data/test/util/tc_validators.rb +1 -1
- data/test/workbook/worksheet/tc_cell.rb +68 -2
- data/test/workbook/worksheet/tc_col.rb +16 -1
- data/test/workbook/worksheet/tc_pivot_table.rb +8 -0
- data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +8 -0
- data/test/workbook/worksheet/tc_rich_text_run.rb +3 -2
- data/test/workbook/worksheet/tc_row.rb +38 -0
- data/test/workbook/worksheet/tc_table.rb +10 -0
- data/test/workbook/worksheet/tc_worksheet.rb +24 -15
- metadata +130 -151
- data/examples/2010_comments.rb +0 -17
- data/examples/anchor_swapping.rb +0 -28
- data/examples/auto_filter.rb +0 -25
- data/examples/basic_charts.rb +0 -58
- data/examples/chart_colors.rb +0 -88
- data/examples/colored_links.rb +0 -59
- data/examples/conditional_formatting/example_conditional_formatting.rb +0 -89
- data/examples/conditional_formatting/getting_barred.rb +0 -37
- data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
- data/examples/conditional_formatting/scaled_colors.rb +0 -39
- data/examples/conditional_formatting/stop_and_go.rb +0 -37
- data/examples/data_validation.rb +0 -67
- data/examples/example.rb +0 -885
- data/examples/extractive.rb +0 -45
- data/examples/ios_preview.rb +0 -14
- data/examples/merge_cells.rb +0 -17
- data/examples/no_grid_with_borders.rb +0 -18
- data/examples/page_setup.rb +0 -11
- data/examples/pivot_table.rb +0 -39
- data/examples/pivot_test.rb +0 -63
- data/examples/sheet_protection.rb +0 -10
- data/examples/skydrive/real_example.rb +0 -63
- data/examples/split.rb +0 -16
- data/examples/styles.rb +0 -66
- data/examples/underline.rb +0 -13
- data/examples/wrap_text.rb +0 -21
- data/lib/axlsx/util/parser.rb +0 -44
File without changes
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
files = if !ARGV.empty?
|
4
|
+
ARGV.select { |file| File.exist?(file) }
|
5
|
+
else
|
6
|
+
Dir['*_example.md']
|
7
|
+
end
|
8
|
+
|
9
|
+
files.each do |file|
|
10
|
+
puts "Executing #{file.split('.')[0].tr('_', ' ')}"
|
11
|
+
code = File.read(file).match(/```ruby(?<code>.+)```/m)[:code]
|
12
|
+
unless code.nil?
|
13
|
+
eval(['$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"', code].join("\n"))
|
14
|
+
end
|
15
|
+
end
|
data/lib/axlsx.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'htmlentities'
|
3
3
|
require 'axlsx/version.rb'
|
4
|
-
require '
|
4
|
+
require 'marcel'
|
5
5
|
|
6
6
|
require 'axlsx/util/simple_typed_list.rb'
|
7
7
|
require 'axlsx/util/constants.rb'
|
@@ -9,9 +9,8 @@ require 'axlsx/util/validators.rb'
|
|
9
9
|
require 'axlsx/util/accessors.rb'
|
10
10
|
require 'axlsx/util/serialized_attributes'
|
11
11
|
require 'axlsx/util/options_parser'
|
12
|
-
# to be included with parsable intitites.
|
13
|
-
#require 'axlsx/util/parser.rb'
|
14
12
|
require 'axlsx/util/mime_type_utils'
|
13
|
+
require 'axlsx/util/zip_command'
|
15
14
|
|
16
15
|
require 'axlsx/stylesheet/styles.rb'
|
17
16
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
module Axlsx
|
3
3
|
|
4
|
-
# The BarChart is a
|
4
|
+
# The BarChart is a two dimentional barchart that you can add to your worksheet.
|
5
5
|
# @see Worksheet#add_chart
|
6
6
|
# @see Chart#add_series
|
7
7
|
# @see Package#serialize
|
@@ -49,7 +49,7 @@ module Axlsx
|
|
49
49
|
@grouping ||= :clustered
|
50
50
|
end
|
51
51
|
|
52
|
-
# The
|
52
|
+
# The shape of the bars or columns
|
53
53
|
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
54
54
|
# @return [Symbol]
|
55
55
|
def shape
|
@@ -106,7 +106,7 @@ module Axlsx
|
|
106
106
|
end
|
107
107
|
alias :gapDepth= :gap_depth=
|
108
108
|
|
109
|
-
# The
|
109
|
+
# The shape of the bars or columns
|
110
110
|
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
111
111
|
def shape=(v)
|
112
112
|
RestrictionValidator.validate "BarChart.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
|
@@ -15,9 +15,8 @@ module Axlsx
|
|
15
15
|
# @return [Array, SimpleTypedList]
|
16
16
|
attr_reader :labels
|
17
17
|
|
18
|
-
# The
|
19
|
-
# must be one of
|
20
|
-
# @return [Symbol]
|
18
|
+
# The shape of the bars or columns
|
19
|
+
# @return [Symbol] must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
21
20
|
attr_reader :shape
|
22
21
|
|
23
22
|
# An array of rgb colors to apply to your bar chart.
|
@@ -41,8 +40,7 @@ module Axlsx
|
|
41
40
|
# @see colors
|
42
41
|
def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end
|
43
42
|
|
44
|
-
#
|
45
|
-
# must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
|
43
|
+
# @see shape
|
46
44
|
def shape=(v)
|
47
45
|
RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
|
48
46
|
@shape = v
|
data/lib/axlsx/drawing/d_lbls.rb
CHANGED
@@ -55,7 +55,7 @@ module Axlsx
|
|
55
55
|
|
56
56
|
# @see DLbls#d_lbl_pos
|
57
57
|
# Assigns the label postion for this data labels on this chart.
|
58
|
-
# Allowed positions are :
|
58
|
+
# Allowed positions are :bestFit, :b, :ctr, :inBase, :inEnd, :l,
|
59
59
|
# :outEnd, :r and :t
|
60
60
|
# The default is :bestFit
|
61
61
|
# @param [Symbol] label_position the postion you want to use.
|
@@ -47,7 +47,7 @@ module Axlsx
|
|
47
47
|
# @return [String]
|
48
48
|
def to_xml_string(str = '')
|
49
49
|
super(str) do
|
50
|
-
str << '<c:explosion val="' + @explosion + '"/>' unless @explosion.nil?
|
50
|
+
str << '<c:explosion val="' + @explosion.to_s + '"/>' unless @explosion.nil?
|
51
51
|
colors.each_with_index do |c, index|
|
52
52
|
str << '<c:dPt>'
|
53
53
|
str << ('<c:idx val="' << index.to_s << '"/>')
|
@@ -7,13 +7,15 @@ module Axlsx
|
|
7
7
|
# @param [String] str
|
8
8
|
# @return [String]
|
9
9
|
def to_xml_string(str = '')
|
10
|
+
clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
|
11
|
+
|
10
12
|
str << '<c:tx>'
|
11
13
|
str << '<c:strRef>'
|
12
14
|
str << ('<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>')
|
13
15
|
str << '<c:strCache>'
|
14
16
|
str << '<c:ptCount val="1"/>'
|
15
17
|
str << '<c:pt idx="0">'
|
16
|
-
str << ('<c:v>' <<
|
18
|
+
str << ('<c:v>' << clean_value << '</c:v>')
|
17
19
|
str << '</c:pt>'
|
18
20
|
str << '</c:strCache>'
|
19
21
|
str << '</c:strRef>'
|
data/lib/axlsx/drawing/title.rb
CHANGED
@@ -62,6 +62,7 @@ module Axlsx
|
|
62
62
|
def to_xml_string(str = '')
|
63
63
|
str << '<c:title>'
|
64
64
|
unless @text.empty?
|
65
|
+
clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
|
65
66
|
str << '<c:tx>'
|
66
67
|
if @cell.is_a?(Cell)
|
67
68
|
str << '<c:strRef>'
|
@@ -69,7 +70,7 @@ module Axlsx
|
|
69
70
|
str << '<c:strCache>'
|
70
71
|
str << '<c:ptCount val="1"/>'
|
71
72
|
str << '<c:pt idx="0">'
|
72
|
-
str << ('<c:v>' <<
|
73
|
+
str << ('<c:v>' << clean_value << '</c:v>')
|
73
74
|
str << '</c:pt>'
|
74
75
|
str << '</c:strCache>'
|
75
76
|
str << '</c:strRef>'
|
@@ -80,7 +81,7 @@ module Axlsx
|
|
80
81
|
str << '<a:p>'
|
81
82
|
str << '<a:r>'
|
82
83
|
str << ('<a:rPr sz="' << @text_size.to_s << '"/>')
|
83
|
-
str << ('<a:t>' <<
|
84
|
+
str << ('<a:t>' << clean_value << '</a:t>')
|
84
85
|
str << '</a:r>'
|
85
86
|
str << '</a:p>'
|
86
87
|
str << '</c:rich>'
|
data/lib/axlsx/package.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Axlsx
|
3
3
|
# Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
|
4
|
-
# xlsx document including
|
4
|
+
# xlsx document including validation and serialization.
|
5
5
|
class Package
|
6
6
|
include Axlsx::OptionsParser
|
7
7
|
|
@@ -68,23 +68,20 @@ module Axlsx
|
|
68
68
|
@workbook
|
69
69
|
end
|
70
70
|
|
71
|
-
#def self.parse(input, confirm_valid = false)
|
72
|
-
# p = Package.new
|
73
|
-
# z = Zip::File.open(input)
|
74
|
-
# p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
|
75
|
-
# p
|
76
|
-
#end
|
77
|
-
|
78
71
|
# @see workbook
|
79
72
|
def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, workbook; @workbook = workbook; end
|
80
73
|
|
81
74
|
# Serialize your workbook to disk as an xlsx document.
|
82
75
|
#
|
83
76
|
# @param [String] output The name of the file you want to serialize your package to
|
84
|
-
# @param [
|
77
|
+
# @param [Hash] options
|
78
|
+
# @option options [Boolean] :confirm_valid Validate the package prior to serialization.
|
79
|
+
# @option options [String] :zip_command When `nil`, `#serialize` with RubyZip to
|
80
|
+
# zip the XLSX file contents. When a String, the provided zip command (e.g.,
|
81
|
+
# "zip") is used to zip the file contents (may be faster for large files)
|
85
82
|
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
86
83
|
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
87
|
-
# confirm_valid should be used in the rare case that you cannot open the serialized file.
|
84
|
+
# options[:confirm_valid] should be used in the rare case that you cannot open the serialized file.
|
88
85
|
# @see Package#validate
|
89
86
|
# @example
|
90
87
|
# # This is how easy it is to create a valid xlsx file. Of course you might want to add a sheet or two, and maybe some data, styles and charts.
|
@@ -95,16 +92,29 @@ module Axlsx
|
|
95
92
|
# # ......add cool stuff to your workbook......
|
96
93
|
# p.serialize("example.xlsx")
|
97
94
|
#
|
95
|
+
# # Serialize to a file, using a system zip binary
|
96
|
+
# p.serialize("example.xlsx", zip_command: "zip", confirm_valid: false)
|
97
|
+
# p.serialize("example.xlsx", zip_command: "/path/to/zip")
|
98
|
+
# p.serialize("example.xlsx", zip_command: "zip -1")
|
99
|
+
#
|
98
100
|
# # Serialize to a stream
|
99
101
|
# s = p.to_stream()
|
100
102
|
# File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
|
101
|
-
def serialize(output,
|
103
|
+
def serialize(output, options = {}, secondary_options = nil)
|
104
|
+
confirm_valid, zip_command = parse_serialize_options(options, secondary_options)
|
102
105
|
return false unless !confirm_valid || self.validate.empty?
|
103
|
-
|
104
|
-
|
106
|
+
zip_provider = if zip_command
|
107
|
+
ZipCommand.new(zip_command)
|
108
|
+
else
|
109
|
+
Zip::OutputStream
|
110
|
+
end
|
111
|
+
Relationship.initialize_ids_cache
|
112
|
+
zip_provider.open(output) do |zip|
|
105
113
|
write_parts(zip)
|
106
114
|
end
|
107
115
|
true
|
116
|
+
ensure
|
117
|
+
Relationship.clear_ids_cache
|
108
118
|
end
|
109
119
|
|
110
120
|
|
@@ -113,11 +123,13 @@ module Axlsx
|
|
113
123
|
# @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
|
114
124
|
def to_stream(confirm_valid=false)
|
115
125
|
return false unless !confirm_valid || self.validate.empty?
|
116
|
-
Relationship.
|
126
|
+
Relationship.initialize_ids_cache
|
117
127
|
zip = write_parts(Zip::OutputStream.new(StringIO.new, true))
|
118
128
|
stream = zip.close_buffer
|
119
129
|
stream.rewind
|
120
130
|
stream
|
131
|
+
ensure
|
132
|
+
Relationship.clear_ids_cache
|
121
133
|
end
|
122
134
|
|
123
135
|
# Encrypt the package into a CFB using the password provided
|
@@ -135,7 +147,7 @@ module Axlsx
|
|
135
147
|
# dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
|
136
148
|
# refer to the local versions.
|
137
149
|
#
|
138
|
-
# If by chance you are able to
|
150
|
+
# If by chance you are able to create a package that does not validate it indicates that the internal
|
139
151
|
# validation is not robust enough and needs to be improved. Please report your errors to the gem author.
|
140
152
|
# @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
|
141
153
|
# @example
|
@@ -156,8 +168,8 @@ module Axlsx
|
|
156
168
|
private
|
157
169
|
|
158
170
|
# Writes the package parts to a zip archive.
|
159
|
-
# @param [Zip::OutputStream] zip
|
160
|
-
# @return [Zip::OutputStream]
|
171
|
+
# @param [Zip::OutputStream, ZipCommand] zip
|
172
|
+
# @return [Zip::OutputStream, ZipCommand]
|
161
173
|
def write_parts(zip)
|
162
174
|
p = parts
|
163
175
|
p.each do |part|
|
@@ -167,7 +179,7 @@ module Axlsx
|
|
167
179
|
end
|
168
180
|
unless part[:path].nil?
|
169
181
|
zip.put_next_entry(zip_entry_for_part(part))
|
170
|
-
zip.write IO.read(part[:path])
|
182
|
+
zip.write IO.read(part[:path], mode: "rb")
|
171
183
|
end
|
172
184
|
end
|
173
185
|
zip
|
@@ -349,6 +361,28 @@ module Axlsx
|
|
349
361
|
rels.lock
|
350
362
|
rels
|
351
363
|
end
|
364
|
+
|
365
|
+
# Parse the arguments of `#serialize`
|
366
|
+
# @return [Boolean, (String or nil)] Returns an array where the first value is
|
367
|
+
# `confirm_valid` and the second is the `zip_command`.
|
368
|
+
# @private
|
369
|
+
def parse_serialize_options(options, secondary_options)
|
370
|
+
if secondary_options
|
371
|
+
warn "[DEPRECATION] Axlsx::Package#serialize with 3 arguments is deprecated. " +
|
372
|
+
"Use keyword args instead e.g., package.serialize(output, confirm_valid: false, zip_command: 'zip')"
|
373
|
+
end
|
374
|
+
if options.is_a?(Hash)
|
375
|
+
options.merge!(secondary_options || {})
|
376
|
+
invalid_keys = options.keys - [:confirm_valid, :zip_command]
|
377
|
+
if invalid_keys.any?
|
378
|
+
raise ArgumentError.new("Invalid keyword arguments: #{invalid_keys}")
|
379
|
+
end
|
380
|
+
[options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil)]
|
381
|
+
else
|
382
|
+
warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " +
|
383
|
+
"Use keyword args instead e.g., package.serialize(output, confirm_valid: false)"
|
384
|
+
parse_serialize_options((secondary_options || {}).merge(confirm_valid: options), nil)
|
385
|
+
end
|
386
|
+
end
|
352
387
|
end
|
353
388
|
end
|
354
|
-
|
@@ -5,32 +5,40 @@ module Axlsx
|
|
5
5
|
class Relationship
|
6
6
|
|
7
7
|
class << self
|
8
|
-
# Keeps track of
|
8
|
+
# Keeps track of relationship ids in use.
|
9
9
|
# @return [Array]
|
10
|
-
def
|
11
|
-
|
10
|
+
def ids_cache
|
11
|
+
Thread.current[:axlsx_relationship_ids_cache] ||= {}
|
12
12
|
end
|
13
|
-
|
14
|
-
#
|
13
|
+
|
14
|
+
# Initialize cached ids.
|
15
15
|
#
|
16
16
|
# This should be called before serializing a package (see {Package#serialize} and
|
17
17
|
# {Package#to_stream}) to make sure that serialization is idempotent (i.e.
|
18
18
|
# Relationship instances are generated with the same IDs everytime the package
|
19
19
|
# is serialized).
|
20
|
+
def initialize_ids_cache
|
21
|
+
Thread.current[:axlsx_relationship_ids_cache] = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clear cached ids.
|
20
25
|
#
|
21
|
-
#
|
26
|
+
# This should be called after serializing a package (see {Package#serialize} and
|
27
|
+
# {Package#to_stream}) to free the memory allocated for cache.
|
28
|
+
#
|
29
|
+
# Also, calling this avoids memory leaks (cached ids lingering around
|
22
30
|
# forever).
|
23
|
-
def
|
24
|
-
|
31
|
+
def clear_ids_cache
|
32
|
+
Thread.current[:axlsx_relationship_ids_cache] = nil
|
25
33
|
end
|
26
34
|
|
27
35
|
# Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
|
28
36
|
#
|
29
|
-
# The generated id depends on the number of cached
|
30
|
-
# {
|
37
|
+
# The generated id depends on the number of previously cached ids, so using
|
38
|
+
# {clear_ids_cache} will automatically reset the generated ids, too.
|
31
39
|
# @return [String]
|
32
40
|
def next_free_id
|
33
|
-
"rId#{
|
41
|
+
"rId#{ids_cache.size + 1}"
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
@@ -80,12 +88,7 @@ module Axlsx
|
|
80
88
|
self.Target=target
|
81
89
|
self.Type=type
|
82
90
|
self.TargetMode = options[:target_mode] if options[:target_mode]
|
83
|
-
@Id =
|
84
|
-
existing.Id
|
85
|
-
else
|
86
|
-
self.class.next_free_id
|
87
|
-
end
|
88
|
-
self.class.instances << self
|
91
|
+
@Id = (self.class.ids_cache[ids_cache_key] ||= self.class.next_free_id)
|
89
92
|
end
|
90
93
|
|
91
94
|
# @see Target
|
@@ -106,7 +109,7 @@ module Axlsx
|
|
106
109
|
str << '/>'
|
107
110
|
end
|
108
111
|
|
109
|
-
#
|
112
|
+
# A key that determines whether this relationship should use already generated id.
|
110
113
|
#
|
111
114
|
# Instances designating the same relationship need to use the same id. We can not simply
|
112
115
|
# compare the {#Target} attribute, though: `foo/bar.xml`, `../foo/bar.xml`,
|
@@ -116,13 +119,11 @@ module Axlsx
|
|
116
119
|
# then {#Target} will be an absolute URL and thus can safely be compared).
|
117
120
|
#
|
118
121
|
# @todo Implement comparison of {#Target} based on normalized path names.
|
119
|
-
# @
|
120
|
-
def
|
121
|
-
|
122
|
-
if self.TargetMode == :External
|
123
|
-
|
124
|
-
end
|
125
|
-
result
|
122
|
+
# @return [Array]
|
123
|
+
def ids_cache_key
|
124
|
+
key = [source_obj, self.Type, self.TargetMode]
|
125
|
+
key << self.Target if self.TargetMode == :External
|
126
|
+
key
|
126
127
|
end
|
127
128
|
|
128
129
|
end
|
@@ -76,7 +76,10 @@ module Axlsx
|
|
76
76
|
attr_reader :i
|
77
77
|
|
78
78
|
# Indicates if the font should be rendered underlined
|
79
|
-
#
|
79
|
+
# It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true, false
|
80
|
+
# @return [String]
|
81
|
+
# @note
|
82
|
+
# true or false is for backwards compatibility and is reassigned to :single or :none respectively
|
80
83
|
attr_reader :u
|
81
84
|
|
82
85
|
# Indicates if the font should be rendered with a strikthrough
|
@@ -118,7 +121,12 @@ module Axlsx
|
|
118
121
|
# @see i
|
119
122
|
def i=(v) Axlsx::validate_boolean v; @i = v end
|
120
123
|
# @see u
|
121
|
-
def u=(v)
|
124
|
+
def u=(v)
|
125
|
+
v = :single if (v == true || v == 1 || v == :true || v == 'true')
|
126
|
+
v = :none if (v == false || v == 0 || v == :false || v == 'false')
|
127
|
+
Axlsx::validate_cell_u v
|
128
|
+
@u = v
|
129
|
+
end
|
122
130
|
# @see strike
|
123
131
|
def strike=(v) Axlsx::validate_boolean v; @strike = v end
|
124
132
|
# @see outline
|
data/lib/axlsx/util/constants.rb
CHANGED
@@ -393,7 +393,8 @@ module Axlsx
|
|
393
393
|
ISO_8601_REGEX = /\A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z/.freeze
|
394
394
|
|
395
395
|
# FLOAT recognition
|
396
|
-
|
396
|
+
SAFE_FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]{1,2})?\Z/.freeze
|
397
|
+
MAYBE_FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+[eE](?<exp>[-+]?[0-9]{3})\Z/.freeze
|
397
398
|
|
398
399
|
# Numeric recognition
|
399
400
|
NUMERIC_REGEX = /\A[+-]?\d+?\Z/.freeze
|
@@ -92,7 +92,7 @@ module Axlsx
|
|
92
92
|
|
93
93
|
# Requires that the value is a Integer or Float and is greater or equal to 0
|
94
94
|
# @param [Any] v The value validated
|
95
|
-
# @raise [ArgumentError] raised if the value is not a
|
95
|
+
# @raise [ArgumentError] raised if the value is not a Integer, Float value greater or equal to 0
|
96
96
|
# @return [Boolean] true if the data is valid
|
97
97
|
def self.validate_unsigned_numeric(v)
|
98
98
|
DataTypeValidator.validate(:unsigned_numeric, Numeric, v, UINT_VALIDATOR)
|
@@ -269,7 +269,7 @@ module Axlsx
|
|
269
269
|
# valid types must be one of custom, data, decimal, list, none, textLength, time, whole
|
270
270
|
# @param [Any] v The value validated
|
271
271
|
def self.validate_data_validation_type(v)
|
272
|
-
RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :time, :whole], v
|
272
|
+
RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :date, :time, :whole], v
|
273
273
|
end
|
274
274
|
|
275
275
|
# Requires that the value is a valid sheet view type.
|