caxlsx 3.4.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +11 -12
- data/Rakefile +7 -5
- data/lib/axlsx/content_type/abstract_content_type.rb +9 -4
- data/lib/axlsx/content_type/content_type.rb +7 -5
- data/lib/axlsx/content_type/default.rb +4 -2
- data/lib/axlsx/content_type/override.rb +4 -2
- data/lib/axlsx/doc_props/app.rb +26 -24
- data/lib/axlsx/doc_props/core.rb +8 -6
- data/lib/axlsx/drawing/area_chart.rb +10 -8
- data/lib/axlsx/drawing/area_series.rb +12 -10
- data/lib/axlsx/drawing/ax_data_source.rb +2 -0
- data/lib/axlsx/drawing/axes.rb +6 -4
- data/lib/axlsx/drawing/axis.rb +21 -19
- data/lib/axlsx/drawing/bar_3D_chart.rb +14 -12
- data/lib/axlsx/drawing/bar_chart.rb +13 -11
- data/lib/axlsx/drawing/bar_series.rb +8 -6
- data/lib/axlsx/drawing/bubble_chart.rb +6 -4
- data/lib/axlsx/drawing/bubble_series.rb +8 -6
- data/lib/axlsx/drawing/cat_axis.rb +12 -10
- data/lib/axlsx/drawing/chart.rb +20 -18
- data/lib/axlsx/drawing/d_lbls.rb +7 -5
- data/lib/axlsx/drawing/drawing.rb +58 -56
- data/lib/axlsx/drawing/graphic_frame.rb +6 -4
- data/lib/axlsx/drawing/hyperlink.rb +10 -8
- data/lib/axlsx/drawing/line_3D_chart.rb +7 -5
- data/lib/axlsx/drawing/line_chart.rb +10 -8
- data/lib/axlsx/drawing/line_series.rb +12 -10
- data/lib/axlsx/drawing/marker.rb +9 -7
- data/lib/axlsx/drawing/num_data.rb +9 -7
- data/lib/axlsx/drawing/num_data_source.rb +9 -7
- data/lib/axlsx/drawing/num_val.rb +7 -5
- data/lib/axlsx/drawing/one_cell_anchor.rb +7 -5
- data/lib/axlsx/drawing/pic.rb +16 -14
- data/lib/axlsx/drawing/picture_locking.rb +3 -1
- data/lib/axlsx/drawing/pie_3D_chart.rb +5 -3
- data/lib/axlsx/drawing/pie_series.rb +8 -6
- data/lib/axlsx/drawing/scaling.rb +8 -6
- data/lib/axlsx/drawing/scatter_chart.rb +7 -5
- data/lib/axlsx/drawing/scatter_series.rb +14 -12
- data/lib/axlsx/drawing/ser_axis.rb +7 -5
- data/lib/axlsx/drawing/series.rb +6 -4
- data/lib/axlsx/drawing/series_title.rb +6 -4
- data/lib/axlsx/drawing/str_data.rb +7 -5
- data/lib/axlsx/drawing/str_val.rb +6 -4
- data/lib/axlsx/drawing/title.rb +13 -14
- data/lib/axlsx/drawing/two_cell_anchor.rb +4 -2
- data/lib/axlsx/drawing/val_axis.rb +4 -2
- data/lib/axlsx/drawing/view_3D.rb +9 -7
- data/lib/axlsx/drawing/vml_drawing.rb +18 -16
- data/lib/axlsx/drawing/vml_shape.rb +24 -22
- data/lib/axlsx/package.rb +69 -66
- data/lib/axlsx/rels/relationship.rb +10 -5
- data/lib/axlsx/rels/relationships.rb +5 -3
- data/lib/axlsx/stylesheet/border.rb +6 -4
- data/lib/axlsx/stylesheet/border_pr.rb +5 -3
- data/lib/axlsx/stylesheet/cell_alignment.rb +12 -10
- data/lib/axlsx/stylesheet/cell_protection.rb +5 -3
- data/lib/axlsx/stylesheet/cell_style.rb +10 -8
- data/lib/axlsx/stylesheet/color.rb +9 -7
- data/lib/axlsx/stylesheet/dxf.rb +5 -3
- data/lib/axlsx/stylesheet/fill.rb +3 -1
- data/lib/axlsx/stylesheet/font.rb +18 -16
- data/lib/axlsx/stylesheet/gradient_fill.rb +6 -4
- data/lib/axlsx/stylesheet/gradient_stop.rb +6 -4
- data/lib/axlsx/stylesheet/num_fmt.rb +8 -10
- data/lib/axlsx/stylesheet/pattern_fill.rb +5 -3
- data/lib/axlsx/stylesheet/styles.rb +69 -71
- data/lib/axlsx/stylesheet/table_style.rb +7 -5
- data/lib/axlsx/stylesheet/table_style_element.rb +6 -4
- data/lib/axlsx/stylesheet/table_styles.rb +6 -4
- data/lib/axlsx/stylesheet/xf.rb +18 -16
- data/lib/axlsx/util/accessors.rb +4 -2
- data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
- data/lib/axlsx/util/constants.rb +117 -104
- data/lib/axlsx/util/mime_type_utils.rb +3 -5
- data/lib/axlsx/util/options_parser.rb +3 -1
- data/lib/axlsx/util/serialized_attributes.rb +42 -17
- data/lib/axlsx/util/simple_typed_list.rb +47 -47
- data/lib/axlsx/util/storage.rb +11 -10
- data/lib/axlsx/util/validators.rb +101 -41
- data/lib/axlsx/util/zip_command.rb +10 -10
- data/lib/axlsx/version.rb +3 -1
- data/lib/axlsx/workbook/defined_name.rb +6 -4
- data/lib/axlsx/workbook/defined_names.rb +3 -1
- data/lib/axlsx/workbook/shared_strings_table.rb +8 -6
- data/lib/axlsx/workbook/workbook.rb +78 -76
- data/lib/axlsx/workbook/workbook_view.rb +3 -1
- data/lib/axlsx/workbook/workbook_views.rb +3 -1
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +65 -8
- data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +7 -3
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +11 -7
- data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +51 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +56 -0
- data/lib/axlsx/workbook/worksheet/border_creator.rb +5 -3
- data/lib/axlsx/workbook/worksheet/break.rb +3 -1
- data/lib/axlsx/workbook/worksheet/cell.rb +55 -48
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +31 -27
- data/lib/axlsx/workbook/worksheet/cfvo.rb +5 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +3 -1
- data/lib/axlsx/workbook/worksheet/col.rb +5 -3
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +5 -3
- data/lib/axlsx/workbook/worksheet/color_scale.rb +12 -10
- data/lib/axlsx/workbook/worksheet/cols.rb +3 -1
- data/lib/axlsx/workbook/worksheet/comment.rb +8 -6
- data/lib/axlsx/workbook/worksheet/comments.rb +6 -4
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +9 -4
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +18 -16
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +3 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +14 -13
- data/lib/axlsx/workbook/worksheet/data_validation.rb +30 -28
- data/lib/axlsx/workbook/worksheet/data_validations.rb +3 -1
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +7 -5
- data/lib/axlsx/workbook/worksheet/dimension.rb +4 -2
- data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -2
- data/lib/axlsx/workbook/worksheet/icon_set.rb +23 -6
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +5 -5
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -2
- data/lib/axlsx/workbook/worksheet/page_margins.rb +15 -10
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -2
- data/lib/axlsx/workbook/worksheet/page_setup.rb +11 -9
- data/lib/axlsx/workbook/worksheet/pane.rb +11 -9
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +20 -19
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +8 -6
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +2 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +3 -1
- data/lib/axlsx/workbook/worksheet/protected_range.rb +3 -1
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -3
- data/lib/axlsx/workbook/worksheet/rich_text.rb +3 -1
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +16 -14
- data/lib/axlsx/workbook/worksheet/row.rb +6 -7
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +6 -4
- data/lib/axlsx/workbook/worksheet/selection.rb +9 -7
- data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +6 -2
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
- data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +6 -2
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +8 -4
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +10 -8
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +15 -13
- data/lib/axlsx/workbook/worksheet/table.rb +9 -7
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +4 -2
- data/lib/axlsx/workbook/worksheet/tables.rb +3 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +38 -37
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -2
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +8 -2
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +6 -4
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +4 -2
- data/lib/axlsx.rb +56 -42
- data/lib/caxlsx.rb +3 -1
- metadata +49 -43
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# the SheetCalcPr object for the worksheet
|
3
5
|
# This object contains calculation properties for the worksheet.
|
@@ -21,8 +23,10 @@ module Axlsx
|
|
21
23
|
# @param [String] str the string to append this objects serialized
|
22
24
|
# content to.
|
23
25
|
# @return [String]
|
24
|
-
def to_xml_string(str = '')
|
25
|
-
str <<
|
26
|
+
def to_xml_string(str = +'')
|
27
|
+
str << '<sheetCalcPr '
|
28
|
+
serialized_attributes(str)
|
29
|
+
str << '/>'
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# This class manages the serialization of rows for worksheets
|
3
5
|
class SheetData
|
@@ -14,7 +16,7 @@ module Axlsx
|
|
14
16
|
# Serialize the sheet data
|
15
17
|
# @param [String] str the string this objects serializaton will be concacted to.
|
16
18
|
# @return [String]
|
17
|
-
def to_xml_string(str = '')
|
19
|
+
def to_xml_string(str = +'')
|
18
20
|
str << '<sheetData>'
|
19
21
|
worksheet.rows.each_with_index do |row, index|
|
20
22
|
row.to_xml_string(index, str)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# Sheet formatting properties
|
3
5
|
# <xsd:complexType name="CT_SheetFormatPr">
|
@@ -46,8 +48,10 @@ module Axlsx
|
|
46
48
|
# serializes this object to an xml string
|
47
49
|
# @param [String] str The string this objects serialization will be appended to
|
48
50
|
# @return [String]
|
49
|
-
def to_xml_string(str = '')
|
50
|
-
str <<
|
51
|
+
def to_xml_string(str = +'')
|
52
|
+
str << '<sheetFormatPr '
|
53
|
+
serialized_attributes(str)
|
54
|
+
str << '/>'
|
51
55
|
end
|
52
56
|
|
53
57
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# The SheetPr class manages serialization of a worksheet's sheetPr element.
|
3
5
|
class SheetPr
|
@@ -48,9 +50,11 @@ module Axlsx
|
|
48
50
|
# Serialize the object
|
49
51
|
# @param [String] str serialized output will be appended to this object if provided.
|
50
52
|
# @return [String]
|
51
|
-
def to_xml_string(str = '')
|
53
|
+
def to_xml_string(str = +'')
|
52
54
|
update_properties
|
53
|
-
str <<
|
55
|
+
str << '<sheetPr '
|
56
|
+
serialized_attributes(str)
|
57
|
+
str << '>'
|
54
58
|
tab_color.to_xml_string(str, 'tabColor') if tab_color
|
55
59
|
outline_pr.to_xml_string(str) if @outline_pr
|
56
60
|
page_setup_pr.to_xml_string(str)
|
@@ -71,14 +75,14 @@ module Axlsx
|
|
71
75
|
|
72
76
|
# @see tab_color
|
73
77
|
def tab_color=(v)
|
74
|
-
@tab_color = Color.new(:
|
78
|
+
@tab_color = Color.new(rgb: v)
|
75
79
|
end
|
76
80
|
|
77
81
|
private
|
78
82
|
|
79
83
|
def update_properties
|
80
84
|
page_setup_pr.fit_to_page = worksheet.fit_to_page?
|
81
|
-
|
85
|
+
unless worksheet.auto_filter.columns.empty?
|
82
86
|
self.filter_mode = 1
|
83
87
|
self.enable_format_conditions_calculation = 1
|
84
88
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# The SheetProtection object manages worksheet protection options per sheet.
|
3
5
|
class SheetProtection
|
@@ -65,7 +67,7 @@ module Axlsx
|
|
65
67
|
|
66
68
|
# encodes password for protection locking
|
67
69
|
def password=(v)
|
68
|
-
return if v
|
70
|
+
return if v.nil?
|
69
71
|
|
70
72
|
@password = create_password_hash(v)
|
71
73
|
end
|
@@ -73,7 +75,7 @@ module Axlsx
|
|
73
75
|
# Serialize the object
|
74
76
|
# @param [String] str
|
75
77
|
# @return [String]
|
76
|
-
def to_xml_string(str = '')
|
78
|
+
def to_xml_string(str = +'')
|
77
79
|
serialized_tag('sheetProtection', str)
|
78
80
|
end
|
79
81
|
|
@@ -85,27 +87,27 @@ module Axlsx
|
|
85
87
|
encoded_password = encode_password(password)
|
86
88
|
|
87
89
|
password_as_hex = [encoded_password].pack("v")
|
88
|
-
password_as_string = password_as_hex.
|
90
|
+
password_as_string = password_as_hex.unpack1("H*").upcase
|
89
91
|
|
90
92
|
password_as_string[2..3] + password_as_string[0..1]
|
91
93
|
end
|
92
94
|
|
93
95
|
# Encodes a given password
|
94
96
|
# Based on the algorithm provided by Daniel Rentz of OpenOffice.
|
95
|
-
#
|
97
|
+
# https://www.openoffice.org/sc/excelfileformat.pdf, Revision 1.42, page 115 (21.05.2012)
|
96
98
|
# @return [String]
|
97
99
|
def encode_password(password)
|
98
100
|
i = 0
|
99
|
-
chars = password.
|
101
|
+
chars = password.chars
|
100
102
|
count = chars.size
|
101
103
|
|
102
104
|
chars.collect! do |char|
|
103
105
|
i += 1
|
104
|
-
char = char.
|
106
|
+
char = char.unpack1('c') << i # ord << i
|
105
107
|
low_15 = char & 0x7fff
|
106
|
-
high_15 = char & 0x7fff << 15
|
108
|
+
high_15 = char & (0x7fff << 15)
|
107
109
|
high_15 = high_15 >> 15
|
108
|
-
|
110
|
+
low_15 | high_15
|
109
111
|
end
|
110
112
|
|
111
113
|
encoded_password = 0x0000
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# View options for a worksheet.
|
3
5
|
#
|
@@ -48,7 +50,7 @@ module Axlsx
|
|
48
50
|
:view, :top_left_cell, :color_id, :zoom_scale
|
49
51
|
|
50
52
|
# instance values that must be serialized as their own elements - e.g. not attributes.
|
51
|
-
CHILD_ELEMENTS = [:pane, :selections]
|
53
|
+
CHILD_ELEMENTS = [:pane, :selections].freeze
|
52
54
|
|
53
55
|
# The pane object for the sheet view
|
54
56
|
# @return [Pane]
|
@@ -156,47 +158,47 @@ module Axlsx
|
|
156
158
|
# param [Hash] options
|
157
159
|
# return [Selection]
|
158
160
|
def add_selection(pane, options = {})
|
159
|
-
@selections[pane] = Selection.new(options.merge(:
|
161
|
+
@selections[pane] = Selection.new(options.merge(pane: pane))
|
160
162
|
end
|
161
163
|
|
162
164
|
# @see color_id
|
163
|
-
def color_id=(v); Axlsx
|
165
|
+
def color_id=(v); Axlsx.validate_unsigned_int(v); @color_id = v end
|
164
166
|
|
165
167
|
# @see top_left_cell
|
166
168
|
def top_left_cell=(v)
|
167
|
-
cell = (v.
|
168
|
-
Axlsx
|
169
|
+
cell = (v.instance_of?(Axlsx::Cell) ? v.r_abs : v)
|
170
|
+
Axlsx.validate_string(cell)
|
169
171
|
@top_left_cell = cell
|
170
172
|
end
|
171
173
|
|
172
174
|
# @see view
|
173
|
-
def view=(v); Axlsx
|
175
|
+
def view=(v); Axlsx.validate_sheet_view_type(v); @view = v end
|
174
176
|
|
175
177
|
# @see workbook_view_id
|
176
|
-
def workbook_view_id=(v); Axlsx
|
178
|
+
def workbook_view_id=(v); Axlsx.validate_unsigned_int(v); @workbook_view_id = v end
|
177
179
|
|
178
180
|
# @see zoom_scale
|
179
|
-
def zoom_scale=(v); Axlsx
|
181
|
+
def zoom_scale=(v); Axlsx.validate_scale_0_10_400(v); @zoom_scale = v end
|
180
182
|
|
181
183
|
# @see zoom_scale_normal
|
182
|
-
def zoom_scale_normal=(v); Axlsx
|
184
|
+
def zoom_scale_normal=(v); Axlsx.validate_scale_0_10_400(v); @zoom_scale_normal = v end
|
183
185
|
|
184
186
|
# @see zoom_scale_page_layout_view
|
185
|
-
def zoom_scale_page_layout_view=(v); Axlsx
|
187
|
+
def zoom_scale_page_layout_view=(v); Axlsx.validate_scale_0_10_400(v); @zoom_scale_page_layout_view = v end
|
186
188
|
|
187
189
|
# @see zoom_scale_sheet_layout_view
|
188
|
-
def zoom_scale_sheet_layout_view=(v); Axlsx
|
190
|
+
def zoom_scale_sheet_layout_view=(v); Axlsx.validate_scale_0_10_400(v); @zoom_scale_sheet_layout_view = v end
|
189
191
|
|
190
192
|
# Serializes the data validation
|
191
193
|
# @param [String] str
|
192
194
|
# @return [String]
|
193
|
-
def to_xml_string(str = '')
|
195
|
+
def to_xml_string(str = +'')
|
194
196
|
str << '<sheetViews>'
|
195
197
|
str << '<sheetView '
|
196
198
|
serialized_attributes str
|
197
199
|
str << '>'
|
198
200
|
@pane.to_xml_string(str) if @pane
|
199
|
-
@selections.
|
201
|
+
@selections.each_value do |selection|
|
200
202
|
selection.to_xml_string(str)
|
201
203
|
end
|
202
204
|
str << '</sheetView>'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# Table
|
3
5
|
# @note Worksheet#add_table is the recommended way to create tables for your worksheets.
|
@@ -42,7 +44,7 @@ module Axlsx
|
|
42
44
|
# The part name for this table
|
43
45
|
# @return [String]
|
44
46
|
def pn
|
45
|
-
|
47
|
+
format(TABLE_PN, index + 1)
|
46
48
|
end
|
47
49
|
|
48
50
|
# The relationship id for this table.
|
@@ -71,14 +73,14 @@ module Axlsx
|
|
71
73
|
# Serializes the object
|
72
74
|
# @param [String] str
|
73
75
|
# @return [String]
|
74
|
-
def to_xml_string(str = '')
|
76
|
+
def to_xml_string(str = +'')
|
75
77
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
76
|
-
str <<
|
77
|
-
str <<
|
78
|
-
str <<
|
79
|
-
str <<
|
78
|
+
str << '<table xmlns="' << XML_NS << '" id="' << (index + 1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/, '_') << '" '
|
79
|
+
str << 'ref="' << @ref << '" totalsRowShown="0">'
|
80
|
+
str << '<autoFilter ref="' << @ref << '"/>'
|
81
|
+
str << '<tableColumns count="' << header_cells.length.to_s << '">'
|
80
82
|
header_cells.each_with_index do |cell, index|
|
81
|
-
str <<
|
83
|
+
str << '<tableColumn id ="' << (index + 1).to_s << '" name="' << cell.clean_value << '"/>'
|
82
84
|
end
|
83
85
|
str << '</tableColumns>'
|
84
86
|
table_style_info.to_xml_string(str)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# The table style info class manages style attributes for defined tables in
|
3
5
|
# a worksheet
|
@@ -32,7 +34,7 @@ module Axlsx
|
|
32
34
|
# explicitly be disabled or all will show.
|
33
35
|
def initialize_defaults
|
34
36
|
%w(show_first_column show_last_column show_row_stripes show_column_stripes).each do |attr|
|
35
|
-
|
37
|
+
send("#{attr}=", 0)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -41,7 +43,7 @@ module Axlsx
|
|
41
43
|
|
42
44
|
# seralizes this object to an xml string
|
43
45
|
# @param [String] str the string to contact this objects serialization to.
|
44
|
-
def to_xml_string(str = '')
|
46
|
+
def to_xml_string(str = +'')
|
45
47
|
serialized_tag('tableStyleInfo', str)
|
46
48
|
end
|
47
49
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# A simple, self serializing class for storing tables
|
3
5
|
class Tables < SimpleTypedList
|
@@ -23,7 +25,7 @@ module Axlsx
|
|
23
25
|
# renders the tables xml
|
24
26
|
# @param [String] str
|
25
27
|
# @return [String]
|
26
|
-
def to_xml_string(str =
|
28
|
+
def to_xml_string(str = +'')
|
27
29
|
return if empty?
|
28
30
|
|
29
31
|
str << "<tableParts count='#{size}'>"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "border_creator"
|
2
4
|
|
3
5
|
module Axlsx
|
@@ -43,7 +45,7 @@ module Axlsx
|
|
43
45
|
# The name of the worksheet
|
44
46
|
# @return [String]
|
45
47
|
def name
|
46
|
-
@name ||= "Sheet
|
48
|
+
@name ||= "Sheet#{index + 1}"
|
47
49
|
end
|
48
50
|
|
49
51
|
# Whether to treat values starting with an equals sign as formulas or as literal strings.
|
@@ -63,7 +65,7 @@ module Axlsx
|
|
63
65
|
# Specifies the visible state of this sheet. Allowed states are
|
64
66
|
# :visible, :hidden or :very_hidden. The default value is :visible.
|
65
67
|
#
|
66
|
-
# Worksheets in the :hidden state can be shown using the sheet formatting properties in
|
68
|
+
# Worksheets in the :hidden state can be shown using the sheet formatting properties in Excel.
|
67
69
|
# :very_hidden sheets should be inaccessible to end users.
|
68
70
|
# @param [Symbol] sheet_state The visible state for this sheet.
|
69
71
|
def state=(sheet_state)
|
@@ -171,7 +173,7 @@ module Axlsx
|
|
171
173
|
@rows.transpose(&block)
|
172
174
|
end
|
173
175
|
|
174
|
-
# A range that
|
176
|
+
# A range that Excel will apply an auto-filter to "A1:B3"
|
175
177
|
# This will turn filtering on for the cells in the range.
|
176
178
|
# The first row is considered the header, while subsequent rows are considered to be data.
|
177
179
|
# @return String
|
@@ -185,7 +187,7 @@ module Axlsx
|
|
185
187
|
# @return Boolean
|
186
188
|
# @see #page_setup
|
187
189
|
def fit_to_page?
|
188
|
-
return false unless Axlsx.instance_values_for(self).
|
190
|
+
return false unless Axlsx.instance_values_for(self).key?('page_setup')
|
189
191
|
|
190
192
|
page_setup.fit_to_page?
|
191
193
|
end
|
@@ -325,7 +327,7 @@ module Axlsx
|
|
325
327
|
# @param [String] name
|
326
328
|
def name=(name)
|
327
329
|
validate_sheet_name name
|
328
|
-
@name = Axlsx
|
330
|
+
@name = Axlsx.coder.encode(name)
|
329
331
|
end
|
330
332
|
|
331
333
|
# The auto filter range for the worksheet
|
@@ -343,13 +345,13 @@ module Axlsx
|
|
343
345
|
# The part name of this worksheet
|
344
346
|
# @return [String]
|
345
347
|
def pn
|
346
|
-
|
348
|
+
format(WORKSHEET_PN, index + 1)
|
347
349
|
end
|
348
350
|
|
349
351
|
# The relationship part name of this worksheet
|
350
352
|
# @return [String]
|
351
353
|
def rels_pn
|
352
|
-
|
354
|
+
format(WORKSHEET_RELS_PN, index + 1)
|
353
355
|
end
|
354
356
|
|
355
357
|
# The relationship id of this worksheet.
|
@@ -427,7 +429,6 @@ module Axlsx
|
|
427
429
|
# Allowing user generated data to be interpreted as formulas can be dangerous
|
428
430
|
# (see https://www.owasp.org/index.php/CSV_Injection for details).
|
429
431
|
def add_row(values = [], options = {})
|
430
|
-
options[:escape_formulas] = escape_formulas if options[:escape_formulas].nil?
|
431
432
|
row = Row.new(self, values, options)
|
432
433
|
update_column_info row, options.delete(:widths)
|
433
434
|
yield row if block_given?
|
@@ -447,7 +448,7 @@ module Axlsx
|
|
447
448
|
# @see ConditionalFormattingRule#initialize
|
448
449
|
# @see file:examples/example_conditional_formatting.rb
|
449
450
|
def add_conditional_formatting(cells, rules)
|
450
|
-
cf = ConditionalFormatting.new(:
|
451
|
+
cf = ConditionalFormatting.new(sqref: cells)
|
451
452
|
cf.add_rules rules
|
452
453
|
conditional_formattings << cf
|
453
454
|
conditional_formattings
|
@@ -518,7 +519,7 @@ module Axlsx
|
|
518
519
|
end
|
519
520
|
|
520
521
|
# Adds a page break (row break) to the worksheet
|
521
|
-
# @param cell A Cell object or
|
522
|
+
# @param cell A Cell object or Excel style string reference indicating where the break
|
522
523
|
# should be added to the sheet.
|
523
524
|
# @example
|
524
525
|
# ws.add_page_break("A4")
|
@@ -530,9 +531,9 @@ module Axlsx
|
|
530
531
|
cell.pos
|
531
532
|
end
|
532
533
|
if column_index > 0
|
533
|
-
col_breaks.add_break(:
|
534
|
+
col_breaks.add_break(id: column_index)
|
534
535
|
end
|
535
|
-
row_breaks.add_break(:
|
536
|
+
row_breaks.add_break(id: row_index)
|
536
537
|
end
|
537
538
|
|
538
539
|
# This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
|
@@ -544,9 +545,9 @@ module Axlsx
|
|
544
545
|
# @param [Integer|Float|nil] widths
|
545
546
|
def column_widths(*widths)
|
546
547
|
widths.each_with_index do |value, index|
|
547
|
-
next if value
|
548
|
+
next if value.nil?
|
548
549
|
|
549
|
-
Axlsx
|
550
|
+
Axlsx.validate_unsigned_numeric(value) unless value.nil?
|
550
551
|
find_or_create_column_info(index).width = value
|
551
552
|
end
|
552
553
|
end
|
@@ -580,10 +581,10 @@ module Axlsx
|
|
580
581
|
end
|
581
582
|
|
582
583
|
# Set the style for cells in a specific column
|
583
|
-
# @param [String|Array]
|
584
|
+
# @param [String|Array] cell_refs Cell references
|
584
585
|
# @param [Hash] styles
|
585
586
|
def add_style(cell_refs, *styles)
|
586
|
-
|
587
|
+
unless cell_refs.is_a?(Array)
|
587
588
|
cell_refs = [cell_refs]
|
588
589
|
end
|
589
590
|
|
@@ -601,8 +602,8 @@ module Axlsx
|
|
601
602
|
end
|
602
603
|
|
603
604
|
# Set the style for cells in a specific column
|
604
|
-
# @param [String|Array]
|
605
|
-
# @param [Hash|Array|Symbol] border options
|
605
|
+
# @param [String|Array] cell_refs Cell references
|
606
|
+
# @param [Hash|Array|Symbol] options border options
|
606
607
|
def add_border(cell_refs, options = nil)
|
607
608
|
if options.is_a?(Hash)
|
608
609
|
border_edges = options[:edges]
|
@@ -612,7 +613,7 @@ module Axlsx
|
|
612
613
|
border_edges = options
|
613
614
|
end
|
614
615
|
|
615
|
-
|
616
|
+
unless cell_refs.is_a?(Array)
|
616
617
|
cell_refs = [cell_refs]
|
617
618
|
end
|
618
619
|
|
@@ -626,18 +627,18 @@ module Axlsx
|
|
626
627
|
end
|
627
628
|
|
628
629
|
# Returns a sheet node serialization for this sheet in the workbook.
|
629
|
-
def to_sheet_node_xml_string(str = '')
|
630
|
+
def to_sheet_node_xml_string(str = +'')
|
630
631
|
add_autofilter_defined_name_to_workbook
|
631
632
|
str << '<sheet '
|
632
633
|
serialized_attributes str
|
633
|
-
str <<
|
634
|
-
str <<
|
634
|
+
str << 'name="' << name << '" '
|
635
|
+
str << 'r:id="' << rId << '"></sheet>'
|
635
636
|
end
|
636
637
|
|
637
638
|
# Serializes the worksheet object to an xml string
|
638
639
|
# This intentionally does not use nokogiri for performance reasons
|
639
640
|
# @return [String]
|
640
|
-
def to_xml_string
|
641
|
+
def to_xml_string(str = +'')
|
641
642
|
add_autofilter_defined_name_to_workbook
|
642
643
|
auto_filter.apply if auto_filter.range
|
643
644
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
@@ -660,7 +661,7 @@ module Axlsx
|
|
660
661
|
r
|
661
662
|
end
|
662
663
|
|
663
|
-
# Returns the cell or cells defined using
|
664
|
+
# Returns the cell or cells defined using Excel style A1:B3 references.
|
664
665
|
# @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber
|
665
666
|
# @return [Cell, Array]
|
666
667
|
def [](cell_def)
|
@@ -672,11 +673,11 @@ module Axlsx
|
|
672
673
|
parts.first
|
673
674
|
else
|
674
675
|
if parts.size > 2
|
675
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_INVALID
|
676
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_INVALID, cell_def)
|
676
677
|
elsif parts.first.nil?
|
677
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_MISSING_CELL
|
678
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_MISSING_CELL, cell_def.split(":").first, cell_def)
|
678
679
|
elsif parts.last.nil?
|
679
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_MISSING_CELL
|
680
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_MISSING_CELL, cell_def.split(":").last, cell_def)
|
680
681
|
end
|
681
682
|
|
682
683
|
range(*parts)
|
@@ -687,12 +688,12 @@ module Axlsx
|
|
687
688
|
# @param [String] name The cell or cell range to return. "A1" will return the first cell of the first row.
|
688
689
|
# @return [Cell]
|
689
690
|
def name_to_cell(name)
|
690
|
-
col_index, row_index = *Axlsx
|
691
|
+
col_index, row_index = *Axlsx.name_to_indices(name)
|
691
692
|
|
692
693
|
r = rows[row_index]
|
693
694
|
|
694
695
|
if r
|
695
|
-
|
696
|
+
r[col_index]
|
696
697
|
end
|
697
698
|
end
|
698
699
|
|
@@ -710,7 +711,7 @@ module Axlsx
|
|
710
711
|
# @note The XLSX format does not support worksheet-specific styles. Even when using this method
|
711
712
|
# you're still working with the single global {Axlsx::Styles} object in the workbook.
|
712
713
|
def styles
|
713
|
-
@styles ||=
|
714
|
+
@styles ||= workbook.styles
|
714
715
|
end
|
715
716
|
|
716
717
|
# shortcut level to specify the outline level for a series of rows
|
@@ -752,15 +753,15 @@ module Axlsx
|
|
752
753
|
def validate_sheet_name(name)
|
753
754
|
DataTypeValidator.validate :worksheet_name, String, name
|
754
755
|
# ignore first character (BOM) after encoding to utf16 because Excel does so, too.
|
755
|
-
raise ArgumentError,
|
756
|
+
raise ArgumentError, ERR_SHEET_NAME_EMPTY if name.empty?
|
756
757
|
|
757
758
|
character_length = name.encode("utf-16")[1..-1].encode("utf-16").bytesize / 2
|
758
|
-
raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG
|
759
|
-
raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN
|
759
|
+
raise ArgumentError, format(ERR_SHEET_NAME_TOO_LONG, name) if character_length > WORKSHEET_MAX_NAME_LENGTH
|
760
|
+
raise ArgumentError, format(ERR_SHEET_NAME_CHARACTER_FORBIDDEN, name) if WORKSHEET_NAME_FORBIDDEN_CHARS.any? { |char| name.include? char }
|
760
761
|
|
761
|
-
name = Axlsx
|
762
|
-
sheet_names = @workbook.worksheets.reject { |s| s == self }.map
|
763
|
-
raise ArgumentError, (ERR_DUPLICATE_SHEET_NAME
|
762
|
+
name = Axlsx.coder.encode(name)
|
763
|
+
sheet_names = @workbook.worksheets.reject { |s| s == self }.map(&:name)
|
764
|
+
raise ArgumentError, format(ERR_DUPLICATE_SHEET_NAME, name) if sheet_names.include?(name)
|
764
765
|
end
|
765
766
|
|
766
767
|
def serializable_parts
|
@@ -849,7 +850,7 @@ module Axlsx
|
|
849
850
|
end
|
850
851
|
|
851
852
|
def add_autofilter_defined_name_to_workbook
|
852
|
-
return
|
853
|
+
return unless auto_filter.range
|
853
854
|
|
854
855
|
workbook.add_defined_name auto_filter.defined_name, name: '_xlnm._FilterDatabase', local_sheet_id: index, hidden: 1
|
855
856
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# A wraper class for comments that defines its on worksheet
|
3
5
|
# serailization
|
@@ -35,7 +37,7 @@ module Axlsx
|
|
35
37
|
|
36
38
|
# Helper method to tell us if there are comments in the comments collection
|
37
39
|
# @return [Boolean]
|
38
|
-
def has_comments?
|
40
|
+
def has_comments? # rubocop:disable Naming/PredicateName
|
39
41
|
!comments.empty?
|
40
42
|
end
|
41
43
|
|
@@ -49,7 +51,7 @@ module Axlsx
|
|
49
51
|
# Seraalize the object
|
50
52
|
# @param [String] str
|
51
53
|
# @return [String]
|
52
|
-
def to_xml_string(str = '')
|
54
|
+
def to_xml_string(str = +'')
|
53
55
|
return unless has_comments?
|
54
56
|
|
55
57
|
str << "<legacyDrawing r:id='#{drawing_rId}' />"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# This is a utility class for serialing the drawing node in a
|
3
5
|
# worksheet. Drawing objects have their own serialization that exports
|
@@ -13,8 +15,12 @@ module Axlsx
|
|
13
15
|
@drawing = nil
|
14
16
|
end
|
15
17
|
|
18
|
+
# The worksheet that owns the drawing
|
19
|
+
# @return [Worksheet]
|
16
20
|
attr_reader :worksheet
|
17
21
|
|
22
|
+
# The drawing object
|
23
|
+
# @return [Drawing]
|
18
24
|
attr_reader :drawing
|
19
25
|
|
20
26
|
# adds a chart to the drawing object
|
@@ -36,7 +42,7 @@ module Axlsx
|
|
36
42
|
|
37
43
|
# helper method to tell us if the drawing has something in it or not
|
38
44
|
# @return [Boolean]
|
39
|
-
def has_drawing?
|
45
|
+
def has_drawing? # rubocop:disable Naming/PredicateName
|
40
46
|
@drawing.is_a? Drawing
|
41
47
|
end
|
42
48
|
|
@@ -50,7 +56,7 @@ module Axlsx
|
|
50
56
|
|
51
57
|
# Serialize the drawing for the worksheet
|
52
58
|
# @param [String] str
|
53
|
-
def to_xml_string(str = '')
|
59
|
+
def to_xml_string(str = +'')
|
54
60
|
return unless has_drawing?
|
55
61
|
|
56
62
|
str << "<drawing r:id='#{relationship.Id}'/>"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# A worksheet hyperlink object. Note that this is not the same as a drawing hyperlink object.
|
3
5
|
class WorksheetHyperlink
|
@@ -39,7 +41,7 @@ module Axlsx
|
|
39
41
|
# @param [String|Cell] cell_reference The string reference or cell that defines where this hyperlink shows in the worksheet.
|
40
42
|
def ref=(cell_reference)
|
41
43
|
cell_reference = cell_reference.r if cell_reference.is_a?(Cell)
|
42
|
-
Axlsx
|
44
|
+
Axlsx.validate_string cell_reference
|
43
45
|
@ref = cell_reference
|
44
46
|
end
|
45
47
|
|
@@ -50,13 +52,13 @@ module Axlsx
|
|
50
52
|
def relationship
|
51
53
|
return unless @target == :external
|
52
54
|
|
53
|
-
Relationship.new(self, HYPERLINK_R, location, :
|
55
|
+
Relationship.new(self, HYPERLINK_R, location, target_mode: :External)
|
54
56
|
end
|
55
57
|
|
56
58
|
# Seralize the object
|
57
59
|
# @param [String] str
|
58
60
|
# @return [String]
|
59
|
-
def to_xml_string(str = '')
|
61
|
+
def to_xml_string(str = +'')
|
60
62
|
str << '<hyperlink '
|
61
63
|
serialized_attributes str, location_or_id
|
62
64
|
str << '/>'
|
@@ -67,7 +69,7 @@ module Axlsx
|
|
67
69
|
# r:id should only be specified for external targets.
|
68
70
|
# @return [Hash]
|
69
71
|
def location_or_id
|
70
|
-
@target == :external ? {
|
72
|
+
@target == :external ? { "r:id": relationship.Id } : { location: Axlsx.coder.encode(location) }
|
71
73
|
end
|
72
74
|
end
|
73
75
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Axlsx
|
2
4
|
# A collection of hyperlink objects for a worksheet
|
3
5
|
class WorksheetHyperlinks < SimpleTypedList
|
@@ -22,12 +24,12 @@ module Axlsx
|
|
22
24
|
def relationships
|
23
25
|
return [] if empty?
|
24
26
|
|
25
|
-
map
|
27
|
+
map(&:relationship)
|
26
28
|
end
|
27
29
|
|
28
30
|
# seralize the collection of hyperlinks
|
29
31
|
# @return [String]
|
30
|
-
def to_xml_string(str = '')
|
32
|
+
def to_xml_string(str = +'')
|
31
33
|
return if empty?
|
32
34
|
|
33
35
|
str << '<hyperlinks>'
|