axlsx 1.1.3 → 1.2.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.
- data/.yardopts +5 -2
- data/CHANGELOG.md +60 -0
- data/LICENSE +1 -1
- data/README.md +115 -415
- data/Rakefile +11 -3
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +88 -0
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +299 -155
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +45 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/scraping_html.rb +91 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_protection.rb +10 -0
- data/examples/sheet_view.rb +34 -0
- data/examples/two_cell_anchor_image.rb +11 -0
- data/lib/axlsx/content_type/content_type.rb +2 -0
- data/lib/axlsx/content_type/default.rb +30 -15
- data/lib/axlsx/content_type/override.rb +29 -14
- data/lib/axlsx/doc_props/app.rb +161 -104
- data/lib/axlsx/doc_props/core.rb +9 -5
- data/lib/axlsx/drawing/ax_data_source.rb +26 -0
- data/lib/axlsx/drawing/axis.rb +92 -37
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +25 -7
- data/lib/axlsx/drawing/cat_axis.rb +50 -22
- data/lib/axlsx/drawing/chart.rb +69 -56
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +28 -12
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/line_series.rb +20 -4
- data/lib/axlsx/drawing/num_data.rb +52 -0
- data/lib/axlsx/drawing/num_data_source.rb +61 -0
- data/lib/axlsx/drawing/num_val.rb +32 -0
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/pie_series.rb +18 -4
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- data/lib/axlsx/drawing/scatter_series.rb +28 -2
- data/lib/axlsx/drawing/ser_axis.rb +1 -1
- data/lib/axlsx/drawing/series.rb +1 -1
- data/lib/axlsx/drawing/str_data.rb +42 -0
- data/lib/axlsx/drawing/str_val.rb +33 -0
- data/lib/axlsx/drawing/title.rb +21 -9
- data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
- data/lib/axlsx/drawing/view_3D.rb +44 -31
- data/lib/axlsx/drawing/vml_drawing.rb +42 -0
- data/lib/axlsx/drawing/vml_shape.rb +125 -0
- data/lib/axlsx/package.rb +44 -16
- data/lib/axlsx/rels/relationship.rb +3 -3
- data/lib/axlsx/rels/relationships.rb +1 -11
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/util/constants.rb +28 -0
- data/lib/axlsx/util/simple_typed_list.rb +15 -21
- data/lib/axlsx/util/validators.rb +81 -8
- data/lib/axlsx/version.rb +2 -7
- data/lib/axlsx/workbook/defined_name.rb +174 -0
- data/lib/axlsx/workbook/defined_names.rb +21 -0
- data/lib/axlsx/workbook/workbook.rb +65 -13
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
- data/lib/axlsx/workbook/worksheet/col.rb +17 -1
- data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
- data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
- data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
- data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
- data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
- data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
- data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
- data/lib/axlsx/workbook/worksheet/row.rb +67 -12
- data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
- data/lib/axlsx/workbook/worksheet/table.rb +3 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx.rb +30 -15
- data/test/content_type/tc_content_type.rb +1 -6
- data/test/doc_props/tc_app.rb +31 -1
- data/test/doc_props/tc_core.rb +3 -1
- data/test/drawing/tc_axis.rb +38 -3
- data/test/drawing/tc_bar_3D_chart.rb +12 -12
- data/test/drawing/tc_bar_series.rb +17 -13
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_cat_axis_data.rb +23 -13
- data/test/drawing/tc_chart.rb +29 -11
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_data_source.rb +17 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +9 -11
- data/test/drawing/tc_named_axis_data.rb +27 -0
- data/test/drawing/tc_num_data.rb +31 -0
- data/test/drawing/tc_num_val.rb +29 -0
- data/test/drawing/tc_pic.rb +22 -2
- data/test/drawing/tc_pie_3D_chart.rb +4 -8
- data/test/drawing/tc_pie_series.rb +11 -13
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +6 -5
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_str_data.rb +18 -0
- data/test/drawing/tc_str_val.rb +21 -0
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +2 -3
- data/test/drawing/tc_view_3D.rb +18 -18
- data/test/drawing/tc_vml_drawing.rb +25 -0
- data/test/drawing/tc_vml_shape.rb +100 -0
- data/test/rels/tc_relationship.rb +1 -0
- data/test/stylesheet/tc_gradient_fill.rb +8 -0
- data/test/stylesheet/tc_pattern_fill.rb +7 -1
- data/test/stylesheet/tc_styles.rb +3 -4
- data/test/stylesheet/tc_table_style.rb +8 -0
- data/test/stylesheet/tc_table_style_element.rb +10 -1
- data/test/tc_helper.rb +1 -0
- data/test/tc_package.rb +93 -17
- data/test/util/tc_simple_typed_list.rb +13 -0
- data/test/util/tc_validators.rb +95 -9
- data/test/workbook/tc_defined_name.rb +41 -0
- data/test/workbook/tc_workbook.rb +5 -3
- data/test/workbook/worksheet/table/tc_table.rb +3 -11
- data/test/workbook/worksheet/tc_cell.rb +30 -6
- data/test/workbook/worksheet/tc_col.rb +9 -0
- data/test/workbook/worksheet/tc_comment.rb +57 -0
- data/test/workbook/worksheet/tc_comments.rb +57 -0
- data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +265 -0
- data/test/workbook/worksheet/tc_page_setup.rb +138 -0
- data/test/workbook/worksheet/tc_pane.rb +94 -0
- data/test/workbook/worksheet/tc_print_options.rb +72 -0
- data/test/workbook/worksheet/tc_protected_range.rb +17 -0
- data/test/workbook/worksheet/tc_row.rb +36 -12
- data/test/workbook/worksheet/tc_selection.rb +94 -0
- data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
- data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
- data/test/workbook/worksheet/tc_worksheet.rb +138 -48
- metadata +164 -52
- data/examples/example.csv +0 -1000
- data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/named_axis_data.rb +0 -36
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/val_axis_data.rb +0 -27
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- data/lib/axlsx/util/font_tables.rb~ +0 -0
- data/lib/axlsx/util/ms_off_crypto.rb +0 -189
- data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
- data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
- data/lib/axlsx/util/parser.rb~ +0 -6
- data/lib/axlsx/util/storage.rb~ +0 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
- data/lib/schema/dc.xsd~ +0 -118
- data/lib/schema/dcterms.xsd~ +0 -331
- data/lib/schema/opc-coreProperties.xsd~ +0 -50
- data/test/drawing/tc_val_axis_data.rb +0 -17
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module Axlsx
|
|
3
|
+
# Selection options for worksheet panes.
|
|
4
|
+
#
|
|
5
|
+
# @note The recommended way to manage the selection pane options is via SheetView#add_selection
|
|
6
|
+
# @see SheetView#add_selection
|
|
7
|
+
class Selection
|
|
8
|
+
|
|
9
|
+
# Active Cell Location
|
|
10
|
+
# Location of the active cell.
|
|
11
|
+
# @see type
|
|
12
|
+
# @return [String]
|
|
13
|
+
# default nil
|
|
14
|
+
attr_reader :active_cell
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Active Cell Index
|
|
18
|
+
# 0-based index of the range reference (in the array of references listed in sqref)
|
|
19
|
+
# containing the active cell. Only used when the selection in sqref is not contiguous.
|
|
20
|
+
# Therefore, this value needs to be aware of the order in which the range references are
|
|
21
|
+
# written in sqref.
|
|
22
|
+
# When this value is out of range then activeCell can be used.
|
|
23
|
+
# @see type
|
|
24
|
+
# @return [Integer]
|
|
25
|
+
# default nil
|
|
26
|
+
attr_reader :active_cell_id
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Pane
|
|
30
|
+
# The pane to which this selection belongs.
|
|
31
|
+
# Options are
|
|
32
|
+
# * bottom_left: Bottom left pane, when both vertical and horizontal
|
|
33
|
+
# splits are applied. This value is also used when only
|
|
34
|
+
# a horizontal split has been applied, dividing the pane
|
|
35
|
+
# into upper and lower regions. In that case, this value
|
|
36
|
+
# specifies the bottom pane.
|
|
37
|
+
# * bottom_right: Bottom right pane, when both vertical and horizontal
|
|
38
|
+
# splits are applied.
|
|
39
|
+
# * top_left: Top left pane, when both vertical and horizontal splits
|
|
40
|
+
# are applied. This value is also used when only a horizontal
|
|
41
|
+
# split has been applied, dividing the pane into upper and lower
|
|
42
|
+
# regions. In that case, this value specifies the top pane.
|
|
43
|
+
# This value is also used when only a vertical split has
|
|
44
|
+
# been applied, dividing the pane into right and left
|
|
45
|
+
# regions. In that case, this value specifies the left pane
|
|
46
|
+
# * top_right: Top right pane, when both vertical and horizontal
|
|
47
|
+
# splits are applied. This value is also used when only
|
|
48
|
+
# a vertical split has been applied, dividing the pane
|
|
49
|
+
# into right and left regions. In that case, this value
|
|
50
|
+
# specifies the right pane.
|
|
51
|
+
# @see type
|
|
52
|
+
# @return [Symbol]
|
|
53
|
+
# default nil
|
|
54
|
+
attr_reader :pane
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Sequence of References
|
|
58
|
+
# Range of the selection. Can be non-contiguous set of ranges.
|
|
59
|
+
# @see type
|
|
60
|
+
# @return [String]
|
|
61
|
+
# default nil
|
|
62
|
+
attr_reader :sqref
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Creates a new {Selection} object
|
|
66
|
+
# @option options [Cell, String] active_cell Active Cell Location
|
|
67
|
+
# @option options [Integer] active_cell_id Active Cell Index
|
|
68
|
+
# @option options [Symbol] pane Pane
|
|
69
|
+
# @option options [String] sqref Sequence of References
|
|
70
|
+
def initialize(options={})
|
|
71
|
+
#defaults
|
|
72
|
+
@active_cell = @active_cell_id = @pane = @sqref = nil
|
|
73
|
+
|
|
74
|
+
# write options to instance variables
|
|
75
|
+
options.each do |o|
|
|
76
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# @see active_cell
|
|
82
|
+
def active_cell=(v)
|
|
83
|
+
cell = (v.class == Axlsx::Cell ? v.r_abs : v)
|
|
84
|
+
Axlsx::validate_string(cell)
|
|
85
|
+
@active_cell = cell
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# @see active_cell_id
|
|
90
|
+
def active_cell_id=(v); Axlsx::validate_unsigned_int(v); @active_cell_id = v end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# @see pane
|
|
94
|
+
def pane=(v); Axlsx::validate_pane_type(v); @pane = v end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# @see sqref
|
|
98
|
+
def sqref=(v); Axlsx::validate_string(v); @sqref = v end
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Serializes the data validation
|
|
102
|
+
# @param [String] str
|
|
103
|
+
# @return [String]
|
|
104
|
+
def to_xml_string(str = '')
|
|
105
|
+
str << '<selection '
|
|
106
|
+
str << instance_values.map { |key, value| '' << key.gsub(/_(.)/){ $1.upcase } <<
|
|
107
|
+
%{="#{[:pane].include?(key.to_sym) ? value.to_s.gsub(/_(.)/){ $1.upcase } : value}"} unless value.nil? }.join(' ')
|
|
108
|
+
str << '/>'
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# This class manages the serialization of rows for worksheets
|
|
4
|
+
class SheetData
|
|
5
|
+
|
|
6
|
+
# Creates a new SheetData object
|
|
7
|
+
# @param [Worksheet] worksheet The worksheet that owns this sheet data.
|
|
8
|
+
def initialize(worksheet)
|
|
9
|
+
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
|
10
|
+
@worksheet = worksheet
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :worksheet
|
|
14
|
+
|
|
15
|
+
# Serialize the sheet data
|
|
16
|
+
# @param [String] str the string this objects serializaton will be concacted to.
|
|
17
|
+
# @return [String]
|
|
18
|
+
def to_xml_string(str = '')
|
|
19
|
+
str << '<sheetData>'
|
|
20
|
+
worksheet.rows.each_with_index{ |row, index| row.to_xml_string(index, str) }
|
|
21
|
+
str << '</sheetData>'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# The SheetPr class manages serialization fo a worksheet's sheetPr element.
|
|
4
|
+
# Only fit_to_page is implemented
|
|
5
|
+
class SheetPr
|
|
6
|
+
|
|
7
|
+
# Creates a new SheetPr object
|
|
8
|
+
# @param [Worksheet] worksheet The worksheet that owns this SheetPr object
|
|
9
|
+
def initialize(worksheet)
|
|
10
|
+
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
|
11
|
+
@worksheet = worksheet
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :worksheet
|
|
15
|
+
|
|
16
|
+
# Serialize the object
|
|
17
|
+
# @param [String] str serialized output will be appended to this object if provided.
|
|
18
|
+
# @return [String]
|
|
19
|
+
def to_xml_string(str = '')
|
|
20
|
+
return unless worksheet.fit_to_page?
|
|
21
|
+
str << "<sheetPr><pageSetUpPr fitToPage=\"%s\"></pageSetUpPr></sheetPr>" % worksheet.fit_to_page?
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module Axlsx
|
|
3
|
+
|
|
4
|
+
# The SheetProtection object manages worksheet protection options per sheet.
|
|
5
|
+
class SheetProtection
|
|
6
|
+
|
|
7
|
+
# If 1 or true then AutoFilters should not be allowed to operate when the sheet is protected.
|
|
8
|
+
# If 0 or false then AutoFilters should be allowed to operate when the sheet is protected.
|
|
9
|
+
# @return [Boolean]
|
|
10
|
+
# default true
|
|
11
|
+
attr_reader :auto_filter
|
|
12
|
+
|
|
13
|
+
# If 1 or true then deleting columns should not be allowed when the sheet is protected.
|
|
14
|
+
# If 0 or false then deleting columns should be allowed when the sheet is protected.
|
|
15
|
+
# @return [Boolean]
|
|
16
|
+
# default true
|
|
17
|
+
attr_reader :delete_columns
|
|
18
|
+
|
|
19
|
+
# If 1 or true then deleting rows should not be allowed when the sheet is protected.
|
|
20
|
+
# If 0 or false then deleting rows should be allowed when the sheet is protected.
|
|
21
|
+
# @return [Boolean]
|
|
22
|
+
# default true
|
|
23
|
+
attr_reader :delete_rows
|
|
24
|
+
|
|
25
|
+
# If 1 or true then formatting cells should not be allowed when the sheet is protected.
|
|
26
|
+
# If 0 or false then formatting cells should be allowed when the sheet is protected.
|
|
27
|
+
# @return [Boolean]
|
|
28
|
+
# default true
|
|
29
|
+
attr_reader :format_cells
|
|
30
|
+
|
|
31
|
+
# If 1 or true then formatting columns should not be allowed when the sheet is protected.
|
|
32
|
+
# If 0 or false then formatting columns should be allowed when the sheet is protected.
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
# default true
|
|
35
|
+
attr_reader :format_columns
|
|
36
|
+
|
|
37
|
+
# If 1 or true then formatting rows should not be allowed when the sheet is protected.
|
|
38
|
+
# If 0 or false then formatting rows should be allowed when the sheet is protected.
|
|
39
|
+
# @return [Boolean]
|
|
40
|
+
# default true
|
|
41
|
+
attr_reader :format_rows
|
|
42
|
+
|
|
43
|
+
# If 1 or true then inserting columns should not be allowed when the sheet is protected.
|
|
44
|
+
# If 0 or false then inserting columns should be allowed when the sheet is protected.
|
|
45
|
+
# @return [Boolean]
|
|
46
|
+
# default true
|
|
47
|
+
attr_reader :insert_columns
|
|
48
|
+
|
|
49
|
+
# If 1 or true then inserting hyperlinks should not be allowed when the sheet is protected.
|
|
50
|
+
# If 0 or false then inserting hyperlinks should be allowed when the sheet is protected.
|
|
51
|
+
# @return [Boolean]
|
|
52
|
+
# default true
|
|
53
|
+
attr_reader :insert_hyperlinks
|
|
54
|
+
|
|
55
|
+
# If 1 or true then inserting rows should not be allowed when the sheet is protected.
|
|
56
|
+
# If 0 or false then inserting rows should be allowed when the sheet is protected.
|
|
57
|
+
# @return [Boolean]
|
|
58
|
+
# default true
|
|
59
|
+
attr_reader :insert_rows
|
|
60
|
+
|
|
61
|
+
# If 1 or true then editing of objects should not be allowed when the sheet is protected.
|
|
62
|
+
# If 0 or false then objects are allowed to be edited when the sheet is protected.
|
|
63
|
+
# @return [Boolean]
|
|
64
|
+
# default false
|
|
65
|
+
attr_reader :objects
|
|
66
|
+
|
|
67
|
+
# If 1 or true then PivotTables should not be allowed to operate when the sheet is protected.
|
|
68
|
+
# If 0 or false then PivotTables should be allowed to operate when the sheet is protected.
|
|
69
|
+
# @return [Boolean]
|
|
70
|
+
# default true
|
|
71
|
+
attr_reader :pivot_tables
|
|
72
|
+
|
|
73
|
+
# Specifies the salt which was prepended to the user-supplied password before it was hashed using the hashing algorithm
|
|
74
|
+
# @return [String]
|
|
75
|
+
attr_reader :salt_value
|
|
76
|
+
|
|
77
|
+
# If 1 or true then Scenarios should not be edited when the sheet is protected.
|
|
78
|
+
# If 0 or false then Scenarios are allowed to be edited when the sheet is protected.
|
|
79
|
+
# @return [Boolean]
|
|
80
|
+
# default false
|
|
81
|
+
attr_reader :scenarios
|
|
82
|
+
|
|
83
|
+
# If 1 or true then selection of locked cells should not be allowed when the sheet is protected.
|
|
84
|
+
# If 0 or false then selection of locked cells should be allowed when the sheet is protected.
|
|
85
|
+
# @return [Boolean]
|
|
86
|
+
# default false
|
|
87
|
+
attr_reader :select_locked_cells
|
|
88
|
+
|
|
89
|
+
# If 1 or true then selection of unlocked cells should not be allowed when the sheet is protected.
|
|
90
|
+
# If 0 or false then selection of unlocked cells should be allowed when the sheet is protected.
|
|
91
|
+
# @return [Boolean]
|
|
92
|
+
# default false
|
|
93
|
+
attr_reader :select_unlocked_cells
|
|
94
|
+
|
|
95
|
+
# If 1 or true then the sheet is protected.
|
|
96
|
+
# If 0 or false then the sheet is not protected.
|
|
97
|
+
# @return [Boolean]
|
|
98
|
+
# default true
|
|
99
|
+
attr_reader :sheet
|
|
100
|
+
|
|
101
|
+
# If 1 or true then sorting should not be allowed when the sheet is protected.
|
|
102
|
+
# If 0 or false then sorting should be allowed when the sheet is protected.
|
|
103
|
+
# @return [Boolean]
|
|
104
|
+
# default true
|
|
105
|
+
attr_reader :sort
|
|
106
|
+
|
|
107
|
+
# Password hash
|
|
108
|
+
# @return [String]
|
|
109
|
+
# default nil
|
|
110
|
+
attr_reader :password
|
|
111
|
+
|
|
112
|
+
# Creates a new SheetProtection instance
|
|
113
|
+
# @option options [Boolean] sheet @see SheetProtection#sheet
|
|
114
|
+
# @option options [Boolean] objects @see SheetProtection#objects
|
|
115
|
+
# @option options [Boolean] scenarios @see SheetProtection#scenarios
|
|
116
|
+
# @option options [Boolean] format_cells @see SheetProtection#objects
|
|
117
|
+
# @option options [Boolean] format_columns @see SheetProtection#format_columns
|
|
118
|
+
# @option options [Boolean] format_rows @see SheetProtection#format_rows
|
|
119
|
+
# @option options [Boolean] insert_columns @see SheetProtection#insert_columns
|
|
120
|
+
# @option options [Boolean] insert_rows @see SheetProtection#insert_rows
|
|
121
|
+
# @option options [Boolean] insert_hyperlinks @see SheetProtection#insert_hyperlinks
|
|
122
|
+
# @option options [Boolean] delete_columns @see SheetProtection#delete_columns
|
|
123
|
+
# @option options [Boolean] delete_rows @see SheetProtection#delete_rows
|
|
124
|
+
# @option options [Boolean] select_locked_cells @see SheetProtection#select_locked_cells
|
|
125
|
+
# @option options [Boolean] sort @see SheetProtection#sort
|
|
126
|
+
# @option options [Boolean] auto_filter @see SheetProtection#auto_filter
|
|
127
|
+
# @option options [Boolean] pivot_tables @see SheetProtection#pivot_tables
|
|
128
|
+
# @option options [Boolean] select_unlocked_cells @see SheetProtection#select_unlocked_cells
|
|
129
|
+
# @option options [String] password. The password required for unlocking. @see SheetProtection#password=
|
|
130
|
+
# @option options [Boolean] objects @see SheetProtection#objects
|
|
131
|
+
def initialize(options={})
|
|
132
|
+
@objects = @scenarios = @select_locked_cells = @select_unlocked_cells = false
|
|
133
|
+
@sheet = @format_cells = @format_rows = @format_columns = @insert_columns = @insert_rows = @insert_hyperlinks = @delete_columns = @delete_rows = @sort = @auto_filter = @pivot_tables = true
|
|
134
|
+
@password = nil
|
|
135
|
+
|
|
136
|
+
options.each do |o|
|
|
137
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# create validating setters for boolean values
|
|
143
|
+
# @return [Boolean]
|
|
144
|
+
[:sheet, :objects, :scenarios, :select_locked_cells, :sort,
|
|
145
|
+
:select_unlocked_cells, :format_cells, :format_rows, :format_columns,
|
|
146
|
+
:insert_columns, :insert_rows, :insert_hyperlinks, :delete_columns,
|
|
147
|
+
:delete_rows, :auto_filter, :pivot_tables].each do |f_name|
|
|
148
|
+
define_method "#{f_name.to_s}=".to_sym do |v|
|
|
149
|
+
Axlsx::validate_boolean(v)
|
|
150
|
+
instance_variable_set "@#{f_name.to_s}".to_sym, v
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# This block is intended to implement the salt_value, hash_value and spin count as per the ECMA-376 standard.
|
|
155
|
+
# However, it does not seem to actually work in EXCEL - instead they are using their old retro algorithm shown below
|
|
156
|
+
# defined in the transitional portion of the speck. I am leaving this code in in the hope that someday Ill be able to
|
|
157
|
+
# figure out why it does not work, and if Excel even supports it.
|
|
158
|
+
# def propper_password=(v)
|
|
159
|
+
# @algorithm_name = v == nil ? nil : 'SHA-1'
|
|
160
|
+
# @salt_value = @spin_count = @hash_value = v if v == nil
|
|
161
|
+
# return if v == nil
|
|
162
|
+
# require 'digest/sha1'
|
|
163
|
+
# @spin_count = 10000
|
|
164
|
+
# @salt_value = Digest::SHA1.hexdigest(rand(36**8).to_s(36))
|
|
165
|
+
# @spin_count.times do |count|
|
|
166
|
+
# @hash_value = Digest::SHA1.hexdigest((@hash_value ||= (@salt_value + v.to_s)) + Array(count).pack('V'))
|
|
167
|
+
# end
|
|
168
|
+
# end
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# encodes password for protection locking
|
|
173
|
+
def password=(v)
|
|
174
|
+
return if v == nil
|
|
175
|
+
@password = create_password_hash(v)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Serialize the object
|
|
179
|
+
# @param [String] str
|
|
180
|
+
# @return [String]
|
|
181
|
+
def to_xml_string(str = '')
|
|
182
|
+
str << '<sheetProtection '
|
|
183
|
+
str << instance_values.map{ |k,v| k.gsub(/_(.)/){ $1.upcase } << %{="#{v.to_s}"} }.join(' ')
|
|
184
|
+
str << '/>'
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
# Creates a password hash for a given password
|
|
189
|
+
# @return [String]
|
|
190
|
+
def create_password_hash(password)
|
|
191
|
+
encoded_password = encode_password(password)
|
|
192
|
+
|
|
193
|
+
password_as_hex = [encoded_password].pack("v")
|
|
194
|
+
password_as_string = password_as_hex.unpack("H*").first.upcase
|
|
195
|
+
|
|
196
|
+
password_as_string[2..3] + password_as_string[0..1]
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# Encodes a given password
|
|
201
|
+
# Based on the algorithm provided by Daniel Rentz of OpenOffice.
|
|
202
|
+
# http://www.openoffice.org/sc/excelfileformat.pdf, Revision 1.42, page 115 (21.05.2012)
|
|
203
|
+
# @return [String]
|
|
204
|
+
def encode_password(password)
|
|
205
|
+
i = 0
|
|
206
|
+
chars = password.split(//)
|
|
207
|
+
count = chars.size
|
|
208
|
+
|
|
209
|
+
chars.collect! do |char|
|
|
210
|
+
i += 1
|
|
211
|
+
char = char.unpack('c')[0] << i #ord << i
|
|
212
|
+
low_15 = char & 0x7fff
|
|
213
|
+
high_15 = char & 0x7fff << 15
|
|
214
|
+
high_15 = high_15 >> 15
|
|
215
|
+
char = low_15 | high_15
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
encoded_password = 0x0000
|
|
219
|
+
chars.each { |c| encoded_password ^= c }
|
|
220
|
+
encoded_password ^= count
|
|
221
|
+
encoded_password ^= 0xCE4B
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|