caxlsx 2.0.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +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
|
|