write_xlsx 0.72.2 → 0.72.3.beta1
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/{README.rdoc → Changes} +3 -94
- data/README.md +96 -0
- data/lib/write_xlsx/chart.rb +115 -259
- data/lib/write_xlsx/chart/axis.rb +4 -4
- data/lib/write_xlsx/chart/bar.rb +1 -1
- data/lib/write_xlsx/chart/column.rb +1 -1
- data/lib/write_xlsx/chart/pie.rb +3 -3
- data/lib/write_xlsx/chart/radar.rb +1 -1
- data/lib/write_xlsx/chart/scatter.rb +1 -1
- data/lib/write_xlsx/chart/series.rb +0 -37
- data/lib/write_xlsx/chartsheet.rb +25 -37
- data/lib/write_xlsx/col_name.rb +40 -0
- data/lib/write_xlsx/drawing.rb +95 -85
- data/lib/write_xlsx/format.rb +32 -32
- data/lib/write_xlsx/package/app.rb +18 -23
- data/lib/write_xlsx/package/button.rb +15 -12
- data/lib/write_xlsx/package/comments.rb +33 -30
- data/lib/write_xlsx/package/conditional_format.rb +18 -14
- data/lib/write_xlsx/package/content_types.rb +22 -17
- data/lib/write_xlsx/package/core.rb +19 -24
- data/lib/write_xlsx/package/relationships.rb +10 -13
- data/lib/write_xlsx/package/shared_strings.rb +8 -16
- data/lib/write_xlsx/package/styles.rb +59 -64
- data/lib/write_xlsx/package/table.rb +27 -37
- data/lib/write_xlsx/package/vml.rb +23 -21
- data/lib/write_xlsx/package/xml_writer_simple.rb +3 -6
- data/lib/write_xlsx/sheets.rb +4 -4
- data/lib/write_xlsx/sparkline.rb +22 -22
- data/lib/write_xlsx/utility.rb +61 -33
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +46 -50
- data/lib/write_xlsx/worksheet.rb +149 -133
- data/lib/write_xlsx/worksheet/cell_data.rb +8 -6
- data/lib/write_xlsx/worksheet/data_validation.rb +14 -14
- data/lib/write_xlsx/worksheet/hyperlink.rb +97 -65
- data/lib/write_xlsx/worksheet/page_setup.rb +23 -22
- data/test/chart/test_write_a_latin.rb +3 -3
- data/test/regression/test_chart_font01.rb +1 -1
- data/test/regression/test_chart_font02.rb +1 -1
- data/test/regression/test_chart_font03.rb +1 -1
- data/test/regression/test_chart_font04.rb +1 -1
- data/test/regression/test_chart_font05.rb +1 -1
- data/test/regression/test_chart_font06.rb +1 -1
- data/test/test_xml_writer_simple.rb +3 -3
- data/test/worksheet/test_write_hyperlink.rb +4 -4
- data/test/worksheet/test_write_worksheet_attributes.rb +3 -3
- data/write_xlsx.gemspec +2 -1
- metadata +9 -8
- data/test/package/table/test_write_xml_declaration.rb +0 -20
@@ -14,17 +14,19 @@ class CellData # :nodoc:
|
|
14
14
|
#
|
15
15
|
def cell_attributes #:nodoc:
|
16
16
|
xf_index = xf ? xf.get_xf_index : 0
|
17
|
-
attributes = [
|
17
|
+
attributes = [
|
18
|
+
['r', xl_rowcol_to_cell(row, col)]
|
19
|
+
]
|
18
20
|
|
19
21
|
# Add the cell format index.
|
20
22
|
if xf_index != 0
|
21
|
-
attributes << 's'
|
23
|
+
attributes << ['s', xf_index]
|
22
24
|
elsif @worksheet.set_rows[row] && @worksheet.set_rows[row][1]
|
23
25
|
row_xf = @worksheet.set_rows[row][1]
|
24
|
-
attributes << 's'
|
26
|
+
attributes << ['s', row_xf.get_xf_index]
|
25
27
|
elsif @worksheet.col_formats[col]
|
26
28
|
col_xf = @worksheet.col_formats[col]
|
27
|
-
attributes << 's'
|
29
|
+
attributes << ['s', col_xf.get_xf_index]
|
28
30
|
end
|
29
31
|
attributes
|
30
32
|
end
|
@@ -63,7 +65,7 @@ def data
|
|
63
65
|
|
64
66
|
def write_cell
|
65
67
|
attributes = cell_attributes
|
66
|
-
attributes << 't'
|
68
|
+
attributes << ['t', 's']
|
67
69
|
@worksheet.writer.tag_elements('c', attributes) do
|
68
70
|
@worksheet.write_cell_value(token)
|
69
71
|
end
|
@@ -87,7 +89,7 @@ def data
|
|
87
89
|
def write_cell
|
88
90
|
attributes = cell_attributes
|
89
91
|
if @result && !(@result.to_s =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
|
90
|
-
attributes << 't'
|
92
|
+
attributes << ['t', 'str']
|
91
93
|
end
|
92
94
|
@worksheet.writer.tag_elements('c', attributes) do
|
93
95
|
@worksheet.write_cell_formula(token)
|
@@ -128,23 +128,23 @@ def attributes
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
attributes << 'type'
|
132
|
-
attributes << 'operator'
|
131
|
+
attributes << ['type', @validate]
|
132
|
+
attributes << ['operator', @criteria] if @criteria != 'between'
|
133
133
|
|
134
134
|
if @error_type
|
135
|
-
attributes << 'errorStyle'
|
136
|
-
attributes << 'errorStyle'
|
135
|
+
attributes << ['errorStyle', 'warning'] if @error_type == 1
|
136
|
+
attributes << ['errorStyle', 'information'] if @error_type == 2
|
137
137
|
end
|
138
|
-
attributes << 'allowBlank'
|
139
|
-
attributes << 'showDropDown'
|
140
|
-
attributes << 'showInputMessage'
|
141
|
-
attributes << 'showErrorMessage'
|
142
|
-
|
143
|
-
attributes << 'errorTitle'
|
144
|
-
attributes << 'error'
|
145
|
-
attributes << 'promptTitle'
|
146
|
-
attributes << 'prompt'
|
147
|
-
attributes << 'sqref'
|
138
|
+
attributes << ['allowBlank', 1] if @ignore_blank != 0
|
139
|
+
attributes << ['showDropDown', 1] if @dropdown == 0
|
140
|
+
attributes << ['showInputMessage', 1] if @show_input != 0
|
141
|
+
attributes << ['showErrorMessage', 1] if @show_error != 0
|
142
|
+
|
143
|
+
attributes << ['errorTitle', @error_title] if @error_title
|
144
|
+
attributes << ['error', @error_message] if @error_message
|
145
|
+
attributes << ['promptTitle', @input_title] if @input_title
|
146
|
+
attributes << ['prompt', @input_message] if @input_message
|
147
|
+
attributes << ['sqref', sqref]
|
148
148
|
end
|
149
149
|
|
150
150
|
def has_key?(key)
|
@@ -8,104 +8,136 @@ class Hyperlink # :nodoc:
|
|
8
8
|
attr_reader :url, :link_type, :str, :url_str
|
9
9
|
attr_accessor :tip, :display
|
10
10
|
|
11
|
-
def
|
12
|
-
link_type = 1
|
13
|
-
|
14
|
-
# Remove the URI scheme from internal links.
|
11
|
+
def self.factory(url, str = nil)
|
15
12
|
if url =~ /^internal:/
|
16
|
-
|
17
|
-
link_type = 2
|
18
|
-
# Remove the URI scheme from external links.
|
13
|
+
InternalHyperlink.new(url, str)
|
19
14
|
elsif url =~ /^external:/
|
20
|
-
|
21
|
-
|
15
|
+
ExternalHyperlink.new(url, str)
|
16
|
+
else
|
17
|
+
new(url, str)
|
22
18
|
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(url, str = nil)
|
22
|
+
@link_type = 1
|
23
23
|
|
24
24
|
# The displayed string defaults to the url string.
|
25
25
|
str ||= url.dup
|
26
26
|
|
27
|
-
# For external links change the directory separator from Unix to Dos.
|
28
|
-
if link_type == 3
|
29
|
-
url = url.gsub(%r|/|, '\\')
|
30
|
-
str.gsub!(%r|/|, '\\')
|
31
|
-
end
|
32
|
-
|
33
27
|
# Strip the mailto header.
|
34
28
|
str.sub!(/^mailto:/, '')
|
35
29
|
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# different characteristics that we have to account for.
|
41
|
-
if link_type == 1
|
42
|
-
# Escape URL unless it looks already escaped.
|
43
|
-
unless url =~ /%[0-9a-fA-F]{2}/
|
44
|
-
# Escape the URL escape symbol.
|
45
|
-
url = url.gsub(/%/, "%25")
|
46
|
-
|
47
|
-
# Escape whitespae in URL.
|
48
|
-
url = url.gsub(/[\s\x00]/, '%20')
|
49
|
-
|
50
|
-
# Escape other special characters in URL.
|
51
|
-
re = /(["<>\[\]`^{}])/
|
52
|
-
while re =~ url
|
53
|
-
match = $~[1]
|
54
|
-
url = url.sub(re, sprintf("%%%x", match.ord))
|
55
|
-
end
|
56
|
-
end
|
30
|
+
# Escape URL unless it looks already escaped.
|
31
|
+
unless url =~ /%[0-9a-fA-F]{2}/
|
32
|
+
# Escape the URL escape symbol.
|
33
|
+
url = url.gsub(/%/, "%25")
|
57
34
|
|
58
|
-
#
|
59
|
-
|
60
|
-
elsif link_type == 3
|
61
|
-
# External Workbook links need to be modified into the right format.
|
62
|
-
# The URL will look something like 'c:\temp\file.xlsx#Sheet!A1'.
|
63
|
-
# We need the part to the left of the # as the URL and the part to
|
64
|
-
# the right as the "location" string (if it exists).
|
65
|
-
url, url_str = url.split(/#/)
|
66
|
-
|
67
|
-
# Add the file:/// URI to the url if non-local.
|
68
|
-
if url =~ %r![:]! || # Windows style "C:/" link.
|
69
|
-
url =~ %r!^\\\\! # Network share.
|
70
|
-
url = "file:///#{url}"
|
71
|
-
end
|
72
|
-
|
73
|
-
# Convert a ./dir/file.xlsx link to dir/file.xlsx.
|
74
|
-
url = url.sub(%r!^.\\!, '')
|
35
|
+
# Escape whitespae in URL.
|
36
|
+
url = url.gsub(/[\s\x00]/, '%20')
|
75
37
|
|
76
|
-
#
|
77
|
-
|
38
|
+
# Escape other special characters in URL.
|
39
|
+
re = /(["<>\[\]`^{}])/
|
40
|
+
while re =~ url
|
41
|
+
match = $~[1]
|
42
|
+
url = url.sub(re, sprintf("%%%x", match.ord))
|
43
|
+
end
|
78
44
|
end
|
79
45
|
|
80
46
|
# Excel limits escaped URL to 255 characters.
|
81
47
|
if url.bytesize > 255
|
82
48
|
raise "URL '#{url}' > 255 characters, it exceeds Excel's limit for URLS."
|
83
49
|
end
|
50
|
+
|
84
51
|
@url = url
|
85
|
-
@link_type = link_type
|
86
52
|
@str = str
|
87
|
-
@url_str =
|
53
|
+
@url_str = nil
|
88
54
|
end
|
89
55
|
|
90
56
|
def write_external_attributes(row, col, id)
|
91
57
|
ref = xl_rowcol_to_cell(row, col)
|
92
58
|
|
93
|
-
attributes = ['ref', ref]
|
94
|
-
attributes
|
59
|
+
attributes = [ ['ref', ref] ]
|
60
|
+
attributes << r_id_attributes(id)
|
95
61
|
|
96
|
-
attributes << 'location'
|
97
|
-
attributes << 'display'
|
98
|
-
attributes << 'tooltip'
|
62
|
+
attributes << ['location', url_str] if url_str
|
63
|
+
attributes << ['display', display] if display
|
64
|
+
attributes << ['tooltip', tip] if tip
|
99
65
|
attributes
|
100
66
|
end
|
101
67
|
|
102
68
|
def write_internal_attributes(row, col)
|
103
69
|
ref = xl_rowcol_to_cell(row, col)
|
104
70
|
|
105
|
-
attributes = [
|
71
|
+
attributes = [
|
72
|
+
['ref', ref],
|
73
|
+
['location', url]
|
74
|
+
]
|
75
|
+
|
76
|
+
attributes << ['tooltip', tip] if tip
|
77
|
+
attributes << ['display', str]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class InternalHyperlink < Hyperlink
|
82
|
+
def initialize(url, str)
|
83
|
+
@link_type = 2
|
84
|
+
@url = url.sub(/^internal:/, '')
|
85
|
+
|
86
|
+
# The displayed string defaults to the url string.
|
87
|
+
str ||= @url.dup
|
88
|
+
|
89
|
+
# Strip the mailto header.
|
90
|
+
@str = str.sub(/^mailto:/, '')
|
91
|
+
|
92
|
+
# Copy string for use in hyperlink elements.
|
93
|
+
@url_str = @str.dup
|
94
|
+
|
95
|
+
# Excel limits escaped URL to 255 characters.
|
96
|
+
if @url.bytesize > 255
|
97
|
+
raise "URL '#{@url}' > 255 characters, it exceeds Excel's limit for URLS."
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class ExternalHyperlink < Hyperlink
|
103
|
+
def initialize(url, str = nil)
|
104
|
+
@link_type = 1
|
105
|
+
|
106
|
+
# Remove the URI scheme from internal links.
|
107
|
+
url = url.sub(/^external:/, '')
|
108
|
+
|
109
|
+
# The displayed string defaults to the url string.
|
110
|
+
str ||= url.dup
|
106
111
|
|
107
|
-
|
108
|
-
|
112
|
+
# For external links change the directory separator from Unix to Dos.
|
113
|
+
url = url.gsub(%r|/|, '\\')
|
114
|
+
str.gsub!(%r|/|, '\\')
|
115
|
+
|
116
|
+
# Strip the mailto header.
|
117
|
+
str.sub!(/^mailto:/, '')
|
118
|
+
|
119
|
+
# External Workbook links need to be modified into the right format.
|
120
|
+
# The URL will look something like 'c:\temp\file.xlsx#Sheet!A1'.
|
121
|
+
# We need the part to the left of the # as the URL and the part to
|
122
|
+
# the right as the "location" string (if it exists).
|
123
|
+
url, url_str = url.split(/#/)
|
124
|
+
|
125
|
+
# Add the file:/// URI to the url if non-local.
|
126
|
+
if url =~ %r![:]! || # Windows style "C:/" link.
|
127
|
+
url =~ %r!^\\\\! # Network share.
|
128
|
+
url = "file:///#{url}"
|
129
|
+
end
|
130
|
+
|
131
|
+
# Convert a ./dir/file.xlsx link to dir/file.xlsx.
|
132
|
+
url = url.sub(%r!^.\\!, '')
|
133
|
+
|
134
|
+
# Excel limits escaped URL to 255 characters.
|
135
|
+
if url.bytesize > 255
|
136
|
+
raise "URL '#{url}' > 255 characters, it exceeds Excel's limit for URLS."
|
137
|
+
end
|
138
|
+
@url = url
|
139
|
+
@str = str
|
140
|
+
@url_str = url_str
|
109
141
|
end
|
110
142
|
end
|
111
143
|
end
|
@@ -95,18 +95,19 @@ def write_page_setup(writer) #:nodoc:
|
|
95
95
|
return unless @page_setup_changed
|
96
96
|
|
97
97
|
attributes = []
|
98
|
-
attributes << 'paperSize'
|
99
|
-
attributes << 'scale'
|
100
|
-
attributes << 'fitToWidth'
|
101
|
-
attributes << 'fitToHeight'
|
102
|
-
attributes << 'pageOrder'
|
103
|
-
attributes << 'orientation'
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
98
|
+
attributes << ['paperSize', @paper_size] if @paper_size
|
99
|
+
attributes << ['scale', @scale] if @scale != 100
|
100
|
+
attributes << ['fitToWidth', @fit_width] if @fit_page && @fit_width != 1
|
101
|
+
attributes << ['fitToHeight', @fit_height] if @fit_page && @fit_height != 1
|
102
|
+
attributes << ['pageOrder', "overThenDown"] if @across
|
103
|
+
attributes << ['orientation',
|
104
|
+
if @orientation
|
105
|
+
'portrait'
|
106
|
+
else
|
107
|
+
'landscape'
|
108
|
+
end
|
109
|
+
]
|
110
|
+
attributes << ['useFirstPageNumber', @page_start] if ptrue?(@page_start)
|
110
111
|
|
111
112
|
writer.empty_tag('pageSetup', attributes)
|
112
113
|
end
|
@@ -125,10 +126,10 @@ def write_print_options(writer) #:nodoc:
|
|
125
126
|
return unless @print_options_changed
|
126
127
|
|
127
128
|
attributes = []
|
128
|
-
attributes << 'horizontalCentered'
|
129
|
-
attributes << 'verticalCentered'
|
130
|
-
attributes << 'headings'
|
131
|
-
attributes << 'gridLines'
|
129
|
+
attributes << ['horizontalCentered', 1] if @hcenter
|
130
|
+
attributes << ['verticalCentered', 1] if @vcenter
|
131
|
+
attributes << ['headings', 1] if @print_headers
|
132
|
+
attributes << ['gridLines', 1] if @print_gridlines
|
132
133
|
writer.empty_tag('printOptions', attributes)
|
133
134
|
end
|
134
135
|
|
@@ -162,12 +163,12 @@ def write_odd_footer(writer) #:nodoc:
|
|
162
163
|
|
163
164
|
def margin_attributes # :nodoc:
|
164
165
|
[
|
165
|
-
'left', @margin_left,
|
166
|
-
'right', @margin_right,
|
167
|
-
'top', @margin_top,
|
168
|
-
'bottom', @margin_bottom,
|
169
|
-
'header', @margin_header,
|
170
|
-
'footer', @margin_footer
|
166
|
+
['left', @margin_left],
|
167
|
+
['right', @margin_right],
|
168
|
+
['top', @margin_top],
|
169
|
+
['bottom', @margin_bottom],
|
170
|
+
['header', @margin_header],
|
171
|
+
['footer', @margin_footer]
|
171
172
|
]
|
172
173
|
end
|
173
174
|
end
|
@@ -32,7 +32,7 @@ def test_start_end_tag
|
|
32
32
|
|
33
33
|
def test_attribute
|
34
34
|
assert_equal(
|
35
|
-
"<foo x=\"1>2\"/>", @obj.empty_tag("foo", ['x', '1>2'])
|
35
|
+
"<foo x=\"1>2\"/>", @obj.empty_tag("foo", [ ['x', '1>2'] ])
|
36
36
|
)
|
37
37
|
end
|
38
38
|
|
@@ -52,8 +52,8 @@ def test_data_element_with_empty_attr
|
|
52
52
|
|
53
53
|
def test_data_element
|
54
54
|
attributes = [
|
55
|
-
'name', '_xlnm.Print_Titles',
|
56
|
-
'localSheetId', 0
|
55
|
+
['name', '_xlnm.Print_Titles'],
|
56
|
+
['localSheetId', 0]
|
57
57
|
]
|
58
58
|
expected =
|
59
59
|
"<definedName name=\"_xlnm.Print_Titles\" localSheetId=\"0\">Sheet1!$1:$1</definedName>"
|
@@ -10,7 +10,7 @@ def setup
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_write_hyperlink_external
|
13
|
-
hyperlink = Writexlsx::Worksheet::Hyperlink.
|
13
|
+
hyperlink = Writexlsx::Worksheet::Hyperlink.factory('')
|
14
14
|
@worksheet.__send__('write_hyperlink_external', hyperlink, 0, 0, 1)
|
15
15
|
result = @worksheet.instance_variable_get(:@writer).string
|
16
16
|
expected = '<hyperlink ref="A1" r:id="rId1"/>'
|
@@ -18,7 +18,7 @@ def test_write_hyperlink_external
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_write_hyperlink_internal_sheet2
|
21
|
-
hyperlink = Writexlsx::Worksheet::Hyperlink.
|
21
|
+
hyperlink = Writexlsx::Worksheet::Hyperlink.factory('internal:Sheet2!A1', 'Sheet2!A1')
|
22
22
|
@worksheet.__send__('write_hyperlink_internal', hyperlink, 0, 0)
|
23
23
|
result = @worksheet.instance_variable_get(:@writer).string
|
24
24
|
expected = '<hyperlink ref="A1" location="Sheet2!A1" display="Sheet2!A1"/>'
|
@@ -26,7 +26,7 @@ def test_write_hyperlink_internal_sheet2
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_write_hyperlink_internal_quoted_sheet
|
29
|
-
hyperlink = Writexlsx::Worksheet::Hyperlink.
|
29
|
+
hyperlink = Writexlsx::Worksheet::Hyperlink.factory("internal:'Data Sheet'!D5", "'Data Sheet'!D5")
|
30
30
|
@worksheet.__send__('write_hyperlink_internal', hyperlink, 4, 0)
|
31
31
|
result = @worksheet.instance_variable_get(:@writer).string
|
32
32
|
expected = %q{<hyperlink ref="A5" location="'Data Sheet'!D5" display="'Data Sheet'!D5"/>}
|
@@ -34,7 +34,7 @@ def test_write_hyperlink_internal_quoted_sheet
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_write_hyperlink_internal_tooltip
|
37
|
-
hyperlink = Writexlsx::Worksheet::Hyperlink.
|
37
|
+
hyperlink = Writexlsx::Worksheet::Hyperlink.factory('internal:Sheet2!A1', 'Sheet2!A1')
|
38
38
|
hyperlink.tip = 'Screen Tip 1'
|
39
39
|
@worksheet.__send__('write_hyperlink_internal', hyperlink, 17, 0)
|
40
40
|
result = @worksheet.instance_variable_get(:@writer).string
|