Class: Xlsxrb::StreamWriter
- Inherits:
-
Object
- Object
- Xlsxrb::StreamWriter
- Defined in:
- lib/xlsxrb.rb
Overview
DSL context for Xlsxrb.generate streaming writes.
Instance Method Summary collapse
-
#add_chart(**options, &block) ⇒ Object
Add a chart to the current sheet.
- #add_col_break(col_index) ⇒ Object
-
#add_comment(cell, text, author: "Author") ⇒ Object
--- Comments ---.
-
#add_conditional_format(sqref, **opts) ⇒ Object
--- Conditional Formatting ---.
-
#add_custom_property(name, value, type: :string) ⇒ Object
Add a custom document property.
-
#add_data_validation(sqref, **opts) ⇒ Object
--- Data Validation ---.
-
#add_defined_name(name, value, sheet: nil, hidden: false) ⇒ Object
Add a defined name.
-
#add_filter_column(col_id, filter) ⇒ Object
rubocop:enable Naming/AccessorMethodName.
-
#add_hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil) ⇒ Object
--- Hyperlinks ---.
-
#add_image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, **opts) ⇒ Object
--- Images ---.
-
#add_pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil) ⇒ Object
--- Pivot Tables ---.
-
#add_row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil) ⇒ Object
Add a row of values.
-
#add_row_break(row_num) ⇒ Object
--- Row / Column Breaks ---.
-
#add_shape(preset: "rect", text: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, **opts) ⇒ Object
--- Shapes ---.
-
#add_sheet(name = nil) {|_self| ... } ⇒ Object
Start or switch to a named sheet.
-
#add_sparkline_group(sparklines:, type: nil, **opts) ⇒ Object
--- Sparklines ---.
-
#add_style(name, **opts, &block) ⇒ Object
Define a named style that can be applied to cells.
-
#add_table(ref, columns:, name: nil, display_name: nil, style: nil, **opts) ⇒ Object
--- Tables ---.
- #close ⇒ Object
-
#initialize(target) ⇒ StreamWriter
constructor
A new instance of StreamWriter.
-
#merge_cells(range) ⇒ Object
--- Merge Cells ---.
-
#set_app_property(name, value) ⇒ Object
Set an app document property.
-
#set_auto_filter(range) ⇒ Object
rubocop:disable Naming/AccessorMethodName.
-
#set_column(index, width: nil, hidden: false, custom_width: false, outline_level: nil) ⇒ Object
Set column width for a 0-based column index.
-
#set_core_property(name, value) ⇒ Object
Set a core document property.
-
#set_freeze_pane(row: 0, col: 0) ⇒ Object
--- Freeze / Split Panes ---.
- #set_header_footer(**opts) ⇒ Object
-
#set_page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil) ⇒ Object
--- Page Setup / Margins / Print ---.
- #set_page_setup(**opts) ⇒ Object
-
#set_print_area(range, sheet: nil) ⇒ Object
Set the print area for the current or named sheet.
- #set_print_option(name, value) ⇒ Object
-
#set_print_titles(rows: nil, cols: nil, sheet: nil) ⇒ Object
Set print titles for the current or named sheet.
- #set_selection(active_cell, sqref: nil, pane: nil) ⇒ Object
-
#set_sheet_property(name, value) ⇒ Object
--- Sheet Properties ---.
-
#set_sheet_protection(**opts) ⇒ Object
--- Sheet Protection ---.
- #set_sheet_view(name, value) ⇒ Object
- #set_sort_state(ref, sort_conditions, **opts) ⇒ Object
- #set_split_pane(x_split: 0, y_split: 0, top_left_cell: nil) ⇒ Object
-
#set_workbook_protection(**opts) ⇒ Object
Set workbook protection.
Constructor Details
#initialize(target) ⇒ StreamWriter
Returns a new instance of StreamWriter.
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 |
# 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 |
Instance Method Details
#add_chart(**options, &block) ⇒ Object
Add a chart to the current sheet.
926 927 928 929 930 931 932 933 934 935 936 |
# File 'lib/xlsxrb.rb', line 926 def add_chart(**, &block) add_sheet if @current_sheet.nil? if block_given? builder = ChartBuilder.new block.call(builder) = builder..merge() end @current_charts << end |
#add_col_break(col_index) ⇒ Object
1127 1128 1129 1130 |
# File 'lib/xlsxrb.rb', line 1127 def add_col_break(col_index) add_sheet if @current_sheet.nil? @current_col_breaks << col_index end |
#add_comment(cell, text, author: "Author") ⇒ Object
--- Comments ---
1010 1011 1012 1013 |
# 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: } end |
#add_conditional_format(sqref, **opts) ⇒ Object
--- Conditional Formatting ---
978 979 980 981 |
# 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 |
#add_custom_property(name, value, type: :string) ⇒ Object
Add a custom document property.
1179 1180 1181 |
# File 'lib/xlsxrb.rb', line 1179 def add_custom_property(name, value, type: :string) @custom_properties << { name: name, value: value, type: type } end |
#add_data_validation(sqref, **opts) ⇒ Object
--- Data Validation ---
971 972 973 974 |
# 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 |
#add_defined_name(name, value, sheet: nil, hidden: false) ⇒ Object
Add a defined name.
1135 1136 1137 1138 1139 1140 1141 1142 |
# 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_filter_column(col_id, filter) ⇒ Object
rubocop:enable Naming/AccessorMethodName
959 960 961 962 |
# 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 |
#add_hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil) ⇒ Object
--- Hyperlinks ---
940 941 942 943 944 945 946 947 948 |
# 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 |
#add_image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, **opts) ⇒ Object
--- Images ---
1091 1092 1093 1094 1095 1096 |
# 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 |
#add_pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil) ⇒ Object
--- Pivot Tables ---
997 998 999 1000 1001 1002 1003 1004 1005 1006 |
# 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 |
#add_row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil) ⇒ Object
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
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 |
# 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_row_break(row_num) ⇒ Object
--- Row / Column Breaks ---
1122 1123 1124 1125 |
# File 'lib/xlsxrb.rb', line 1122 def add_row_break(row_num) add_sheet if @current_sheet.nil? @current_row_breaks << row_num end |
#add_shape(preset: "rect", text: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, **opts) ⇒ Object
--- Shapes ---
1100 1101 1102 1103 1104 1105 1106 |
# 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 |
#add_sheet(name = nil) {|_self| ... } ⇒ Object
Start or switch to a named sheet.
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 |
# 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 |
#add_sparkline_group(sparklines:, type: nil, **opts) ⇒ Object
--- Sparklines ---
1017 1018 1019 1020 1021 1022 1023 |
# 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 |
#add_style(name, **opts, &block) ⇒ Object
Define a named style that can be applied to cells.
831 832 833 834 835 836 837 838 839 840 841 |
# File 'lib/xlsxrb.rb', line 831 def add_style(name, **opts, &block) style_builder = StyleBuilder.new(name) style_builder.(**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 |
#add_table(ref, columns:, name: nil, display_name: nil, style: nil, **opts) ⇒ Object
--- Tables ---
985 986 987 988 989 990 991 992 993 |
# 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 |
#close ⇒ Object
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 |
# 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 |
#merge_cells(range) ⇒ Object
--- Merge Cells ---
1027 1028 1029 1030 |
# File 'lib/xlsxrb.rb', line 1027 def merge_cells(range) add_sheet if @current_sheet.nil? @current_merge_cells << range end |
#set_app_property(name, value) ⇒ Object
Set an app document property.
1174 1175 1176 |
# File 'lib/xlsxrb.rb', line 1174 def set_app_property(name, value) @app_properties[name] = value end |
#set_auto_filter(range) ⇒ Object
rubocop:disable Naming/AccessorMethodName
953 954 955 956 |
# File 'lib/xlsxrb.rb', line 953 def set_auto_filter(range) add_sheet if @current_sheet.nil? @current_auto_filter = range end |
#set_column(index, width: nil, hidden: false, custom_width: false, outline_level: nil) ⇒ Object
Set column width for a 0-based column index.
919 920 921 922 923 |
# 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_core_property(name, value) ⇒ Object
Set a core document property.
1169 1170 1171 |
# File 'lib/xlsxrb.rb', line 1169 def set_core_property(name, value) @core_properties[name] = value end |
#set_freeze_pane(row: 0, col: 0) ⇒ Object
--- Freeze / Split Panes ---
1034 1035 1036 1037 |
# 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 |
#set_header_footer(**opts) ⇒ Object
1062 1063 1064 1065 |
# File 'lib/xlsxrb.rb', line 1062 def (**opts) add_sheet if @current_sheet.nil? @current_header_footer.merge!(opts) end |
#set_page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil) ⇒ Object
--- Page Setup / Margins / Print ---
1052 1053 1054 1055 |
# 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: }.compact end |
#set_page_setup(**opts) ⇒ Object
1057 1058 1059 1060 |
# File 'lib/xlsxrb.rb', line 1057 def set_page_setup(**opts) add_sheet if @current_sheet.nil? @current_page_setup.merge!(opts) end |
#set_print_area(range, sheet: nil) ⇒ Object
Set the print area for the current or named sheet.
1145 1146 1147 1148 1149 1150 |
# 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_print_option(name, value) ⇒ Object
1067 1068 1069 1070 |
# File 'lib/xlsxrb.rb', line 1067 def set_print_option(name, value) add_sheet if @current_sheet.nil? @current_print_options[name] = value end |
#set_print_titles(rows: nil, cols: nil, sheet: nil) ⇒ Object
Set print titles for the current or named sheet.
1153 1154 1155 1156 1157 1158 1159 1160 1161 |
# 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_selection(active_cell, sqref: nil, pane: nil) ⇒ Object
1044 1045 1046 1047 1048 |
# 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 |
#set_sheet_property(name, value) ⇒ Object
--- Sheet Properties ---
1110 1111 1112 1113 |
# File 'lib/xlsxrb.rb', line 1110 def set_sheet_property(name, value) add_sheet if @current_sheet.nil? @current_sheet_properties[name] = value end |
#set_sheet_protection(**opts) ⇒ Object
--- Sheet Protection ---
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
# 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 |
#set_sheet_view(name, value) ⇒ Object
1115 1116 1117 1118 |
# File 'lib/xlsxrb.rb', line 1115 def set_sheet_view(name, value) add_sheet if @current_sheet.nil? @current_sheet_view[name] = value end |
#set_sort_state(ref, sort_conditions, **opts) ⇒ Object
964 965 966 967 |
# 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 |
#set_split_pane(x_split: 0, y_split: 0, top_left_cell: nil) ⇒ Object
1039 1040 1041 1042 |
# 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 |
#set_workbook_protection(**opts) ⇒ Object
Set workbook protection.
1164 1165 1166 |
# File 'lib/xlsxrb.rb', line 1164 def set_workbook_protection(**opts) @workbook_protection = opts end |