xlsxrb 0.1.16 → 0.1.17
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 +64 -0
- data/README.md +2 -2
- data/lib/xlsxrb/chart_builder.rb +41 -2
- data/lib/xlsxrb/dsl_helpers.rb +522 -6
- data/lib/xlsxrb/elements/cell.rb +34 -9
- data/lib/xlsxrb/elements/column.rb +2 -2
- data/lib/xlsxrb/elements/types.rb +1 -0
- data/lib/xlsxrb/elements/workbook.rb +48 -0
- data/lib/xlsxrb/elements/worksheet.rb +158 -11
- data/lib/xlsxrb/ooxml/reader/listeners/core_listeners.rb +22 -1
- data/lib/xlsxrb/ooxml/reader/listeners/drawing_listeners.rb +187 -24
- data/lib/xlsxrb/ooxml/reader/listeners/feature_listeners.rb +108 -1
- data/lib/xlsxrb/ooxml/reader/listeners/style_listeners.rb +16 -11
- data/lib/xlsxrb/ooxml/reader.rb +88 -0
- data/lib/xlsxrb/ooxml/styles_parser.rb +19 -11
- data/lib/xlsxrb/ooxml/workbook_parser.rb +18 -3
- data/lib/xlsxrb/ooxml/workbook_writer.rb +266 -46
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +18 -4
- data/lib/xlsxrb/ooxml/worksheet_writer.rb +289 -88
- data/lib/xlsxrb/ooxml/writer/drawing_xml.rb +579 -441
- data/lib/xlsxrb/ooxml/writer/features_xml.rb +26 -9
- data/lib/xlsxrb/ooxml/writer/styles_xml.rb +23 -9
- data/lib/xlsxrb/ooxml/writer.rb +268 -31
- data/lib/xlsxrb/ooxml/zip_writer.rb +15 -5
- data/lib/xlsxrb/stream_sheet.rb +157 -3
- data/lib/xlsxrb/stream_writer.rb +946 -74
- data/lib/xlsxrb/style_builder.rb +59 -6
- data/lib/xlsxrb/utils.rb +65 -0
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb/workbook_builder.rb +197 -14
- data/lib/xlsxrb/worksheet_builder.rb +1137 -44
- data/lib/xlsxrb.rb +302 -47
- data/sig/generated/xlsxrb/chart_builder.rbs +31 -3
- data/sig/generated/xlsxrb/dsl_helpers.rbs +119 -4
- data/sig/generated/xlsxrb/elements/cell.rbs +20 -3
- data/sig/generated/xlsxrb/elements/column.rbs +3 -3
- data/sig/generated/xlsxrb/elements/types.rbs +2 -0
- data/sig/generated/xlsxrb/elements/workbook.rbs +37 -0
- data/sig/generated/xlsxrb/elements/worksheet.rbs +82 -2
- data/sig/generated/xlsxrb/ooxml/reader/listeners/core_listeners.rbs +2 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/drawing_listeners.rbs +74 -2
- data/sig/generated/xlsxrb/ooxml/reader/listeners/feature_listeners.rbs +36 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/style_listeners.rbs +3 -0
- data/sig/generated/xlsxrb/ooxml/reader.rbs +17 -0
- data/sig/generated/xlsxrb/ooxml/styles_parser.rbs +3 -0
- data/sig/generated/xlsxrb/ooxml/workbook_parser.rbs +8 -0
- data/sig/generated/xlsxrb/ooxml/workbook_writer.rbs +8 -4
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +1 -1
- data/sig/generated/xlsxrb/ooxml/worksheet_writer.rbs +12 -1
- data/sig/generated/xlsxrb/ooxml/writer/drawing_xml.rbs +16 -0
- data/sig/generated/xlsxrb/ooxml/writer.rbs +42 -8
- data/sig/generated/xlsxrb/ooxml/zip_writer.rbs +8 -2
- data/sig/generated/xlsxrb/stream_sheet.rbs +101 -1
- data/sig/generated/xlsxrb/stream_writer.rbs +592 -23
- data/sig/generated/xlsxrb/style_builder.rbs +24 -6
- data/sig/generated/xlsxrb/utils.rbs +20 -0
- data/sig/generated/xlsxrb/workbook_builder.rbs +87 -5
- data/sig/generated/xlsxrb/worksheet_builder.rbs +554 -10
- data/sig/generated/xlsxrb.rbs +77 -16
- metadata +1 -1
|
@@ -322,13 +322,21 @@ module Xlsxrb
|
|
|
322
322
|
rpr << "<i/>" if font[:italic]
|
|
323
323
|
rpr << "<strike/>" if font[:strike]
|
|
324
324
|
if font[:underline]
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
325
|
+
u_val = font[:underline]
|
|
326
|
+
if u_val == true || u_val.to_s == "single"
|
|
327
|
+
rpr << "<u/>"
|
|
328
|
+
else
|
|
329
|
+
mapped_u = StyleBuilder::UNDERLINE_MAP[u_val.to_sym] || u_val
|
|
330
|
+
rpr << %(<u val="#{mapped_u}"/>)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
va_val = font[:vert_align] || font[:vertical_align]
|
|
334
|
+
va_val ||= "superscript" if font[:superscript]
|
|
335
|
+
va_val ||= "subscript" if font[:subscript]
|
|
336
|
+
if va_val
|
|
337
|
+
mapped_va = StyleBuilder::VERT_ALIGN_MAP[va_val.to_sym] || va_val
|
|
338
|
+
rpr << %(<vertAlign val="#{mapped_va}"/>)
|
|
330
339
|
end
|
|
331
|
-
rpr << %(<vertAlign val="#{font[:vert_align]}"/>) if font[:vert_align]
|
|
332
340
|
rpr << %(<sz val="#{font[:sz]}"/>) if font[:sz]
|
|
333
341
|
rpr << emit_color_xml(font)
|
|
334
342
|
rpr << %(<rFont val="#{xml_escape(font[:name])}"/>) if font[:name]
|
|
@@ -378,7 +386,12 @@ module Xlsxrb
|
|
|
378
386
|
t_attr = ' t="b"'
|
|
379
387
|
cached_val_str = "0"
|
|
380
388
|
end
|
|
381
|
-
|
|
389
|
+
f_tag = if value.expression && !value.expression.empty?
|
|
390
|
+
"<f#{f_attrs}>#{xml_escape(value.expression)}</f>"
|
|
391
|
+
else
|
|
392
|
+
"<f#{f_attrs}/>"
|
|
393
|
+
end
|
|
394
|
+
parts = %(<c r="#{cell_ref}"#{t_attr}#{s_attr}#{ph_attr}>#{f_tag})
|
|
382
395
|
parts << "<v>#{xml_escape(cached_val_str)}</v>" unless value.cached_value.nil?
|
|
383
396
|
parts << "</c>"
|
|
384
397
|
parts
|
|
@@ -538,13 +551,17 @@ module Xlsxrb
|
|
|
538
551
|
rule_attrs << %( percent="1") if rule[:percent]
|
|
539
552
|
rule_attrs << %( bottom="1") if rule[:bottom]
|
|
540
553
|
rule_attrs << %( text="#{xml_escape(rule[:text])}") if rule[:text]
|
|
541
|
-
|
|
554
|
+
if rule[:time_period]
|
|
555
|
+
tp = rule[:time_period]
|
|
556
|
+
tp_str = DslHelpers::CF_TIME_PERIODS[tp.to_sym] || tp.to_s
|
|
557
|
+
rule_attrs << %( timePeriod="#{tp_str}")
|
|
558
|
+
end
|
|
542
559
|
rule_attrs << %( stdDev="#{rule[:std_dev]}") if rule[:std_dev]
|
|
543
560
|
|
|
544
561
|
case type
|
|
545
562
|
when :cell_is, :expression, :above_average, :top10, :duplicate_values, :unique_values,
|
|
546
563
|
:contains_text, :not_contains_text, :begins_with, :ends_with,
|
|
547
|
-
:contains_blanks, :not_contains_blanks, :time_period
|
|
564
|
+
:contains_blanks, :not_contains_blanks, :contains_errors, :not_contains_errors, :time_period
|
|
548
565
|
formulas = rule[:formulas] || [rule[:formula]].compact
|
|
549
566
|
if formulas.empty?
|
|
550
567
|
parts << "<cfRule #{rule_attrs}/>"
|
|
@@ -231,21 +231,35 @@ module Xlsxrb
|
|
|
231
231
|
# : (untyped font) -> untyped
|
|
232
232
|
def emit_font_xml(font)
|
|
233
233
|
parts = ["<font>"]
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
if font.key?(:bold)
|
|
235
|
+
parts << (font[:bold] ? "<b/>" : '<b val="0"/>')
|
|
236
|
+
end
|
|
237
|
+
if font.key?(:italic)
|
|
238
|
+
parts << (font[:italic] ? "<i/>" : '<i val="0"/>')
|
|
239
|
+
end
|
|
240
|
+
if font.key?(:strike)
|
|
241
|
+
parts << (font[:strike] ? "<strike/>" : '<strike val="0"/>')
|
|
242
|
+
end
|
|
237
243
|
parts << "<shadow/>" if font[:shadow]
|
|
238
244
|
parts << "<outline/>" if font[:outline]
|
|
239
245
|
parts << "<condense/>" if font[:condense]
|
|
240
246
|
parts << "<extend/>" if font[:extend]
|
|
241
247
|
if font[:underline]
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
248
|
+
u_val = font[:underline]
|
|
249
|
+
if u_val == true || u_val.to_s == "single"
|
|
250
|
+
parts << "<u/>"
|
|
251
|
+
else
|
|
252
|
+
mapped_u = StyleBuilder::UNDERLINE_MAP[u_val.to_sym] || u_val
|
|
253
|
+
parts << %(<u val="#{mapped_u}"/>)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
va_val = font[:vert_align] || font[:vertical_align]
|
|
257
|
+
va_val ||= "superscript" if font[:superscript]
|
|
258
|
+
va_val ||= "subscript" if font[:subscript]
|
|
259
|
+
if va_val
|
|
260
|
+
mapped_va = StyleBuilder::VERT_ALIGN_MAP[va_val.to_sym] || va_val
|
|
261
|
+
parts << %(<vertAlign val="#{mapped_va}"/>)
|
|
247
262
|
end
|
|
248
|
-
parts << %(<vertAlign val="#{font[:vert_align]}"/>) if font[:vert_align]
|
|
249
263
|
parts << %(<sz val="#{font[:sz]}"/>) if font[:sz]
|
|
250
264
|
parts << emit_color_xml(font)
|
|
251
265
|
parts << %(<name val="#{xml_escape(font[:name])}"/>) if font[:name]
|
data/lib/xlsxrb/ooxml/writer.rb
CHANGED
|
@@ -33,10 +33,10 @@ module Xlsxrb
|
|
|
33
33
|
MAX_ROW = 1_048_576
|
|
34
34
|
MAX_COLUMN_INDEX = 16_384 # XFD
|
|
35
35
|
|
|
36
|
-
attr_reader :fonts, :fills, :borders, :xf_entries, :num_fmts
|
|
36
|
+
attr_reader :fonts, :fills, :borders, :xf_entries, :num_fmts, :dxfs
|
|
37
37
|
|
|
38
|
-
# : () -> void
|
|
39
|
-
def initialize
|
|
38
|
+
# : (?default_font: untyped?) -> void
|
|
39
|
+
def initialize(default_font: nil)
|
|
40
40
|
@sheets = { "Sheet1" => {} }
|
|
41
41
|
@column_widths = { "Sheet1" => {} }
|
|
42
42
|
@column_attrs = { "Sheet1" => {} }
|
|
@@ -50,6 +50,7 @@ module Xlsxrb
|
|
|
50
50
|
@sort_state = { "Sheet1" => nil }
|
|
51
51
|
@num_fmts = []
|
|
52
52
|
@fonts = [{ sz: 11, name: "Calibri" }]
|
|
53
|
+
default_font(default_font) if default_font
|
|
53
54
|
@fills = [{ pattern: "none" }, { pattern: "gray125" }]
|
|
54
55
|
@borders = [{ left: nil, right: nil, top: nil, bottom: nil }]
|
|
55
56
|
@xf_entries = [{ num_fmt_id: 0, font_id: 0, fill_id: 0, border_id: 0 }]
|
|
@@ -96,6 +97,9 @@ module Xlsxrb
|
|
|
96
97
|
@charts_data = { "Sheet1" => [] }
|
|
97
98
|
@shapes_data = { "Sheet1" => [] }
|
|
98
99
|
@comments_data = { "Sheet1" => [] }
|
|
100
|
+
@threaded_comments_data = { "Sheet1" => [] }
|
|
101
|
+
@threaded_comment_count = 0
|
|
102
|
+
@persons_data = []
|
|
99
103
|
@pivot_tables_data = { "Sheet1" => [] }
|
|
100
104
|
@extra_entries = {}
|
|
101
105
|
@extra_ct_defaults = {}
|
|
@@ -146,6 +150,7 @@ module Xlsxrb
|
|
|
146
150
|
@charts_data[name] = []
|
|
147
151
|
@shapes_data[name] = []
|
|
148
152
|
@comments_data[name] = []
|
|
153
|
+
@threaded_comments_data[name] = []
|
|
149
154
|
@pivot_tables_data[name] = []
|
|
150
155
|
@sheet_protection[name] = nil
|
|
151
156
|
@protected_ranges[name] = []
|
|
@@ -542,6 +547,36 @@ module Xlsxrb
|
|
|
542
547
|
@dxfs.size - 1
|
|
543
548
|
end
|
|
544
549
|
|
|
550
|
+
# Sets the workbook-wide default font (font 0).
|
|
551
|
+
#
|
|
552
|
+
# @param name [String, Hash, nil] Font name or font options Hash.
|
|
553
|
+
# @param size [Float, Integer, nil] Font size in points.
|
|
554
|
+
# @param opts [Hash] Additional font options (e.g. `bold:`, `italic:`, `family:`, `charset:`, `color:`).
|
|
555
|
+
# @return [void]
|
|
556
|
+
# @api public
|
|
557
|
+
#: (?String | Hash[Symbol, untyped]? name, ?Float | Integer | nil size, **untyped opts) -> void
|
|
558
|
+
def default_font(name = nil, size = nil, **opts)
|
|
559
|
+
if name.is_a?(Hash)
|
|
560
|
+
opts = name.merge(opts)
|
|
561
|
+
name = opts[:name]
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
font = @fonts[0] ? @fonts[0].dup : { name: "Calibri", sz: 11 }
|
|
565
|
+
font[:name] = (name || opts[:name]).to_s if name || opts[:name]
|
|
566
|
+
font[:sz] = size || opts[:size] || opts[:sz] if size || opts[:size] || opts[:sz]
|
|
567
|
+
font[:family] = opts[:family] if opts.key?(:family)
|
|
568
|
+
font[:charset] = opts[:charset] if opts.key?(:charset)
|
|
569
|
+
font[:scheme] = opts[:scheme].to_s if opts.key?(:scheme)
|
|
570
|
+
font[:color] = opts[:color] if opts.key?(:color)
|
|
571
|
+
font[:bold] = opts[:bold] if opts.key?(:bold)
|
|
572
|
+
font[:italic] = opts[:italic] if opts.key?(:italic)
|
|
573
|
+
font[:strike] = opts[:strike] if opts.key?(:strike)
|
|
574
|
+
font[:underline] = opts[:underline] if opts.key?(:underline)
|
|
575
|
+
|
|
576
|
+
@fonts[0] = font
|
|
577
|
+
end
|
|
578
|
+
alias set_default_font default_font
|
|
579
|
+
|
|
545
580
|
# Sets the indexed colors palette (array of ARGB hex strings, e.g. ["FF000000", "FFFFFFFF"]).
|
|
546
581
|
# rubocop:disable Naming/AccessorMethodName
|
|
547
582
|
# : (untyped colors) -> untyped
|
|
@@ -883,12 +918,19 @@ module Xlsxrb
|
|
|
883
918
|
# Adds a conditional formatting rule to the specified range.
|
|
884
919
|
# Options: type (:cell_is, :expression, :color_scale, :data_bar, :icon_set),
|
|
885
920
|
# operator, priority, formula/formulas, format_id, color_scale, data_bar, icon_set.
|
|
886
|
-
# : (untyped sqref, ?sheet: untyped?, **untyped opts) -> untyped
|
|
887
|
-
def add_conditional_format(sqref, sheet: nil, **opts)
|
|
921
|
+
# : (?untyped sqref, ?sheet: untyped?, **untyped opts) ?{ (ConditionalFormatBuilder) -> void } -> untyped
|
|
922
|
+
def add_conditional_format(sqref = nil, sheet: nil, **opts, &)
|
|
888
923
|
sheet_name = sheet || @sheet_order.first
|
|
889
924
|
raise ArgumentError, "unknown sheet: #{sheet_name}" unless @conditional_formats.key?(sheet_name)
|
|
890
925
|
|
|
891
|
-
|
|
926
|
+
normalized_list = DslHelpers.normalize_conditional_format(sqref, **opts, &)
|
|
927
|
+
normalized_list.each do |rule|
|
|
928
|
+
if (rule[:dxf] || rule[:font_color] || rule[:fill_color] || rule[:bold] || rule[:italic]) && rule[:format_id].nil?
|
|
929
|
+
dxf = rule.delete(:dxf) || DslHelpers.extract_dxf_from_rule!(rule)
|
|
930
|
+
rule[:format_id] = @dxfs.index(dxf) || add_dxf(**dxf) if dxf
|
|
931
|
+
end
|
|
932
|
+
@conditional_formats[sheet_name] << rule
|
|
933
|
+
end
|
|
892
934
|
end
|
|
893
935
|
|
|
894
936
|
# Returns conditional formatting rules for the first (or given) sheet.
|
|
@@ -916,7 +958,8 @@ module Xlsxrb
|
|
|
916
958
|
%i[header_row_count published comment insert_row insert_row_shift
|
|
917
959
|
header_row_dxf_id data_dxf_id totals_row_dxf_id
|
|
918
960
|
header_row_border_dxf_id table_border_dxf_id totals_row_border_dxf_id
|
|
919
|
-
header_row_cell_style totals_row_cell_style connection_id table_type
|
|
961
|
+
header_row_cell_style totals_row_cell_style connection_id table_type
|
|
962
|
+
auto_filter show_first_column show_last_column show_row_stripes show_column_stripes].each do |key|
|
|
920
963
|
tbl[key] = opts[key] if opts.key?(key)
|
|
921
964
|
end
|
|
922
965
|
@tables[sheet_name] << tbl
|
|
@@ -1278,8 +1321,8 @@ module Xlsxrb
|
|
|
1278
1321
|
# Adds a chart to the given sheet.
|
|
1279
1322
|
# type: :bar, :line, :pie. title: chart title string.
|
|
1280
1323
|
# data_ref: e.g. "Sheet1!$A$1:$B$4". cat_ref/val_ref for explicit series.
|
|
1281
|
-
# : (?type: ::Symbol, ?title: untyped?, ?title_overlay: untyped?, ?title_font: untyped?, ?title_fill_color: untyped?, ?title_no_fill: untyped?, ?title_line_color: untyped?, ?title_line_width: untyped?, ?title_line_dash: untyped?, ?title_rotation: untyped?, ?auto_title_deleted: untyped?, ?cat_ref: untyped?, ?val_ref: untyped?, ?series: untyped?, ?legend: untyped?, ?data_labels: untyped?, ?cat_axis_title: untyped?, ?val_axis_title: untyped?, ?cat_axis_title_font: untyped?, ?cat_axis_title_fill: untyped?, ?cat_axis_title_no_fill: untyped?, ?cat_axis_title_line_color: untyped?, ?cat_axis_title_line_width: untyped?, ?cat_axis_title_line_dash: untyped?, ?cat_axis_title_rotation: untyped?, ?val_axis_title_font: untyped?, ?val_axis_title_fill: untyped?, ?val_axis_title_no_fill: untyped?, ?val_axis_title_line_color: untyped?, ?val_axis_title_line_width: untyped?, ?val_axis_title_line_dash: untyped?, ?val_axis_title_rotation: untyped?, ?cat_axis_tick_lbl_pos: untyped?, ?val_axis_tick_lbl_pos: untyped?, ?cat_axis_major_gridlines: untyped?, ?val_axis_major_gridlines: untyped?, ?cat_axis_minor_gridlines: untyped?, ?val_axis_minor_gridlines: untyped?, ?cat_axis_delete: untyped?, ?val_axis_delete: untyped?, ?cat_axis_orientation: untyped?, ?val_axis_orientation: untyped?, ?cat_axis_num_fmt: untyped?, ?val_axis_num_fmt: untyped?, ?cat_axis_major_tick_mark: untyped?, ?cat_axis_minor_tick_mark: untyped?, ?val_axis_major_tick_mark: untyped?, ?val_axis_minor_tick_mark: untyped?, ?cat_axis_crosses: untyped?, ?val_axis_crosses: untyped?, ?cat_axis_crosses_at: untyped?, ?val_axis_crosses_at: untyped?, ?cat_axis_tick_lbl_skip: untyped?, ?cat_axis_tick_mark_skip: untyped?, ?cat_axis_lbl_offset: untyped?, ?cat_axis_auto: untyped?, ?cat_axis_lbl_algn: untyped?, ?cat_axis_no_multi_lvl_lbl: untyped?, ?val_axis_cross_between: untyped?, ?val_axis_major_unit: untyped?, ?val_axis_minor_unit: untyped?, ?cat_axis_scaling_max: untyped?, ?cat_axis_scaling_min: untyped?, ?val_axis_scaling_max: untyped?, ?val_axis_scaling_min: untyped?, ?cat_axis_log_base: untyped?, ?val_axis_log_base: untyped?, ?val_axis_disp_units: untyped?, ?gap_width: untyped?, ?gap_depth: untyped?, ?overlap: untyped?, ?first_slice_ang: untyped?, ?hole_size: untyped?, ?smooth: untyped?, ?marker: untyped?, ?scatter_style: untyped?, ?radar_style: untyped?, ?bar_shape: untyped?, ?bubble_3d: untyped?, ?bubble_scale: untyped?, ?show_neg_bubbles: untyped?, ?size_represents: untyped?, ?wireframe: untyped?, ?grouping: untyped?, ?bar_dir: untyped?, ?vary_colors: untyped?, ?style: untyped?, ?rounded_corners: untyped?, ?view_3d: untyped?, ?cat_axis_pos: untyped?, ?val_axis_pos: untyped?, ?name: untyped?, ?description: untyped?, ?frame_title: untyped?, ?frame_hidden: untyped?, ?frame_macro: untyped?, ?frame_no_grp: untyped?, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, ?from_col_off: untyped?, ?from_row_off: untyped?, ?to_col_off: untyped?, ?to_row_off: untyped?, ?edit_as: untyped?, ?published: untyped?, ?locks_with_sheet: untyped?, ?prints_with_sheet: untyped?, ?plot_vis_only: untyped?, ?disp_blanks_as: untyped?, ?show_d_lbls_over_max: untyped?, ?data_table: untyped?, ?plot_area_fill: untyped?, ?plot_area_no_fill: untyped?, ?plot_area_line_color: untyped?, ?plot_area_line_width: untyped?, ?plot_area_line_dash: untyped?, ?plot_area_layout: untyped?, ?floor: untyped?, ?side_wall: untyped?, ?back_wall: untyped?, ?drop_lines: untyped?, ?hi_low_lines: untyped?, ?ser_lines: untyped?, ?up_down_bars: untyped?, ?band_fmts: untyped?, ?of_pie_type: untyped?, ?split_type: untyped?, ?split_pos: untyped?, ?cust_split: untyped?, ?second_pie_size: untyped?, ?cat_axis_label_rotation: untyped?, ?val_axis_label_rotation: untyped?, ?cat_axis_font: untyped?, ?val_axis_font: untyped?, ?cat_axis_line_color: untyped?, ?cat_axis_line_width: untyped?, ?cat_axis_line_dash: untyped?, ?val_axis_line_color: untyped?, ?val_axis_line_width: untyped?, ?val_axis_line_dash: untyped?, ?cat_axis_fill: untyped?, ?cat_axis_no_fill: untyped?, ?val_axis_fill: untyped?, ?val_axis_no_fill: untyped?, ?cat_axis_type: untyped?, ?cat_axis_base_time_unit: untyped?, ?cat_axis_major_time_unit: untyped?, ?cat_axis_minor_time_unit: untyped?, ?cat_axis_major_unit: untyped?, ?cat_axis_minor_unit: untyped?, ?chart_fill: untyped?, ?chart_no_fill: untyped?, ?chart_line_color: untyped?, ?chart_line_width: untyped?, ?chart_line_dash: untyped?, ?protection: untyped?, ?print_settings: untyped?, ?chart_font: untyped?, ?sheet: untyped
|
|
1282
|
-
def add_chart(type: :bar, title: nil, title_overlay: nil, title_font: nil, title_fill_color: nil, title_no_fill: nil, title_line_color: nil, title_line_width: nil, title_line_dash: nil, title_rotation: nil, auto_title_deleted: nil, cat_ref: nil, val_ref: nil, series: nil, legend: nil, data_labels: nil, cat_axis_title: nil, val_axis_title: nil, cat_axis_title_font: nil, cat_axis_title_fill: nil, cat_axis_title_no_fill: nil, cat_axis_title_line_color: nil, cat_axis_title_line_width: nil, cat_axis_title_line_dash: nil, cat_axis_title_rotation: nil, val_axis_title_font: nil, val_axis_title_fill: nil, val_axis_title_no_fill: nil, val_axis_title_line_color: nil, val_axis_title_line_width: nil, val_axis_title_line_dash: nil, val_axis_title_rotation: nil, cat_axis_tick_lbl_pos: nil, val_axis_tick_lbl_pos: nil, cat_axis_major_gridlines: nil, val_axis_major_gridlines: nil, cat_axis_minor_gridlines: nil, val_axis_minor_gridlines: nil, cat_axis_delete: nil, val_axis_delete: nil, cat_axis_orientation: nil, val_axis_orientation: nil, cat_axis_num_fmt: nil, val_axis_num_fmt: nil, cat_axis_major_tick_mark: nil, cat_axis_minor_tick_mark: nil, val_axis_major_tick_mark: nil, val_axis_minor_tick_mark: nil, cat_axis_crosses: nil, val_axis_crosses: nil, cat_axis_crosses_at: nil, val_axis_crosses_at: nil, cat_axis_tick_lbl_skip: nil, cat_axis_tick_mark_skip: nil, cat_axis_lbl_offset: nil, cat_axis_auto: nil, cat_axis_lbl_algn: nil, cat_axis_no_multi_lvl_lbl: nil, val_axis_cross_between: nil, val_axis_major_unit: nil, val_axis_minor_unit: nil, cat_axis_scaling_max: nil, cat_axis_scaling_min: nil, val_axis_scaling_max: nil, val_axis_scaling_min: nil, cat_axis_log_base: nil, val_axis_log_base: nil, val_axis_disp_units: nil, gap_width: nil, gap_depth: nil, overlap: nil, first_slice_ang: nil, hole_size: nil, smooth: nil, marker: nil, scatter_style: nil, radar_style: nil, bar_shape: nil, bubble_3d: nil, bubble_scale: nil, show_neg_bubbles: nil, size_represents: nil, wireframe: nil, grouping: nil, bar_dir: nil, vary_colors: nil, style: nil, rounded_corners: nil, view_3d: nil, cat_axis_pos: nil, val_axis_pos: nil, name: nil, description: nil, frame_title: nil, frame_hidden: nil, frame_macro: nil, frame_no_grp: nil, from_col: 0, from_row: 0, to_col: 10, to_row: 15, from_col_off: nil, from_row_off: nil, to_col_off: nil, to_row_off: nil, edit_as: nil, published: nil, locks_with_sheet: nil, prints_with_sheet: nil, plot_vis_only: nil, disp_blanks_as: nil, show_d_lbls_over_max: nil, data_table: nil, plot_area_fill: nil, plot_area_no_fill: nil, plot_area_line_color: nil, plot_area_line_width: nil, plot_area_line_dash: nil, plot_area_layout: nil, floor: nil, side_wall: nil, back_wall: nil, drop_lines: nil, hi_low_lines: nil, ser_lines: nil, up_down_bars: nil, band_fmts: nil, of_pie_type: nil, split_type: nil, split_pos: nil, cust_split: nil, second_pie_size: nil, cat_axis_label_rotation: nil, val_axis_label_rotation: nil, cat_axis_font: nil, val_axis_font: nil, cat_axis_line_color: nil, cat_axis_line_width: nil, cat_axis_line_dash: nil, val_axis_line_color: nil, val_axis_line_width: nil, val_axis_line_dash: nil, cat_axis_fill: nil, cat_axis_no_fill: nil, val_axis_fill: nil, val_axis_no_fill: nil, cat_axis_type: nil, cat_axis_base_time_unit: nil, cat_axis_major_time_unit: nil, cat_axis_minor_time_unit: nil, cat_axis_major_unit: nil, cat_axis_minor_unit: nil, chart_fill: nil, chart_no_fill: nil, chart_line_color: nil, chart_line_width: nil, chart_line_dash: nil, protection: nil, print_settings: nil, chart_font: nil, sheet: nil)
|
|
1324
|
+
# : (?type: ::Symbol, ?title: untyped?, ?title_overlay: untyped?, ?title_font: untyped?, ?title_fill_color: untyped?, ?title_no_fill: untyped?, ?title_line_color: untyped?, ?title_line_width: untyped?, ?title_line_dash: untyped?, ?title_rotation: untyped?, ?auto_title_deleted: untyped?, ?cat_ref: untyped?, ?val_ref: untyped?, ?series: untyped?, ?legend: untyped?, ?data_labels: untyped?, ?cat_axis_title: untyped?, ?val_axis_title: untyped?, ?cat_axis_title_font: untyped?, ?cat_axis_title_fill: untyped?, ?cat_axis_title_no_fill: untyped?, ?cat_axis_title_line_color: untyped?, ?cat_axis_title_line_width: untyped?, ?cat_axis_title_line_dash: untyped?, ?cat_axis_title_rotation: untyped?, ?val_axis_title_font: untyped?, ?val_axis_title_fill: untyped?, ?val_axis_title_no_fill: untyped?, ?val_axis_title_line_color: untyped?, ?val_axis_title_line_width: untyped?, ?val_axis_title_line_dash: untyped?, ?val_axis_title_rotation: untyped?, ?cat_axis_tick_lbl_pos: untyped?, ?val_axis_tick_lbl_pos: untyped?, ?cat_axis_major_gridlines: untyped?, ?val_axis_major_gridlines: untyped?, ?cat_axis_minor_gridlines: untyped?, ?val_axis_minor_gridlines: untyped?, ?cat_axis_delete: untyped?, ?val_axis_delete: untyped?, ?cat_axis_orientation: untyped?, ?val_axis_orientation: untyped?, ?cat_axis_num_fmt: untyped?, ?val_axis_num_fmt: untyped?, ?cat_axis_major_tick_mark: untyped?, ?cat_axis_minor_tick_mark: untyped?, ?val_axis_major_tick_mark: untyped?, ?val_axis_minor_tick_mark: untyped?, ?cat_axis_crosses: untyped?, ?val_axis_crosses: untyped?, ?cat_axis_crosses_at: untyped?, ?val_axis_crosses_at: untyped?, ?cat_axis_tick_lbl_skip: untyped?, ?cat_axis_tick_mark_skip: untyped?, ?cat_axis_lbl_offset: untyped?, ?cat_axis_auto: untyped?, ?cat_axis_lbl_algn: untyped?, ?cat_axis_no_multi_lvl_lbl: untyped?, ?val_axis_cross_between: untyped?, ?val_axis_major_unit: untyped?, ?val_axis_minor_unit: untyped?, ?cat_axis_scaling_max: untyped?, ?cat_axis_scaling_min: untyped?, ?val_axis_scaling_max: untyped?, ?val_axis_scaling_min: untyped?, ?cat_axis_log_base: untyped?, ?val_axis_log_base: untyped?, ?val_axis_disp_units: untyped?, ?gap_width: untyped?, ?gap_depth: untyped?, ?overlap: untyped?, ?first_slice_ang: untyped?, ?hole_size: untyped?, ?smooth: untyped?, ?marker: untyped?, ?scatter_style: untyped?, ?radar_style: untyped?, ?bar_shape: untyped?, ?bubble_3d: untyped?, ?bubble_scale: untyped?, ?show_neg_bubbles: untyped?, ?size_represents: untyped?, ?wireframe: untyped?, ?grouping: untyped?, ?bar_dir: untyped?, ?vary_colors: untyped?, ?style: untyped?, ?rounded_corners: untyped?, ?view_3d: untyped?, ?cat_axis_pos: untyped?, ?val_axis_pos: untyped?, ?name: untyped?, ?description: untyped?, ?frame_title: untyped?, ?frame_hidden: untyped?, ?frame_macro: untyped?, ?frame_no_grp: untyped?, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, ?from_col_off: untyped?, ?from_row_off: untyped?, ?to_col_off: untyped?, ?to_row_off: untyped?, ?edit_as: untyped?, ?published: untyped?, ?locks_with_sheet: untyped?, ?prints_with_sheet: untyped?, ?plot_vis_only: untyped?, ?disp_blanks_as: untyped?, ?show_d_lbls_over_max: untyped?, ?data_table: untyped?, ?plot_area_fill: untyped?, ?plot_area_no_fill: untyped?, ?plot_area_line_color: untyped?, ?plot_area_line_width: untyped?, ?plot_area_line_dash: untyped?, ?plot_area_layout: untyped?, ?floor: untyped?, ?side_wall: untyped?, ?back_wall: untyped?, ?drop_lines: untyped?, ?hi_low_lines: untyped?, ?ser_lines: untyped?, ?up_down_bars: untyped?, ?band_fmts: untyped?, ?of_pie_type: untyped?, ?split_type: untyped?, ?split_pos: untyped?, ?cust_split: untyped?, ?second_pie_size: untyped?, ?cat_axis_label_rotation: untyped?, ?val_axis_label_rotation: untyped?, ?cat_axis_font: untyped?, ?val_axis_font: untyped?, ?cat_axis_line_color: untyped?, ?cat_axis_line_width: untyped?, ?cat_axis_line_dash: untyped?, ?val_axis_line_color: untyped?, ?val_axis_line_width: untyped?, ?val_axis_line_dash: untyped?, ?cat_axis_fill: untyped?, ?cat_axis_no_fill: untyped?, ?val_axis_fill: untyped?, ?val_axis_no_fill: untyped?, ?cat_axis_type: untyped?, ?cat_axis_base_time_unit: untyped?, ?cat_axis_major_time_unit: untyped?, ?cat_axis_minor_time_unit: untyped?, ?cat_axis_major_unit: untyped?, ?cat_axis_minor_unit: untyped?, ?chart_fill: untyped?, ?chart_no_fill: untyped?, ?chart_line_color: untyped?, ?chart_line_width: untyped?, ?chart_line_dash: untyped?, ?protection: untyped?, ?print_settings: untyped?, ?chart_font: untyped?, ?secondary_value_axis: untyped?, ?secondary_axis: untyped?, ?category_axis: untyped?, ?value_axis: untyped?, ?sheet: untyped?, **untyped extra_options) -> untyped
|
|
1325
|
+
def add_chart(type: :bar, title: nil, title_overlay: nil, title_font: nil, title_fill_color: nil, title_no_fill: nil, title_line_color: nil, title_line_width: nil, title_line_dash: nil, title_rotation: nil, auto_title_deleted: nil, cat_ref: nil, val_ref: nil, series: nil, legend: nil, data_labels: nil, cat_axis_title: nil, val_axis_title: nil, cat_axis_title_font: nil, cat_axis_title_fill: nil, cat_axis_title_no_fill: nil, cat_axis_title_line_color: nil, cat_axis_title_line_width: nil, cat_axis_title_line_dash: nil, cat_axis_title_rotation: nil, val_axis_title_font: nil, val_axis_title_fill: nil, val_axis_title_no_fill: nil, val_axis_title_line_color: nil, val_axis_title_line_width: nil, val_axis_title_line_dash: nil, val_axis_title_rotation: nil, cat_axis_tick_lbl_pos: nil, val_axis_tick_lbl_pos: nil, cat_axis_major_gridlines: nil, val_axis_major_gridlines: nil, cat_axis_minor_gridlines: nil, val_axis_minor_gridlines: nil, cat_axis_delete: nil, val_axis_delete: nil, cat_axis_orientation: nil, val_axis_orientation: nil, cat_axis_num_fmt: nil, val_axis_num_fmt: nil, cat_axis_major_tick_mark: nil, cat_axis_minor_tick_mark: nil, val_axis_major_tick_mark: nil, val_axis_minor_tick_mark: nil, cat_axis_crosses: nil, val_axis_crosses: nil, cat_axis_crosses_at: nil, val_axis_crosses_at: nil, cat_axis_tick_lbl_skip: nil, cat_axis_tick_mark_skip: nil, cat_axis_lbl_offset: nil, cat_axis_auto: nil, cat_axis_lbl_algn: nil, cat_axis_no_multi_lvl_lbl: nil, val_axis_cross_between: nil, val_axis_major_unit: nil, val_axis_minor_unit: nil, cat_axis_scaling_max: nil, cat_axis_scaling_min: nil, val_axis_scaling_max: nil, val_axis_scaling_min: nil, cat_axis_log_base: nil, val_axis_log_base: nil, val_axis_disp_units: nil, gap_width: nil, gap_depth: nil, overlap: nil, first_slice_ang: nil, hole_size: nil, smooth: nil, marker: nil, scatter_style: nil, radar_style: nil, bar_shape: nil, bubble_3d: nil, bubble_scale: nil, show_neg_bubbles: nil, size_represents: nil, wireframe: nil, grouping: nil, bar_dir: nil, vary_colors: nil, style: nil, rounded_corners: nil, view_3d: nil, cat_axis_pos: nil, val_axis_pos: nil, name: nil, description: nil, frame_title: nil, frame_hidden: nil, frame_macro: nil, frame_no_grp: nil, from_col: 0, from_row: 0, to_col: 10, to_row: 15, from_col_off: nil, from_row_off: nil, to_col_off: nil, to_row_off: nil, edit_as: nil, published: nil, locks_with_sheet: nil, prints_with_sheet: nil, plot_vis_only: nil, disp_blanks_as: nil, show_d_lbls_over_max: nil, data_table: nil, plot_area_fill: nil, plot_area_no_fill: nil, plot_area_line_color: nil, plot_area_line_width: nil, plot_area_line_dash: nil, plot_area_layout: nil, floor: nil, side_wall: nil, back_wall: nil, drop_lines: nil, hi_low_lines: nil, ser_lines: nil, up_down_bars: nil, band_fmts: nil, of_pie_type: nil, split_type: nil, split_pos: nil, cust_split: nil, second_pie_size: nil, cat_axis_label_rotation: nil, val_axis_label_rotation: nil, cat_axis_font: nil, val_axis_font: nil, cat_axis_line_color: nil, cat_axis_line_width: nil, cat_axis_line_dash: nil, val_axis_line_color: nil, val_axis_line_width: nil, val_axis_line_dash: nil, cat_axis_fill: nil, cat_axis_no_fill: nil, val_axis_fill: nil, val_axis_no_fill: nil, cat_axis_type: nil, cat_axis_base_time_unit: nil, cat_axis_major_time_unit: nil, cat_axis_minor_time_unit: nil, cat_axis_major_unit: nil, cat_axis_minor_unit: nil, chart_fill: nil, chart_no_fill: nil, chart_line_color: nil, chart_line_width: nil, chart_line_dash: nil, protection: nil, print_settings: nil, chart_font: nil, secondary_value_axis: nil, secondary_axis: nil, category_axis: nil, value_axis: nil, sheet: nil, **extra_options)
|
|
1283
1326
|
sheet_name = sheet || @sheet_order.first
|
|
1284
1327
|
raise ArgumentError, "unknown sheet: #{sheet_name}" unless @charts_data.key?(sheet_name)
|
|
1285
1328
|
|
|
@@ -1438,6 +1481,73 @@ module Xlsxrb
|
|
|
1438
1481
|
chart[:protection] = protection if protection
|
|
1439
1482
|
chart[:print_settings] = print_settings if print_settings
|
|
1440
1483
|
chart[:chart_font] = chart_font if chart_font
|
|
1484
|
+
chart[:category_axis] = category_axis if category_axis
|
|
1485
|
+
chart[:value_axis] = value_axis if value_axis
|
|
1486
|
+
chart[:secondary_value_axis] = secondary_value_axis || secondary_axis if secondary_value_axis || secondary_axis
|
|
1487
|
+
chart.merge!(extra_options) if extra_options && !extra_options.empty?
|
|
1488
|
+
|
|
1489
|
+
if chart[:category_axis].is_a?(Hash)
|
|
1490
|
+
ca = chart[:category_axis]
|
|
1491
|
+
chart[:cat_axis_title] ||= ca[:title]
|
|
1492
|
+
chart[:cat_axis_num_fmt] ||= ca[:num_fmt]
|
|
1493
|
+
chart[:cat_axis_pos] ||= ca[:pos]
|
|
1494
|
+
chart[:cat_axis_major_gridlines] = ca[:major_gridlines] if chart[:cat_axis_major_gridlines].nil? && !ca[:major_gridlines].nil?
|
|
1495
|
+
chart[:cat_axis_minor_gridlines] = ca[:minor_gridlines] if chart[:cat_axis_minor_gridlines].nil? && !ca[:minor_gridlines].nil?
|
|
1496
|
+
chart[:cat_axis_font] ||= ca[:font]
|
|
1497
|
+
chart[:cat_axis_line_color] ||= ca[:line_color]
|
|
1498
|
+
chart[:cat_axis_line_width] ||= ca[:line_width]
|
|
1499
|
+
chart[:cat_axis_line_dash] ||= ca[:line_dash]
|
|
1500
|
+
chart[:cat_axis_scaling_min] ||= ca[:min]
|
|
1501
|
+
chart[:cat_axis_scaling_max] ||= ca[:max]
|
|
1502
|
+
chart[:cat_axis_label_rotation] ||= ca[:label_rotation] || ca[:rotation]
|
|
1503
|
+
end
|
|
1504
|
+
|
|
1505
|
+
if chart[:value_axis].is_a?(Hash)
|
|
1506
|
+
va = chart[:value_axis]
|
|
1507
|
+
chart[:val_axis_title] ||= va[:title]
|
|
1508
|
+
chart[:val_axis_num_fmt] ||= va[:num_fmt]
|
|
1509
|
+
chart[:val_axis_pos] ||= va[:pos]
|
|
1510
|
+
chart[:val_axis_major_gridlines] = va[:major_gridlines] if chart[:val_axis_major_gridlines].nil? && !va[:major_gridlines].nil?
|
|
1511
|
+
chart[:val_axis_minor_gridlines] = va[:minor_gridlines] if chart[:val_axis_minor_gridlines].nil? && !va[:minor_gridlines].nil?
|
|
1512
|
+
chart[:val_axis_font] ||= va[:font]
|
|
1513
|
+
chart[:val_axis_line_color] ||= va[:line_color]
|
|
1514
|
+
chart[:val_axis_line_width] ||= va[:line_width]
|
|
1515
|
+
chart[:val_axis_line_dash] ||= va[:line_dash]
|
|
1516
|
+
chart[:val_axis_scaling_min] ||= va[:min]
|
|
1517
|
+
chart[:val_axis_scaling_max] ||= va[:max]
|
|
1518
|
+
chart[:val_axis_major_unit] ||= va[:major_unit]
|
|
1519
|
+
chart[:val_axis_minor_unit] ||= va[:minor_unit]
|
|
1520
|
+
chart[:val_axis_label_rotation] ||= va[:label_rotation] || va[:rotation]
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
if chart[:secondary_value_axis].is_a?(Hash)
|
|
1524
|
+
sva = chart[:secondary_value_axis]
|
|
1525
|
+
chart[:sec_val_axis_title] ||= sva[:title]
|
|
1526
|
+
chart[:sec_val_axis_num_fmt] ||= sva[:num_fmt]
|
|
1527
|
+
chart[:sec_val_axis_pos] ||= sva[:pos] || "r"
|
|
1528
|
+
chart[:sec_val_axis_major_gridlines] = sva[:major_gridlines] unless sva[:major_gridlines].nil?
|
|
1529
|
+
chart[:sec_val_axis_minor_gridlines] = sva[:minor_gridlines] unless sva[:minor_gridlines].nil?
|
|
1530
|
+
chart[:sec_val_axis_font] ||= sva[:font]
|
|
1531
|
+
chart[:sec_val_axis_line_color] ||= sva[:line_color]
|
|
1532
|
+
chart[:sec_val_axis_line_width] ||= sva[:line_width]
|
|
1533
|
+
chart[:sec_val_axis_line_dash] ||= sva[:line_dash]
|
|
1534
|
+
chart[:sec_val_axis_scaling_min] ||= sva[:min]
|
|
1535
|
+
chart[:sec_val_axis_scaling_max] ||= sva[:max]
|
|
1536
|
+
chart[:sec_val_axis_major_unit] ||= sva[:major_unit]
|
|
1537
|
+
chart[:sec_val_axis_minor_unit] ||= sva[:minor_unit]
|
|
1538
|
+
chart[:sec_val_axis_label_rotation] ||= sva[:label_rotation] || sva[:rotation]
|
|
1539
|
+
chart[:sec_val_axis_crosses] ||= sva[:crosses] || "max"
|
|
1540
|
+
chart[:sec_val_axis_crosses_at] ||= sva[:crosses_at]
|
|
1541
|
+
chart[:sec_val_axis_cross_between] ||= sva[:cross_between]
|
|
1542
|
+
chart[:sec_val_axis_delete] = sva[:delete] unless sva[:delete].nil?
|
|
1543
|
+
chart[:sec_val_axis_orientation] ||= sva[:orientation]
|
|
1544
|
+
chart[:sec_val_axis_log_base] ||= sva[:log_base]
|
|
1545
|
+
chart[:sec_val_axis_disp_units] ||= sva[:disp_units]
|
|
1546
|
+
chart[:sec_val_axis_major_tick_mark] ||= sva[:major_tick_mark]
|
|
1547
|
+
chart[:sec_val_axis_minor_tick_mark] ||= sva[:minor_tick_mark]
|
|
1548
|
+
chart[:sec_val_axis_tick_lbl_pos] ||= sva[:tick_lbl_pos]
|
|
1549
|
+
end
|
|
1550
|
+
|
|
1441
1551
|
@charts_data[sheet_name] << chart
|
|
1442
1552
|
end
|
|
1443
1553
|
|
|
@@ -1571,6 +1681,81 @@ module Xlsxrb
|
|
|
1571
1681
|
@comments_data[sheet_name] || []
|
|
1572
1682
|
end
|
|
1573
1683
|
|
|
1684
|
+
# Adds a threaded comment to a cell in the given sheet.
|
|
1685
|
+
# : (String | Integer cell_address, String text, ?author: untyped, ?timestamp: untyped, ?id: String?, ?parent_id: String?, ?done: bool?, ?user_id: String?, ?provider_id: String?, ?sheet: untyped?) -> Hash[Symbol, untyped]
|
|
1686
|
+
def add_threaded_comment(cell_address, text, author: "Author", timestamp: nil, id: nil, parent_id: nil, done: false, user_id: nil, provider_id: nil, sheet: nil)
|
|
1687
|
+
sheet_name = sheet || @sheet_order.first
|
|
1688
|
+
raise ArgumentError, "unknown sheet: #{sheet_name}" unless @threaded_comments_data.key?(sheet_name)
|
|
1689
|
+
|
|
1690
|
+
person = if author.is_a?(Hash)
|
|
1691
|
+
add_person(author[:display_name] || author[:name] || "Author", id: author[:id], user_id: author[:user_id], provider_id: author[:provider_id])
|
|
1692
|
+
else
|
|
1693
|
+
add_person(author, user_id: user_id, provider_id: provider_id)
|
|
1694
|
+
end
|
|
1695
|
+
|
|
1696
|
+
dt = case timestamp
|
|
1697
|
+
when Time, DateTime
|
|
1698
|
+
timestamp.to_time.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
1699
|
+
when String
|
|
1700
|
+
timestamp
|
|
1701
|
+
else
|
|
1702
|
+
Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
1703
|
+
end
|
|
1704
|
+
|
|
1705
|
+
comment_id = format_guid(id)
|
|
1706
|
+
parent_guid = parent_id ? format_guid(parent_id) : nil
|
|
1707
|
+
|
|
1708
|
+
entry = {
|
|
1709
|
+
cell: cell_address.to_s.upcase,
|
|
1710
|
+
ref: cell_address.to_s.upcase,
|
|
1711
|
+
text: text.to_s,
|
|
1712
|
+
author: person[:display_name],
|
|
1713
|
+
person_id: person[:id],
|
|
1714
|
+
id: comment_id,
|
|
1715
|
+
parent_id: parent_guid,
|
|
1716
|
+
timestamp: dt,
|
|
1717
|
+
dt: dt,
|
|
1718
|
+
done: done ? true : false
|
|
1719
|
+
}.compact
|
|
1720
|
+
@threaded_comments_data[sheet_name] << entry
|
|
1721
|
+
entry
|
|
1722
|
+
end
|
|
1723
|
+
alias threaded_comment add_threaded_comment
|
|
1724
|
+
|
|
1725
|
+
# Returns threaded comments for the first (or given) sheet.
|
|
1726
|
+
# : (?sheet: untyped?) -> Array[Hash[Symbol, untyped]]
|
|
1727
|
+
def threaded_comments(sheet: nil)
|
|
1728
|
+
sheet_name = sheet || @sheet_order.first
|
|
1729
|
+
@threaded_comments_data[sheet_name] || []
|
|
1730
|
+
end
|
|
1731
|
+
|
|
1732
|
+
# Registers a person in the workbook person list.
|
|
1733
|
+
# : (String name, ?id: String?, ?user_id: String?, ?provider_id: String?) -> Hash[Symbol, untyped]
|
|
1734
|
+
def add_person(name, id: nil, user_id: nil, provider_id: nil)
|
|
1735
|
+
person_name = name.to_s
|
|
1736
|
+
person_id = id ? format_guid(id) : nil
|
|
1737
|
+
existing = @persons_data.find do |p|
|
|
1738
|
+
(person_id && p[:id] == person_id) || p[:display_name] == person_name
|
|
1739
|
+
end
|
|
1740
|
+
return existing if existing
|
|
1741
|
+
|
|
1742
|
+
person = {
|
|
1743
|
+
id: person_id || format_guid(nil),
|
|
1744
|
+
display_name: person_name,
|
|
1745
|
+
user_id: user_id || "AD:#{person_name}",
|
|
1746
|
+
provider_id: provider_id || "AD"
|
|
1747
|
+
}
|
|
1748
|
+
@persons_data << person
|
|
1749
|
+
person
|
|
1750
|
+
end
|
|
1751
|
+
|
|
1752
|
+
# Returns the workbook person list.
|
|
1753
|
+
# : () -> Array[Hash[Symbol, untyped]]
|
|
1754
|
+
def persons
|
|
1755
|
+
@persons_data
|
|
1756
|
+
end
|
|
1757
|
+
alias person_list persons
|
|
1758
|
+
|
|
1574
1759
|
# Adds a pivot table to the given sheet.
|
|
1575
1760
|
# source_ref: data source range (e.g. "Sheet1!A1:C4").
|
|
1576
1761
|
# row_fields: array of 0-based field indices for row axis.
|
|
@@ -1717,13 +1902,16 @@ module Xlsxrb
|
|
|
1717
1902
|
sheet_charts = @charts_data[sheet_name] || []
|
|
1718
1903
|
sheet_shapes = @shapes_data[sheet_name] || []
|
|
1719
1904
|
sheet_comments = @comments_data[sheet_name] || []
|
|
1905
|
+
sheet_threaded_comments = @threaded_comments_data[sheet_name] || []
|
|
1720
1906
|
sheet_pivots = @pivot_tables_data[sheet_name] || []
|
|
1721
1907
|
has_drawing = sheet_images.any? || sheet_charts.any? || sheet_shapes.any?
|
|
1722
1908
|
has_comments = sheet_comments.any?
|
|
1909
|
+
has_tc = sheet_threaded_comments.any?
|
|
1723
1910
|
|
|
1724
1911
|
# Pre-increment counters so rels reference correct paths.
|
|
1725
1912
|
sheet_drawing_idx = has_drawing ? (@drawing_count += 1) : nil
|
|
1726
1913
|
sheet_comment_idx = has_comments ? (@comment_count += 1) : nil
|
|
1914
|
+
sheet_tc_idx = has_tc ? (@threaded_comment_count += 1) : nil
|
|
1727
1915
|
sheet_pivot_start = @pivot_table_count
|
|
1728
1916
|
sheet_cache_start = @pivot_cache_count
|
|
1729
1917
|
sheet_pivots.each do
|
|
@@ -1736,7 +1924,8 @@ module Xlsxrb
|
|
|
1736
1924
|
sheet_rels_parts = build_sheet_rels_parts_v2(
|
|
1737
1925
|
sheet_name, sheet_tables, table_index,
|
|
1738
1926
|
sheet_drawing_idx, sheet_comment_idx,
|
|
1739
|
-
sheet_pivot_start, sheet_pivots.size
|
|
1927
|
+
sheet_pivot_start, sheet_pivots.size,
|
|
1928
|
+
sheet_tc_idx
|
|
1740
1929
|
)
|
|
1741
1930
|
|
|
1742
1931
|
# Calculate the legacyDrawing rId if comments exist.
|
|
@@ -1805,6 +1994,9 @@ module Xlsxrb
|
|
|
1805
1994
|
entries["xl/drawings/vmlDrawing#{sheet_comment_idx}.vml"] = generate_vml_drawing_xml(sheet_comments)
|
|
1806
1995
|
end
|
|
1807
1996
|
|
|
1997
|
+
# Generate threaded comments XML.
|
|
1998
|
+
entries["xl/threadedComments/threadedComment#{sheet_tc_idx}.xml"] = generate_threaded_comments_xml(sheet_threaded_comments) if has_tc
|
|
1999
|
+
|
|
1808
2000
|
# Generate pivot table + cache entries.
|
|
1809
2001
|
sheet_pivots.each_with_index do |pt, pi|
|
|
1810
2002
|
cache_idx = sheet_cache_start + pi + 1
|
|
@@ -1836,6 +2028,9 @@ module Xlsxrb
|
|
|
1836
2028
|
entries["xl/externalLinks/_rels/externalLink#{link_num}.xml.rels"] = generate_external_link_rels(el)
|
|
1837
2029
|
end
|
|
1838
2030
|
|
|
2031
|
+
# Generate persons entry if any persons registered.
|
|
2032
|
+
entries["xl/persons/person.xml"] = generate_persons_xml(@persons_data) if @persons_data.any?
|
|
2033
|
+
|
|
1839
2034
|
# Generate workbook rels (needs to know pivot cache count).
|
|
1840
2035
|
entries["xl/_rels/workbook.xml.rels"] = generate_workbook_rels(has_calc_chain: entries.key?("xl/calcChain.xml"))
|
|
1841
2036
|
|
|
@@ -1866,6 +2061,8 @@ module Xlsxrb
|
|
|
1866
2061
|
ends_with: "endsWith",
|
|
1867
2062
|
contains_blanks: "containsBlanks",
|
|
1868
2063
|
not_contains_blanks: "notContainsBlanks",
|
|
2064
|
+
contains_errors: "containsErrors",
|
|
2065
|
+
not_contains_errors: "notContainsErrors",
|
|
1869
2066
|
time_period: "timePeriod"
|
|
1870
2067
|
}.freeze
|
|
1871
2068
|
|
|
@@ -1879,7 +2076,8 @@ module Xlsxrb
|
|
|
1879
2076
|
pie3d: "pie3DChart", area3d: "area3DChart", surface: "surfaceChart",
|
|
1880
2077
|
surface3d: "surface3DChart",
|
|
1881
2078
|
stock: "stockChart", bubble: "bubbleChart",
|
|
1882
|
-
of_pie: "ofPieChart"
|
|
2079
|
+
of_pie: "ofPieChart",
|
|
2080
|
+
combo: "comboChart", column: "barChart"
|
|
1883
2081
|
}.freeze
|
|
1884
2082
|
|
|
1885
2083
|
NO_AXIS_CHARTS = %w[pieChart doughnutChart pie3DChart ofPieChart].freeze
|
|
@@ -1959,6 +2157,14 @@ module Xlsxrb
|
|
|
1959
2157
|
overrides["/xl/comments#{c}.xml"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
|
|
1960
2158
|
end
|
|
1961
2159
|
|
|
2160
|
+
# Threaded comments.
|
|
2161
|
+
(1..@threaded_comment_count.to_i).each do |tc|
|
|
2162
|
+
overrides["/xl/threadedComments/threadedComment#{tc}.xml"] = "application/vnd.ms-excel.threadedcomments+xml"
|
|
2163
|
+
end
|
|
2164
|
+
|
|
2165
|
+
# Persons.
|
|
2166
|
+
overrides["/xl/persons/person.xml"] = "application/vnd.ms-excel.person+xml" if @persons_data.any?
|
|
2167
|
+
|
|
1962
2168
|
# Pivot tables and cache.
|
|
1963
2169
|
(1..@pivot_table_count.to_i).each do |p|
|
|
1964
2170
|
overrides["/xl/pivotTables/pivotTable#{p}.xml"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"
|
|
@@ -2247,6 +2453,10 @@ module Xlsxrb
|
|
|
2247
2453
|
parts << %(<Relationship Id="rId#{next_rid}" Type="#{DOC_REL_NS}/calcChain" Target="calcChain.xml"/>)
|
|
2248
2454
|
next_rid += 1
|
|
2249
2455
|
end
|
|
2456
|
+
if @persons_data.any?
|
|
2457
|
+
parts << %(<Relationship Id="rId#{next_rid}" Type="http://schemas.microsoft.com/office/2017/10/relationships/person" Target="persons/person.xml"/>)
|
|
2458
|
+
next_rid += 1
|
|
2459
|
+
end
|
|
2250
2460
|
parts << "</Relationships>"
|
|
2251
2461
|
parts.join
|
|
2252
2462
|
end
|
|
@@ -2292,8 +2502,17 @@ module Xlsxrb
|
|
|
2292
2502
|
sp_attrs << 'published="0"' if sheet_props[:published] == false
|
|
2293
2503
|
sp_attrs << 'enableFormatConditionsCalculation="0"' if sheet_props[:enable_format_conditions_calculation] == false
|
|
2294
2504
|
sp_children = []
|
|
2295
|
-
|
|
2296
|
-
|
|
2505
|
+
tc = sheet_props[:tab_color]
|
|
2506
|
+
if tc.is_a?(Hash)
|
|
2507
|
+
tc_attrs = []
|
|
2508
|
+
tc_attrs << 'auto="1"' if tc[:auto]
|
|
2509
|
+
tc_attrs << %(indexed="#{tc[:indexed]}") if tc[:indexed]
|
|
2510
|
+
tc_attrs << %(rgb="#{tc[:rgb].to_s.delete_prefix("#")}") if tc[:rgb]
|
|
2511
|
+
tc_attrs << %(theme="#{tc[:theme]}") if tc[:theme]
|
|
2512
|
+
tc_attrs << %(tint="#{tc[:tint]}") if tc[:tint]
|
|
2513
|
+
sp_children << "<tabColor #{tc_attrs.join(" ")}/>" unless tc_attrs.empty?
|
|
2514
|
+
elsif tc
|
|
2515
|
+
sp_children << %(<tabColor rgb="#{tc.to_s.delete_prefix("#")}"/>)
|
|
2297
2516
|
elsif sheet_props[:tab_color_theme]
|
|
2298
2517
|
tc_attrs = [%(theme="#{sheet_props[:tab_color_theme]}")]
|
|
2299
2518
|
tc_attrs << %(tint="#{sheet_props[:tab_color_tint]}") if sheet_props[:tab_color_tint]
|
|
@@ -2920,24 +3139,27 @@ module Xlsxrb
|
|
|
2920
3139
|
table_attrs << %( tableType="#{xml_escape(tbl[:table_type])}") if tbl[:table_type]
|
|
2921
3140
|
parts = [
|
|
2922
3141
|
XML_HEADER,
|
|
2923
|
-
"<table #{table_attrs}>"
|
|
2924
|
-
%(<autoFilter ref="#{tbl[:ref]}"/>),
|
|
2925
|
-
%(<tableColumns count="#{tbl[:columns].size}">)
|
|
3142
|
+
"<table #{table_attrs}>"
|
|
2926
3143
|
]
|
|
3144
|
+
parts << %(<autoFilter ref="#{tbl[:ref]}"/>) unless tbl[:auto_filter] == false
|
|
3145
|
+
parts << %(<tableColumns count="#{tbl[:columns].size}">)
|
|
2927
3146
|
tbl[:columns].each_with_index do |col, i|
|
|
2928
3147
|
col_name = col.is_a?(Hash) ? col[:name] : col
|
|
2929
3148
|
col_attrs = %(id="#{i + 1}" name="#{xml_escape(col_name)}")
|
|
2930
3149
|
if col.is_a?(Hash)
|
|
2931
|
-
|
|
3150
|
+
calc_formula = col[:calculated_column_formula] || col[:data_formula] || col[:formula]
|
|
3151
|
+
tot_formula = col[:totals_row_formula] || col[:total_row_formula] || col[:total_formula]
|
|
3152
|
+
trf = col[:totals_row_function] || ("custom" if tot_formula)
|
|
3153
|
+
col_attrs << %( totalsRowFunction="#{trf}") if trf
|
|
2932
3154
|
col_attrs << %( totalsRowLabel="#{xml_escape(col[:totals_row_label])}") if col[:totals_row_label]
|
|
2933
3155
|
col_attrs << %( dataDxfId="#{col[:data_dxf_id]}") if col[:data_dxf_id]
|
|
2934
3156
|
col_attrs << %( totalsRowDxfId="#{col[:totals_row_dxf_id]}") if col[:totals_row_dxf_id]
|
|
2935
3157
|
col_attrs << %( headerRowDxfId="#{col[:header_row_dxf_id]}") if col[:header_row_dxf_id]
|
|
2936
3158
|
col_attrs << %( dataCellStyle="#{xml_escape(col[:data_cell_style])}") if col[:data_cell_style]
|
|
2937
|
-
if
|
|
3159
|
+
if calc_formula || tot_formula
|
|
2938
3160
|
parts << "<tableColumn #{col_attrs}>"
|
|
2939
|
-
parts << "<calculatedColumnFormula>#{xml_escape(
|
|
2940
|
-
parts << "<totalsRowFormula>#{xml_escape(
|
|
3161
|
+
parts << "<calculatedColumnFormula>#{xml_escape(calc_formula.to_s)}</calculatedColumnFormula>" if calc_formula
|
|
3162
|
+
parts << "<totalsRowFormula>#{xml_escape(tot_formula.to_s)}</totalsRowFormula>" if tot_formula
|
|
2941
3163
|
parts << "</tableColumn>"
|
|
2942
3164
|
else
|
|
2943
3165
|
parts << "<tableColumn #{col_attrs}/>"
|
|
@@ -2947,16 +3169,30 @@ module Xlsxrb
|
|
|
2947
3169
|
end
|
|
2948
3170
|
end
|
|
2949
3171
|
parts << "</tableColumns>"
|
|
2950
|
-
|
|
3172
|
+
raw_style = tbl[:style]
|
|
3173
|
+
style = if raw_style.is_a?(Hash)
|
|
3174
|
+
raw_style
|
|
3175
|
+
elsif raw_style
|
|
3176
|
+
{ name: raw_style.to_s }
|
|
3177
|
+
else
|
|
3178
|
+
{}
|
|
3179
|
+
end
|
|
2951
3180
|
style_name = style[:name] || "TableStyleMedium2"
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
3181
|
+
show_first_column = style.key?(:show_first_column) ? style[:show_first_column] : tbl[:show_first_column]
|
|
3182
|
+
show_last_column = style.key?(:show_last_column) ? style[:show_last_column] : tbl[:show_last_column]
|
|
3183
|
+
show_row_stripes = if style.key?(:show_row_stripes)
|
|
3184
|
+
style[:show_row_stripes]
|
|
3185
|
+
elsif tbl.key?(:show_row_stripes)
|
|
3186
|
+
tbl[:show_row_stripes]
|
|
3187
|
+
else
|
|
3188
|
+
true
|
|
3189
|
+
end
|
|
3190
|
+
show_column_stripes = style.key?(:show_column_stripes) ? style[:show_column_stripes] : tbl[:show_column_stripes]
|
|
3191
|
+
|
|
3192
|
+
sfc = show_first_column ? "1" : "0"
|
|
3193
|
+
slc = show_last_column ? "1" : "0"
|
|
3194
|
+
srs = show_row_stripes ? "1" : "0"
|
|
3195
|
+
scs = show_column_stripes ? "1" : "0"
|
|
2960
3196
|
parts << %(<tableStyleInfo name="#{xml_escape(style_name)}" showFirstColumn="#{sfc}" showLastColumn="#{slc}" showRowStripes="#{srs}" showColumnStripes="#{scs}"/>)
|
|
2961
3197
|
parts << "</table>"
|
|
2962
3198
|
parts.join
|
|
@@ -2983,8 +3219,8 @@ module Xlsxrb
|
|
|
2983
3219
|
parts.join
|
|
2984
3220
|
end
|
|
2985
3221
|
|
|
2986
|
-
# : (untyped sheet_name, untyped sheet_tables, untyped table_start_index, untyped drawing_idx, untyped comment_idx, untyped pivot_start, untyped pivot_count) -> untyped
|
|
2987
|
-
def build_sheet_rels_parts_v2(sheet_name, sheet_tables, table_start_index, drawing_idx, comment_idx, pivot_start, pivot_count)
|
|
3222
|
+
# : (untyped sheet_name, untyped sheet_tables, untyped table_start_index, untyped drawing_idx, untyped comment_idx, untyped pivot_start, untyped pivot_count, ?untyped? threaded_comment_idx) -> untyped
|
|
3223
|
+
def build_sheet_rels_parts_v2(sheet_name, sheet_tables, table_start_index, drawing_idx, comment_idx, pivot_start, pivot_count, threaded_comment_idx = nil)
|
|
2988
3224
|
rels = []
|
|
2989
3225
|
@hyperlinks[sheet_name].each do |(_cell_ref, link)|
|
|
2990
3226
|
next unless link[:url]
|
|
@@ -2998,6 +3234,7 @@ module Xlsxrb
|
|
|
2998
3234
|
rels << { type: "#{DOC_REL_NS}/comments", target: "../comments#{comment_idx}.xml" }
|
|
2999
3235
|
rels << { type: "#{DOC_REL_NS}/vmlDrawing", target: "../drawings/vmlDrawing#{comment_idx}.vml" }
|
|
3000
3236
|
end
|
|
3237
|
+
rels << { type: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment", target: "../threadedComments/threadedComment#{threaded_comment_idx}.xml" } if threaded_comment_idx
|
|
3001
3238
|
rels << { type: "#{DOC_REL_NS}/drawing", target: "../drawings/drawing#{drawing_idx}.xml" } if drawing_idx
|
|
3002
3239
|
pivot_count.times do |i|
|
|
3003
3240
|
pt_idx = pivot_start + i + 1
|