class Xlsxrb::StreamWriter
DSL context for Xlsxrb.generate streaming writes.
Public Class Methods
Source
# File lib/xlsxrb.rb, line 784 def initialize(target) @target = target @sst = [] @sst_index = {} @sheets = [] @current_sheet = nil @current_row_index = 0 @tempfiles = [] @current_tempfile = nil @current_row_writer = nil @current_columns = [] @current_charts = [] @current_hyperlinks = [] @current_auto_filter = nil @current_filter_columns = {} @current_sort_state = nil @current_data_validations = [] @current_conditional_formats = [] @current_tables = [] @current_comments = [] @current_merge_cells = [] @current_freeze_pane = nil @current_split_pane = nil @current_selection = nil @current_page_margins = nil @current_page_setup = {} @current_header_footer = {} @current_print_options = {} @current_sheet_protection = nil @current_images = [] @current_shapes = [] @current_sheet_properties = {} @current_sheet_view = {} @current_row_breaks = [] @current_col_breaks = [] @styles = {} # { style_name => StyleBuilder } @style_writer = Ooxml::Writer.new @style_name_to_id = {} # Workbook-level settings @defined_names = [] @core_properties = {} @app_properties = {} @custom_properties = [] @workbook_protection = nil end
Public Instance Methods
# File lib/xlsxrb.rb, line 926 def add_chart(**options, &block) add_sheet if @current_sheet.nil? if block_given? builder = ChartBuilder.new block.call(builder) options = builder.options.merge(options) end @current_charts << options end
Add a chart to the current sheet.
Source
# File lib/xlsxrb.rb, line 1127 def add_col_break(col_index) add_sheet if @current_sheet.nil? @current_col_breaks << col_index end
# File lib/xlsxrb.rb, line 1010 def add_comment(cell, text, author: "Author") add_sheet if @current_sheet.nil? @current_comments << { cell: cell, text: text, author: author } end
— Comments —
# File lib/xlsxrb.rb, line 978 def add_conditional_format(sqref, **opts) add_sheet if @current_sheet.nil? @current_conditional_formats << opts.merge(sqref: sqref) end
— Conditional Formatting —
# File lib/xlsxrb.rb, line 1179 def add_custom_property(name, value, type: :string) @custom_properties << { name: name, value: value, type: type } end
Add a custom document property.
# File lib/xlsxrb.rb, line 971 def add_data_validation(sqref, **opts) add_sheet if @current_sheet.nil? @current_data_validations << opts.merge(sqref: sqref) end
— Data Validation —
# File lib/xlsxrb.rb, line 1135 def add_defined_name(name, value, sheet: nil, hidden: false) entry = { name: name, value: value, hidden: hidden } if sheet # local_sheet_id will be resolved at close time entry[:local_sheet_name] = sheet end @defined_names << entry end
Add a defined name.
# File lib/xlsxrb.rb, line 959 def add_filter_column(col_id, filter) add_sheet if @current_sheet.nil? @current_filter_columns[col_id] = filter end
rubocop:enable Naming/AccessorMethodName
# File lib/xlsxrb.rb, line 940 def add_hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil) add_sheet if @current_sheet.nil? link = { cell: cell } link[:url] = url if url link[:display] = display if display link[:tooltip] = tooltip if tooltip link[:location] = location if location @current_hyperlinks << link end
— Hyperlinks —
# File lib/xlsxrb.rb, line 1091 def add_image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, **opts) add_sheet if @current_sheet.nil? img = { file_data: file_data, ext: ext, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row } img.merge!(opts) @current_images << img end
— Images —
# File lib/xlsxrb.rb, line 997 def add_pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil) add_sheet if @current_sheet.nil? @current_pivot_tables ||= [] @current_pivot_tables << { source_ref: source_ref, row_fields: row_fields, data_fields: data_fields, col_fields: col_fields, dest_ref: dest_ref, name: name, field_names: field_names, items: items } end
— Pivot Tables —
Source
# File lib/xlsxrb.rb, line 891 def add_row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil) add_sheet if @current_sheet.nil? row_index = @current_row_index @current_row_index += 1 @current_cells ||= {} row_num = row_index + 1 values.each_with_index do |val, col_idx| next if val.nil? addr = "#{Elements::Cell.column_letter(col_idx)}#{row_num}" @current_cells[addr] = val end attrs = nil if height || hidden || outline_level attrs = {} attrs[:height] = height if height attrs[:hidden] = true if hidden attrs[:custom_height] = custom_height || !height.nil? attrs[:outline_level] = outline_level if outline_level end @current_row_writer.write_row_values(row_index, values, styles: styles, style_map: @style_name_to_id, sst: @sst, sst_index: @sst_index, attrs: attrs) end
Add a row of values. values is an Array.
- styles
-
Hash mapping column indices to style names, or Array of style names for each column
Source
# File lib/xlsxrb.rb, line 1122 def add_row_break(row_num) add_sheet if @current_sheet.nil? @current_row_breaks << row_num end
— Row / Column Breaks —
Source
# File lib/xlsxrb.rb, line 1100 def add_shape(preset: "rect", text: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, **opts) add_sheet if @current_sheet.nil? shape = { preset: preset, text: text, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row } shape[:name] = opts.delete(:name) || "Shape #{@current_shapes.size + 1}" shape.merge!(opts) @current_shapes << shape end
— Shapes —
# File lib/xlsxrb.rb, line 844 def add_sheet(name = nil) flush_current_sheet name ||= "Sheet#{@sheets.size + 1}" @current_sheet = name @current_row_index = 0 @current_tempfile = Tempfile.new(["xlsxrb_rows", ".xml"]) @current_tempfile.binmode @current_row_writer = Ooxml::WorksheetWriter.new(@current_tempfile) @current_row_writer.instance_variable_set(:@started, true) @current_columns = [] @current_charts = [] @current_hyperlinks = [] @current_auto_filter = nil @current_filter_columns = {} @current_sort_state = nil @current_data_validations = [] @current_conditional_formats = [] @current_tables = [] @current_pivot_tables = [] @current_sparkline_groups = [] @current_comments = [] @current_merge_cells = [] @current_freeze_pane = nil @current_split_pane = nil @current_selection = nil @current_page_margins = nil @current_page_setup = {} @current_header_footer = {} @current_print_options = {} @current_sheet_protection = nil @current_images = [] @current_shapes = [] @current_sheet_properties = {} @current_sheet_view = {} @current_row_breaks = [] @current_col_breaks = [] @current_cells = {} return unless block_given? yield self flush_current_sheet end
Start or switch to a named sheet.
# File lib/xlsxrb.rb, line 1017 def add_sparkline_group(sparklines:, type: nil, **opts) add_sheet if @current_sheet.nil? group = { sparklines: sparklines } group[:type] = type if type group.merge!(opts) @current_sparkline_groups << group end
— Sparklines —
# File lib/xlsxrb.rb, line 831 def add_style(name, **opts, &block) style_builder = StyleBuilder.new(name) style_builder.apply_options!(**opts) unless opts.empty? block.call(style_builder) if block_given? @styles[name] = style_builder # Register immediately @style_name_to_id[name] = style_builder.register_with(@style_writer) style_builder end
Define a named style that can be applied to cells.
# File lib/xlsxrb.rb, line 985 def add_table(ref, columns:, name: nil, display_name: nil, style: nil, **opts) add_sheet if @current_sheet.nil? tbl = { ref: ref, columns: columns } tbl[:name] = name if name tbl[:display_name] = display_name if display_name tbl[:style] = style if style tbl.merge!(opts) @current_tables << tbl end
— Tables —
Source
# File lib/xlsxrb.rb, line 1183 def close TRACER.in_span("StreamWriter#close") do flush_current_sheet styles_definition = { fonts: @style_writer.instance_variable_get(:@fonts).dup, fills: @style_writer.instance_variable_get(:@fills).dup, borders: @style_writer.instance_variable_get(:@borders).dup, xf_entries: @style_writer.instance_variable_get(:@xf_entries).dup, num_fmts: @style_writer.instance_variable_get(:@num_fmts).dup } resolved_names = resolve_defined_names(@defined_names, @sheets) Ooxml::WorkbookWriter.write( @target, sheets: @sheets, shared_strings: @sst, styles: styles_definition, defined_names: resolved_names.empty? ? nil : resolved_names, core_properties: @core_properties.empty? ? nil : @core_properties, app_properties: @app_properties.empty? ? nil : @app_properties, custom_properties: @custom_properties.empty? ? nil : @custom_properties, workbook_protection: @workbook_protection ) end ensure @tempfiles.each do |tmp| tmp.close tmp.unlink end end
Source
# File lib/xlsxrb.rb, line 1027 def merge_cells(range) add_sheet if @current_sheet.nil? @current_merge_cells << range end
— Merge Cells —
# File lib/xlsxrb.rb, line 1174 def set_app_property(name, value) @app_properties[name] = value end
Set an app document property.
Source
# File lib/xlsxrb.rb, line 953 def set_auto_filter(range) add_sheet if @current_sheet.nil? @current_auto_filter = range end
rubocop:disable Naming/AccessorMethodName
# File lib/xlsxrb.rb, line 919 def set_column(index, width: nil, hidden: false, custom_width: false, outline_level: nil) add_sheet if @current_sheet.nil? @current_columns << { index: index, width: width, hidden: hidden, custom_width: custom_width || !width.nil?, outline_level: outline_level } end
Set column width for a 0-based column index.
# File lib/xlsxrb.rb, line 1169 def set_core_property(name, value) @core_properties[name] = value end
Set a core document property.
# File lib/xlsxrb.rb, line 1034 def set_freeze_pane(row: 0, col: 0) add_sheet if @current_sheet.nil? @current_freeze_pane = { row: row, col: col } end
— Freeze / Split Panes —
# File lib/xlsxrb.rb, line 1052 def set_page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil) add_sheet if @current_sheet.nil? @current_page_margins = { left: left, right: right, top: top, bottom: bottom, header: header, footer: footer }.compact end
— Page Setup / Margins / Print —
Source
# File lib/xlsxrb.rb, line 1057 def set_page_setup(**opts) add_sheet if @current_sheet.nil? @current_page_setup.merge!(opts) end
# File lib/xlsxrb.rb, line 1145 def set_print_area(range, sheet: nil) sheet_name = sheet || @current_sheet || "Sheet1" value = "'#{sheet_name}'!#{absolute_range(range)}" @defined_names.reject! { |dn| dn[:name] == "_xlnm.Print_Area" && dn[:local_sheet_name] == sheet_name } add_defined_name("_xlnm.Print_Area", value, sheet: sheet_name) end
Set the print area for the current or named sheet.
# File lib/xlsxrb.rb, line 1067 def set_print_option(name, value) add_sheet if @current_sheet.nil? @current_print_options[name] = value end
# File lib/xlsxrb.rb, line 1153 def set_print_titles(rows: nil, cols: nil, sheet: nil) sheet_name = sheet || @current_sheet || "Sheet1" parts = [] parts << "'#{sheet_name}'!$#{cols.sub(":", ":$")}" if cols parts << "'#{sheet_name}'!$#{rows.sub(":", ":$")}" if rows value = parts.join(",") @defined_names.reject! { |dn| dn[:name] == "_xlnm.Print_Titles" && dn[:local_sheet_name] == sheet_name } add_defined_name("_xlnm.Print_Titles", value, sheet: sheet_name) end
Set print titles for the current or named sheet.
# File lib/xlsxrb.rb, line 1044 def set_selection(active_cell, sqref: nil, pane: nil) add_sheet if @current_sheet.nil? @current_selection = { active_cell: active_cell, sqref: sqref || active_cell } @current_selection[:pane] = pane if pane end
# File lib/xlsxrb.rb, line 1110 def set_sheet_property(name, value) add_sheet if @current_sheet.nil? @current_sheet_properties[name] = value end
— Sheet Properties —
# File lib/xlsxrb.rb, line 1074 def set_sheet_protection(**opts) add_sheet if @current_sheet.nil? normalized = opts.dup plain_password = normalized[:password] needs_hash = plain_password.is_a?(String) && !plain_password.empty? && normalized[:algorithm_name].nil? && normalized[:hash_value].nil? && normalized[:salt_value].nil? && normalized[:spin_count].nil? && !plain_password.match?(/\A[0-9A-Fa-f]{4}\z/) if needs_hash normalized.delete(:password) normalized.merge!(Xlsxrb::Ooxml::Utils.hash_password(plain_password)) end @current_sheet_protection = normalized end
— Sheet Protection —
Source
# File lib/xlsxrb.rb, line 1115 def set_sheet_view(name, value) add_sheet if @current_sheet.nil? @current_sheet_view[name] = value end
# File lib/xlsxrb.rb, line 964 def set_sort_state(ref, sort_conditions, **opts) add_sheet if @current_sheet.nil? @current_sort_state = { ref: ref, sort_conditions: sort_conditions }.merge(opts) end
# File lib/xlsxrb.rb, line 1039 def set_split_pane(x_split: 0, y_split: 0, top_left_cell: nil) add_sheet if @current_sheet.nil? @current_split_pane = { x_split: x_split, y_split: y_split, top_left_cell: top_left_cell } end
# File lib/xlsxrb.rb, line 1164 def set_workbook_protection(**opts) @workbook_protection = opts end
Set workbook protection.