axlsx 1.1.4 → 1.3.1
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 +6 -2
- data/CHANGELOG.md +72 -0
- data/README.md +114 -31
- data/Rakefile +11 -3
- data/examples/auto_filter.rb +16 -0
- data/examples/auto_filter.xlsx +0 -0
- data/examples/basic_charts.rb +58 -0
- data/examples/chart_colors.rb +17 -2
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +171 -60
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +3 -0
- data/examples/extractive.xlsx +0 -0
- data/examples/hyperlinks.rb +23 -0
- data/examples/hyperlinks.xlsx +0 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/page_setup.rb +11 -0
- data/examples/page_setup.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/skydrive/axlsx.csv +1 -0
- data/examples/skydrive/axlsx.xlsx +0 -0
- data/examples/skydrive/real_example.rb +8 -8
- data/examples/sprk2012/Screen Shot 2012-09-11 at 10.42.06 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 11.07.48 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 8.31.50 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 9.23.27 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 9.32.06 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 9.33.35 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-11 at 9.46.44 PM.png +0 -0
- data/examples/sprk2012/Screen Shot 2012-09-12 at 5.07.23 PM.png +0 -0
- data/examples/sprk2012/basics.rb +11 -0
- data/examples/sprk2012/basics.xlsx +0 -0
- data/examples/sprk2012/gravatar.jpeg +0 -0
- data/examples/sprk2012/hair_club.jpg +0 -0
- data/examples/sprk2012/images.rb +9 -0
- data/examples/sprk2012/images.xlsx +0 -0
- data/examples/sprk2012/line_chart.rb +56 -0
- data/examples/sprk2012/line_chart.xlsx +0 -0
- data/examples/sprk2012/sprk2012.key +0 -0
- data/examples/sprk2012/styles.rb +20 -0
- data/examples/sprk2012/styles.xlsx +0 -0
- data/examples/styles.rb +62 -0
- data/examples/styles.xlsx +0 -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 +7 -6
- data/lib/axlsx/drawing/axis.rb +82 -36
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +2 -1
- data/lib/axlsx/drawing/cat_axis.rb +43 -39
- data/lib/axlsx/drawing/chart.rb +65 -54
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +20 -8
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/num_data.rb +2 -2
- data/lib/axlsx/drawing/num_data_source.rb +4 -1
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- 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 +42 -32
- data/lib/axlsx/drawing/vml_drawing.rb +42 -0
- data/lib/axlsx/drawing/vml_shape.rb +125 -0
- data/lib/axlsx/package.rb +43 -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 +11 -2
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/util/constants.rb +131 -2
- data/lib/axlsx/util/simple_typed_list.rb +18 -22
- data/lib/axlsx/util/validators.rb +100 -9
- 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 +70 -13
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +102 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +253 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +41 -8
- data/lib/axlsx/workbook/worksheet/col.rb +15 -0
- 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/date_time_converter.rb +1 -1
- 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_set_up_pr.rb +47 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +241 -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 +36 -20
- data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
- data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +49 -0
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +107 -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 +10 -3
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +68 -0
- data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +414 -254
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +101 -0
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
- data/lib/axlsx.rb +38 -16
- 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 +1 -2
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_chart.rb +29 -9
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +7 -3
- data/test/drawing/tc_num_data.rb +5 -1
- 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 +7 -2
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +1 -1
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +1 -2
- 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 +16 -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 +94 -17
- data/test/util/tc_simple_typed_list.rb +13 -0
- data/test/util/tc_validators.rb +101 -8
- data/test/workbook/tc_defined_name.rb +41 -0
- data/test/workbook/tc_workbook.rb +5 -3
- data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
- data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
- data/test/workbook/worksheet/tc_cell.rb +53 -7
- 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_set_up_pr.rb +15 -0
- data/test/workbook/worksheet/tc_page_setup.rb +143 -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 +32 -14
- data/test/workbook/worksheet/tc_selection.rb +94 -0
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
- data/test/workbook/worksheet/tc_sheet_pr.rb +27 -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/{table/tc_table.rb → tc_table.rb} +9 -12
- data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
- data/test/workbook/worksheet/tc_worksheet.rb +155 -51
- data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +64 -0
- metadata +194 -81
- data/examples/#extractive.csv# +0 -0
- data/examples/#extractive.rb# +0 -45
- data/examples/chart_colors.rb~ +0 -0
- data/examples/chart_colors.xlsx +0 -0
- data/examples/colored_series_data.xlsx +0 -0
- data/examples/conditional_formatting/getting_barred.xlsx +0 -0
- data/examples/example.csv +0 -1000
- data/examples/extractive.csv +0 -1
- data/examples/extractive.csv~ +0 -1
- data/examples/extractive.rb~ +0 -3
- data/examples/stack.rb +0 -21
- data/examples/stack.rb~ +0 -27
- data/examples/stack.xlsx +0 -0
- data/examples/~$chart_colors.xlsx +0 -0
- data/examples/~$extractive.xlsx +0 -0
- data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
- data/lib/axlsx/drawing/data_source.rb~ +0 -51
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/num_data.rb~ +0 -51
- data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
- data/lib/axlsx/drawing/num_val.rb~ +0 -40
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/ref.rb~ +0 -41
- data/lib/axlsx/drawing/str_data.rb~ +0 -58
- data/lib/axlsx/drawing/str_val.rb~ +0 -35
- 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_data_source.rb~ +0 -30
- data/test/drawing/tc_num_data.rb~ +0 -35
- data/test/drawing/tc_num_val.rb~ +0 -29
- data/test/drawing/tc_str_data.rb~ +0 -30
- data/test/drawing/tc_str_val.rb~ +0 -26
- 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,253 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# When multiple values are chosen to filter by, or when a group of date values are chosen to filter by,
|
|
4
|
+
# this object groups those criteria together.
|
|
5
|
+
class Filters
|
|
6
|
+
|
|
7
|
+
# Allowed calendar types
|
|
8
|
+
CALENDAR_TYPES = %w(gregorian gregorianUs gregorianMeFrench gregorianArabic hijri hebrew taiwan japan thai korea saka gregorianXlitEnglish gregorianXlitFrench none)
|
|
9
|
+
|
|
10
|
+
# Creates a new Filters object
|
|
11
|
+
# @param [Hash] options Options used to set this objects attributes and
|
|
12
|
+
# create filter and/or date group items
|
|
13
|
+
# @option [Boolean] blank @see blank
|
|
14
|
+
# @option [String] calendar_type @see calendar_type
|
|
15
|
+
# @option [Array] filter_items An array of values that will be used to create filter objects.
|
|
16
|
+
# @option [Array] date_group_items An array of hases defining date group item filters to apply.
|
|
17
|
+
# @note The recommended way to interact with filter objects is via AutoFilter#add_column
|
|
18
|
+
# @example
|
|
19
|
+
# ws.auto_filter.add_column(0, :filters, :blank => true, :calendar_type => 'japan', :filter_items => [100, 'a'])
|
|
20
|
+
def initialize(options={})
|
|
21
|
+
options.each do |key, value|
|
|
22
|
+
self.send("#{key}=", value) if self.respond_to? "#{key}="
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Flag indicating whether to filter by blank.
|
|
27
|
+
# @return [Boolean]
|
|
28
|
+
attr_reader :blank
|
|
29
|
+
|
|
30
|
+
# Calendar type for date grouped items.
|
|
31
|
+
# Used to interpret the values in dateGroupItem.
|
|
32
|
+
# This is the calendar type used to evaluate all dates in the filter column,
|
|
33
|
+
# even when those dates are not using the same calendar system / date formatting.
|
|
34
|
+
attr_reader :calendar_type
|
|
35
|
+
|
|
36
|
+
# Tells us if the row of the cell provided should be filterd as it
|
|
37
|
+
# does not meet any of the specified filter_items or
|
|
38
|
+
# date_group_items restrictions.
|
|
39
|
+
# @param [Cell] cell The cell to test against items
|
|
40
|
+
# TODO implement this for date filters as well!
|
|
41
|
+
def apply(cell)
|
|
42
|
+
return false unless cell
|
|
43
|
+
filter_items.each do |filter|
|
|
44
|
+
return false if cell.value == filter.val
|
|
45
|
+
end
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The filter values in this filters object
|
|
50
|
+
def filter_items
|
|
51
|
+
@filter_items ||= []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# the date group values in this filters object
|
|
55
|
+
def date_group_items
|
|
56
|
+
@date_group_items ||= []
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @see calendar_type
|
|
60
|
+
# @param [String] calendar The calendar type to use. This must be one of the types defined in CALENDAR_TYPES
|
|
61
|
+
# @return [String]
|
|
62
|
+
def calendar_type=(calendar)
|
|
63
|
+
RestrictionValidator.validate 'Filters.calendar_type', CALENDAR_TYPES, calendar
|
|
64
|
+
@calendar_type = calendar
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Set the value for blank
|
|
68
|
+
# @see blank
|
|
69
|
+
def blank=(use_blank)
|
|
70
|
+
Axlsx.validate_boolean use_blank
|
|
71
|
+
@blank = use_blank
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Serialize the object to xml
|
|
75
|
+
def to_xml_string(str = '')
|
|
76
|
+
str << "<filters #{serialized_attributes}>"
|
|
77
|
+
filter_items.each { |filter| filter.to_xml_string(str) }
|
|
78
|
+
date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) }
|
|
79
|
+
str << '</filters>'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# not entirely happy with this.
|
|
83
|
+
# filter_items should be a simple typed list that overrides << etc
|
|
84
|
+
# to create Filter objects from the inserted values. However this
|
|
85
|
+
# is most likely so rarely used...(really? do you know that?)
|
|
86
|
+
def filter_items=(values)
|
|
87
|
+
values.each do |value|
|
|
88
|
+
filter_items << Filter.new(value)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Date group items are date group filter items where you specify the
|
|
93
|
+
# date_group and a value for that option as part of the auto_filter
|
|
94
|
+
# @note This can be specified, but will not be applied to the date
|
|
95
|
+
# values in your workbook at this time.
|
|
96
|
+
def date_group_items=(options)
|
|
97
|
+
options.each do |date_group|
|
|
98
|
+
raise ArgumentError, "date_group_items should be an array of hashes specifying the options for each date_group_item" unless date_group.is_a?(Hash)
|
|
99
|
+
date_group_items << DateGroupItem.new(date_group)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def serialized_attributes(str='')
|
|
106
|
+
instance_values.each do |key, value|
|
|
107
|
+
if %(blank claendar_type).include? key.to_s
|
|
108
|
+
str << "#{Axlsx.camel(key, false)}='#{value}' "
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
str
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# This class expresses a filter criteria value.
|
|
115
|
+
class Filter
|
|
116
|
+
|
|
117
|
+
# Creates a new filter value object
|
|
118
|
+
# @param [Any] value The value of the filter. This is not restricted, but
|
|
119
|
+
# will be serialized via to_s so if you are passing an object
|
|
120
|
+
# be careful.
|
|
121
|
+
def initialize(value)
|
|
122
|
+
@val = value
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
#Filter value used in the criteria.
|
|
127
|
+
attr_accessor :val
|
|
128
|
+
|
|
129
|
+
# Serializes the filter value object
|
|
130
|
+
# @param [String] str The string to concact the serialization information to.
|
|
131
|
+
def to_xml_string(str = '')
|
|
132
|
+
str << "<filter val='#{@val.to_s}' />"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# This collection is used to express a group of dates or times which are
|
|
138
|
+
# used in an AutoFilter criteria. Values are always written in the calendar
|
|
139
|
+
# type of the first date encountered in the filter range, so that all
|
|
140
|
+
# subsequent dates, even when formatted or represented by other calendar
|
|
141
|
+
# types, can be correctly compared for the purposes of filtering.
|
|
142
|
+
class DateGroupItem
|
|
143
|
+
|
|
144
|
+
# Allowed date time groupings
|
|
145
|
+
DATE_TIME_GROUPING = %w(year month day hour minute second)
|
|
146
|
+
|
|
147
|
+
# Creates a new DateGroupItem
|
|
148
|
+
# @param [Hash] options A hash of options to use when
|
|
149
|
+
# instanciating the object
|
|
150
|
+
# @option [String] date_time_grouping the part of the date this
|
|
151
|
+
# filter should apply for grouping
|
|
152
|
+
# @option [Integer|String] year @see year
|
|
153
|
+
# @option [Integer] month @see month
|
|
154
|
+
# @option [Integer] day @see day
|
|
155
|
+
# @option [Integer] hour @see hour
|
|
156
|
+
# @option [Integer] minute @see minute
|
|
157
|
+
# @option [Integer] second @see second
|
|
158
|
+
def initialize(options={})
|
|
159
|
+
raise ArgumentError, "You must specify a year for date time grouping" unless options[:year]
|
|
160
|
+
raise ArgumentError, "You must specify a date_time_grouping when creating a DateGroupItem for auto filter" unless options[:date_time_grouping]
|
|
161
|
+
options.each do |key, value|
|
|
162
|
+
self.send("#{key}=", value) if self.respond_to?("#{key}=")
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Grouping level
|
|
167
|
+
# This must be one of year, month, day, hour, minute or second.
|
|
168
|
+
# @return [String]
|
|
169
|
+
attr_reader :date_time_grouping
|
|
170
|
+
|
|
171
|
+
# Year (4 digits)
|
|
172
|
+
# @return [Integer|String]
|
|
173
|
+
attr_reader :year
|
|
174
|
+
|
|
175
|
+
# Month (1..12)
|
|
176
|
+
# @return [Integer]
|
|
177
|
+
attr_reader :month
|
|
178
|
+
|
|
179
|
+
# Day (1-31)
|
|
180
|
+
# @return [Integer]
|
|
181
|
+
attr_reader :day
|
|
182
|
+
|
|
183
|
+
# Hour (0..23)
|
|
184
|
+
# @return [Integer]
|
|
185
|
+
attr_reader :hour
|
|
186
|
+
|
|
187
|
+
# Minute (0..59(
|
|
188
|
+
# @return [Integer]
|
|
189
|
+
attr_reader :minute
|
|
190
|
+
|
|
191
|
+
# Second (0..59)
|
|
192
|
+
# @return [Integer]
|
|
193
|
+
attr_reader :second
|
|
194
|
+
|
|
195
|
+
# The year value for the date group item
|
|
196
|
+
# This must be a four digit value
|
|
197
|
+
def year=(value)
|
|
198
|
+
RegexValidator.validate "DateGroupItem.year", /\d{4}/, value
|
|
199
|
+
@year = value
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# The month value for the date group item
|
|
203
|
+
# This must be between 1 and 12
|
|
204
|
+
def month=(value)
|
|
205
|
+
RangeValidator.validate "DateGroupItem.month", 0, 12, value
|
|
206
|
+
@month = value
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# The day value for the date group item
|
|
210
|
+
# This must be between 1 and 31
|
|
211
|
+
# @note no attempt is made to ensure the date value is valid for any given month
|
|
212
|
+
def day=(value)
|
|
213
|
+
RangeValidator.validate "DateGroupItem.day", 0, 31, value
|
|
214
|
+
@day = value
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# The hour value for the date group item
|
|
218
|
+
# # this must be between 0 and 23
|
|
219
|
+
def hour=(value)
|
|
220
|
+
RangeValidator.validate "DateGroupItem.hour", 0, 23, value
|
|
221
|
+
@hour = value
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# The minute value for the date group item
|
|
225
|
+
# This must be between 0 and 59
|
|
226
|
+
def minute=(value)
|
|
227
|
+
RangeValidator.validate "DateGroupItem.minute", 0, 59, value
|
|
228
|
+
@minute = value
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# The second value for the date group item
|
|
232
|
+
# This must be between 0 and 59
|
|
233
|
+
def second=(value)
|
|
234
|
+
RangeValidator.validate "DateGroupItem.second", 0, 59, value
|
|
235
|
+
@second = value
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# The date time grouping for this filter.
|
|
239
|
+
def date_time_grouping=(grouping)
|
|
240
|
+
RestrictionValidator.validate 'DateGroupItem.date_time_grouping', DATE_TIME_GROUPING, grouping.to_s
|
|
241
|
+
@date_time_grouping = grouping.to_s
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Serialize the object to xml
|
|
245
|
+
# @param [String] str The string object this serialization will be concatenated to.
|
|
246
|
+
def to_xml_string(str = '')
|
|
247
|
+
str << '<dateGroupItem '
|
|
248
|
+
instance_values.each { |key, value| str << "#{key}='#{value.to_s}' " }
|
|
249
|
+
str << '/>'
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
@@ -142,7 +142,7 @@ module Axlsx
|
|
|
142
142
|
# The inline color property for the cell
|
|
143
143
|
# @return [Color]
|
|
144
144
|
attr_reader :color
|
|
145
|
-
# @param [String] The 8 character representation for an rgb color #FFFFFFFF"
|
|
145
|
+
# @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
|
|
146
146
|
def color=(v)
|
|
147
147
|
@color = v.is_a?(Color) ? v : Color.new(:rgb=>v)
|
|
148
148
|
@is_text_run = true
|
|
@@ -195,7 +195,7 @@ module Axlsx
|
|
|
195
195
|
# @option options [Symbol] scheme must be one of :none, major, :minor
|
|
196
196
|
def initialize(row, value="", options={})
|
|
197
197
|
self.row=row
|
|
198
|
-
@font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
|
|
198
|
+
@value = @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
|
|
199
199
|
@condense = @u = @vertAlign = @sz = @color = @scheme = @extend = @ssti = nil
|
|
200
200
|
@styles = row.worksheet.workbook.styles
|
|
201
201
|
@row.cells << self
|
|
@@ -261,9 +261,8 @@ module Axlsx
|
|
|
261
261
|
# @return [String]
|
|
262
262
|
def run_xml_string(str = '')
|
|
263
263
|
if is_text_run?
|
|
264
|
-
data =
|
|
264
|
+
data = instance_values.reject{|key, value| value == nil || key == 'value' || key == 'type' }
|
|
265
265
|
keys = data.keys & INLINE_STYLES
|
|
266
|
-
keys.delete ['value', 'type']
|
|
267
266
|
str << "<r><rPr>"
|
|
268
267
|
keys.each do |key|
|
|
269
268
|
case key
|
|
@@ -272,7 +271,7 @@ module Axlsx
|
|
|
272
271
|
when 'color'
|
|
273
272
|
str << data[key].to_xml_string
|
|
274
273
|
else
|
|
275
|
-
"<" << key.to_s << " val='" << data[key].to_s << "'/>"
|
|
274
|
+
str << "<" << key.to_s << " val='" << data[key].to_s << "'/>"
|
|
276
275
|
end
|
|
277
276
|
end
|
|
278
277
|
str << "</rPr>" << "<t>" << value.to_s << "</t></r>"
|
|
@@ -288,13 +287,15 @@ module Axlsx
|
|
|
288
287
|
# @param [String] str The string index the cell content will be appended to. Defaults to empty string.
|
|
289
288
|
# @return [String] xml text for the cell
|
|
290
289
|
def to_xml_string(r_index, c_index, str = '')
|
|
291
|
-
return str if @value.nil?
|
|
292
290
|
str << '<c r="' << Axlsx::cell_r(c_index, r_index) << '" s="' << @style.to_s << '" '
|
|
291
|
+
return str << '/>' if @value.nil?
|
|
292
|
+
|
|
293
293
|
case @type
|
|
294
|
+
|
|
294
295
|
when :string
|
|
295
296
|
#parse formula
|
|
296
297
|
if @value.start_with?('=')
|
|
297
|
-
str << 't="str"><f>' << @value.to_s.
|
|
298
|
+
str << 't="str"><f>' << @value.to_s.sub('=', '') << '</f>'
|
|
298
299
|
else
|
|
299
300
|
#parse shared
|
|
300
301
|
if @ssti
|
|
@@ -316,8 +317,40 @@ module Axlsx
|
|
|
316
317
|
str << '</c>'
|
|
317
318
|
end
|
|
318
319
|
|
|
320
|
+
def is_formula?
|
|
321
|
+
@type == :string && @value.to_s.start_with?('=')
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# This is still not perfect...
|
|
325
|
+
# - scaling is not linear as font sizes increst
|
|
326
|
+
# - different fonts have different mdw and char widths
|
|
327
|
+
def autowidth
|
|
328
|
+
return if is_formula? || value == nil
|
|
329
|
+
mdw = 1.78 #This is the widest width of 0..9 in arial@10px)
|
|
330
|
+
font_scale = (font_size/10.0).to_f
|
|
331
|
+
((value.to_s.count(Worksheet.thin_chars) * mdw + 5) / mdw * 256) / 256.0 * font_scale
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# returns the absolute or relative string style reference for
|
|
335
|
+
# this cell.
|
|
336
|
+
# @param [Boolean] absolute -when false a relative reference will be
|
|
337
|
+
# returned.
|
|
338
|
+
# @return [String]
|
|
339
|
+
def reference(absolute=true)
|
|
340
|
+
absolute ? r_abs : r
|
|
341
|
+
end
|
|
342
|
+
|
|
319
343
|
private
|
|
320
344
|
|
|
345
|
+
# we scale the font size if bold style is applied to either the style font or
|
|
346
|
+
# the cell itself. Yes, it is a bit of a hack, but it is much better than using
|
|
347
|
+
# imagemagick and loading metrics for every character.
|
|
348
|
+
def font_size
|
|
349
|
+
font = @styles.fonts[@styles.cellXfs[style].fontId] || @styles.fonts[0]
|
|
350
|
+
size_from_styles = (font.b || b) ? font.sz * 1.5 : font.sz
|
|
351
|
+
sz || size_from_styles
|
|
352
|
+
end
|
|
353
|
+
|
|
321
354
|
# Utility method for setting inline style attributes
|
|
322
355
|
def set_run_style( validator, attr, value)
|
|
323
356
|
return unless INLINE_STYLES.include?(attr.to_s)
|
|
@@ -352,7 +385,7 @@ module Axlsx
|
|
|
352
385
|
:boolean
|
|
353
386
|
elsif v.to_s.match(/\A[+-]?\d+?\Z/) #numeric
|
|
354
387
|
:integer
|
|
355
|
-
elsif v.to_s.match(/\A[
|
|
388
|
+
elsif v.to_s.match(/\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\Z/) #float
|
|
356
389
|
:float
|
|
357
390
|
else
|
|
358
391
|
:string
|
|
@@ -102,6 +102,21 @@ module Axlsx
|
|
|
102
102
|
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
|
+
|
|
106
|
+
# updates the width for this col based on the cells autowidth and
|
|
107
|
+
# an optionally specified fixed width
|
|
108
|
+
# @param [Cell] cell The cell to use in updating this col's width
|
|
109
|
+
# @param [Integer] fixed_width If this is specified the width is set
|
|
110
|
+
# to this value and the cell's attributes are ignored.
|
|
111
|
+
# @param [Boolean] use_autowidth If this is false, the cell's
|
|
112
|
+
# autowidth value will be ignored.
|
|
113
|
+
def update_width(cell, fixed_width=nil, use_autowidth=true)
|
|
114
|
+
if fixed_width.is_a? Numeric
|
|
115
|
+
self.width = fixed_width
|
|
116
|
+
elsif use_autowidth
|
|
117
|
+
self.width = [width || 0, cell.autowidth || 0].max
|
|
118
|
+
end
|
|
119
|
+
end
|
|
105
120
|
|
|
106
121
|
# Serialize this columns data to an xml string
|
|
107
122
|
# @param [String] str
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# The cols class manages the col object used to manage column widths.
|
|
4
|
+
# This is where the magic happens with autowidth
|
|
5
|
+
class Cols < SimpleTypedList
|
|
6
|
+
|
|
7
|
+
def initialize(worksheet)
|
|
8
|
+
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
|
9
|
+
super Col
|
|
10
|
+
@worksheet = worksheet
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_xml_string(str = '')
|
|
14
|
+
return if empty?
|
|
15
|
+
str << '<cols>'
|
|
16
|
+
each { |item| item.to_xml_string(str) }
|
|
17
|
+
str << '</cols>'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# A comment is the text data for a comment
|
|
4
|
+
class Comment
|
|
5
|
+
|
|
6
|
+
# The text to render
|
|
7
|
+
# @return [String]
|
|
8
|
+
attr_reader :text
|
|
9
|
+
|
|
10
|
+
# The author of this comment
|
|
11
|
+
# @see Comments
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_reader :author
|
|
14
|
+
|
|
15
|
+
# The owning Comments object
|
|
16
|
+
# @return [Comments]
|
|
17
|
+
attr_reader :comments
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# The string based cell position reference (e.g. 'A1') that determines the positioning of this comment
|
|
21
|
+
# @return [String]
|
|
22
|
+
attr_reader :ref
|
|
23
|
+
|
|
24
|
+
# TODO
|
|
25
|
+
# r (Rich Text Run)
|
|
26
|
+
# rPh (Phonetic Text Run)
|
|
27
|
+
# phoneticPr (Phonetic Properties)
|
|
28
|
+
|
|
29
|
+
def initialize(comments, options={})
|
|
30
|
+
raise ArgumentError, "A comment needs a parent comments object" unless comments.is_a?(Comments)
|
|
31
|
+
@comments = comments
|
|
32
|
+
options.each do |o|
|
|
33
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
|
34
|
+
end
|
|
35
|
+
yield self if block_given?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The vml shape that will render this comment
|
|
39
|
+
# @return [VmlShape]
|
|
40
|
+
def vml_shape
|
|
41
|
+
@vml_shape ||= initialize_vml_shape
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# The index of this author in a unique sorted list of all authors in
|
|
46
|
+
# the comment.
|
|
47
|
+
# @return [Integer]
|
|
48
|
+
def author_index
|
|
49
|
+
@comments.authors.index(author)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @see ref
|
|
53
|
+
def ref=(v)
|
|
54
|
+
Axlsx::DataTypeValidator.validate "Comment.ref", [String, Cell], v
|
|
55
|
+
@ref = v if v.is_a?(String)
|
|
56
|
+
@ref = v.r if v.is_a?(Cell)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @see text
|
|
60
|
+
def text=(v)
|
|
61
|
+
Axlsx::validate_string(v)
|
|
62
|
+
@text = v
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @see author
|
|
66
|
+
def author=(v)
|
|
67
|
+
@author = v
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# serialize the object
|
|
71
|
+
# @param [String] str
|
|
72
|
+
# @return [String]
|
|
73
|
+
def to_xml_string(str = "")
|
|
74
|
+
author = @comments.authors[author_index]
|
|
75
|
+
str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">'
|
|
76
|
+
str << '<text><r>'
|
|
77
|
+
str << '<rPr> <b/><color indexed="81"/></rPr>'
|
|
78
|
+
str << '<t>' << author.to_s << ':
|
|
79
|
+
</t></r>'
|
|
80
|
+
str << '<r>'
|
|
81
|
+
str << '<rPr><color indexed="81"/></rPr>'
|
|
82
|
+
str << '<t>' << text << '</t></r></text>'
|
|
83
|
+
str << '</comment>'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
# initialize the vml shape based on this comment's ref/position in the worksheet.
|
|
89
|
+
# by default, all columns are 5 columns wide and 5 rows high
|
|
90
|
+
def initialize_vml_shape
|
|
91
|
+
pos = Axlsx::name_to_indices(ref)
|
|
92
|
+
@vml_shape = VmlShape.new(:row => pos[1], :column => pos[0]) do |vml|
|
|
93
|
+
vml.left_column = vml.column
|
|
94
|
+
vml.right_column = vml.column + 2
|
|
95
|
+
vml.top_row = vml.row
|
|
96
|
+
vml.bottom_row = vml.row + 4
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
module Axlsx
|
|
3
|
+
|
|
4
|
+
# Comments is a collection of Comment objects for a worksheet
|
|
5
|
+
class Comments < SimpleTypedList
|
|
6
|
+
|
|
7
|
+
# the vml_drawing that holds the shapes for comments
|
|
8
|
+
# @return [VmlDrawing]
|
|
9
|
+
attr_reader :vml_drawing
|
|
10
|
+
|
|
11
|
+
# The worksheet that these comments belong to
|
|
12
|
+
# @return [Worksheet]
|
|
13
|
+
attr_reader :worksheet
|
|
14
|
+
|
|
15
|
+
# The index of this collection in the workbook. Effectively the index of the worksheet.
|
|
16
|
+
# @return [Integer]
|
|
17
|
+
def index
|
|
18
|
+
@worksheet.index
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The part name for this object
|
|
22
|
+
# @return [String]
|
|
23
|
+
def pn
|
|
24
|
+
"#{COMMENT_PN % (index+1)}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Creates a new Comments object
|
|
28
|
+
# @param [Worksheet] worksheet The sheet that these comments belong to.
|
|
29
|
+
def initialize(worksheet)
|
|
30
|
+
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
|
31
|
+
super(Comment)
|
|
32
|
+
@worksheet = worksheet
|
|
33
|
+
@vml_drawing = VmlDrawing.new(self)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Adds a new comment to the worksheet that owns these comments.
|
|
37
|
+
# @note the author, text and ref options are required
|
|
38
|
+
# @option options [String] author The name of the author for this comment
|
|
39
|
+
# @option options [String] text The text for this comment
|
|
40
|
+
# @option options [Stirng|Cell] ref The cell that this comment is attached to.
|
|
41
|
+
def add_comment(options={})
|
|
42
|
+
raise ArgumentError, "Comment require an author" unless options[:author]
|
|
43
|
+
raise ArgumentError, "Comment requires text" unless options[:text]
|
|
44
|
+
raise ArgumentError, "Comment requires ref" unless options[:ref]
|
|
45
|
+
@list << Comment.new(self, options)
|
|
46
|
+
yield @list.last if block_given?
|
|
47
|
+
@list.last
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# A sorted list of the unique authors in the contained comments
|
|
51
|
+
# @return [Array]
|
|
52
|
+
def authors
|
|
53
|
+
@list.map { |comment| comment.author.to_s }.uniq.sort
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The relationships required by this object
|
|
57
|
+
# @return [Array]
|
|
58
|
+
def relationships
|
|
59
|
+
[Relationship.new(VML_DRAWING_R, "../#{vml_drawing.pn}"),
|
|
60
|
+
Relationship.new(COMMENT_R, "../#{pn}"),
|
|
61
|
+
Relationship.new(COMMENT_R_NULL, "NULL")]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# serialize the object
|
|
65
|
+
# @param [String] str
|
|
66
|
+
# @return [String]
|
|
67
|
+
def to_xml_string(str="")
|
|
68
|
+
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
|
69
|
+
str << '<comments xmlns="' << XML_NS << '">'
|
|
70
|
+
str << '<authors>'
|
|
71
|
+
authors.each do |author|
|
|
72
|
+
str << '<author>' << author.to_s << '</author>'
|
|
73
|
+
end
|
|
74
|
+
str << '</authors>'
|
|
75
|
+
str << '<commentList>'
|
|
76
|
+
@list.each do |comment|
|
|
77
|
+
comment.to_xml_string str
|
|
78
|
+
end
|
|
79
|
+
str << '</commentList></comments>'
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Axlsx
|
|
2
|
+
|
|
3
|
+
# A simple, self serializing class for storing conditional formattings
|
|
4
|
+
class ConditionalFormattings < SimpleTypedList
|
|
5
|
+
|
|
6
|
+
# creates a new Tables object
|
|
7
|
+
def initialize(worksheet)
|
|
8
|
+
raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
|
|
9
|
+
super ConditionalFormatting
|
|
10
|
+
@worksheet = worksheet
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The worksheet that owns this collection of tables
|
|
14
|
+
# @return [Worksheet]
|
|
15
|
+
attr_reader :worksheet
|
|
16
|
+
|
|
17
|
+
# serialize the conditional formattings
|
|
18
|
+
def to_xml_string(str = "")
|
|
19
|
+
return if empty?
|
|
20
|
+
each { |item| item.to_xml_string(str) }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
@@ -65,7 +65,7 @@ module Axlsx
|
|
|
65
65
|
def showValue=(v); Axlsx.validate_boolean(v); @showValue = v end
|
|
66
66
|
|
|
67
67
|
# Sets the color for the data bars.
|
|
68
|
-
# @param [Color|String] The color object, or rgb string value to apply
|
|
68
|
+
# @param [Color|String] v The color object, or rgb string value to apply
|
|
69
69
|
def color=(v)
|
|
70
70
|
@color = v if v.is_a? Color
|
|
71
71
|
self.color.rgb = v if v.is_a? String
|