class Xlsxrb::Ooxml::Writer
Writes spreadsheet data into an XLSX file.
Constants
- APP_NS
- A_NS
- CELL_ADDRESS_PATTERN
- CF_TYPE_MAP
- CHART_TYPE_MAP
- CP_NS
- CT_NS
- C_NS
- DCTERMS_NS
- DC_NS
- DOC_REL_NS
- GROUPING_CHARTS
- MAX_COLUMN_INDEX
- MAX_ROW
- NO_AXIS_CHARTS
- REL_NS
- SSML_NS
- THREE_AXIS_CHARTS
- VT_NS
- XDR_NS
- XML_HEADER
- XSI_NS
Attributes
Returns ordered sheet names.
Public Class Methods
Source
# File lib/xlsxrb/ooxml/writer.rb, line 26 def initialize @sheets = { "Sheet1" => {} } @column_widths = { "Sheet1" => {} } @column_attrs = { "Sheet1" => {} } @row_attrs = { "Sheet1" => {} } @merge_cells = { "Sheet1" => [] } @hyperlinks = { "Sheet1" => {} } @cell_styles = { "Sheet1" => {} } @cell_phonetic = { "Sheet1" => {} } @auto_filters = { "Sheet1" => nil } @filter_columns = { "Sheet1" => {} } @sort_state = { "Sheet1" => nil } @num_fmts = [] @fonts = [{ sz: 11, name: "Calibri" }] @fills = [{ pattern: "none" }, { pattern: "gray125" }] @borders = [{ left: nil, right: nil, top: nil, bottom: nil }] @xf_entries = [{ num_fmt_id: 0, font_id: 0, fill_id: 0, border_id: 0 }] @cell_style_xfs = [{ num_fmt_id: 0, font_id: 0, fill_id: 0, border_id: 0 }] @cell_style_names = [{ name: "Normal", xf_id: 0, builtin_id: 0 }] @dxfs = [] @indexed_colors = [] @mru_colors = [] @table_styles = {} @sheet_order = ["Sheet1"] @core_properties = {} @app_properties = {} @custom_properties = [] @file_version = {} @file_sharing = {} @workbook_properties = {} @workbook_views = {} @calc_properties = {} @file_recovery_properties = {} @sheet_states = {} @defined_names = [] @sheet_properties = { "Sheet1" => {} } @phonetic_properties = { "Sheet1" => nil } @sheet_formats = { "Sheet1" => {} } @sheet_views = { "Sheet1" => {} } @freeze_panes = { "Sheet1" => nil } @selections = { "Sheet1" => nil } @print_options = { "Sheet1" => {} } @page_margins = { "Sheet1" => nil } @page_setup = { "Sheet1" => {} } @header_footer = { "Sheet1" => {} } @row_breaks = { "Sheet1" => [] } @col_breaks = { "Sheet1" => [] } @data_validations = { "Sheet1" => [] } @data_validations_options = { "Sheet1" => {} } @conditional_formats = { "Sheet1" => [] } @tables = { "Sheet1" => [] } @cell_watches = { "Sheet1" => [] } @ignored_errors = { "Sheet1" => [] } @data_consolidate = { "Sheet1" => nil } @scenarios = { "Sheet1" => nil } @use_shared_strings = true @images = { "Sheet1" => [] } @charts_data = { "Sheet1" => [] } @shapes_data = { "Sheet1" => [] } @comments_data = { "Sheet1" => [] } @pivot_tables_data = { "Sheet1" => [] } @extra_entries = {} @extra_ct_defaults = {} @extra_ct_overrides = {} @preserve_macros = false @sheet_protection = { "Sheet1" => nil } @protected_ranges = { "Sheet1" => [] } @workbook_protection = nil @external_links = [] end
Public Instance Methods
Source
# File lib/xlsxrb/ooxml/writer.rb, line 413 def add_border(**opts) existing = @borders.index(opts) return existing if existing @borders << opts @borders.size - 1 end
Registers a border and returns its border_id. Opts: left, right, top, bottom (each a hash with :style and optional :color).
Source
# File lib/xlsxrb/ooxml/writer.rb, line 423 def add_cell_style(**opts) entry = { num_fmt_id: opts[:num_fmt_id] || 0, font_id: opts[:font_id] || 0, fill_id: opts[:fill_id] || 0, border_id: opts[:border_id] || 0, xf_id: opts[:xf_id] || 0 } entry[:alignment] = opts[:alignment] if opts[:alignment] entry[:protection] = opts[:protection] if opts[:protection] entry[:quote_prefix] = true if opts[:quote_prefix] entry[:pivot_button] = true if opts[:pivot_button] existing = @xf_entries.index(entry) return existing if existing @xf_entries << entry @xf_entries.size - 1 end
Registers a cell style (xf entry) and returns its index for use with set_cell_style. Opts: font_id, fill_id, border_id, num_fmt_id, alignment (hash with horizontal, vertical, wrap_text, text_rotation, indent, shrink_to_fit).
# File lib/xlsxrb/ooxml/writer.rb, line 991 def add_cell_watch(cell_ref, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) @cell_watches[sheet_name] << cell_ref end
Adds a cell watch to the given sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 1135 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) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @charts_data.key?(sheet_name) chart = { type: type, title: title, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row } chart[:from_col_off] = from_col_off if from_col_off chart[:from_row_off] = from_row_off if from_row_off chart[:to_col_off] = to_col_off if to_col_off chart[:to_row_off] = to_row_off if to_row_off chart[:series] = (series || [{ cat_ref: cat_ref, val_ref: val_ref }]) chart[:auto_title_deleted] = auto_title_deleted unless auto_title_deleted.nil? chart[:title_overlay] = title_overlay unless title_overlay.nil? chart[:title_font] = title_font if title_font chart[:title_fill_color] = title_fill_color if title_fill_color chart[:title_no_fill] = title_no_fill unless title_no_fill.nil? chart[:title_line_color] = title_line_color if title_line_color chart[:title_line_width] = title_line_width if title_line_width chart[:title_line_dash] = title_line_dash if title_line_dash chart[:title_rotation] = title_rotation if title_rotation chart[:legend] = legend if legend chart[:data_labels] = data_labels if data_labels chart[:cat_axis_title] = cat_axis_title if cat_axis_title chart[:val_axis_title] = val_axis_title if val_axis_title chart[:cat_axis_title_font] = cat_axis_title_font if cat_axis_title_font chart[:cat_axis_title_fill] = cat_axis_title_fill if cat_axis_title_fill chart[:cat_axis_title_no_fill] = cat_axis_title_no_fill unless cat_axis_title_no_fill.nil? chart[:cat_axis_title_line_color] = cat_axis_title_line_color if cat_axis_title_line_color chart[:cat_axis_title_line_width] = cat_axis_title_line_width if cat_axis_title_line_width chart[:cat_axis_title_line_dash] = cat_axis_title_line_dash if cat_axis_title_line_dash chart[:cat_axis_title_rotation] = cat_axis_title_rotation if cat_axis_title_rotation chart[:val_axis_title_font] = val_axis_title_font if val_axis_title_font chart[:val_axis_title_fill] = val_axis_title_fill if val_axis_title_fill chart[:val_axis_title_no_fill] = val_axis_title_no_fill unless val_axis_title_no_fill.nil? chart[:val_axis_title_line_color] = val_axis_title_line_color if val_axis_title_line_color chart[:val_axis_title_line_width] = val_axis_title_line_width if val_axis_title_line_width chart[:val_axis_title_line_dash] = val_axis_title_line_dash if val_axis_title_line_dash chart[:val_axis_title_rotation] = val_axis_title_rotation if val_axis_title_rotation chart[:cat_axis_tick_lbl_pos] = cat_axis_tick_lbl_pos if cat_axis_tick_lbl_pos chart[:val_axis_tick_lbl_pos] = val_axis_tick_lbl_pos if val_axis_tick_lbl_pos chart[:cat_axis_major_gridlines] = cat_axis_major_gridlines unless cat_axis_major_gridlines.nil? chart[:val_axis_major_gridlines] = val_axis_major_gridlines unless val_axis_major_gridlines.nil? chart[:cat_axis_minor_gridlines] = cat_axis_minor_gridlines unless cat_axis_minor_gridlines.nil? chart[:val_axis_minor_gridlines] = val_axis_minor_gridlines unless val_axis_minor_gridlines.nil? chart[:cat_axis_delete] = cat_axis_delete unless cat_axis_delete.nil? chart[:val_axis_delete] = val_axis_delete unless val_axis_delete.nil? chart[:cat_axis_orientation] = cat_axis_orientation if cat_axis_orientation chart[:val_axis_orientation] = val_axis_orientation if val_axis_orientation chart[:cat_axis_num_fmt] = cat_axis_num_fmt if cat_axis_num_fmt chart[:val_axis_num_fmt] = val_axis_num_fmt if val_axis_num_fmt chart[:cat_axis_major_tick_mark] = cat_axis_major_tick_mark if cat_axis_major_tick_mark chart[:cat_axis_minor_tick_mark] = cat_axis_minor_tick_mark if cat_axis_minor_tick_mark chart[:val_axis_major_tick_mark] = val_axis_major_tick_mark if val_axis_major_tick_mark chart[:val_axis_minor_tick_mark] = val_axis_minor_tick_mark if val_axis_minor_tick_mark chart[:cat_axis_crosses] = cat_axis_crosses if cat_axis_crosses chart[:val_axis_crosses] = val_axis_crosses if val_axis_crosses chart[:cat_axis_crosses_at] = cat_axis_crosses_at if cat_axis_crosses_at chart[:val_axis_crosses_at] = val_axis_crosses_at if val_axis_crosses_at chart[:cat_axis_tick_lbl_skip] = cat_axis_tick_lbl_skip if cat_axis_tick_lbl_skip chart[:cat_axis_tick_mark_skip] = cat_axis_tick_mark_skip if cat_axis_tick_mark_skip chart[:cat_axis_lbl_offset] = cat_axis_lbl_offset if cat_axis_lbl_offset chart[:cat_axis_auto] = cat_axis_auto unless cat_axis_auto.nil? chart[:cat_axis_lbl_algn] = cat_axis_lbl_algn if cat_axis_lbl_algn chart[:cat_axis_no_multi_lvl_lbl] = cat_axis_no_multi_lvl_lbl unless cat_axis_no_multi_lvl_lbl.nil? chart[:val_axis_cross_between] = val_axis_cross_between if val_axis_cross_between chart[:val_axis_major_unit] = val_axis_major_unit if val_axis_major_unit chart[:val_axis_minor_unit] = val_axis_minor_unit if val_axis_minor_unit chart[:cat_axis_scaling_max] = cat_axis_scaling_max if cat_axis_scaling_max chart[:cat_axis_scaling_min] = cat_axis_scaling_min if cat_axis_scaling_min chart[:val_axis_scaling_max] = val_axis_scaling_max if val_axis_scaling_max chart[:val_axis_scaling_min] = val_axis_scaling_min if val_axis_scaling_min chart[:cat_axis_log_base] = cat_axis_log_base if cat_axis_log_base chart[:val_axis_log_base] = val_axis_log_base if val_axis_log_base chart[:val_axis_disp_units] = val_axis_disp_units if val_axis_disp_units chart[:first_slice_ang] = first_slice_ang if first_slice_ang chart[:hole_size] = hole_size if hole_size chart[:smooth] = smooth unless smooth.nil? chart[:marker] = marker unless marker.nil? chart[:scatter_style] = scatter_style if scatter_style chart[:radar_style] = radar_style if radar_style chart[:cat_axis_pos] = cat_axis_pos if cat_axis_pos chart[:val_axis_pos] = val_axis_pos if val_axis_pos chart[:gap_width] = gap_width if gap_width chart[:gap_depth] = gap_depth if gap_depth chart[:bar_shape] = bar_shape if bar_shape chart[:bubble_3d] = bubble_3d unless bubble_3d.nil? chart[:bubble_scale] = bubble_scale if bubble_scale chart[:show_neg_bubbles] = show_neg_bubbles unless show_neg_bubbles.nil? chart[:size_represents] = size_represents if size_represents chart[:overlap] = overlap if overlap chart[:grouping] = grouping if grouping chart[:bar_dir] = bar_dir if bar_dir chart[:vary_colors] = vary_colors unless vary_colors.nil? chart[:wireframe] = wireframe unless wireframe.nil? chart[:band_fmts] = band_fmts if band_fmts chart[:of_pie_type] = of_pie_type if of_pie_type chart[:split_type] = split_type if split_type chart[:split_pos] = split_pos if split_pos chart[:cust_split] = cust_split if cust_split chart[:second_pie_size] = second_pie_size if second_pie_size chart[:style] = style if style chart[:rounded_corners] = rounded_corners unless rounded_corners.nil? chart[:view_3d] = view_3d if view_3d chart[:floor] = floor if floor chart[:side_wall] = side_wall if side_wall chart[:back_wall] = back_wall if back_wall chart[:name] = name if name chart[:description] = description if description chart[:frame_title] = frame_title if frame_title chart[:frame_hidden] = frame_hidden unless frame_hidden.nil? chart[:frame_macro] = frame_macro if frame_macro chart[:frame_no_grp] = frame_no_grp unless frame_no_grp.nil? chart[:edit_as] = edit_as if edit_as chart[:published] = published unless published.nil? chart[:locks_with_sheet] = locks_with_sheet unless locks_with_sheet.nil? chart[:prints_with_sheet] = prints_with_sheet unless prints_with_sheet.nil? chart[:plot_vis_only] = plot_vis_only unless plot_vis_only.nil? chart[:disp_blanks_as] = disp_blanks_as if disp_blanks_as chart[:show_d_lbls_over_max] = show_d_lbls_over_max unless show_d_lbls_over_max.nil? chart[:data_table] = data_table if data_table chart[:plot_area_fill] = plot_area_fill if plot_area_fill chart[:plot_area_no_fill] = plot_area_no_fill unless plot_area_no_fill.nil? chart[:plot_area_line_color] = plot_area_line_color if plot_area_line_color chart[:plot_area_line_width] = plot_area_line_width if plot_area_line_width chart[:plot_area_line_dash] = plot_area_line_dash if plot_area_line_dash chart[:plot_area_layout] = plot_area_layout if plot_area_layout chart[:drop_lines] = drop_lines unless drop_lines.nil? chart[:hi_low_lines] = hi_low_lines unless hi_low_lines.nil? chart[:ser_lines] = ser_lines unless ser_lines.nil? chart[:up_down_bars] = up_down_bars if up_down_bars chart[:cat_axis_label_rotation] = cat_axis_label_rotation if cat_axis_label_rotation chart[:val_axis_label_rotation] = val_axis_label_rotation if val_axis_label_rotation chart[:cat_axis_font] = cat_axis_font if cat_axis_font chart[:val_axis_font] = val_axis_font if val_axis_font chart[:cat_axis_line_color] = cat_axis_line_color if cat_axis_line_color chart[:cat_axis_line_width] = cat_axis_line_width if cat_axis_line_width chart[:cat_axis_line_dash] = cat_axis_line_dash if cat_axis_line_dash chart[:val_axis_line_color] = val_axis_line_color if val_axis_line_color chart[:val_axis_line_width] = val_axis_line_width if val_axis_line_width chart[:val_axis_line_dash] = val_axis_line_dash if val_axis_line_dash chart[:cat_axis_fill] = cat_axis_fill if cat_axis_fill chart[:cat_axis_no_fill] = cat_axis_no_fill unless cat_axis_no_fill.nil? chart[:val_axis_fill] = val_axis_fill if val_axis_fill chart[:val_axis_no_fill] = val_axis_no_fill unless val_axis_no_fill.nil? chart[:cat_axis_type] = cat_axis_type if cat_axis_type chart[:cat_axis_base_time_unit] = cat_axis_base_time_unit if cat_axis_base_time_unit chart[:cat_axis_major_time_unit] = cat_axis_major_time_unit if cat_axis_major_time_unit chart[:cat_axis_minor_time_unit] = cat_axis_minor_time_unit if cat_axis_minor_time_unit chart[:cat_axis_major_unit] = cat_axis_major_unit if cat_axis_major_unit chart[:cat_axis_minor_unit] = cat_axis_minor_unit if cat_axis_minor_unit chart[:chart_fill] = chart_fill if chart_fill chart[:chart_no_fill] = chart_no_fill unless chart_no_fill.nil? chart[:chart_line_color] = chart_line_color if chart_line_color chart[:chart_line_width] = chart_line_width if chart_line_width chart[:chart_line_dash] = chart_line_dash if chart_line_dash chart[:protection] = protection if protection chart[:print_settings] = print_settings if print_settings chart[:chart_font] = chart_font if chart_font @charts_data[sheet_name] << chart end
Adds a chart to the given sheet. type: :bar, :line, :pie. title: chart title string. data_ref: e.g. “Sheet1!$A$1:$B$4”. cat_ref/val_ref for explicit series.
# File lib/xlsxrb/ooxml/writer.rb, line 742 def add_col_break(col_index, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @col_breaks.key?(sheet_name) @col_breaks[sheet_name] << col_index end
Adds a column break (page break before a given column index, 1-based).
# File lib/xlsxrb/ooxml/writer.rb, line 1405 def add_comment(cell_address, text, author: "Author", sheet: nil, guid: nil, shape_id: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @comments_data.key?(sheet_name) entry = { ref: cell_address, text: text, author: author } entry[:guid] = guid if guid entry[:shape_id] = shape_id if shape_id @comments_data[sheet_name] << entry end
Adds a comment on a cell.
# File lib/xlsxrb/ooxml/writer.rb, line 783 def add_conditional_format(sqref, sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @conditional_formats.key?(sheet_name) @conditional_formats[sheet_name] << opts.merge(sqref: sqref) end
Adds a conditional formatting rule to the specified range. Options: type (:cell_is, :expression, :color_scale, :data_bar, :icon_set), operator, priority, formula/formulas, format_id, color_scale, data_bar, icon_set.
# File lib/xlsxrb/ooxml/writer.rb, line 559 def add_custom_property(name, value, type: :string) @custom_properties << { name: name, value: value, type: type } end
Adds a custom document property. type: :string (default), :number, :bool, :date.
# File lib/xlsxrb/ooxml/writer.rb, line 759 def add_data_validation(sqref, sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @data_validations.key?(sheet_name) @data_validations[sheet_name] << opts.merge(sqref: sqref) end
Adds a data validation rule. sqref: cell range (e.g. “A1:A100”) Options: type:, operator:, formula1:, formula2:, allow_blank:, show_input_message:,
show_error_message:, error_style:, error_title:, error:, prompt_title:, prompt:
# File lib/xlsxrb/ooxml/writer.rb, line 844 def add_defined_name(name, value, sheet: nil, hidden: false, **opts) entry = { name: name, value: value, hidden: hidden } %i[comment description function vb_procedure xlm shortcut_key publish_to_server workbook_parameter function_group_id custom_menu help status_bar].each do |key| entry[key] = opts[key] if opts.key?(key) end if sheet idx = @sheet_order.index(sheet) raise ArgumentError, "unknown sheet: #{sheet}" unless idx entry[:local_sheet_id] = idx end @defined_names << entry end
Adds a defined name. Options: sheet: (local scope), hidden: true, value: (formula or constant).
Source
# File lib/xlsxrb/ooxml/writer.rb, line 478 def add_dxf(**opts) @dxfs << opts @dxfs.size - 1 end
Registers a differential format (dxf) for conditional formatting. Returns dxf_id. Opts: font (hash), fill (hash), border (hash), num_fmt (hash).
# File lib/xlsxrb/ooxml/writer.rb, line 1491 def add_external_link(target:, sheet_names: []) @external_links << { target: target, sheet_names: sheet_names } end
Adds an external link reference to another workbook. target: path or URI to the external workbook (e.g. “Book2.xlsx”). sheet_names: array of sheet name strings in the external workbook.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 403 def add_fill(**opts) existing = @fills.index(opts) return existing if existing @fills << opts @fills.size - 1 end
Registers a fill and returns its fill_id. Opts: pattern, fg_color, bg_color.
# File lib/xlsxrb/ooxml/writer.rb, line 342 def add_filter_column(col_id, filter, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @filter_columns.key?(sheet_name) @filter_columns[sheet_name][col_id] = filter end
Adds a filter column to the autoFilter. col_id: 0-based column index within the autoFilter range. filter: hash describing the filter, e.g.
{ type: :filters, values: ["A", "B"] }
{ type: :filters, blank: true }
{ type: :custom, operator: "greaterThan", val: "100" }
{ type: :custom, filters: [{ operator: "greaterThan", val: "10" }, { operator: "lessThan", val: "100" }], and: true }
{ type: :dynamic, dynamic_type: "today" }
{ type: :top10, top: true, percent: false, val: 10 }
Source
# File lib/xlsxrb/ooxml/writer.rb, line 394 def add_font(**opts) existing = @fonts.index(opts) return existing if existing @fonts << opts @fonts.size - 1 end
Registers a font and returns its font_id. Opts: bold, italic, sz, color, name.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 297 def add_hyperlink(cell_address, url = nil, sheet: nil, display: nil, tooltip: nil, location: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @hyperlinks.key?(sheet_name) raise ArgumentError, "url or location required" if url.nil? && location.nil? link = {} link[:url] = url if url link[:display] = display if display link[:tooltip] = tooltip if tooltip link[:location] = location if location @hyperlinks[sheet_name][cell_address] = link end
Adds a hyperlink on a cell.
# File lib/xlsxrb/ooxml/writer.rb, line 1007 def add_ignored_error(sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) raise ArgumentError, "sqref is required" unless opts[:sqref] @ignored_errors[sheet_name] << opts end
Adds an ignored error entry for the given sheet. Options: sqref:, eval_error:, two_digit_text_year:, number_stored_as_text:, formula:,
formula_range:, unlocked_formula:, empty_cell_reference:, list_data_validation:, calculated_column:
# File lib/xlsxrb/ooxml/writer.rb, line 444 def add_named_cell_style(name:, num_fmt_id: 0, font_id: 0, fill_id: 0, border_id: 0, builtin_id: nil, i_level: nil, hidden: nil, custom_builtin: nil) entry = { num_fmt_id: num_fmt_id, font_id: font_id, fill_id: fill_id, border_id: border_id } @cell_style_xfs << entry xf_id = @cell_style_xfs.size - 1 cs = { name: name, xf_id: xf_id } cs[:builtin_id] = builtin_id if builtin_id cs[:i_level] = i_level if i_level cs[:hidden] = true if hidden cs[:custom_builtin] = true if custom_builtin @cell_style_names << cs xf_id end
Registers a base style definition (cellStyleXf) and a named cellStyle. Returns the xfId for the new base style.
# File lib/xlsxrb/ooxml/writer.rb, line 375 def add_number_format(format_code) existing = @num_fmts.find { |nf| nf[:format_code] == format_code } return existing[:num_fmt_id] if existing num_fmt_id = 164 + @num_fmts.size @num_fmts << { num_fmt_id: num_fmt_id, format_code: format_code } num_fmt_id end
Registers a custom number format and returns its numFmtId (starting at 164).
# File lib/xlsxrb/ooxml/writer.rb, line 1429 def add_pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil, sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @pivot_tables_data.key?(sheet_name) pt_name = name || "PivotTable#{@pivot_tables_data.values.flatten.size + 1}" @pivot_tables_data[sheet_name] << { name: pt_name, source_ref: source_ref, row_fields: row_fields, col_fields: col_fields, data_fields: data_fields, dest_ref: dest_ref, field_names: field_names, items: items, data_caption: opts[:data_caption], data_on_rows: opts[:data_on_rows], row_grand_totals: opts[:row_grand_totals], col_grand_totals: opts[:col_grand_totals], compact: opts[:compact], outline: opts[:outline], show_headers: opts[:show_headers], source_name: opts[:source_name], grand_total_caption: opts[:grand_total_caption], error_caption: opts[:error_caption], show_error: opts[:show_error], missing_caption: opts[:missing_caption], show_missing: opts[:show_missing], tag: opts[:tag], indent: opts[:indent], published: opts[:published], created_version: opts[:created_version], updated_version: opts[:updated_version], min_refreshable_version: opts[:min_refreshable_version], pivot_table_style: opts[:pivot_table_style], cache_save_data: opts[:cache_save_data], cache_enable_refresh: opts[:cache_enable_refresh], cache_refreshed_by: opts[:cache_refreshed_by], cache_refreshed_version: opts[:cache_refreshed_version], cache_created_version: opts[:cache_created_version], cache_record_count: opts[:cache_record_count], cache_optimize_memory: opts[:cache_optimize_memory], row_page_count: opts[:row_page_count], col_page_count: opts[:col_page_count], field_attrs: opts[:field_attrs], apply_number_formats: opts[:apply_number_formats], apply_border_formats: opts[:apply_border_formats], apply_font_formats: opts[:apply_font_formats], apply_pattern_formats: opts[:apply_pattern_formats], apply_alignment_formats: opts[:apply_alignment_formats], apply_width_height_formats: opts[:apply_width_height_formats], multiple_field_filters: opts[:multiple_field_filters], show_drill: opts[:show_drill], show_data_tips: opts[:show_data_tips], enable_drill: opts[:enable_drill], show_member_property_tips: opts[:show_member_property_tips], item_print_titles: opts[:item_print_titles], field_print_titles: opts[:field_print_titles], preserve_formatting: opts[:preserve_formatting], page_over_then_down: opts[:page_over_then_down], page_wrap: opts[:page_wrap], compact_data: opts[:compact_data], outline_data: opts[:outline_data], show_multiple_label: opts[:show_multiple_label], show_data_drop_down: opts[:show_data_drop_down], edit_data: opts[:edit_data], disable_field_list: opts[:disable_field_list], visual_totals: opts[:visual_totals], print_drill: opts[:print_drill] } end
Adds a pivot table to the given sheet. source_ref: data source range (e.g. “Sheet1!A1:C4”). row_fields: array of 0-based field indices for row axis. data_fields: array of { fld:, name:, subtotal: } hashes. col_fields: array of 0-based field indices for column axis. field_names: array of field name strings (for cache definition). items: hash mapping field index to array of item values.
# File lib/xlsxrb/ooxml/writer.rb, line 975 def add_protected_range(sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) raise ArgumentError, "name is required" unless opts[:name] raise ArgumentError, "sqref is required" unless opts[:sqref] @protected_ranges[sheet_name] << opts end
Adds a protected range to the given sheet. Required: name:, sqref: Optional: algorithm_name:, hash_value:, salt_value:, spin_count:, security_descriptors: []
# File lib/xlsxrb/ooxml/writer.rb, line 1066 def add_raw_entry(path, content, content_type: nil) @extra_entries[path] = content return unless content_type ext = File.extname(path).delete(".") if ext.empty? || path.include?("/") @extra_ct_overrides["/#{path}"] = content_type else @extra_ct_defaults[ext] = content_type end end
Adds a raw ZIP entry to be included in the output (for pass-through retention).
# File lib/xlsxrb/ooxml/writer.rb, line 728 def add_row_break(row_num, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_breaks.key?(sheet_name) @row_breaks[sheet_name] << row_num end
Adds a row break (page break before a given row number).
# File lib/xlsxrb/ooxml/writer.rb, line 1307 def add_shape(preset: "rect", text: nil, name: nil, description: nil, title: nil, hidden: nil, macro: nil, textlink: nil, f_locks_text: nil, no_grp: nil, no_rot: nil, fill_color: nil, fill_alpha: nil, fill_color_transforms: nil, no_fill: nil, gradient_fill: nil, pattern_fill: nil, line_color: nil, line_alpha: nil, line_color_transforms: nil, line_width: nil, no_line: nil, line_dash: nil, line_custom_dash: nil, line_cap: nil, line_align: nil, line_compound: nil, line_join: nil, line_miter_limit: nil, head_end: nil, tail_end: nil, rotation: nil, text_wrap: nil, text_anchor: nil, text_vert_overflow: nil, text_horz_overflow: nil, text_spc_first_last_para: nil, text_num_col: nil, text_spc_col: nil, text_rtl_col: nil, text_from_word_art: nil, text_upright: nil, text_compat_ln_spc: nil, text_force_aa: nil, text_warp: nil, text_vertical: nil, text_insets: nil, text_rot: nil, adjust_values: nil, text_font: nil, text_end_para_rpr: nil, text_def_rpr: nil, text_align: nil, text_font_align: nil, text_def_tab_sz: nil, text_indent: nil, text_anchor_ctr: nil, text_spacing: nil, text_rtl: nil, text_ea_ln_brk: nil, text_latin_ln_brk: nil, text_hanging_punct: nil, text_tab_stops: nil, text_bullet: nil, text_level: nil, text_paragraphs: nil, autofit: nil, outer_shadow: nil, inner_shadow: nil, glow: nil, soft_edge: nil, reflection: nil, blur: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, 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, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @shapes_data.key?(sheet_name) shape_name = name || "Shape #{@shapes_data[sheet_name].size + 1}" shape = { preset: preset, text: text, name: shape_name, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row } shape[:from_col_off] = from_col_off if from_col_off shape[:from_row_off] = from_row_off if from_row_off shape[:to_col_off] = to_col_off if to_col_off shape[:to_row_off] = to_row_off if to_row_off shape[:description] = description if description shape[:title] = title if title shape[:hidden] = hidden unless hidden.nil? shape[:macro] = macro if macro shape[:textlink] = textlink if textlink shape[:f_locks_text] = f_locks_text unless f_locks_text.nil? shape[:no_grp] = no_grp unless no_grp.nil? shape[:no_rot] = no_rot unless no_rot.nil? shape[:fill_color] = fill_color if fill_color shape[:fill_alpha] = fill_alpha if fill_alpha shape[:fill_color_transforms] = fill_color_transforms if fill_color_transforms shape[:no_fill] = no_fill unless no_fill.nil? shape[:line_color] = line_color if line_color shape[:line_alpha] = line_alpha if line_alpha shape[:line_color_transforms] = line_color_transforms if line_color_transforms shape[:line_width] = line_width if line_width shape[:line_dash] = line_dash if line_dash shape[:line_custom_dash] = line_custom_dash if line_custom_dash shape[:line_cap] = line_cap if line_cap shape[:line_align] = line_align if line_align shape[:line_compound] = line_compound if line_compound shape[:line_join] = line_join if line_join shape[:line_miter_limit] = line_miter_limit if line_miter_limit shape[:head_end] = head_end if head_end shape[:tail_end] = tail_end if tail_end shape[:no_line] = no_line unless no_line.nil? shape[:text_wrap] = text_wrap if text_wrap shape[:text_anchor] = text_anchor if text_anchor shape[:text_vert_overflow] = text_vert_overflow if text_vert_overflow shape[:text_horz_overflow] = text_horz_overflow if text_horz_overflow shape[:text_spc_first_last_para] = text_spc_first_last_para unless text_spc_first_last_para.nil? shape[:text_num_col] = text_num_col if text_num_col shape[:text_spc_col] = text_spc_col if text_spc_col shape[:text_rtl_col] = text_rtl_col unless text_rtl_col.nil? shape[:text_from_word_art] = text_from_word_art unless text_from_word_art.nil? shape[:text_upright] = text_upright unless text_upright.nil? shape[:text_compat_ln_spc] = text_compat_ln_spc unless text_compat_ln_spc.nil? shape[:text_force_aa] = text_force_aa unless text_force_aa.nil? shape[:text_warp] = text_warp if text_warp shape[:text_vertical] = text_vertical if text_vertical shape[:text_insets] = text_insets if text_insets shape[:text_rot] = text_rot if text_rot shape[:rotation] = rotation if rotation shape[:adjust_values] = adjust_values if adjust_values shape[:text_font] = text_font if text_font shape[:text_end_para_rpr] = text_end_para_rpr if text_end_para_rpr shape[:text_def_rpr] = text_def_rpr if text_def_rpr shape[:text_align] = text_align if text_align shape[:text_font_align] = text_font_align if text_font_align shape[:text_def_tab_sz] = text_def_tab_sz if text_def_tab_sz shape[:text_indent] = text_indent if text_indent shape[:text_anchor_ctr] = text_anchor_ctr unless text_anchor_ctr.nil? shape[:text_spacing] = text_spacing if text_spacing shape[:text_rtl] = text_rtl unless text_rtl.nil? shape[:text_ea_ln_brk] = text_ea_ln_brk unless text_ea_ln_brk.nil? shape[:text_latin_ln_brk] = text_latin_ln_brk unless text_latin_ln_brk.nil? shape[:text_hanging_punct] = text_hanging_punct unless text_hanging_punct.nil? shape[:text_tab_stops] = text_tab_stops if text_tab_stops shape[:text_bullet] = text_bullet if text_bullet shape[:text_level] = text_level if text_level shape[:text_paragraphs] = text_paragraphs if text_paragraphs shape[:autofit] = autofit if autofit shape[:outer_shadow] = outer_shadow if outer_shadow shape[:inner_shadow] = inner_shadow if inner_shadow shape[:glow] = glow if glow shape[:soft_edge] = soft_edge if soft_edge shape[:reflection] = reflection if reflection shape[:blur] = blur if blur shape[:gradient_fill] = gradient_fill if gradient_fill shape[:pattern_fill] = pattern_fill if pattern_fill shape[:edit_as] = edit_as if edit_as shape[:published] = published unless published.nil? shape[:locks_with_sheet] = locks_with_sheet unless locks_with_sheet.nil? shape[:prints_with_sheet] = prints_with_sheet unless prints_with_sheet.nil? @shapes_data[sheet_name] << shape end
Adds a shape to the given sheet. preset: preset geometry name (e.g. “rect”, “ellipse”, “roundRect”). text: optional text body string. from_col/from_row/to_col/to_row: anchor coordinates.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 98 def add_sheet(name) raise ArgumentError, "sheet already exists: #{name}" if @sheets.key?(name) @sheets[name] = {} @column_widths[name] = {} @column_attrs[name] = {} @row_attrs[name] = {} @merge_cells[name] = [] @hyperlinks[name] = {} @cell_styles[name] = {} @cell_phonetic[name] = {} @auto_filters[name] = nil @filter_columns[name] = {} @sort_state[name] = nil @sheet_properties[name] = {} @sheet_formats[name] = {} @sheet_views[name] = {} @freeze_panes[name] = nil @selections[name] = nil @print_options[name] = {} @page_margins[name] = nil @page_setup[name] = {} @header_footer[name] = {} @row_breaks[name] = [] @col_breaks[name] = [] @data_validations[name] = [] @data_validations_options[name] = {} @conditional_formats[name] = [] @tables[name] = [] @cell_watches[name] = [] @ignored_errors[name] = [] @data_consolidate[name] = nil @scenarios[name] = nil @images[name] = [] @charts_data[name] = [] @shapes_data[name] = [] @comments_data[name] = [] @pivot_tables_data[name] = [] @sheet_protection[name] = nil @protected_ranges[name] = [] @phonetic_properties[name] = nil @sheet_order << name end
Adds a new sheet. Raises if name is already taken.
# File lib/xlsxrb/ooxml/writer.rb, line 798 def add_table(ref, columns:, name: nil, display_name: nil, sheet: nil, totals_row_count: 0, style: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @tables.key?(sheet_name) table_id = @tables.values.flatten.size + 1 tbl_name = name || "Table#{table_id}" tbl = { id: table_id, ref: ref, name: tbl_name, display_name: display_name || tbl_name, columns: columns, totals_row_count: totals_row_count } tbl[:style] = style if style %i[header_row_count published comment insert_row insert_row_shift header_row_dxf_id data_dxf_id totals_row_dxf_id header_row_border_dxf_id table_border_dxf_id totals_row_border_dxf_id header_row_cell_style totals_row_cell_style connection_id table_type].each do |key| tbl[key] = opts[key] if opts.key?(key) end @tables[sheet_name] << tbl end
Adds a table definition to a sheet. columns: array of column name strings.
# File lib/xlsxrb/ooxml/writer.rb, line 516 def add_table_style(name:, elements: [], pivot: nil, table: nil) @table_styles[:styles] ||= [] style = { name: name, elements: elements } style[:pivot] = pivot unless pivot.nil? style[:table] = table unless table.nil? @table_styles[:styles] << style name end
Adds a table style definition. Returns the style name. elements: array of { type:, dxf_id:, size: }
Source
# File lib/xlsxrb/ooxml/writer.rb, line 554 def app_properties @app_properties.dup end
Returns app properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 328 def auto_filter(sheet: nil) sheet_name = sheet || @sheet_order.first @auto_filters[sheet_name] end
Returns the autoFilter range for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 940 def calc_properties @calc_properties.dup end
Returns calc properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 999 def cell_watches(sheet: nil) sheet_name = sheet || @sheet_order.first (@cell_watches[sheet_name] || []).dup end
Returns cell watches for the given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 152 def cells(sheet: nil) sheet_name = sheet || @sheet_order.first @sheets[sheet_name] || {} end
Returns the registered cells for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1298 def charts(sheet: nil) sheet_name = sheet || @sheet_order.first @charts_data[sheet_name] || [] end
Returns chart definitions for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 750 def col_breaks(sheet: nil) sheet_name = sheet || @sheet_order.first @col_breaks[sheet_name] || [] end
Returns column breaks for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 188 def column_attributes(sheet: nil) sheet_name = sheet || @sheet_order.first @column_attrs[sheet_name] || {} end
Returns column attributes for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 171 def column_widths(sheet: nil) sheet_name = sheet || @sheet_order.first @column_widths[sheet_name] || {} end
Returns column widths for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1417 def comments(sheet: nil) sheet_name = sheet || @sheet_order.first @comments_data[sheet_name] || [] end
Returns comment definitions for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 791 def conditional_formats(sheet: nil) sheet_name = sheet || @sheet_order.first @conditional_formats[sheet_name] || [] end
Returns conditional formatting rules for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1080 def copy_entries_from(filepath) reader = Xlsxrb::Ooxml::Reader.new(filepath) reader.entry_names.each do |name| @extra_entries[name] = reader.raw_entry(name) end # Parse [Content_Types].xml for extra content types. ct_xml = reader.raw_entry("[Content_Types].xml") parse_extra_content_types(ct_xml) if ct_xml && !ct_xml.empty? end
Copies all ZIP entries from an existing XLSX file as pass-through. Generated parts override pass-through parts with the same path.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 542 def core_properties @core_properties.dup end
Returns core properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 564 def custom_properties @custom_properties.map(&:dup) end
Returns custom properties array.
# File lib/xlsxrb/ooxml/writer.rb, line 1031 def data_consolidate(sheet: nil) sheet_name = sheet || @sheet_order.first @data_consolidate[sheet_name]&.dup end
Returns data consolidation settings for the given sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 767 def data_validations(sheet: nil) sheet_name = sheet || @sheet_order.first @data_validations[sheet_name] || [] end
Returns data validations for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 860 def defined_names @defined_names.map(&:dup) end
Returns defined names array.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1496 def external_links @external_links.dup end
Returns external link definitions.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 950 def file_recovery_properties @file_recovery_properties.dup end
Returns file recovery properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 920 def file_sharing @file_sharing.dup end
Returns file sharing hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 910 def file_version @file_version.dup end
Returns file version hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 350 def filter_columns(sheet: nil) sheet_name = sheet || @sheet_order.first @filter_columns[sheet_name] || {} end
Returns filter columns for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 642 def freeze_pane(sheet: nil) sheet_name = sheet || @sheet_order.first @freeze_panes[sheet_name] end
Returns freeze pane settings for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 312 def hyperlinks(sheet: nil) sheet_name = sheet || @sheet_order.first @hyperlinks[sheet_name] || {} end
Returns hyperlinks for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1016 def ignored_errors(sheet: nil) sheet_name = sheet || @sheet_order.first (@ignored_errors[sheet_name] || []).dup end
Returns ignored errors for the given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1127 def images(sheet: nil) sheet_name = sheet || @sheet_order.first @images[sheet_name] || [] end
Returns images for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 491 def indexed_colors @indexed_colors.dup end
Returns the indexed colors palette.
# File lib/xlsxrb/ooxml/writer.rb, line 1094 def insert_image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, from_col_off: nil, from_row_off: nil, to_col_off: nil, to_row_off: nil, name: nil, description: nil, title: nil, hidden: nil, macro: nil, no_change_aspect: true, no_crop: nil, line_color: nil, line_width: nil, rotation: nil, edit_as: nil, published: nil, locks_with_sheet: nil, prints_with_sheet: nil, src_rect: nil, alpha_mod_fix: nil, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @images.key?(sheet_name) img_name = name || "Picture #{@images[sheet_name].size + 1}" img = { file_data: file_data, ext: ext, name: img_name, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row } img[:from_col_off] = from_col_off if from_col_off img[:from_row_off] = from_row_off if from_row_off img[:to_col_off] = to_col_off if to_col_off img[:to_row_off] = to_row_off if to_row_off img[:description] = description if description img[:title] = title if title img[:hidden] = hidden unless hidden.nil? img[:macro] = macro if macro img[:no_change_aspect] = no_change_aspect img[:no_crop] = no_crop unless no_crop.nil? img[:line_color] = line_color if line_color img[:line_width] = line_width if line_width img[:rotation] = rotation if rotation img[:edit_as] = edit_as if edit_as img[:published] = published unless published.nil? img[:locks_with_sheet] = locks_with_sheet unless locks_with_sheet.nil? img[:prints_with_sheet] = prints_with_sheet unless prints_with_sheet.nil? img[:src_rect] = src_rect if src_rect img[:alpha_mod_fix] = alpha_mod_fix if alpha_mod_fix @images[sheet_name] << img end
Inserts an image from file data into the given sheet. file_data: raw image bytes. ext: file extension (e.g. “png”). from_col/from_row: anchor start. to_col/to_row: anchor end.
# File lib/xlsxrb/ooxml/writer.rb, line 281 def merge_cells(range, sheet: nil) raise ArgumentError, "range must be a String like 'A1:B2'" unless range.is_a?(String) && range.match?(/\A[A-Z]+\d+:[A-Z]+\d+\z/) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @merge_cells.key?(sheet_name) @merge_cells[sheet_name] << range end
Merges a range of cells (e.g. “A1:B2”).
Source
# File lib/xlsxrb/ooxml/writer.rb, line 291 def merged_cells(sheet: nil) sheet_name = sheet || @sheet_order.first @merge_cells[sheet_name] || [] end
Returns merged cell ranges for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 503 def mru_colors @mru_colors.map(&:dup) end
Returns the MRU colors.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 694 def page_margins(sheet: nil) sheet_name = sheet || @sheet_order.first @page_margins[sheet_name] end
Returns page margins for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 708 def page_setup(sheet: nil) sheet_name = sheet || @sheet_order.first (@page_setup[sheet_name] || {}).dup end
Returns page setup for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 591 def phonetic_properties(sheet: nil) sheet_name = sheet || @sheet_order.first @phonetic_properties[sheet_name]&.dup end
Returns phonetic properties for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1483 def pivot_tables(sheet: nil) sheet_name = sheet || @sheet_order.first @pivot_tables_data[sheet_name] || [] end
Returns pivot table definitions for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1501 def preserve_macros! @preserve_macros = true end
Enables macro preservation mode. Required when copy_entries_from loads a .xlsm file.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1506 def preserve_macros? @preserve_macros end
Returns whether macro preservation is enabled.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 673 def print_options(sheet: nil) sheet_name = sheet || @sheet_order.first (@print_options[sheet_name] || {}).dup end
Returns print options for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 985 def protected_ranges(sheet: nil) sheet_name = sheet || @sheet_order.first (@protected_ranges[sheet_name] || []).map(&:dup) end
Returns protected ranges for the given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 275 def row_attributes(sheet: nil) sheet_name = sheet || @sheet_order.first @row_attrs[sheet_name] || {} end
Returns row attributes for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 736 def row_breaks(sheet: nil) sheet_name = sheet || @sheet_order.first @row_breaks[sheet_name] || [] end
Returns row breaks for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1046 def scenarios(sheet: nil) sheet_name = sheet || @sheet_order.first @scenarios[sheet_name]&.dup end
Returns scenarios for the given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 659 def selection(sheet: nil) sheet_name = sheet || @sheet_order.first @selections[sheet_name] end
Returns selection for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 547 def set_app_property(name, value) raise ArgumentError, "name must be a Symbol" unless name.is_a?(Symbol) @app_properties[name] = value end
Sets an app property.
# File lib/xlsxrb/ooxml/writer.rb, line 318 def set_auto_filter(range, sheet: nil) raise ArgumentError, "range must be a String like 'A1:B10'" unless range.is_a?(String) && range.match?(/\A[A-Z]+\d+:[A-Z]+\d+\z/) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @auto_filters.key?(sheet_name) @auto_filters[sheet_name] = range end
Sets an autoFilter range (e.g. “A1:B10”) for the given sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 935 def set_calc_property(name, value) @calc_properties[name] = value end
Sets a calc property (e.g. :calc_id, :full_calc_on_load).
# File lib/xlsxrb/ooxml/writer.rb, line 143 def set_cell(cell_address, value, sheet: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) @sheets[sheet_name][cell_address] = value end
Registers a cell value at the given address (e.g. “A1”).
# File lib/xlsxrb/ooxml/writer.rb, line 385 def set_cell_format(cell_address, num_fmt_id, sheet: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @cell_styles.key?(sheet_name) @cell_styles[sheet_name][cell_address] = num_fmt_id end
Sets a number format on a cell. num_fmt_id is from add_number_format or a built-in id.
# File lib/xlsxrb/ooxml/writer.rb, line 468 def set_cell_phonetic(cell_address, sheet: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @cell_phonetic.key?(sheet_name) @cell_phonetic[sheet_name][cell_address] = true end
Marks a cell as containing phonetic text (ph=“1” on the <c> element).
# File lib/xlsxrb/ooxml/writer.rb, line 459 def set_cell_style(cell_address, style_id, sheet: nil) validate_cell_address!(cell_address) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @cell_styles.key?(sheet_name) @cell_styles[sheet_name][cell_address] = { xf_index: style_id } end
Sets a cell style by xf index (from add_cell_style).
# File lib/xlsxrb/ooxml/writer.rb, line 177 def set_column_attribute(col_letter, name, value, sheet: nil) raise ArgumentError, "column must be a String of uppercase letters" unless col_letter.is_a?(String) && col_letter.match?(/\A[A-Z]+\z/) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @column_attrs.key?(sheet_name) @column_attrs[sheet_name][col_letter] ||= {} @column_attrs[sheet_name][col_letter][name] = value end
Sets a column attribute (e.g. :hidden, :best_fit, :outline_level, :collapsed, :style).
# File lib/xlsxrb/ooxml/writer.rb, line 158 def set_column_width(col_letter, width, sheet: nil) raise ArgumentError, "column must be a String of uppercase letters" unless col_letter.is_a?(String) && col_letter.match?(/\A[A-Z]+\z/) col_index = column_letter_to_index(col_letter) raise ArgumentError, "column out of range: #{col_letter}" unless col_index.between?(1, MAX_COLUMN_INDEX) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @column_widths.key?(sheet_name) @column_widths[sheet_name][col_letter] = width end
Sets the width for a column (e.g. “A”, “BC”).
# File lib/xlsxrb/ooxml/writer.rb, line 535 def set_core_property(name, value) raise ArgumentError, "name must be a Symbol" unless name.is_a?(Symbol) @core_properties[name] = value end
Sets a core property.
# File lib/xlsxrb/ooxml/writer.rb, line 1023 def set_data_consolidate(sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) @data_consolidate[sheet_name] = opts end
Sets data consolidation options for the given sheet. Options: function:, start_labels:, top_labels:, link:, data_refs: [{ref:, name:, sheet:}]
# File lib/xlsxrb/ooxml/writer.rb, line 773 def set_data_validations_option(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @data_validations_options.key?(sheet_name) @data_validations_options[sheet_name][name] = value end
Sets a data validations container option (e.g. disable_prompts, x_window, y_window).
# File lib/xlsxrb/ooxml/writer.rb, line 945 def set_file_recovery_property(name, value) @file_recovery_properties[name] = value end
Sets a file recovery property (e.g. :auto_recover, :crash_save).
# File lib/xlsxrb/ooxml/writer.rb, line 915 def set_file_sharing(name, value) @file_sharing[name] = value end
Sets a file sharing property (e.g. :read_only_recommended, :user_name).
# File lib/xlsxrb/ooxml/writer.rb, line 905 def set_file_version(name, value) @file_version[name] = value end
Sets a file version property (e.g. :app_name, :last_edited, :lowest_edited, :rup_build, :code_name).
# File lib/xlsxrb/ooxml/writer.rb, line 625 def set_freeze_pane(row: 0, col: 0, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @freeze_panes.key?(sheet_name) @freeze_panes[sheet_name] = { row: row, col: col, state: :frozen } end
Sets a freeze pane. row: rows to freeze from top, col: columns to freeze from left.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 485 def set_indexed_colors(colors) @indexed_colors = colors end
Sets the indexed colors palette (array of ARGB hex strings, e.g. [“FF000000”, “FFFFFFFF”]). rubocop:disable Naming/AccessorMethodName
Source
# File lib/xlsxrb/ooxml/writer.rb, line 497 def set_mru_colors(colors) @mru_colors = colors end
Sets the MRU (most recently used) colors (array of color hashes, e.g. [{rgb: “FFFF0000”}]). rubocop:disable Naming/AccessorMethodName
# File lib/xlsxrb/ooxml/writer.rb, line 679 def set_page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @page_margins.key?(sheet_name) m = {} m[:left] = left if left m[:right] = right if right m[:top] = top if top m[:bottom] = bottom if bottom m[:header] = header if header m[:footer] = footer if footer @page_margins[sheet_name] = m end
Sets page margins (all values in inches).
# File lib/xlsxrb/ooxml/writer.rb, line 700 def set_page_setup(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @page_setup.key?(sheet_name) @page_setup[sheet_name][name] = value end
Sets a page setup property (e.g. :orientation, :paper_size, :scale, :fit_to_width, :fit_to_height).
# File lib/xlsxrb/ooxml/writer.rb, line 583 def set_phonetic_properties(props, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @phonetic_properties.key?(sheet_name) @phonetic_properties[sheet_name] = props end
Sets phonetic properties for a sheet (e.g. :font_id, :type, :alignment).
# File lib/xlsxrb/ooxml/writer.rb, line 866 def set_print_area(range, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) value = "'#{sheet_name}'!#{absolute_range(range)}" # Remove any existing print area for this sheet idx = @sheet_order.index(sheet_name) @defined_names.reject! { |dn| dn[:name] == "_xlnm.Print_Area" && dn[:local_sheet_id] == idx } add_defined_name("_xlnm.Print_Area", value, sheet: sheet_name) end
Sets the print area for a sheet. range should be like “A1:D20”. Generates the _xlnm.Print_Area defined name automatically.
# File lib/xlsxrb/ooxml/writer.rb, line 665 def set_print_option(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @print_options.key?(sheet_name) @print_options[sheet_name][name] = value end
Sets a print option (e.g. :grid_lines, :headings, :horizontal_centered, :vertical_centered).
# File lib/xlsxrb/ooxml/writer.rb, line 879 def set_print_titles(rows: nil, cols: nil, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) raise ArgumentError, "at least one of rows: or cols: must be specified" unless rows || cols parts = [] parts << "'#{sheet_name}'!$#{cols.sub(":", ":$")}" if cols parts << "'#{sheet_name}'!$#{rows.sub(":", ":$")}" if rows value = parts.join(",") idx = @sheet_order.index(sheet_name) @defined_names.reject! { |dn| dn[:name] == "_xlnm.Print_Titles" && dn[:local_sheet_id] == idx } add_defined_name("_xlnm.Print_Titles", value, sheet: sheet_name) end
Sets print titles (rows and/or columns to repeat on each page). rows: “1:3” repeats rows 1-3, cols: “A:B” repeats columns A-B.
# File lib/xlsxrb/ooxml/writer.rb, line 224 def set_row_collapsed(row_num, collapsed: true, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:collapsed] = collapsed end
Sets a row collapsed state.
# File lib/xlsxrb/ooxml/writer.rb, line 194 def set_row_height(row_num, height, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:height] = height end
Sets a row height.
# File lib/xlsxrb/ooxml/writer.rb, line 214 def set_row_outline_level(row_num, level, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:outline_level] = level end
Sets a row outline level.
# File lib/xlsxrb/ooxml/writer.rb, line 265 def set_row_phonetic(row_num, phonetic: true, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:ph] = phonetic end
Sets a row phonetic flag.
# File lib/xlsxrb/ooxml/writer.rb, line 234 def set_row_style(row_num, style_id, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 raise ArgumentError, "style_id must be a non-negative Integer" unless style_id.is_a?(Integer) && style_id >= 0 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:style] = style_id end
Sets a row default style index (cellXfs index).
# File lib/xlsxrb/ooxml/writer.rb, line 255 def set_row_thick_bot(row_num, thick: true, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:thick_bot] = thick end
Sets a row thick bottom border flag.
# File lib/xlsxrb/ooxml/writer.rb, line 245 def set_row_thick_top(row_num, thick: true, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @row_attrs.key?(sheet_name) raise ArgumentError, "row must be a positive Integer" unless row_num.is_a?(Integer) && row_num >= 1 @row_attrs[sheet_name][row_num] ||= {} @row_attrs[sheet_name][row_num][:thick_top] = thick end
Sets a row thick top border flag.
# File lib/xlsxrb/ooxml/writer.rb, line 1038 def set_scenarios(sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) @scenarios[sheet_name] = opts end
Sets scenarios for the given sheet. Options: current:, show:, sqref:, scenarios: [{name:, input_cells: [{r:, val:, …}], …}]
# File lib/xlsxrb/ooxml/writer.rb, line 648 def set_selection(active_cell, sqref: nil, pane: nil, active_cell_id: nil, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @selections.key?(sheet_name) sel = { active_cell: active_cell, sqref: sqref || active_cell } sel[:pane] = pane if pane sel[:active_cell_id] = active_cell_id if active_cell_id @selections[sheet_name] = sel end
Sets the active cell selection.
# File lib/xlsxrb/ooxml/writer.rb, line 597 def set_sheet_format(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheet_formats.key?(sheet_name) @sheet_formats[sheet_name][name] = value end
Sets a sheet format property (e.g. :default_row_height, :default_col_width, :base_col_width).
# File lib/xlsxrb/ooxml/writer.rb, line 569 def set_sheet_property(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheet_properties.key?(sheet_name) @sheet_properties[sheet_name][name] = value end
Sets a sheet-level property (e.g. :tab_color, :summary_below, :summary_right).
# File lib/xlsxrb/ooxml/writer.rb, line 959 def set_sheet_protection(sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) @sheet_protection[sheet_name] = opts end
Sets sheet protection options. Options: :password, :sheet, :objects, :scenarios, :format_cells, :format_columns,
:format_rows, :insert_columns, :insert_rows, :insert_hyperlinks, :delete_columns, :delete_rows, :select_locked_cells, :sort, :auto_filter, :pivot_tables, :select_unlocked_cells, :algorithm_name, :hash_value, :salt_value, :spin_count
# File lib/xlsxrb/ooxml/writer.rb, line 831 def set_sheet_state(sheet_name, state) raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheets.key?(sheet_name) raise ArgumentError, "state must be :visible, :hidden, or :very_hidden" unless %i[visible hidden very_hidden].include?(state) @sheet_states[sheet_name] = state end
Sets a sheet’s visibility state (:visible, :hidden, :very_hidden).
# File lib/xlsxrb/ooxml/writer.rb, line 611 def set_sheet_view(name, value, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sheet_views.key?(sheet_name) @sheet_views[sheet_name][name] = value end
Sets a sheet view property (e.g. :show_grid_lines, :show_row_col_headers, :right_to_left, :zoom_scale).
# File lib/xlsxrb/ooxml/writer.rb, line 357 def set_sort_state(ref, sort_conditions, sheet: nil, **opts) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @sort_state.key?(sheet_name) ss = { ref: ref, sort_conditions: sort_conditions } %i[column_sort case_sensitive sort_method].each do |key| ss[key] = opts[key] if opts.key?(key) end @sort_state[sheet_name] = ss end
Sets a sort state for the sheet. ref: sort range, sort_conditions: array of { ref:, descending: }. Options: column_sort:, case_sensitive:, sort_method:
# File lib/xlsxrb/ooxml/writer.rb, line 634 def set_split_pane(x_split: 0, y_split: 0, top_left_cell: nil, sheet: nil) sheet_name = sheet || @sheet_order.first raise ArgumentError, "unknown sheet: #{sheet_name}" unless @freeze_panes.key?(sheet_name) @freeze_panes[sheet_name] = { x_split: x_split, y_split: y_split, top_left_cell: top_left_cell, state: :split } end
Sets a split pane (non-frozen). x_split/y_split are in 1/20th of a point (twips). top_left_cell: the cell at top-left of the bottom-right pane.
# File lib/xlsxrb/ooxml/writer.rb, line 508 def set_table_styles_option(name, value) raise ArgumentError, "name must be a Symbol" unless name.is_a?(Symbol) @table_styles[name] = value end
Sets table styles options (defaultTableStyle, defaultPivotStyle).
# File lib/xlsxrb/ooxml/writer.rb, line 895 def set_workbook_property(name, value) @workbook_properties[name] = value end
Sets a workbook property (e.g. :date1904, :default_theme_version).
# File lib/xlsxrb/ooxml/writer.rb, line 1053 def set_workbook_protection(**opts) @workbook_protection = opts end
Sets workbook protection options. Options: :lock_structure, :lock_windows, :password, :algorithm_name, :hash_value, :salt_value, :spin_count
# File lib/xlsxrb/ooxml/writer.rb, line 925 def set_workbook_view(name, value) @workbook_views[name] = value end
Sets a workbook view property (e.g. :active_tab, :first_sheet).
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1399 def shapes(sheet: nil) sheet_name = sheet || @sheet_order.first @shapes_data[sheet_name] || [] end
Returns shape definitions for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 605 def sheet_format(sheet: nil) sheet_name = sheet || @sheet_order.first (@sheet_formats[sheet_name] || {}).dup end
Returns sheet format properties for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 577 def sheet_properties(sheet: nil) sheet_name = sheet || @sheet_order.first (@sheet_properties[sheet_name] || {}).dup end
Returns sheet properties for the first (or given) sheet.
# File lib/xlsxrb/ooxml/writer.rb, line 967 def sheet_protection(sheet: nil) sheet_name = sheet || @sheet_order.first @sheet_protection[sheet_name]&.dup end
Returns sheet protection settings for the given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 839 def sheet_state(sheet_name) @sheet_states[sheet_name] || :visible end
Returns the sheet state for a given sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 619 def sheet_view(sheet: nil) sheet_name = sheet || @sheet_order.first (@sheet_views[sheet_name] || {}).dup end
Returns sheet view properties for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 369 def sort_state(sheet: nil) sheet_name = sheet || @sheet_order.first @sort_state[sheet_name] end
Returns sort state for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 526 def table_styles deep_copy = {} @table_styles.each do |k, v| deep_copy[k] = v.is_a?(Array) ? v.map(&:dup) : v end deep_copy end
Returns table styles configuration.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 820 def tables(sheet: nil) sheet_name = sheet || @sheet_order.first @tables[sheet_name] || [] end
Returns table definitions for the first (or given) sheet.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 900 def workbook_properties @workbook_properties.dup end
Returns workbook properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1058 def workbook_protection @workbook_protection&.dup end
Returns workbook protection settings.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 930 def workbook_views @workbook_views.dup end
Returns workbook view properties hash.
Source
# File lib/xlsxrb/ooxml/writer.rb, line 1511 def write(filepath) # Pre-register date/datetime formats if any sheet contains Date or Time values. needs_date = false needs_datetime = false @sheet_order.each do |sn| @sheets[sn].each_value do |v| needs_datetime = true if v.is_a?(Time) needs_date = true if v.is_a?(Date) && !v.is_a?(Time) end break if needs_date && needs_datetime end date_num_fmt_id if needs_date datetime_num_fmt_id if needs_datetime # Clear memoized xf index map so it picks up all registered formats. @xf_index_map = nil # Pre-populate xf entries for legacy num_fmt-based styles. @num_fmts.each { |nf| resolve_style_index(nf[:num_fmt_id]) } # Build shared string table if enabled. sst = build_shared_string_table if @use_shared_strings # Track generated drawing/image/chart/comment/pivot indices. @drawing_count = 0 @chart_count = 0 @comment_count = 0 @pivot_cache_count = 0 @pivot_table_count = 0 @media_count = 0 # Pre-compute total pivot cache count for workbook XML. total_pivot_caches = @pivot_tables_data.values.sum(&:size) entries = { "_rels/.rels" => generate_rels_root, "xl/workbook.xml" => generate_workbook_xml(total_pivot_caches), "xl/styles.xml" => generate_styles_xml } entries["docProps/core.xml"] = generate_core_properties_xml unless @core_properties.empty? entries["docProps/app.xml"] = generate_app_properties_xml unless @app_properties.empty? entries["docProps/custom.xml"] = generate_custom_properties_xml unless @custom_properties.empty? entries["xl/sharedStrings.xml"] = generate_shared_strings_xml(sst) if sst table_index = 0 @sheet_order.each_with_index do |sheet_name, i| sheet_images = @images[sheet_name] || [] sheet_charts = @charts_data[sheet_name] || [] sheet_shapes = @shapes_data[sheet_name] || [] sheet_comments = @comments_data[sheet_name] || [] sheet_pivots = @pivot_tables_data[sheet_name] || [] has_drawing = sheet_images.any? || sheet_charts.any? || sheet_shapes.any? has_comments = sheet_comments.any? # Pre-increment counters so rels reference correct paths. sheet_drawing_idx = has_drawing ? (@drawing_count += 1) : nil sheet_comment_idx = has_comments ? (@comment_count += 1) : nil sheet_pivot_start = @pivot_table_count sheet_cache_start = @pivot_cache_count sheet_pivots.each do @pivot_cache_count += 1 @pivot_table_count += 1 end # Build per-sheet rels first (needed for rId calculation in worksheet XML). sheet_tables = @tables[sheet_name] || [] sheet_rels_parts = build_sheet_rels_parts_v2( sheet_name, sheet_tables, table_index, sheet_drawing_idx, sheet_comment_idx, sheet_pivot_start, sheet_pivots.size ) # Calculate the legacyDrawing rId if comments exist. # The VML rel is always the one after the comments rel in rels. vml_rid = nil if has_comments vml_idx = sheet_rels_parts.index { |r| r[:type]&.end_with?("/vmlDrawing") } vml_rid = vml_idx + 1 if vml_idx # 1-based rId end entries["xl/worksheets/sheet#{i + 1}.xml"] = generate_worksheet_xml( @sheets[sheet_name], @column_widths[sheet_name], @column_attrs[sheet_name], @row_attrs[sheet_name], @auto_filters[sheet_name], @filter_columns[sheet_name], @sort_state[sheet_name], @merge_cells[sheet_name], @hyperlinks[sheet_name], @cell_styles[sheet_name], @sheet_properties[sheet_name], @sheet_formats[sheet_name], @sheet_views[sheet_name], @freeze_panes[sheet_name], @selections[sheet_name], @print_options[sheet_name], @page_margins[sheet_name], @page_setup[sheet_name], @header_footer[sheet_name], @row_breaks[sheet_name], @col_breaks[sheet_name], @data_validations[sheet_name], @conditional_formats[sheet_name], sst, @tables[sheet_name] || [], @hyperlinks[sheet_name].size, has_drawing:, has_comments:, sheet_prot: @sheet_protection[sheet_name], vml_rid:, phonetic_pr: @phonetic_properties[sheet_name], dv_options: @data_validations_options[sheet_name], prot_ranges: @protected_ranges[sheet_name], cell_watches: @cell_watches[sheet_name], ignored_errors: @ignored_errors[sheet_name], data_consol: @data_consolidate[sheet_name], sheet_scenarios: @scenarios[sheet_name], cell_phonetic: @cell_phonetic[sheet_name] ) # Generate drawing XML + media + chart entries. if has_drawing drawing_rels_data = [] drawing_parts = [] sheet_images.each do |img| @media_count += 1 media_path = "xl/media/image#{@media_count}.#{img[:ext]}" entries[media_path] = img[:file_data] drawing_rels_data << { type: :image, target: "../media/image#{@media_count}.#{img[:ext]}" } drawing_parts << { kind: :pic, img: img, rid_index: drawing_rels_data.size } end sheet_charts.each do |chart| @chart_count += 1 chart_path = "xl/charts/chart#{@chart_count}.xml" entries[chart_path] = generate_chart_xml(chart) drawing_rels_data << { type: :chart, target: "../charts/chart#{@chart_count}.xml" } drawing_parts << { kind: :chart, chart: chart, rid_index: drawing_rels_data.size } end shape_id_base = drawing_parts.size + 1 sheet_shapes.each_with_index do |shape, si| drawing_parts << { kind: :sp, shape: shape, id: shape_id_base + si + 1 } end entries["xl/drawings/drawing#{sheet_drawing_idx}.xml"] = generate_drawing_xml(drawing_parts) entries["xl/drawings/_rels/drawing#{sheet_drawing_idx}.xml.rels"] = generate_drawing_rels(drawing_rels_data) unless drawing_rels_data.empty? end # Generate comments XML and VML drawing. if has_comments entries["xl/comments#{sheet_comment_idx}.xml"] = generate_comments_xml(sheet_comments) entries["xl/drawings/vmlDrawing#{sheet_comment_idx}.vml"] = generate_vml_drawing_xml(sheet_comments) end # Generate pivot table + cache entries. sheet_pivots.each_with_index do |pt, pi| cache_idx = sheet_cache_start + pi + 1 pt_idx = sheet_pivot_start + pi + 1 entries["xl/pivotCache/pivotCacheDefinition#{cache_idx}.xml"] = generate_pivot_cache_definition_xml(pt, cache_idx) entries["xl/pivotCache/pivotCacheRecords#{cache_idx}.xml"] = generate_pivot_cache_records_xml(pt) entries["xl/pivotTables/pivotTable#{pt_idx}.xml"] = generate_pivot_table_xml(pt, cache_idx) entries["xl/pivotCache/_rels/pivotCacheDefinition#{cache_idx}.xml.rels"] = generate_pivot_cache_rels(cache_idx) entries["xl/pivotTables/_rels/pivotTable#{pt_idx}.xml.rels"] = generate_pivot_table_rels(cache_idx) end # Emit worksheet rels if any relationships exist. entries["xl/worksheets/_rels/sheet#{i + 1}.xml.rels"] = generate_generic_rels(sheet_rels_parts) unless sheet_rels_parts.empty? sheet_tables.each do |tbl| table_index += 1 entries["xl/tables/table#{table_index}.xml"] = generate_table_xml(tbl) end end # Generate calcChain.xml if any cells have formulas. calc_chain_xml = generate_calc_chain_xml entries["xl/calcChain.xml"] = calc_chain_xml if calc_chain_xml # Generate external link entries. @external_links.each_with_index do |el, idx| link_num = idx + 1 entries["xl/externalLinks/externalLink#{link_num}.xml"] = generate_external_link_xml(el) entries["xl/externalLinks/_rels/externalLink#{link_num}.xml.rels"] = generate_external_link_rels(el) end # Generate workbook rels (needs to know pivot cache count). entries["xl/_rels/workbook.xml.rels"] = generate_workbook_rels(has_calc_chain: entries.key?("xl/calcChain.xml")) # Content types must be generated after all entries are known. entries["[Content_Types].xml"] = generate_content_types_xml(entries) # Merge extra (pass-through) entries — generated entries take priority. merged = @extra_entries.merge(entries) generator = ZipGenerator.new(filepath) merged.each { |path, content| generator.add_entry(path, content) } generator.generate end
Writes the workbook as an XLSX file to the given path.