axlsx 2.0.1 → 2.1.0.pre
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/README.md +6 -3
- data/Rakefile +9 -10
- data/examples/IMAGE1UP.JPEG +0 -0
- data/examples/auto_filter.rb +10 -1
- data/examples/conditional_formatting/example_conditional_formatting.rb +3 -3
- data/examples/example.rb +72 -4
- 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 +30 -16
- 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/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_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 +44 -7
- data/lib/axlsx/drawing/drawing.rb +3 -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 +14 -2
- 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 +1 -1
- data/lib/axlsx/drawing/one_cell_anchor.rb +1 -1
- data/lib/axlsx/drawing/pic.rb +2 -3
- 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 +4 -4
- data/lib/axlsx/drawing/scatter_chart.rb +10 -10
- data/lib/axlsx/drawing/scatter_series.rb +26 -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 +1 -1
- data/lib/axlsx/drawing/title.rb +3 -3
- data/lib/axlsx/drawing/val_axis.rb +1 -1
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +39 -28
- data/lib/axlsx/rels/relationship.rb +1 -1
- data/lib/axlsx/rels/relationships.rb +2 -2
- 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 +1 -3
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +6 -6
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/constants.rb +106 -101
- 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/string.rb +7 -0
- data/lib/axlsx/util/validators.rb +20 -13
- 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 +19 -12
- data/lib/axlsx/workbook/workbook_view.rb +78 -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 +128 -73
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +50 -40
- data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +1 -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/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 +2 -2
- 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 +17 -24
- 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 +1 -1
- data/lib/axlsx/workbook/worksheet/rich_text.rb +35 -0
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +254 -0
- data/lib/axlsx/workbook/worksheet/row.rb +33 -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_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 +1 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +59 -30
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
- data/test/drawing/tc_axis.rb +27 -0
- data/test/drawing/tc_bubble_chart.rb +44 -0
- data/test/drawing/tc_bubble_series.rb +21 -0
- data/test/drawing/tc_data_source.rb +6 -0
- data/test/drawing/tc_line_chart.rb +5 -5
- data/test/drawing/tc_line_series.rb +10 -2
- data/test/drawing/tc_pic.rb +4 -0
- data/test/drawing/tc_scatter_series.rb +25 -1
- data/test/tc_helper.rb +1 -1
- data/test/tc_package.rb +7 -1
- data/test/util/tc_simple_typed_list.rb +1 -2
- data/test/workbook/tc_defined_name.rb +12 -4
- data/test/workbook/tc_workbook.rb +16 -2
- 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 +30 -4
- 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_page_setup.rb +3 -3
- 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 +2 -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_protection.rb +5 -5
- data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
- data/test/workbook/worksheet/tc_worksheet.rb +49 -10
- metadata +81 -55
- data/test/axlsx.qcachegrind +0 -2226
|
@@ -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,6 +5,8 @@ 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'
|
|
@@ -37,7 +39,8 @@ require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
|
|
|
37
39
|
require 'axlsx/workbook/worksheet/break'
|
|
38
40
|
require 'axlsx/workbook/worksheet/row_breaks'
|
|
39
41
|
require 'axlsx/workbook/worksheet/col_breaks'
|
|
40
|
-
|
|
42
|
+
require 'axlsx/workbook/workbook_view'
|
|
43
|
+
require 'axlsx/workbook/workbook_views'
|
|
41
44
|
|
|
42
45
|
|
|
43
46
|
require 'axlsx/workbook/worksheet/worksheet.rb'
|
|
@@ -139,6 +142,10 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
139
142
|
# @return [SimpleTypedList]
|
|
140
143
|
attr_reader :pivot_tables
|
|
141
144
|
|
|
145
|
+
# A collection of views for this workbook
|
|
146
|
+
def views
|
|
147
|
+
@views ||= WorkbookViews.new
|
|
148
|
+
end
|
|
142
149
|
|
|
143
150
|
# A collection of defined names for this workbook
|
|
144
151
|
# @note The recommended way to manage defined names is Workbook#add_defined_name
|
|
@@ -263,6 +270,10 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
263
270
|
worksheet
|
|
264
271
|
end
|
|
265
272
|
|
|
273
|
+
def add_view(options={})
|
|
274
|
+
views << WorkbookView.new(options)
|
|
275
|
+
end
|
|
276
|
+
|
|
266
277
|
# Adds a defined name to this workbook
|
|
267
278
|
# @return [DefinedName]
|
|
268
279
|
# @param [String] formula @see DefinedName
|
|
@@ -283,7 +294,7 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
283
294
|
end
|
|
284
295
|
r << Relationship.new(self, STYLES_R, STYLES_PN)
|
|
285
296
|
if use_shared_strings
|
|
286
|
-
r << Relationship.new(self, SHARED_STRINGS_R,
|
|
297
|
+
r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
|
|
287
298
|
end
|
|
288
299
|
r
|
|
289
300
|
end
|
|
@@ -327,23 +338,19 @@ require 'axlsx/workbook/worksheet/selection.rb'
|
|
|
327
338
|
# @param [String] str
|
|
328
339
|
# @return [String]
|
|
329
340
|
def to_xml_string(str='')
|
|
330
|
-
add_worksheet unless worksheets.size > 0
|
|
341
|
+
add_worksheet(name: 'Sheet1') unless worksheets.size > 0
|
|
331
342
|
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 << '"/>'
|
|
343
|
+
str << ('<workbook xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '">')
|
|
344
|
+
str << ('<workbookPr date1904="' << @@date1904.to_s << '"/>')
|
|
345
|
+
views.to_xml_string(str)
|
|
334
346
|
str << '<sheets>'
|
|
335
|
-
|
|
336
|
-
str << '<sheet name="' << sheet.name << '" sheetId="' << (index+1).to_s << '" r:id="' << sheet.rId << '"/>'
|
|
337
|
-
if defined_name = sheet.auto_filter.defined_name
|
|
338
|
-
add_defined_name defined_name, :name => '_xlnm._FilterDatabase', :local_sheet_id => index, :hidden => 1
|
|
339
|
-
end
|
|
340
|
-
end
|
|
347
|
+
worksheets.each { |sheet| sheet.to_sheet_node_xml_string(str) }
|
|
341
348
|
str << '</sheets>'
|
|
342
349
|
defined_names.to_xml_string(str)
|
|
343
350
|
unless pivot_tables.empty?
|
|
344
351
|
str << '<pivotCaches>'
|
|
345
352
|
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 << '"/>'
|
|
353
|
+
str << ('<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>')
|
|
347
354
|
end
|
|
348
355
|
str << '</pivotCaches>'
|
|
349
356
|
end
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
# @params [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
|
+
|
|
72
|
+
def to_xml_string(str = '')
|
|
73
|
+
str << '<workbookView '
|
|
74
|
+
serialized_attributes str
|
|
75
|
+
str << '></workbookView>'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
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,15 +60,20 @@ 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
|
+
CELL_TYPES = [:date, :time, :float, :integer, :richtext,
|
|
69
|
+
:string, :boolean, :iso_8601].freeze
|
|
60
70
|
|
|
61
71
|
# The index of the cellXfs item to be applied to this cell.
|
|
62
72
|
# @return [Integer]
|
|
63
73
|
# @see Axlsx::Styles
|
|
64
|
-
|
|
74
|
+
def style
|
|
75
|
+
defined?(@style) ? @style : 0
|
|
76
|
+
end
|
|
65
77
|
|
|
66
78
|
# The row this cell belongs to.
|
|
67
79
|
# @return [Row]
|
|
@@ -78,18 +90,21 @@ module Axlsx
|
|
|
78
90
|
# :string to :integer or :float, type conversions always return 0 or 0.0
|
|
79
91
|
# :string, :integer, or :float to :time conversions always return the original value as a string and set the cells type to :string.
|
|
80
92
|
# No support is currently implemented for parsing time strings.
|
|
81
|
-
|
|
93
|
+
def type
|
|
94
|
+
defined?(@type) ? @type : :string
|
|
95
|
+
end
|
|
96
|
+
|
|
82
97
|
# @see type
|
|
83
98
|
def type=(v)
|
|
84
|
-
RestrictionValidator.validate
|
|
85
|
-
@type=v
|
|
86
|
-
self.value = @value unless @value.nil?
|
|
99
|
+
RestrictionValidator.validate :cell_type, CELL_TYPES, v
|
|
100
|
+
@type = v
|
|
101
|
+
self.value = @value unless !defined?(@value) || @value.nil?
|
|
87
102
|
end
|
|
88
103
|
|
|
89
|
-
|
|
90
104
|
# The value of this cell.
|
|
91
105
|
# @return [String, Integer, Float, Time, Boolean] casted value based on cell's type attribute.
|
|
92
106
|
attr_reader :value
|
|
107
|
+
|
|
93
108
|
# @see value
|
|
94
109
|
def value=(v)
|
|
95
110
|
#TODO: consider doing value based type determination first?
|
|
@@ -99,16 +114,20 @@ module Axlsx
|
|
|
99
114
|
# Indicates that the cell has one or more of the custom cell styles applied.
|
|
100
115
|
# @return [Boolean]
|
|
101
116
|
def is_text_run?
|
|
102
|
-
@is_text_run
|
|
117
|
+
defined?(@is_text_run) && @is_text_run && !contains_rich_text?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def contains_rich_text?
|
|
121
|
+
type == :richtext
|
|
103
122
|
end
|
|
104
|
-
|
|
123
|
+
|
|
105
124
|
# Indicates if the cell is good for shared string table
|
|
106
125
|
def plain_string?
|
|
107
|
-
|
|
126
|
+
type == :string && # String typed
|
|
108
127
|
!is_text_run? && # No inline styles
|
|
109
128
|
!@value.nil? && # Not nil
|
|
110
129
|
!@value.empty? && # Not empty
|
|
111
|
-
!@value.start_with?(
|
|
130
|
+
!@value.start_with?(?=) # Not a formula
|
|
112
131
|
end
|
|
113
132
|
|
|
114
133
|
# The inline font_name property for the cell
|
|
@@ -231,7 +250,7 @@ module Axlsx
|
|
|
231
250
|
attr_reader :vertAlign
|
|
232
251
|
# @see vertAlign
|
|
233
252
|
def vertAlign=(v)
|
|
234
|
-
RestrictionValidator.validate
|
|
253
|
+
RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v
|
|
235
254
|
set_run_style nil, :vertAlign, v
|
|
236
255
|
end
|
|
237
256
|
|
|
@@ -241,7 +260,7 @@ module Axlsx
|
|
|
241
260
|
attr_reader :scheme
|
|
242
261
|
# @see scheme
|
|
243
262
|
def scheme=(v)
|
|
244
|
-
RestrictionValidator.validate
|
|
263
|
+
RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v
|
|
245
264
|
set_run_style nil, :scheme, v
|
|
246
265
|
end
|
|
247
266
|
|
|
@@ -251,14 +270,14 @@ module Axlsx
|
|
|
251
270
|
|
|
252
271
|
# @return [Integer] The index of the cell in the containing row.
|
|
253
272
|
def index
|
|
254
|
-
@row.
|
|
273
|
+
@row.index(self)
|
|
255
274
|
end
|
|
256
275
|
|
|
257
276
|
# @return [String] The alpha(column)numeric(row) reference for this sell.
|
|
258
277
|
# @example Relative Cell Reference
|
|
259
278
|
# ws.rows.first.cells.first.r #=> "A1"
|
|
260
279
|
def r
|
|
261
|
-
Axlsx::cell_r index, @row.
|
|
280
|
+
Axlsx::cell_r index, @row.row_index
|
|
262
281
|
end
|
|
263
282
|
|
|
264
283
|
# @return [String] The absolute alpha(column)numeric(row) reference for this sell.
|
|
@@ -272,26 +291,26 @@ module Axlsx
|
|
|
272
291
|
# @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range.
|
|
273
292
|
def style=(v)
|
|
274
293
|
Axlsx::validate_unsigned_int(v)
|
|
275
|
-
count =
|
|
294
|
+
count = styles.cellXfs.size
|
|
276
295
|
raise ArgumentError, "Invalid cellXfs id" unless v < count
|
|
277
296
|
@style = v
|
|
278
297
|
end
|
|
279
298
|
|
|
280
|
-
# @return [Array] of x/y coordinates in the
|
|
299
|
+
# @return [Array] of x/y coordinates in the sheet for this cell.
|
|
281
300
|
def pos
|
|
282
|
-
[index, row.
|
|
301
|
+
[index, row.row_index]
|
|
283
302
|
end
|
|
284
303
|
|
|
285
304
|
# Merges all the cells in a range created between this cell and the cell or string name for a cell provided
|
|
286
305
|
# @see worksheet.merge_cells
|
|
287
306
|
# @param [Cell, String] target The last cell, or str ref for the cell in the merge range
|
|
288
307
|
def merge(target)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
self.row.worksheet.merge_cells "#{
|
|
308
|
+
start, stop = if target.is_a?(String)
|
|
309
|
+
[self.r, target]
|
|
310
|
+
elsif(target.is_a?(Cell))
|
|
311
|
+
Axlsx.sort_cells([self, target]).map { |c| c.r }
|
|
312
|
+
end
|
|
313
|
+
self.row.worksheet.merge_cells "#{start}:#{stop}" unless stop.nil?
|
|
295
314
|
end
|
|
296
315
|
|
|
297
316
|
# Serializes the cell
|
|
@@ -304,17 +323,11 @@ module Axlsx
|
|
|
304
323
|
end
|
|
305
324
|
|
|
306
325
|
def is_formula?
|
|
307
|
-
|
|
326
|
+
type == :string && @value.to_s.start_with?(?=)
|
|
308
327
|
end
|
|
309
328
|
|
|
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
|
|
329
|
+
def is_array_formula?
|
|
330
|
+
type == :string && @value.to_s.start_with?('{=') && @value.to_s.end_with?('}')
|
|
318
331
|
end
|
|
319
332
|
|
|
320
333
|
# returns the absolute or relative string style reference for
|
|
@@ -326,21 +339,69 @@ module Axlsx
|
|
|
326
339
|
absolute ? r_abs : r
|
|
327
340
|
end
|
|
328
341
|
|
|
342
|
+
# Creates a defined name in the workbook for this cell.
|
|
343
|
+
def name=(label)
|
|
344
|
+
row.worksheet.workbook.add_defined_name "#{row.worksheet.name}!#{r_abs}", name: label
|
|
345
|
+
@name = label
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# returns the name of the cell
|
|
349
|
+
attr_reader :name
|
|
350
|
+
|
|
351
|
+
def autowidth
|
|
352
|
+
return if is_formula? || value.nil?
|
|
353
|
+
if contains_rich_text?
|
|
354
|
+
string_width('', font_size) + value.autowidth
|
|
355
|
+
elsif styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text
|
|
356
|
+
max_width = 0
|
|
357
|
+
value.to_s.split(/\r?\n/).each do |line|
|
|
358
|
+
width = string_width(line, font_size)
|
|
359
|
+
max_width = width if width > max_width
|
|
360
|
+
end
|
|
361
|
+
max_width
|
|
362
|
+
else
|
|
363
|
+
string_width(value, font_size)
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# Returns the sanatized value
|
|
368
|
+
# TODO find a better way to do this as it accounts for 30% of
|
|
369
|
+
# processing time in benchmarking...
|
|
370
|
+
def clean_value
|
|
371
|
+
if type == :string && !Axlsx::trust_input
|
|
372
|
+
Axlsx::sanitize(::CGI.escapeHTML(@value.to_s))
|
|
373
|
+
else
|
|
374
|
+
@value.to_s
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
329
378
|
private
|
|
379
|
+
|
|
380
|
+
def styles
|
|
381
|
+
row.worksheet.styles
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# Returns the width of a string according to the current style
|
|
385
|
+
# This is still not perfect...
|
|
386
|
+
# - scaling is not linear as font sizes increase
|
|
387
|
+
def string_width(string, font_size)
|
|
388
|
+
font_scale = font_size / 10.0
|
|
389
|
+
(string.to_s.count(Worksheet::THIN_CHARS) + 3.0) * (font_size/10.0)
|
|
390
|
+
end
|
|
330
391
|
|
|
331
392
|
# we scale the font size if bold style is applied to either the style font or
|
|
332
393
|
# the cell itself. Yes, it is a bit of a hack, but it is much better than using
|
|
333
394
|
# imagemagick and loading metrics for every character.
|
|
334
395
|
def font_size
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
396
|
+
return sz if sz
|
|
397
|
+
font = styles.fonts[styles.cellXfs[style].fontId] || styles.fonts[0]
|
|
398
|
+
(font.b || (defined?(@b) && @b)) ? (font.sz * 1.5) : font.sz
|
|
338
399
|
end
|
|
339
400
|
|
|
340
401
|
# 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
|
|
402
|
+
def set_run_style(validator, attr, value)
|
|
403
|
+
return unless INLINE_STYLES.include?(attr.to_sym)
|
|
404
|
+
Axlsx.send(validator, value) unless validator.nil?
|
|
344
405
|
self.instance_variable_set :"@#{attr.to_s}", value
|
|
345
406
|
@is_text_run = true
|
|
346
407
|
end
|
|
@@ -351,9 +412,6 @@ module Axlsx
|
|
|
351
412
|
@ssti = v
|
|
352
413
|
end
|
|
353
414
|
|
|
354
|
-
# assigns the owning row for this cell.
|
|
355
|
-
def row=(v) @row=v end
|
|
356
|
-
|
|
357
415
|
# Determines the cell type based on the cell value.
|
|
358
416
|
# @note This is only used when a cell is created but no :type option is specified, the following rules apply:
|
|
359
417
|
# 1. If the value is an instance of Date, the type is set to :date
|
|
@@ -369,15 +427,14 @@ module Axlsx
|
|
|
369
427
|
:time
|
|
370
428
|
elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
|
371
429
|
:boolean
|
|
372
|
-
elsif v.to_s =~
|
|
430
|
+
elsif v.to_s =~ Axlsx::NUMERIC_REGEX
|
|
373
431
|
:integer
|
|
374
|
-
elsif v.to_s =~
|
|
432
|
+
elsif v.to_s =~ Axlsx::FLOAT_REGEX
|
|
375
433
|
: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/
|
|
434
|
+
elsif v.to_s =~ Axlsx::ISO_8601_REGEX
|
|
380
435
|
:iso_8601
|
|
436
|
+
elsif v.is_a? RichText
|
|
437
|
+
:richtext
|
|
381
438
|
else
|
|
382
439
|
:string
|
|
383
440
|
end
|
|
@@ -388,27 +445,25 @@ module Axlsx
|
|
|
388
445
|
# 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
446
|
# @see Axlsx#date1904
|
|
390
447
|
def cast_value(v)
|
|
391
|
-
return
|
|
392
|
-
|
|
448
|
+
return v if v.is_a?(RichText) || v.nil?
|
|
449
|
+
case type
|
|
450
|
+
when :date
|
|
393
451
|
self.style = STYLE_DATE if self.style == 0
|
|
394
452
|
v
|
|
395
|
-
|
|
453
|
+
when :time
|
|
396
454
|
self.style = STYLE_DATE if self.style == 0
|
|
397
455
|
v.respond_to?(:to_time) ? v.to_time : v
|
|
398
|
-
|
|
456
|
+
when :float
|
|
399
457
|
v.to_f
|
|
400
|
-
|
|
458
|
+
when :integer
|
|
401
459
|
v.to_i
|
|
402
|
-
|
|
460
|
+
when :boolean
|
|
403
461
|
v ? 1 : 0
|
|
404
|
-
|
|
462
|
+
when :iso_8601
|
|
405
463
|
#consumer is responsible for ensuring the iso_8601 format when specifying this type
|
|
406
464
|
v
|
|
407
465
|
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)
|
|
466
|
+
v.to_s
|
|
412
467
|
end
|
|
413
468
|
end
|
|
414
469
|
|