caxlsx 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +41 -33
- data/Rakefile +9 -11
- data/examples/auto_filter.rb +10 -1
- data/examples/conditional_formatting/example_conditional_formatting.rb +18 -3
- data/examples/data_validation.rb +57 -40
- data/examples/example.rb +115 -7
- data/examples/merge_cells.rb +17 -0
- data/examples/no_grid_with_borders.rb +18 -0
- data/examples/pivot_test.rb +63 -0
- data/examples/split.rb +16 -0
- data/lib/axlsx.rb +34 -15
- data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +5 -5
- data/lib/axlsx/drawing/area_chart.rb +99 -0
- data/lib/axlsx/drawing/area_series.rb +110 -0
- data/lib/axlsx/drawing/axes.rb +1 -1
- data/lib/axlsx/drawing/axis.rb +12 -9
- data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
- data/lib/axlsx/drawing/bar_chart.rb +143 -0
- data/lib/axlsx/drawing/bar_series.rb +9 -9
- data/lib/axlsx/drawing/bubble_chart.rb +59 -0
- data/lib/axlsx/drawing/bubble_series.rb +63 -0
- data/lib/axlsx/drawing/cat_axis.rb +5 -5
- data/lib/axlsx/drawing/chart.rb +52 -8
- data/lib/axlsx/drawing/d_lbls.rb +3 -3
- data/lib/axlsx/drawing/drawing.rb +6 -1
- data/lib/axlsx/drawing/graphic_frame.rb +3 -3
- data/lib/axlsx/drawing/hyperlink.rb +1 -3
- data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/line_chart.rb +10 -10
- data/lib/axlsx/drawing/line_series.rb +32 -3
- data/lib/axlsx/drawing/marker.rb +1 -1
- data/lib/axlsx/drawing/num_data.rb +4 -4
- data/lib/axlsx/drawing/num_data_source.rb +6 -6
- data/lib/axlsx/drawing/num_val.rb +3 -1
- data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
- data/lib/axlsx/drawing/pic.rb +25 -19
- data/lib/axlsx/drawing/picture_locking.rb +1 -3
- data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
- data/lib/axlsx/drawing/pie_series.rb +6 -6
- data/lib/axlsx/drawing/scaling.rb +6 -6
- data/lib/axlsx/drawing/scatter_chart.rb +10 -10
- data/lib/axlsx/drawing/scatter_series.rb +40 -7
- data/lib/axlsx/drawing/ser_axis.rb +2 -2
- data/lib/axlsx/drawing/series.rb +3 -3
- data/lib/axlsx/drawing/series_title.rb +2 -2
- data/lib/axlsx/drawing/str_data.rb +3 -3
- data/lib/axlsx/drawing/str_val.rb +3 -1
- data/lib/axlsx/drawing/title.rb +22 -4
- data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
- data/lib/axlsx/drawing/val_axis.rb +1 -1
- data/lib/axlsx/drawing/view_3D.rb +2 -2
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +33 -31
- data/lib/axlsx/rels/relationship.rb +1 -1
- data/lib/axlsx/rels/relationships.rb +7 -4
- data/lib/axlsx/stylesheet/border_pr.rb +2 -2
- data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
- data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
- data/lib/axlsx/stylesheet/cell_style.rb +1 -3
- data/lib/axlsx/stylesheet/color.rb +1 -3
- data/lib/axlsx/stylesheet/font.rb +1 -1
- data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +7 -7
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/constants.rb +107 -99
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +2 -1
- data/lib/axlsx/util/parser.rb +4 -4
- data/lib/axlsx/util/serialized_attributes.rb +16 -6
- data/lib/axlsx/util/simple_typed_list.rb +28 -52
- data/lib/axlsx/util/storage.rb +4 -4
- data/lib/axlsx/util/validators.rb +29 -17
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/defined_name.rb +11 -12
- data/lib/axlsx/workbook/defined_names.rb +2 -2
- data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
- data/lib/axlsx/workbook/workbook.rb +36 -11
- data/lib/axlsx/workbook/workbook_view.rb +80 -0
- data/lib/axlsx/workbook/workbook_views.rb +22 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
- data/lib/axlsx/workbook/worksheet/break.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cell.rb +136 -74
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
- data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
- data/lib/axlsx/workbook/worksheet/col.rb +7 -10
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
- data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
- data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
- data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
- data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
- data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
- data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
- data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
- data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
- data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
- data/lib/axlsx/workbook/worksheet/row.rb +40 -51
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/table.rb +6 -6
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +64 -78
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
- data/test/drawing/tc_area_chart.rb +39 -0
- data/test/drawing/tc_area_series.rb +71 -0
- data/test/drawing/tc_axis.rb +27 -0
- data/test/drawing/tc_bar_chart.rb +71 -0
- data/test/drawing/tc_bubble_chart.rb +44 -0
- data/test/drawing/tc_bubble_series.rb +21 -0
- data/test/drawing/tc_chart.rb +23 -10
- data/test/drawing/tc_data_source.rb +6 -0
- data/test/drawing/tc_drawing.rb +2 -2
- data/test/drawing/tc_line_chart.rb +5 -5
- data/test/drawing/tc_line_series.rb +47 -6
- data/test/drawing/tc_pic.rb +11 -15
- data/test/drawing/tc_scatter_series.rb +36 -1
- data/test/drawing/tc_str_val.rb +9 -0
- data/test/drawing/tc_title.rb +5 -0
- data/test/stylesheet/tc_styles.rb +2 -2
- data/test/tc_axlsx.rb +31 -0
- data/test/tc_helper.rb +2 -0
- data/test/tc_package.rb +19 -1
- data/test/util/tc_mime_type_utils.rb +13 -0
- data/test/util/tc_simple_typed_list.rb +2 -3
- data/test/util/tc_validators.rb +34 -10
- data/test/workbook/tc_defined_name.rb +12 -4
- data/test/workbook/tc_shared_strings_table.rb +16 -1
- data/test/workbook/tc_workbook.rb +38 -3
- data/test/workbook/tc_workbook_view.rb +50 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
- data/test/workbook/worksheet/tc_break.rb +1 -1
- data/test/workbook/worksheet/tc_cell.rb +76 -8
- data/test/workbook/worksheet/tc_col.rb +2 -2
- data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +11 -11
- data/test/workbook/worksheet/tc_header_footer.rb +2 -2
- data/test/workbook/worksheet/tc_icon_set.rb +1 -1
- data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
- data/test/workbook/worksheet/tc_page_setup.rb +3 -3
- data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
- data/test/workbook/worksheet/tc_print_options.rb +1 -1
- data/test/workbook/worksheet/tc_rich_text.rb +44 -0
- data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
- data/test/workbook/worksheet/tc_row.rb +7 -2
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
- data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
- data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
- data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
- data/test/workbook/worksheet/tc_table.rb +2 -3
- data/test/workbook/worksheet/tc_worksheet.rb +99 -45
- metadata +89 -16
@@ -11,8 +11,8 @@ module Axlsx
|
|
11
11
|
# @param [String] str
|
12
12
|
# @return [String]
|
13
13
|
def to_xml_string(str = '')
|
14
|
-
return if
|
15
|
-
str <<
|
14
|
+
return if empty?
|
15
|
+
str << '<definedNames>'
|
16
16
|
each { |defined_name| defined_name.to_xml_string(str) }
|
17
17
|
str << '</definedNames>'
|
18
18
|
end
|
@@ -38,7 +38,7 @@ module Axlsx
|
|
38
38
|
@xml_space = xml_space
|
39
39
|
@unique_cells = {}
|
40
40
|
@shared_xml_string = ""
|
41
|
-
shareable_cells = cells.flatten.select{ |cell| cell.plain_string? }
|
41
|
+
shareable_cells = cells.flatten.select{ |cell| cell.plain_string? || cell.contains_rich_text? }
|
42
42
|
@count = shareable_cells.size
|
43
43
|
resolve(shareable_cells)
|
44
44
|
end
|
@@ -47,10 +47,10 @@ module Axlsx
|
|
47
47
|
# @param [String] str
|
48
48
|
# @return [String]
|
49
49
|
def to_xml_string(str='')
|
50
|
-
|
51
|
-
str << '
|
52
|
-
str << '
|
53
|
-
str =
|
50
|
+
Axlsx::sanitize(@shared_xml_string)
|
51
|
+
str << ('<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"')
|
52
|
+
str << (' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"')
|
53
|
+
str << (' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>')
|
54
54
|
end
|
55
55
|
|
56
56
|
private
|
@@ -5,10 +5,13 @@ require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb'
|
|
5
5
|
require 'axlsx/workbook/worksheet/date_time_converter.rb'
|
6
6
|
require 'axlsx/workbook/worksheet/protected_range.rb'
|
7
7
|
require 'axlsx/workbook/worksheet/protected_ranges.rb'
|
8
|
+
require 'axlsx/workbook/worksheet/rich_text_run'
|
9
|
+
require 'axlsx/workbook/worksheet/rich_text'
|
8
10
|
require 'axlsx/workbook/worksheet/cell_serializer.rb'
|
9
11
|
require 'axlsx/workbook/worksheet/cell.rb'
|
10
12
|
require 'axlsx/workbook/worksheet/page_margins.rb'
|
11
13
|
require 'axlsx/workbook/worksheet/page_set_up_pr.rb'
|
14
|
+
require 'axlsx/workbook/worksheet/outline_pr.rb'
|
12
15
|
require 'axlsx/workbook/worksheet/page_setup.rb'
|
13
16
|
require 'axlsx/workbook/worksheet/header_footer.rb'
|
14
17
|
require 'axlsx/workbook/worksheet/print_options.rb'
|
@@ -37,7 +40,8 @@ require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
|
|
37
40
|
require 'axlsx/workbook/worksheet/break'
|
38
41
|
require 'axlsx/workbook/worksheet/row_breaks'
|
39
42
|
require 'axlsx/workbook/worksheet/col_breaks'
|
40
|
-
|
43
|
+
require 'axlsx/workbook/workbook_view'
|
44
|
+
require 'axlsx/workbook/workbook_views'
|
41
45
|
|
42
46
|
|
43
47
|
require 'axlsx/workbook/worksheet/worksheet.rb'
|
@@ -93,6 +97,15 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
93
97
|
@use_shared_strings = v
|
94
98
|
end
|
95
99
|
|
100
|
+
# If true reverse the order in which the workbook is serialized
|
101
|
+
# @return [Boolean]
|
102
|
+
attr_reader :is_reversed
|
103
|
+
|
104
|
+
def is_reversed=(v)
|
105
|
+
Axlsx::validate_boolean(v)
|
106
|
+
@is_reversed = v
|
107
|
+
end
|
108
|
+
|
96
109
|
|
97
110
|
# A collection of worksheets associated with this workbook.
|
98
111
|
# @note The recommended way to manage worksheets is add_worksheet
|
@@ -139,6 +152,10 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
139
152
|
# @return [SimpleTypedList]
|
140
153
|
attr_reader :pivot_tables
|
141
154
|
|
155
|
+
# A collection of views for this workbook
|
156
|
+
def views
|
157
|
+
@views ||= WorkbookViews.new
|
158
|
+
end
|
142
159
|
|
143
160
|
# A collection of defined names for this workbook
|
144
161
|
# @note The recommended way to manage defined names is Workbook#add_defined_name
|
@@ -263,6 +280,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
263
280
|
worksheet
|
264
281
|
end
|
265
282
|
|
283
|
+
# Adds a new WorkbookView
|
284
|
+
# @return WorkbookViews
|
285
|
+
# @option options [Hash] options passed into the added WorkbookView
|
286
|
+
# @see WorkbookView#initialize
|
287
|
+
def add_view(options={})
|
288
|
+
views << WorkbookView.new(options)
|
289
|
+
end
|
290
|
+
|
266
291
|
# Adds a defined name to this workbook
|
267
292
|
# @return [DefinedName]
|
268
293
|
# @param [String] formula @see DefinedName
|
@@ -283,7 +308,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
283
308
|
end
|
284
309
|
r << Relationship.new(self, STYLES_R, STYLES_PN)
|
285
310
|
if use_shared_strings
|
286
|
-
r << Relationship.new(self, SHARED_STRINGS_R,
|
311
|
+
r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
287
312
|
end
|
288
313
|
r
|
289
314
|
end
|
@@ -327,23 +352,23 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
327
352
|
# @param [String] str
|
328
353
|
# @return [String]
|
329
354
|
def to_xml_string(str='')
|
330
|
-
add_worksheet unless worksheets.size > 0
|
355
|
+
add_worksheet(name: 'Sheet1') unless worksheets.size > 0
|
331
356
|
str << '<?xml version="1.0" encoding="UTF-8"?>'
|
332
|
-
str << '<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">'
|
333
|
-
str << '<workbookPr date1904="' << @@date1904.to_s << '"/>'
|
357
|
+
str << ('<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">')
|
358
|
+
str << ('<workbookPr date1904="' << @@date1904.to_s << '"/>')
|
359
|
+
views.to_xml_string(str)
|
334
360
|
str << '<sheets>'
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
end
|
361
|
+
if is_reversed
|
362
|
+
worksheets.reverse_each { |sheet| sheet.to_sheet_node_xml_string(str) }
|
363
|
+
else
|
364
|
+
worksheets.each { |sheet| sheet.to_sheet_node_xml_string(str) }
|
340
365
|
end
|
341
366
|
str << '</sheets>'
|
342
367
|
defined_names.to_xml_string(str)
|
343
368
|
unless pivot_tables.empty?
|
344
369
|
str << '<pivotCaches>'
|
345
370
|
pivot_tables.each do |pivot_table|
|
346
|
-
str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
|
371
|
+
str << ('<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>')
|
347
372
|
end
|
348
373
|
str << '</pivotCaches>'
|
349
374
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# <xsd:complexType name="CT_BookView">
|
2
|
+
# <xsd:sequence>
|
3
|
+
# <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
|
4
|
+
# </xsd:sequence>
|
5
|
+
# <xsd:attribute name="visibility" type="ST_Visibility" use="optional" default="visible"/>
|
6
|
+
# <xsd:attribute name="minimized" type="xsd:boolean" use="optional" default="false"/>
|
7
|
+
# <xsd:attribute name="showHorizontalScroll" type="xsd:boolean" use="optional" default="true"/>
|
8
|
+
# <xsd:attribute name="showVerticalScroll" type="xsd:boolean" use="optional" default="true"/>
|
9
|
+
# <xsd:attribute name="showSheetTabs" type="xsd:boolean" use="optional" default="true"/>
|
10
|
+
# <xsd:attribute name="xWindow" type="xsd:int" use="optional"/>
|
11
|
+
# <xsd:attribute name="yWindow" type="xsd:int" use="optional"/>
|
12
|
+
# <xsd:attribute name="windowWidth" type="xsd:unsignedInt" use="optional"/>
|
13
|
+
# <xsd:attribute name="windowHeight" type="xsd:unsignedInt" use="optional"/>
|
14
|
+
# <xsd:attribute name="tabRatio" type="xsd:unsignedInt" use="optional" default="600"/>
|
15
|
+
# <xsd:attribute name="firstSheet" type="xsd:unsignedInt" use="optional" default="0"/>
|
16
|
+
# <xsd:attribute name="activeTab" type="xsd:unsignedInt" use="optional" default="0"/>
|
17
|
+
# <xsd:attribute name="autoFilterDateGrouping" type="xsd:boolean" use="optional"
|
18
|
+
# default="true"/>
|
19
|
+
# </xsd:complexType>
|
20
|
+
|
21
|
+
module Axlsx
|
22
|
+
|
23
|
+
# A BookView defines the display properties for a workbook.
|
24
|
+
# Units for window widths and other dimensions are expressed in twips.
|
25
|
+
# Twip measurements are portable between different display resolutions.
|
26
|
+
# The formula is (screen pixels) * (20 * 72) / (logical device dpi),
|
27
|
+
# where the logical device dpi can be different for x and y coordinates.
|
28
|
+
class WorkbookView
|
29
|
+
|
30
|
+
include Axlsx::SerializedAttributes
|
31
|
+
include Axlsx::OptionsParser
|
32
|
+
include Axlsx::Accessors
|
33
|
+
|
34
|
+
|
35
|
+
# Creates a new BookView object
|
36
|
+
# @param [Hash] options A hash of key/value pairs that will be mapped to this instances attributes.
|
37
|
+
# @option [Symbol] visibility Specifies visible state of the workbook window. The default value for this attribute is :visible.
|
38
|
+
# @option [Boolean] minimized Specifies a boolean value that indicates whether the workbook window is minimized.
|
39
|
+
# @option [Boolean] show_horizontal_scroll Specifies a boolean value that indicates whether to display the horizontal scroll bar in the user interface.
|
40
|
+
# @option [Boolean] show_vertical_scroll Specifies a boolean value that indicates whether to display the vertical scroll bar.
|
41
|
+
# @option [Boolean] show_sheet_tabs Specifies a boolean value that indicates whether to display the sheet tabs in the user interface.
|
42
|
+
# @option [Integer] tab_ratio Specifies ratio between the workbook tabs bar and the horizontal scroll bar.
|
43
|
+
# @option [Integer] first_sheet Specifies the index to the first sheet in this book view.
|
44
|
+
# @option [Integer] active_tab Specifies an unsignedInt that contains the index to the active sheet in this book view.
|
45
|
+
# @option [Integer] x_window Specifies the X coordinate for the upper left corner of the workbook window. The unit of measurement for this value is twips.
|
46
|
+
# @option [Integer] y_window Specifies the Y coordinate for the upper left corner of the workbook window. The unit of measurement for this value is twips.
|
47
|
+
# @option [Integer] window_width Specifies the width of the workbook window. The unit of measurement for this value is twips.
|
48
|
+
# @option [Integer] window_height Specifies the height of the workbook window. The unit of measurement for this value is twips.
|
49
|
+
# @option [Boolean] auto_filter_date_grouping Specifies a boolean value that indicates whether to group dates when presenting the user with filtering options in the user interface.
|
50
|
+
def initialize(options={})
|
51
|
+
parse_options options
|
52
|
+
yield self if block_given?
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
unsigned_int_attr_accessor :x_window, :y_window, :window_width, :window_height,
|
57
|
+
:tab_ratio, :first_sheet, :active_tab
|
58
|
+
|
59
|
+
validated_attr_accessor [:visibility], :validate_view_visibility
|
60
|
+
|
61
|
+
serializable_attributes :visibility, :minimized,
|
62
|
+
:show_horizontal_scroll, :show_vertical_scroll,
|
63
|
+
:show_sheet_tabs, :tab_ratio, :first_sheet, :active_tab,
|
64
|
+
:x_window, :y_window, :window_width, :window_height,
|
65
|
+
:auto_filter_date_grouping
|
66
|
+
|
67
|
+
boolean_attr_accessor :minimized, :show_horizontal_scroll, :show_vertical_scroll,
|
68
|
+
:show_sheet_tabs, :auto_filter_date_grouping
|
69
|
+
|
70
|
+
|
71
|
+
# Serialize the WorkbookView
|
72
|
+
# @param [String] str
|
73
|
+
# @return [String]
|
74
|
+
def to_xml_string(str = '')
|
75
|
+
str << '<workbookView '
|
76
|
+
serialized_attributes str
|
77
|
+
str << '></workbookView>'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# a simple types list of BookView objects
|
3
|
+
class WorkbookViews < SimpleTypedList
|
4
|
+
|
5
|
+
# creates the book views object
|
6
|
+
def initialize
|
7
|
+
super WorkbookView
|
8
|
+
end
|
9
|
+
|
10
|
+
# Serialize to xml
|
11
|
+
# @param [String] str
|
12
|
+
# @return [String]
|
13
|
+
def to_xml_string(str = '')
|
14
|
+
return if empty?
|
15
|
+
str << "<bookViews>"
|
16
|
+
each { |view| view.to_xml_string(str) }
|
17
|
+
str << '</bookViews>'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
@@ -47,8 +47,8 @@ module Axlsx
|
|
47
47
|
columns.last
|
48
48
|
end
|
49
49
|
|
50
|
-
# actually performs the filtering of rows who's cells do not
|
51
|
-
# match the filter.
|
50
|
+
# actually performs the filtering of rows who's cells do not
|
51
|
+
# match the filter.
|
52
52
|
def apply
|
53
53
|
first_cell, last_cell = range.split(':')
|
54
54
|
start_point = Axlsx::name_to_indices(first_cell)
|
@@ -237,9 +237,7 @@ include Axlsx::SerializedAttributes
|
|
237
237
|
# Serialize the object to xml
|
238
238
|
# @param [String] str The string object this serialization will be concatenated to.
|
239
239
|
def to_xml_string(str = '')
|
240
|
-
|
241
|
-
serialized_attributes str
|
242
|
-
str << '/>'
|
240
|
+
serialized_tag('dateGroupItem', str)
|
243
241
|
end
|
244
242
|
end
|
245
243
|
end
|
@@ -30,17 +30,24 @@ module Axlsx
|
|
30
30
|
# @option options [String] color an 8 letter rgb specification
|
31
31
|
# @option options [Number] formula_value The value to cache for a formula cell.
|
32
32
|
# @option options [Symbol] scheme must be one of :none, major, :minor
|
33
|
-
def initialize(row, value=
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
33
|
+
def initialize(row, value = nil, options = {})
|
34
|
+
@row = row
|
35
|
+
# Do not use instance vars if not needed to use less RAM
|
36
|
+
# And do not call parse_options on frequently used options
|
37
|
+
# to get less GC cycles
|
38
|
+
type = options.delete(:type) || cell_type_from_value(value)
|
39
|
+
self.type = type unless type == :string
|
40
|
+
|
41
|
+
|
42
|
+
val = options.delete(:style)
|
43
|
+
self.style = val unless val.nil? || val == 0
|
44
|
+
val = options.delete(:formula_value)
|
45
|
+
self.formula_value = val unless val.nil?
|
46
|
+
|
47
|
+
parse_options(options)
|
48
|
+
|
49
|
+
self.value = value
|
50
|
+
value.cell = self if contains_rich_text?
|
44
51
|
end
|
45
52
|
|
46
53
|
# this is the cached value for formula cells. If you want the values to render in iOS/Mac OSX preview
|
@@ -53,21 +60,27 @@ module Axlsx
|
|
53
60
|
# needs to define bla=(v) and bla methods on the class that hook into a
|
54
61
|
# set_attr method that kicks the suplied validator and updates the instance_variable
|
55
62
|
# for the key
|
56
|
-
INLINE_STYLES = [
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
INLINE_STYLES = [:value, :type, :font_name, :charset,
|
64
|
+
:family, :b, :i, :strike, :outline,
|
65
|
+
:shadow, :condense, :extend, :u,
|
66
|
+
:vertAlign, :sz, :color, :scheme].freeze
|
67
|
+
|
68
|
+
# An array of valid cell types
|
69
|
+
CELL_TYPES = [:date, :time, :float, :integer, :richtext,
|
70
|
+
:string, :boolean, :iso_8601, :text].freeze
|
60
71
|
|
61
72
|
# The index of the cellXfs item to be applied to this cell.
|
62
73
|
# @return [Integer]
|
63
74
|
# @see Axlsx::Styles
|
64
|
-
|
75
|
+
def style
|
76
|
+
defined?(@style) ? @style : 0
|
77
|
+
end
|
65
78
|
|
66
79
|
# The row this cell belongs to.
|
67
80
|
# @return [Row]
|
68
81
|
attr_reader :row
|
69
82
|
|
70
|
-
# The cell's data type.
|
83
|
+
# The cell's data type.
|
71
84
|
# Changing the type for a cell will recast the value into that type. If no type option is specified in the constructor, the type is
|
72
85
|
# automatically determed.
|
73
86
|
# @see Cell#cell_type_from_value
|
@@ -78,18 +91,21 @@ module Axlsx
|
|
78
91
|
# :string to :integer or :float, type conversions always return 0 or 0.0
|
79
92
|
# :string, :integer, or :float to :time conversions always return the original value as a string and set the cells type to :string.
|
80
93
|
# No support is currently implemented for parsing time strings.
|
81
|
-
|
94
|
+
def type
|
95
|
+
defined?(@type) ? @type : :string
|
96
|
+
end
|
97
|
+
|
82
98
|
# @see type
|
83
99
|
def type=(v)
|
84
|
-
RestrictionValidator.validate
|
85
|
-
@type=v
|
86
|
-
self.value = @value unless @value.nil?
|
100
|
+
RestrictionValidator.validate :cell_type, CELL_TYPES, v
|
101
|
+
@type = v
|
102
|
+
self.value = @value unless !defined?(@value) || @value.nil?
|
87
103
|
end
|
88
104
|
|
89
|
-
|
90
105
|
# The value of this cell.
|
91
106
|
# @return [String, Integer, Float, Time, Boolean] casted value based on cell's type attribute.
|
92
107
|
attr_reader :value
|
108
|
+
|
93
109
|
# @see value
|
94
110
|
def value=(v)
|
95
111
|
#TODO: consider doing value based type determination first?
|
@@ -99,16 +115,20 @@ module Axlsx
|
|
99
115
|
# Indicates that the cell has one or more of the custom cell styles applied.
|
100
116
|
# @return [Boolean]
|
101
117
|
def is_text_run?
|
102
|
-
@is_text_run
|
118
|
+
defined?(@is_text_run) && @is_text_run && !contains_rich_text?
|
119
|
+
end
|
120
|
+
|
121
|
+
def contains_rich_text?
|
122
|
+
type == :richtext
|
103
123
|
end
|
104
124
|
|
105
125
|
# Indicates if the cell is good for shared string table
|
106
126
|
def plain_string?
|
107
|
-
|
127
|
+
(type == :string || type == :text) && # String typed
|
108
128
|
!is_text_run? && # No inline styles
|
109
129
|
!@value.nil? && # Not nil
|
110
130
|
!@value.empty? && # Not empty
|
111
|
-
!@value.start_with?(
|
131
|
+
!@value.start_with?(?=) # Not a formula
|
112
132
|
end
|
113
133
|
|
114
134
|
# The inline font_name property for the cell
|
@@ -231,7 +251,7 @@ module Axlsx
|
|
231
251
|
attr_reader :vertAlign
|
232
252
|
# @see vertAlign
|
233
253
|
def vertAlign=(v)
|
234
|
-
RestrictionValidator.validate
|
254
|
+
RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v
|
235
255
|
set_run_style nil, :vertAlign, v
|
236
256
|
end
|
237
257
|
|
@@ -241,7 +261,7 @@ module Axlsx
|
|
241
261
|
attr_reader :scheme
|
242
262
|
# @see scheme
|
243
263
|
def scheme=(v)
|
244
|
-
RestrictionValidator.validate
|
264
|
+
RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v
|
245
265
|
set_run_style nil, :scheme, v
|
246
266
|
end
|
247
267
|
|
@@ -251,14 +271,14 @@ module Axlsx
|
|
251
271
|
|
252
272
|
# @return [Integer] The index of the cell in the containing row.
|
253
273
|
def index
|
254
|
-
@row.
|
274
|
+
@row.index(self)
|
255
275
|
end
|
256
276
|
|
257
277
|
# @return [String] The alpha(column)numeric(row) reference for this sell.
|
258
278
|
# @example Relative Cell Reference
|
259
279
|
# ws.rows.first.cells.first.r #=> "A1"
|
260
280
|
def r
|
261
|
-
Axlsx::cell_r index, @row.
|
281
|
+
Axlsx::cell_r index, @row.row_index
|
262
282
|
end
|
263
283
|
|
264
284
|
# @return [String] The absolute alpha(column)numeric(row) reference for this sell.
|
@@ -272,26 +292,26 @@ module Axlsx
|
|
272
292
|
# @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
|
273
293
|
def style=(v)
|
274
294
|
Axlsx::validate_unsigned_int(v)
|
275
|
-
count =
|
295
|
+
count = styles.cellXfs.size
|
276
296
|
raise ArgumentError, "Invalid cellXfs id" unless v < count
|
277
297
|
@style = v
|
278
298
|
end
|
279
299
|
|
280
|
-
# @return [Array] of x/y coordinates in the
|
300
|
+
# @return [Array] of x/y coordinates in the sheet for this cell.
|
281
301
|
def pos
|
282
|
-
[index, row.
|
302
|
+
[index, row.row_index]
|
283
303
|
end
|
284
304
|
|
285
305
|
# Merges all the cells in a range created between this cell and the cell or string name for a cell provided
|
286
306
|
# @see worksheet.merge_cells
|
287
307
|
# @param [Cell, String] target The last cell, or str ref for the cell in the merge range
|
288
308
|
def merge(target)
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
self.row.worksheet.merge_cells "#{
|
309
|
+
start, stop = if target.is_a?(String)
|
310
|
+
[self.r, target]
|
311
|
+
elsif(target.is_a?(Cell))
|
312
|
+
Axlsx.sort_cells([self, target]).map { |c| c.r }
|
313
|
+
end
|
314
|
+
self.row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
|
295
315
|
end
|
296
316
|
|
297
317
|
# Serializes the cell
|
@@ -304,17 +324,11 @@ module Axlsx
|
|
304
324
|
end
|
305
325
|
|
306
326
|
def is_formula?
|
307
|
-
|
327
|
+
type == :string && @value.to_s.start_with?(?=)
|
308
328
|
end
|
309
329
|
|
310
|
-
|
311
|
-
|
312
|
-
# - different fonts have different mdw and char widths
|
313
|
-
def autowidth
|
314
|
-
return if is_formula? || value == nil
|
315
|
-
mdw = 1.78 #This is the widest width of 0..9 in arial@10px)
|
316
|
-
font_scale = (font_size/10.0).to_f
|
317
|
-
((value.to_s.count(Worksheet.thin_chars) * mdw + 5) / mdw * 256) / 256.0 * font_scale
|
330
|
+
def is_array_formula?
|
331
|
+
type == :string && @value.to_s.start_with?('{=') && @value.to_s.end_with?('}')
|
318
332
|
end
|
319
333
|
|
320
334
|
# returns the absolute or relative string style reference for
|
@@ -326,21 +340,71 @@ module Axlsx
|
|
326
340
|
absolute ? r_abs : r
|
327
341
|
end
|
328
342
|
|
343
|
+
# Creates a defined name in the workbook for this cell.
|
344
|
+
def name=(label)
|
345
|
+
row.worksheet.workbook.add_defined_name "#{row.worksheet.name}!#{r_abs}", name: label
|
346
|
+
@name = label
|
347
|
+
end
|
348
|
+
|
349
|
+
# returns the name of the cell
|
350
|
+
attr_reader :name
|
351
|
+
|
352
|
+
# Attempts to determine the correct width for this cell's content
|
353
|
+
# @return [Float]
|
354
|
+
def autowidth
|
355
|
+
return if is_formula? || value.nil?
|
356
|
+
if contains_rich_text?
|
357
|
+
string_width('', font_size) + value.autowidth
|
358
|
+
elsif styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text
|
359
|
+
max_width = 0
|
360
|
+
value.to_s.split(/\r?\n/).each do |line|
|
361
|
+
width = string_width(line, font_size)
|
362
|
+
max_width = width if width > max_width
|
363
|
+
end
|
364
|
+
max_width
|
365
|
+
else
|
366
|
+
string_width(value, font_size)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
# Returns the sanatized value
|
371
|
+
# TODO find a better way to do this as it accounts for 30% of
|
372
|
+
# processing time in benchmarking...
|
373
|
+
def clean_value
|
374
|
+
if (type == :string || type == :text) && !Axlsx::trust_input
|
375
|
+
Axlsx::sanitize(::CGI.escapeHTML(@value.to_s))
|
376
|
+
else
|
377
|
+
@value.to_s
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
329
381
|
private
|
330
382
|
|
383
|
+
def styles
|
384
|
+
row.worksheet.styles
|
385
|
+
end
|
386
|
+
|
387
|
+
# Returns the width of a string according to the current style
|
388
|
+
# This is still not perfect...
|
389
|
+
# - scaling is not linear as font sizes increase
|
390
|
+
def string_width(string, font_size)
|
391
|
+
font_scale = font_size / 10.0
|
392
|
+
(string.to_s.count(Worksheet::THIN_CHARS) + 3.0) * font_scale
|
393
|
+
end
|
394
|
+
|
331
395
|
# we scale the font size if bold style is applied to either the style font or
|
332
396
|
# the cell itself. Yes, it is a bit of a hack, but it is much better than using
|
333
397
|
# imagemagick and loading metrics for every character.
|
334
398
|
def font_size
|
335
|
-
|
336
|
-
|
337
|
-
|
399
|
+
return sz if sz
|
400
|
+
font = styles.fonts[styles.cellXfs[style].fontId] || styles.fonts[0]
|
401
|
+
(font.b || (defined?(@b) && @b)) ? (font.sz * 1.5) : font.sz
|
338
402
|
end
|
339
403
|
|
340
404
|
# Utility method for setting inline style attributes
|
341
|
-
def set_run_style(
|
342
|
-
return unless INLINE_STYLES.include?(attr.
|
343
|
-
Axlsx.send(validator, value) unless validator
|
405
|
+
def set_run_style(validator, attr, value)
|
406
|
+
return unless INLINE_STYLES.include?(attr.to_sym)
|
407
|
+
Axlsx.send(validator, value) unless validator.nil?
|
344
408
|
self.instance_variable_set :"@#{attr.to_s}", value
|
345
409
|
@is_text_run = true
|
346
410
|
end
|
@@ -351,9 +415,6 @@ module Axlsx
|
|
351
415
|
@ssti = v
|
352
416
|
end
|
353
417
|
|
354
|
-
# assigns the owning row for this cell.
|
355
|
-
def row=(v) @row=v end
|
356
|
-
|
357
418
|
# Determines the cell type based on the cell value.
|
358
419
|
# @note This is only used when a cell is created but no :type option is specified, the following rules apply:
|
359
420
|
# 1. If the value is an instance of Date, the type is set to :date
|
@@ -369,15 +430,14 @@ module Axlsx
|
|
369
430
|
:time
|
370
431
|
elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
371
432
|
:boolean
|
372
|
-
elsif v.to_s =~
|
433
|
+
elsif v.to_s =~ Axlsx::NUMERIC_REGEX
|
373
434
|
:integer
|
374
|
-
elsif v.to_s =~
|
435
|
+
elsif v.to_s =~ Axlsx::FLOAT_REGEX
|
375
436
|
:float
|
376
|
-
|
377
|
-
# T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?
|
378
|
-
# (Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z
|
379
|
-
elsif v.to_s =~/\A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z/
|
437
|
+
elsif v.to_s =~ Axlsx::ISO_8601_REGEX
|
380
438
|
:iso_8601
|
439
|
+
elsif v.is_a? RichText
|
440
|
+
:richtext
|
381
441
|
else
|
382
442
|
:string
|
383
443
|
end
|
@@ -388,27 +448,29 @@ module Axlsx
|
|
388
448
|
# About Time - Time in OOXML is *different* from what you might expect. The history as to why is interesting, but you can safely assume that if you are generating docs on a mac, you will want to specify Workbook.1904 as true when using time typed values.
|
389
449
|
# @see Axlsx#date1904
|
390
450
|
def cast_value(v)
|
391
|
-
return
|
392
|
-
|
451
|
+
return v if v.is_a?(RichText) || v.nil?
|
452
|
+
case type
|
453
|
+
when :date
|
393
454
|
self.style = STYLE_DATE if self.style == 0
|
394
455
|
v
|
395
|
-
|
456
|
+
when :time
|
396
457
|
self.style = STYLE_DATE if self.style == 0
|
397
|
-
v.
|
398
|
-
|
458
|
+
if !v.is_a?(Time) && v.respond_to?(:to_time)
|
459
|
+
v.to_time
|
460
|
+
else
|
461
|
+
v
|
462
|
+
end
|
463
|
+
when :float
|
399
464
|
v.to_f
|
400
|
-
|
465
|
+
when :integer
|
401
466
|
v.to_i
|
402
|
-
|
467
|
+
when :boolean
|
403
468
|
v ? 1 : 0
|
404
|
-
|
469
|
+
when :iso_8601
|
405
470
|
#consumer is responsible for ensuring the iso_8601 format when specifying this type
|
406
471
|
v
|
407
472
|
else
|
408
|
-
|
409
|
-
# TODO find a better way to do this as it accounts for 30% of
|
410
|
-
# processing time in benchmarking...
|
411
|
-
Axlsx::trust_input ? v.to_s : ::CGI.escapeHTML(v.to_s)
|
473
|
+
v.to_s
|
412
474
|
end
|
413
475
|
end
|
414
476
|
|