caxlsx 3.3.0 → 4.0.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 +25 -0
- data/README.md +25 -7
- data/Rakefile +7 -6
- data/lib/axlsx/content_type/abstract_content_type.rb +11 -9
- data/lib/axlsx/content_type/content_type.rb +7 -9
- data/lib/axlsx/content_type/default.rb +4 -6
- data/lib/axlsx/content_type/override.rb +3 -5
- data/lib/axlsx/doc_props/app.rb +27 -30
- data/lib/axlsx/doc_props/core.rb +9 -12
- data/lib/axlsx/drawing/area_chart.rb +13 -14
- data/lib/axlsx/drawing/area_series.rb +13 -14
- data/lib/axlsx/drawing/ax_data_source.rb +3 -6
- data/lib/axlsx/drawing/axes.rb +10 -9
- data/lib/axlsx/drawing/axis.rb +27 -30
- data/lib/axlsx/drawing/bar_3D_chart.rb +17 -18
- data/lib/axlsx/drawing/bar_chart.rb +16 -17
- data/lib/axlsx/drawing/bar_series.rb +9 -13
- data/lib/axlsx/drawing/bubble_chart.rb +8 -9
- data/lib/axlsx/drawing/bubble_series.rb +9 -10
- data/lib/axlsx/drawing/cat_axis.rb +14 -17
- data/lib/axlsx/drawing/chart.rb +25 -28
- data/lib/axlsx/drawing/d_lbls.rb +29 -26
- data/lib/axlsx/drawing/drawing.rb +60 -62
- data/lib/axlsx/drawing/graphic_frame.rb +6 -7
- data/lib/axlsx/drawing/hyperlink.rb +12 -13
- data/lib/axlsx/drawing/line_3D_chart.rb +13 -15
- data/lib/axlsx/drawing/line_chart.rb +13 -14
- data/lib/axlsx/drawing/line_series.rb +13 -14
- data/lib/axlsx/drawing/marker.rb +14 -16
- data/lib/axlsx/drawing/num_data.rb +13 -16
- data/lib/axlsx/drawing/num_data_source.rb +11 -13
- data/lib/axlsx/drawing/num_val.rb +9 -10
- data/lib/axlsx/drawing/one_cell_anchor.rb +10 -10
- data/lib/axlsx/drawing/pic.rb +57 -22
- data/lib/axlsx/drawing/picture_locking.rb +6 -7
- data/lib/axlsx/drawing/pie_3D_chart.rb +6 -9
- data/lib/axlsx/drawing/pie_series.rb +9 -12
- data/lib/axlsx/drawing/scaling.rb +9 -10
- data/lib/axlsx/drawing/scatter_chart.rb +9 -10
- data/lib/axlsx/drawing/scatter_series.rb +15 -16
- data/lib/axlsx/drawing/ser_axis.rb +9 -11
- data/lib/axlsx/drawing/series.rb +8 -8
- data/lib/axlsx/drawing/series_title.rb +6 -6
- data/lib/axlsx/drawing/str_data.rb +10 -13
- data/lib/axlsx/drawing/str_val.rb +8 -9
- data/lib/axlsx/drawing/title.rb +23 -27
- data/lib/axlsx/drawing/two_cell_anchor.rb +8 -8
- data/lib/axlsx/drawing/val_axis.rb +5 -6
- data/lib/axlsx/drawing/view_3D.rb +32 -30
- data/lib/axlsx/drawing/vml_drawing.rb +19 -20
- data/lib/axlsx/drawing/vml_shape.rb +25 -26
- data/lib/axlsx/package.rb +81 -79
- data/lib/axlsx/rels/relationship.rb +30 -28
- data/lib/axlsx/rels/relationships.rb +7 -8
- data/lib/axlsx/stylesheet/border.rb +7 -8
- data/lib/axlsx/stylesheet/border_pr.rb +8 -8
- data/lib/axlsx/stylesheet/cell_alignment.rb +14 -20
- data/lib/axlsx/stylesheet/cell_protection.rb +6 -7
- data/lib/axlsx/stylesheet/cell_style.rb +12 -14
- data/lib/axlsx/stylesheet/color.rb +15 -12
- data/lib/axlsx/stylesheet/dxf.rb +7 -9
- data/lib/axlsx/stylesheet/fill.rb +3 -5
- data/lib/axlsx/stylesheet/font.rb +24 -21
- data/lib/axlsx/stylesheet/gradient_fill.rb +9 -9
- data/lib/axlsx/stylesheet/gradient_stop.rb +7 -6
- data/lib/axlsx/stylesheet/num_fmt.rb +9 -14
- data/lib/axlsx/stylesheet/pattern_fill.rb +8 -8
- data/lib/axlsx/stylesheet/styles.rb +104 -98
- data/lib/axlsx/stylesheet/table_style.rb +8 -9
- data/lib/axlsx/stylesheet/table_style_element.rb +7 -8
- data/lib/axlsx/stylesheet/table_styles.rb +8 -10
- data/lib/axlsx/stylesheet/xf.rb +21 -22
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
- data/lib/axlsx/util/constants.rb +119 -108
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +4 -3
- data/lib/axlsx/util/serialized_attributes.rb +45 -21
- data/lib/axlsx/util/simple_typed_list.rb +58 -57
- data/lib/axlsx/util/storage.rb +38 -41
- data/lib/axlsx/util/validators.rb +107 -44
- data/lib/axlsx/util/zip_command.rb +10 -12
- data/lib/axlsx/version.rb +3 -2
- data/lib/axlsx/workbook/defined_name.rb +11 -8
- data/lib/axlsx/workbook/defined_names.rb +4 -3
- data/lib/axlsx/workbook/shared_strings_table.rb +10 -11
- data/lib/axlsx/workbook/workbook.rb +121 -114
- data/lib/axlsx/workbook/workbook_view.rb +8 -11
- data/lib/axlsx/workbook/workbook_views.rb +4 -4
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +72 -14
- data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -7
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +24 -21
- 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 +30 -25
- data/lib/axlsx/workbook/worksheet/break.rb +4 -5
- data/lib/axlsx/workbook/worksheet/cell.rb +92 -65
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +32 -28
- data/lib/axlsx/workbook/worksheet/cfvo.rb +7 -5
- data/lib/axlsx/workbook/worksheet/cfvos.rb +5 -5
- data/lib/axlsx/workbook/worksheet/col.rb +9 -10
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +8 -7
- data/lib/axlsx/workbook/worksheet/color_scale.rb +16 -16
- data/lib/axlsx/workbook/worksheet/cols.rb +9 -7
- data/lib/axlsx/workbook/worksheet/comment.rb +12 -11
- data/lib/axlsx/workbook/worksheet/comments.rb +10 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +12 -8
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +19 -21
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +5 -5
- data/lib/axlsx/workbook/worksheet/data_bar.rb +29 -30
- data/lib/axlsx/workbook/worksheet/data_validation.rb +34 -33
- data/lib/axlsx/workbook/worksheet/data_validations.rb +5 -6
- data/lib/axlsx/workbook/worksheet/date_time_converter.rb +8 -8
- data/lib/axlsx/workbook/worksheet/dimension.rb +9 -6
- data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -3
- data/lib/axlsx/workbook/worksheet/icon_set.rb +24 -8
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +10 -10
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -3
- data/lib/axlsx/workbook/worksheet/page_margins.rb +17 -12
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -4
- data/lib/axlsx/workbook/worksheet/page_setup.rb +128 -129
- data/lib/axlsx/workbook/worksheet/pane.rb +27 -26
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +23 -25
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +12 -13
- data/lib/axlsx/workbook/worksheet/pivot_tables.rb +5 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +3 -2
- data/lib/axlsx/workbook/worksheet/protected_range.rb +6 -5
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +12 -10
- data/lib/axlsx/workbook/worksheet/rich_text.rb +6 -6
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +35 -17
- data/lib/axlsx/workbook/worksheet/row.rb +30 -22
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +8 -7
- data/lib/axlsx/workbook/worksheet/selection.rb +16 -16
- data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +10 -7
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +7 -7
- data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +23 -19
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +11 -7
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +21 -20
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +48 -53
- data/lib/axlsx/workbook/worksheet/table.rb +13 -13
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +6 -5
- data/lib/axlsx/workbook/worksheet/tables.rb +7 -5
- data/lib/axlsx/workbook/worksheet/worksheet.rb +92 -63
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +10 -8
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +11 -4
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +9 -8
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +7 -5
- data/lib/axlsx.rb +75 -47
- data/lib/caxlsx.rb +3 -2
- metadata +50 -44
@@ -1,10 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Axlsx
|
3
4
|
# Table
|
4
5
|
# @note Worksheet#add_table is the recommended way to create tables for your worksheets.
|
5
6
|
# @see README for examples
|
6
7
|
class Table
|
7
|
-
|
8
8
|
include Axlsx::OptionsParser
|
9
9
|
|
10
10
|
# Creates a new Table object
|
@@ -12,13 +12,13 @@ module Axlsx
|
|
12
12
|
# @param [Worksheet] sheet The sheet containing the table data.
|
13
13
|
# @option options [Cell, String] name
|
14
14
|
# @option options [TableStyle] style
|
15
|
-
def initialize(ref, sheet, options={})
|
15
|
+
def initialize(ref, sheet, options = {})
|
16
16
|
@ref = ref
|
17
17
|
@sheet = sheet
|
18
18
|
@style = nil
|
19
19
|
@sheet.workbook.tables << self
|
20
20
|
@table_style_info = TableStyleInfo.new(options[:style_info]) if options[:style_info]
|
21
|
-
@name = "Table#{index+1}"
|
21
|
+
@name = "Table#{index + 1}"
|
22
22
|
parse_options options
|
23
23
|
yield self if block_given?
|
24
24
|
end
|
@@ -44,7 +44,7 @@ module Axlsx
|
|
44
44
|
# The part name for this table
|
45
45
|
# @return [String]
|
46
46
|
def pn
|
47
|
-
|
47
|
+
format(TABLE_PN, index + 1)
|
48
48
|
end
|
49
49
|
|
50
50
|
# The relationship id for this table.
|
@@ -64,7 +64,7 @@ module Axlsx
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
# TableStyleInfo for the table.
|
67
|
+
# TableStyleInfo for the table.
|
68
68
|
# initialization can be fed via the :style_info option
|
69
69
|
def table_style_info
|
70
70
|
@table_style_info ||= TableStyleInfo.new
|
@@ -73,14 +73,14 @@ module Axlsx
|
|
73
73
|
# Serializes the object
|
74
74
|
# @param [String] str
|
75
75
|
# @return [String]
|
76
|
-
def to_xml_string(str = '')
|
76
|
+
def to_xml_string(str = +'')
|
77
77
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
78
|
-
str <<
|
79
|
-
str <<
|
80
|
-
str <<
|
81
|
-
str <<
|
82
|
-
header_cells.each_with_index do |cell,index|
|
83
|
-
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 << '">'
|
82
|
+
header_cells.each_with_index do |cell, index|
|
83
|
+
str << '<tableColumn id ="' << (index + 1).to_s << '" name="' << cell.clean_value << '"/>'
|
84
84
|
end
|
85
85
|
str << '</tableColumns>'
|
86
86
|
table_style_info.to_xml_string(str)
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Axlsx
|
3
4
|
# The table style info class manages style attributes for defined tables in
|
4
5
|
# a worksheet
|
5
6
|
class TableStyleInfo
|
@@ -15,7 +16,7 @@ module Axlsx
|
|
15
16
|
# @option [Boolean] show_column_stripes indicates if column stripes should
|
16
17
|
# be shown
|
17
18
|
# @option [Boolean] show_row_stripes indicates if row stripes should be shown
|
18
|
-
# @option [String] name The name of the style to apply to your table.
|
19
|
+
# @option [String] name The name of the style to apply to your table.
|
19
20
|
# Only predefined styles are currently supported.
|
20
21
|
# @see Annex G. (normative) Predefined SpreadsheetML Style Definitions in part 1 of the specification.
|
21
22
|
def initialize(options = {})
|
@@ -27,13 +28,13 @@ module Axlsx
|
|
27
28
|
# boolean attributes for this object
|
28
29
|
boolean_attr_accessor :show_first_column, :show_last_column, :show_row_stripes, :show_column_stripes
|
29
30
|
serializable_attributes :show_first_column, :show_last_column, :show_row_stripes, :show_column_stripes,
|
30
|
-
|
31
|
+
:name
|
31
32
|
|
32
33
|
# Initialize all the values to false as Excel requires them to
|
33
34
|
# explicitly be disabled or all will show.
|
34
35
|
def initialize_defaults
|
35
36
|
%w(show_first_column show_last_column show_row_stripes show_column_stripes).each do |attr|
|
36
|
-
|
37
|
+
send("#{attr}=", 0)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -42,7 +43,7 @@ module Axlsx
|
|
42
43
|
|
43
44
|
# seralizes this object to an xml string
|
44
45
|
# @param [String] str the string to contact this objects serialization to.
|
45
|
-
def to_xml_string(str = '')
|
46
|
+
def to_xml_string(str = +'')
|
46
47
|
serialized_tag('tableStyleInfo', str)
|
47
48
|
end
|
48
49
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Axlsx
|
3
4
|
# A simple, self serializing class for storing tables
|
4
5
|
class Tables < SimpleTypedList
|
5
|
-
|
6
6
|
# creates a new Tables object
|
7
7
|
def initialize(worksheet)
|
8
8
|
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
9
|
+
|
9
10
|
super Table
|
10
11
|
@worksheet = worksheet
|
11
12
|
end
|
@@ -17,18 +18,19 @@ module Axlsx
|
|
17
18
|
# returns the relationships required by this collection
|
18
19
|
def relationships
|
19
20
|
return [] if empty?
|
20
|
-
|
21
|
+
|
22
|
+
map { |table| Relationship.new(table, TABLE_R, "../#{table.pn}") }
|
21
23
|
end
|
22
24
|
|
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?
|
30
|
+
|
28
31
|
str << "<tableParts count='#{size}'>"
|
29
32
|
each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
|
30
33
|
str << '</tableParts>'
|
31
34
|
end
|
32
35
|
end
|
33
|
-
|
34
36
|
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "border_creator"
|
4
4
|
|
5
5
|
module Axlsx
|
6
|
-
|
7
6
|
# The Worksheet class represents a worksheet in the workbook.
|
8
7
|
class Worksheet
|
9
8
|
include Axlsx::OptionsParser
|
@@ -16,12 +15,15 @@ module Axlsx
|
|
16
15
|
# @option options [Hash] page_margins A hash containing page margins for this worksheet. @see PageMargins
|
17
16
|
# @option options [Hash] print_options A hash containing print options for this worksheet. @see PrintOptions
|
18
17
|
# @option options [Hash] header_footer A hash containing header/footer options for this worksheet. @see HeaderFooter
|
19
|
-
# @option options [Boolean] show_gridlines
|
20
|
-
|
18
|
+
# @option options [Boolean] show_gridlines Whether gridlines should be shown for this sheet.
|
19
|
+
# @option options [Boolean] escape_formulas Whether formulas should be escaped by default. Can be overridden at a
|
20
|
+
# row/cell level.
|
21
|
+
def initialize(wb, options = {})
|
21
22
|
self.workbook = wb
|
22
23
|
@sheet_protection = nil
|
23
24
|
initialize_page_options(options)
|
24
25
|
parse_options options
|
26
|
+
self.escape_formulas = wb.escape_formulas unless defined? @escape_formulas
|
25
27
|
@workbook.worksheets << self
|
26
28
|
@sheet_id = index + 1
|
27
29
|
yield self if block_given?
|
@@ -43,13 +45,27 @@ 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}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Whether to treat values starting with an equals sign as formulas or as literal strings.
|
52
|
+
# Allowing user-generated data to be interpreted as formulas is a security risk.
|
53
|
+
# See https://www.owasp.org/index.php/CSV_Injection for details.
|
54
|
+
# @return [Boolean]
|
55
|
+
attr_reader :escape_formulas
|
56
|
+
|
57
|
+
# Sets whether to treat values starting with an equals sign as formulas or as literal strings.
|
58
|
+
# @param [Boolean] value The value to set.
|
59
|
+
# @return [Boolean]
|
60
|
+
def escape_formulas=(value)
|
61
|
+
Axlsx.validate_boolean(value)
|
62
|
+
@escape_formulas = value
|
47
63
|
end
|
48
64
|
|
49
65
|
# Specifies the visible state of this sheet. Allowed states are
|
50
66
|
# :visible, :hidden or :very_hidden. The default value is :visible.
|
51
67
|
#
|
52
|
-
# 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.
|
53
69
|
# :very_hidden sheets should be inaccessible to end users.
|
54
70
|
# @param [Symbol] sheet_state The visible state for this sheet.
|
55
71
|
def state=(sheet_state)
|
@@ -102,13 +118,13 @@ module Axlsx
|
|
102
118
|
# The tables in this worksheet
|
103
119
|
# @return [Array] of Table
|
104
120
|
def tables
|
105
|
-
@tables ||=
|
121
|
+
@tables ||= Tables.new self
|
106
122
|
end
|
107
123
|
|
108
124
|
# The pivot tables in this worksheet
|
109
125
|
# @return [Array] of Table
|
110
126
|
def pivot_tables
|
111
|
-
@pivot_tables ||=
|
127
|
+
@pivot_tables ||= PivotTables.new self
|
112
128
|
end
|
113
129
|
|
114
130
|
# A collection of column breaks added to this worksheet
|
@@ -157,7 +173,7 @@ module Axlsx
|
|
157
173
|
@rows.transpose(&block)
|
158
174
|
end
|
159
175
|
|
160
|
-
# A range that
|
176
|
+
# A range that Excel will apply an auto-filter to "A1:B3"
|
161
177
|
# This will turn filtering on for the cells in the range.
|
162
178
|
# The first row is considered the header, while subsequent rows are considered to be data.
|
163
179
|
# @return String
|
@@ -171,11 +187,11 @@ module Axlsx
|
|
171
187
|
# @return Boolean
|
172
188
|
# @see #page_setup
|
173
189
|
def fit_to_page?
|
174
|
-
return false unless Axlsx.instance_values_for(self).
|
190
|
+
return false unless Axlsx.instance_values_for(self).key?('page_setup')
|
191
|
+
|
175
192
|
page_setup.fit_to_page?
|
176
193
|
end
|
177
194
|
|
178
|
-
|
179
195
|
# Column info for the sheet
|
180
196
|
# @return [SimpleTypedList]
|
181
197
|
def column_info
|
@@ -311,7 +327,7 @@ module Axlsx
|
|
311
327
|
# @param [String] name
|
312
328
|
def name=(name)
|
313
329
|
validate_sheet_name name
|
314
|
-
@name=Axlsx
|
330
|
+
@name = Axlsx.coder.encode(name)
|
315
331
|
end
|
316
332
|
|
317
333
|
# The auto filter range for the worksheet
|
@@ -329,13 +345,13 @@ module Axlsx
|
|
329
345
|
# The part name of this worksheet
|
330
346
|
# @return [String]
|
331
347
|
def pn
|
332
|
-
|
348
|
+
format(WORKSHEET_PN, index + 1)
|
333
349
|
end
|
334
350
|
|
335
351
|
# The relationship part name of this worksheet
|
336
352
|
# @return [String]
|
337
353
|
def rels_pn
|
338
|
-
|
354
|
+
format(WORKSHEET_RELS_PN, index + 1)
|
339
355
|
end
|
340
356
|
|
341
357
|
# The relationship id of this worksheet.
|
@@ -412,7 +428,7 @@ module Axlsx
|
|
412
428
|
# sign as formula (default) or as simple string.
|
413
429
|
# Allowing user generated data to be interpreted as formulas can be dangerous
|
414
430
|
# (see https://www.owasp.org/index.php/CSV_Injection for details).
|
415
|
-
def add_row(values=[], options={})
|
431
|
+
def add_row(values = [], options = {})
|
416
432
|
row = Row.new(self, values, options)
|
417
433
|
update_column_info row, options.delete(:widths)
|
418
434
|
yield row if block_given?
|
@@ -432,7 +448,7 @@ module Axlsx
|
|
432
448
|
# @see ConditionalFormattingRule#initialize
|
433
449
|
# @see file:examples/example_conditional_formatting.rb
|
434
450
|
def add_conditional_formatting(cells, rules)
|
435
|
-
cf = ConditionalFormatting.new(
|
451
|
+
cf = ConditionalFormatting.new(sqref: cells)
|
436
452
|
cf.add_rules rules
|
437
453
|
conditional_formattings << cf
|
438
454
|
conditional_formattings
|
@@ -453,7 +469,7 @@ module Axlsx
|
|
453
469
|
# @param [Hash] options for the hyperlink
|
454
470
|
# @see WorksheetHyperlink for a list of options
|
455
471
|
# @return [WorksheetHyperlink]
|
456
|
-
def add_hyperlink(options={})
|
472
|
+
def add_hyperlink(options = {})
|
457
473
|
hyperlinks.add(options)
|
458
474
|
end
|
459
475
|
|
@@ -470,54 +486,54 @@ module Axlsx
|
|
470
486
|
# @see Bar3DChart
|
471
487
|
# @see Line3DChart
|
472
488
|
# @see README for examples
|
473
|
-
def add_chart(chart_type, options={})
|
489
|
+
def add_chart(chart_type, options = {})
|
474
490
|
chart = worksheet_drawing.add_chart(chart_type, options)
|
475
491
|
yield chart if block_given?
|
476
492
|
chart
|
477
493
|
end
|
478
494
|
|
479
495
|
# needs documentation
|
480
|
-
def add_table(ref, options={})
|
496
|
+
def add_table(ref, options = {})
|
481
497
|
tables << Table.new(ref, self, options)
|
482
498
|
yield tables.last if block_given?
|
483
499
|
tables.last
|
484
500
|
end
|
485
501
|
|
486
|
-
def add_pivot_table(ref, range, options={})
|
502
|
+
def add_pivot_table(ref, range, options = {})
|
487
503
|
pivot_tables << PivotTable.new(ref, range, self, options)
|
488
504
|
yield pivot_tables.last if block_given?
|
489
505
|
pivot_tables.last
|
490
506
|
end
|
491
507
|
|
492
508
|
# Shortcut to worsksheet_comments#add_comment
|
493
|
-
def add_comment(options={})
|
509
|
+
def add_comment(options = {})
|
494
510
|
worksheet_comments.add_comment(options)
|
495
511
|
end
|
496
512
|
|
497
513
|
# Adds a media item to the worksheets drawing
|
498
514
|
# @option [Hash] options options passed to drawing.add_image
|
499
|
-
def add_image(options={})
|
515
|
+
def add_image(options = {})
|
500
516
|
image = worksheet_drawing.add_image(options)
|
501
517
|
yield image if block_given?
|
502
518
|
image
|
503
519
|
end
|
504
520
|
|
505
521
|
# Adds a page break (row break) to the worksheet
|
506
|
-
# @param cell A Cell object or
|
522
|
+
# @param cell A Cell object or Excel style string reference indicating where the break
|
507
523
|
# should be added to the sheet.
|
508
524
|
# @example
|
509
525
|
# ws.add_page_break("A4")
|
510
526
|
def add_page_break(cell)
|
511
527
|
DataTypeValidator.validate :worksheet_page_break, [String, Cell], cell
|
512
528
|
column_index, row_index = if cell.is_a?(String)
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
529
|
+
Axlsx.name_to_indices(cell)
|
530
|
+
else
|
531
|
+
cell.pos
|
532
|
+
end
|
517
533
|
if column_index > 0
|
518
|
-
col_breaks.add_break(:
|
534
|
+
col_breaks.add_break(id: column_index)
|
519
535
|
end
|
520
|
-
row_breaks.add_break(:
|
536
|
+
row_breaks.add_break(id: row_index)
|
521
537
|
end
|
522
538
|
|
523
539
|
# This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
|
@@ -529,8 +545,9 @@ module Axlsx
|
|
529
545
|
# @param [Integer|Float|nil] widths
|
530
546
|
def column_widths(*widths)
|
531
547
|
widths.each_with_index do |value, index|
|
532
|
-
next if value
|
533
|
-
|
548
|
+
next if value.nil?
|
549
|
+
|
550
|
+
Axlsx.validate_unsigned_numeric(value) unless value.nil?
|
534
551
|
find_or_create_column_info(index).width = value
|
535
552
|
end
|
536
553
|
end
|
@@ -543,7 +560,7 @@ module Axlsx
|
|
543
560
|
# @note You can also specify the style for specific columns in the call to add_row by using an array for the :styles option
|
544
561
|
# @see Worksheet#add_row
|
545
562
|
# @see README.md for an example
|
546
|
-
def col_style(index, style, options={})
|
563
|
+
def col_style(index, style, options = {})
|
547
564
|
offset = options.delete(:row_offset) || 0
|
548
565
|
cells = @rows[(offset..-1)].map { |row| row[index] }.flatten.compact
|
549
566
|
cells.each { |cell| cell.style = style }
|
@@ -557,17 +574,17 @@ module Axlsx
|
|
557
574
|
# @note You can also specify the style in the add_row call
|
558
575
|
# @see Worksheet#add_row
|
559
576
|
# @see README.md for an example
|
560
|
-
def row_style(index, style, options={})
|
577
|
+
def row_style(index, style, options = {})
|
561
578
|
offset = options.delete(:col_offset) || 0
|
562
579
|
cells = cols[(offset..-1)].map { |column| column[index] }.flatten.compact
|
563
580
|
cells.each { |cell| cell.style = style }
|
564
581
|
end
|
565
582
|
|
566
583
|
# Set the style for cells in a specific column
|
567
|
-
# @param [String|Array]
|
584
|
+
# @param [String|Array] cell_refs Cell references
|
568
585
|
# @param [Hash] styles
|
569
586
|
def add_style(cell_refs, *styles)
|
570
|
-
|
587
|
+
unless cell_refs.is_a?(Array)
|
571
588
|
cell_refs = [cell_refs]
|
572
589
|
end
|
573
590
|
|
@@ -585,32 +602,43 @@ module Axlsx
|
|
585
602
|
end
|
586
603
|
|
587
604
|
# Set the style for cells in a specific column
|
588
|
-
# @param [String|Array]
|
589
|
-
# @param [Hash|Array|Symbol] border options
|
590
|
-
def add_border(cell_refs, options =
|
591
|
-
if
|
605
|
+
# @param [String|Array] cell_refs Cell references
|
606
|
+
# @param [Hash|Array|Symbol] options border options
|
607
|
+
def add_border(cell_refs, options = nil)
|
608
|
+
if options.is_a?(Hash)
|
609
|
+
border_edges = options[:edges]
|
610
|
+
border_style = options[:style]
|
611
|
+
border_color = options[:color]
|
612
|
+
else
|
613
|
+
border_edges = options
|
614
|
+
end
|
615
|
+
|
616
|
+
unless cell_refs.is_a?(Array)
|
592
617
|
cell_refs = [cell_refs]
|
593
618
|
end
|
594
619
|
|
595
620
|
cell_refs.each do |cell_ref|
|
596
|
-
|
597
|
-
|
621
|
+
item = self[cell_ref]
|
622
|
+
|
623
|
+
cells = item.is_a?(Array) ? item : [item]
|
624
|
+
|
625
|
+
Axlsx::BorderCreator.new(worksheet: self, cells: cells, edges: border_edges, style: border_style, color: border_color).draw
|
598
626
|
end
|
599
627
|
end
|
600
628
|
|
601
629
|
# Returns a sheet node serialization for this sheet in the workbook.
|
602
|
-
def to_sheet_node_xml_string(str='')
|
630
|
+
def to_sheet_node_xml_string(str = +'')
|
603
631
|
add_autofilter_defined_name_to_workbook
|
604
632
|
str << '<sheet '
|
605
633
|
serialized_attributes str
|
606
|
-
str <<
|
607
|
-
str <<
|
634
|
+
str << 'name="' << name << '" '
|
635
|
+
str << 'r:id="' << rId << '"></sheet>'
|
608
636
|
end
|
609
637
|
|
610
638
|
# Serializes the worksheet object to an xml string
|
611
639
|
# This intentionally does not use nokogiri for performance reasons
|
612
640
|
# @return [String]
|
613
|
-
def to_xml_string
|
641
|
+
def to_xml_string(str = +'')
|
614
642
|
add_autofilter_defined_name_to_workbook
|
615
643
|
auto_filter.apply if auto_filter.range
|
616
644
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
@@ -633,23 +661,23 @@ module Axlsx
|
|
633
661
|
r
|
634
662
|
end
|
635
663
|
|
636
|
-
# Returns the cell or cells defined using
|
664
|
+
# Returns the cell or cells defined using Excel style A1:B3 references.
|
637
665
|
# @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber
|
638
666
|
# @return [Cell, Array]
|
639
667
|
def [](cell_def)
|
640
668
|
return rows[cell_def] if cell_def.is_a?(Integer)
|
641
669
|
|
642
|
-
parts = cell_def.split(':').map{ |part| name_to_cell part }
|
670
|
+
parts = cell_def.split(':').map { |part| name_to_cell part }
|
643
671
|
|
644
672
|
if parts.size == 1
|
645
673
|
parts.first
|
646
674
|
else
|
647
675
|
if parts.size > 2
|
648
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_INVALID
|
676
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_INVALID, cell_def)
|
649
677
|
elsif parts.first.nil?
|
650
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_MISSING_CELL
|
678
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_MISSING_CELL, cell_def.split(":").first, cell_def)
|
651
679
|
elsif parts.last.nil?
|
652
|
-
raise ArgumentError, (ERR_CELL_REFERENCE_MISSING_CELL
|
680
|
+
raise ArgumentError, format(ERR_CELL_REFERENCE_MISSING_CELL, cell_def.split(":").last, cell_def)
|
653
681
|
end
|
654
682
|
|
655
683
|
range(*parts)
|
@@ -660,12 +688,12 @@ module Axlsx
|
|
660
688
|
# @param [String] name The cell or cell range to return. "A1" will return the first cell of the first row.
|
661
689
|
# @return [Cell]
|
662
690
|
def name_to_cell(name)
|
663
|
-
col_index, row_index = *Axlsx
|
691
|
+
col_index, row_index = *Axlsx.name_to_indices(name)
|
664
692
|
|
665
693
|
r = rows[row_index]
|
666
694
|
|
667
695
|
if r
|
668
|
-
|
696
|
+
r[col_index]
|
669
697
|
end
|
670
698
|
end
|
671
699
|
|
@@ -683,7 +711,7 @@ module Axlsx
|
|
683
711
|
# @note The XLSX format does not support worksheet-specific styles. Even when using this method
|
684
712
|
# you're still working with the single global {Axlsx::Styles} object in the workbook.
|
685
713
|
def styles
|
686
|
-
@styles ||=
|
714
|
+
@styles ||= workbook.styles
|
687
715
|
end
|
688
716
|
|
689
717
|
# shortcut level to specify the outline level for a series of rows
|
@@ -713,7 +741,7 @@ module Axlsx
|
|
713
741
|
end
|
714
742
|
|
715
743
|
def outline(collection, range, level = 1, collapsed = true)
|
716
|
-
|
744
|
+
range.each do |index|
|
717
745
|
unless (item = collection[index]).nil?
|
718
746
|
item.outline_level = level
|
719
747
|
item.hidden = collapsed
|
@@ -725,13 +753,15 @@ module Axlsx
|
|
725
753
|
def validate_sheet_name(name)
|
726
754
|
DataTypeValidator.validate :worksheet_name, String, name
|
727
755
|
# ignore first character (BOM) after encoding to utf16 because Excel does so, too.
|
728
|
-
raise ArgumentError,
|
756
|
+
raise ArgumentError, ERR_SHEET_NAME_EMPTY if name.empty?
|
757
|
+
|
729
758
|
character_length = name.encode("utf-16")[1..-1].encode("utf-16").bytesize / 2
|
730
|
-
raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG
|
731
|
-
raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN
|
732
|
-
|
733
|
-
|
734
|
-
|
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 }
|
761
|
+
|
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)
|
735
765
|
end
|
736
766
|
|
737
767
|
def serializable_parts
|
@@ -783,7 +813,6 @@ module Axlsx
|
|
783
813
|
@merged_cells ||= MergedCells.new self
|
784
814
|
end
|
785
815
|
|
786
|
-
|
787
816
|
# Helper method for parsingout the root node for worksheet
|
788
817
|
# @return [String]
|
789
818
|
def worksheet_node
|
@@ -821,9 +850,9 @@ module Axlsx
|
|
821
850
|
end
|
822
851
|
|
823
852
|
def add_autofilter_defined_name_to_workbook
|
824
|
-
return
|
853
|
+
return unless auto_filter.range
|
854
|
+
|
825
855
|
workbook.add_defined_name auto_filter.defined_name, name: '_xlnm._FilterDatabase', local_sheet_id: index, hidden: 1
|
826
856
|
end
|
827
|
-
|
828
857
|
end
|
829
858
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Axlsx
|
3
4
|
# A wraper class for comments that defines its on worksheet
|
4
5
|
# serailization
|
5
6
|
class WorksheetComments
|
6
|
-
|
7
7
|
# Creates a new WorksheetComments object
|
8
8
|
# param [Worksheet] worksheet The worksheet comments in thes object belong to
|
9
9
|
def initialize(worksheet)
|
10
10
|
raise ArugumentError, 'You must provide a worksheet' unless worksheet.is_a?(Worksheet)
|
11
|
+
|
11
12
|
@worksheet = worksheet
|
12
13
|
end
|
13
14
|
|
@@ -22,21 +23,21 @@ module Axlsx
|
|
22
23
|
# Adds a comment
|
23
24
|
# @param [Hash] options
|
24
25
|
# @see Comments#add_comment
|
25
|
-
def add_comment(options={})
|
26
|
+
def add_comment(options = {})
|
26
27
|
comments.add_comment(options)
|
27
|
-
end
|
28
|
+
end
|
28
29
|
|
29
30
|
# The relationships defined by this objects comments collection
|
30
31
|
# @return [Relationships]
|
31
32
|
def relationships
|
32
33
|
return [] unless has_comments?
|
34
|
+
|
33
35
|
comments.relationships
|
34
36
|
end
|
35
37
|
|
36
|
-
|
37
38
|
# Helper method to tell us if there are comments in the comments collection
|
38
39
|
# @return [Boolean]
|
39
|
-
def has_comments?
|
40
|
+
def has_comments? # rubocop:disable Naming/PredicateName
|
40
41
|
!comments.empty?
|
41
42
|
end
|
42
43
|
|
@@ -44,14 +45,15 @@ module Axlsx
|
|
44
45
|
# @see Relationship#Id
|
45
46
|
# @return [String]
|
46
47
|
def drawing_rId
|
47
|
-
comments.relationships.find{ |r| r.Type == VML_DRAWING_R }.Id
|
48
|
+
comments.relationships.find { |r| r.Type == VML_DRAWING_R }.Id
|
48
49
|
end
|
49
50
|
|
50
51
|
# Seraalize the object
|
51
52
|
# @param [String] str
|
52
53
|
# @return [String]
|
53
|
-
def to_xml_string(str = '')
|
54
|
+
def to_xml_string(str = +'')
|
54
55
|
return unless has_comments?
|
56
|
+
|
55
57
|
str << "<legacyDrawing r:id='#{drawing_rId}' />"
|
56
58
|
end
|
57
59
|
end
|
@@ -1,21 +1,26 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Axlsx
|
3
4
|
# This is a utility class for serialing the drawing node in a
|
4
5
|
# worksheet. Drawing objects have their own serialization that exports
|
5
6
|
# a drawing document. This is only for the single node in the
|
6
7
|
# worksheet
|
7
8
|
class WorksheetDrawing
|
8
|
-
|
9
9
|
# Creates a new WorksheetDrawing
|
10
10
|
# @param [Worksheet] worksheet
|
11
11
|
def initialize(worksheet)
|
12
12
|
raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
|
13
|
+
|
13
14
|
@worksheet = worksheet
|
14
15
|
@drawing = nil
|
15
16
|
end
|
16
17
|
|
18
|
+
# The worksheet that owns the drawing
|
19
|
+
# @return [Worksheet]
|
17
20
|
attr_reader :worksheet
|
18
21
|
|
22
|
+
# The drawing object
|
23
|
+
# @return [Drawing]
|
19
24
|
attr_reader :drawing
|
20
25
|
|
21
26
|
# adds a chart to the drawing object
|
@@ -37,7 +42,7 @@ module Axlsx
|
|
37
42
|
|
38
43
|
# helper method to tell us if the drawing has something in it or not
|
39
44
|
# @return [Boolean]
|
40
|
-
def has_drawing?
|
45
|
+
def has_drawing? # rubocop:disable Naming/PredicateName
|
41
46
|
@drawing.is_a? Drawing
|
42
47
|
end
|
43
48
|
|
@@ -45,13 +50,15 @@ module Axlsx
|
|
45
50
|
# @return [Relationship]
|
46
51
|
def relationship
|
47
52
|
return unless has_drawing?
|
53
|
+
|
48
54
|
Relationship.new(self, DRAWING_R, "../#{drawing.pn}")
|
49
55
|
end
|
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?
|
61
|
+
|
55
62
|
str << "<drawing r:id='#{relationship.Id}'/>"
|
56
63
|
end
|
57
64
|
end
|