xlsxrb 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/README.md +2 -0
- data/lib/xlsxrb/colors.rb +118 -0
- data/lib/xlsxrb/elements/cell.rb +205 -16
- data/lib/xlsxrb/elements/column.rb +6 -4
- data/lib/xlsxrb/elements/coordinate_access.rb +32 -0
- data/lib/xlsxrb/elements/image.rb +128 -0
- data/lib/xlsxrb/elements/row.rb +206 -9
- data/lib/xlsxrb/elements/styles.rb +157 -0
- data/lib/xlsxrb/elements/types.rb +95 -1
- data/lib/xlsxrb/elements/workbook.rb +85 -4
- data/lib/xlsxrb/elements/worksheet.rb +424 -29
- data/lib/xlsxrb/elements.rb +2 -0
- data/lib/xlsxrb/number_formatter.rb +429 -0
- data/lib/xlsxrb/ooxml/cfb.rb +1 -1
- data/lib/xlsxrb/ooxml/reader/listeners/core_listeners.rb +7 -5
- data/lib/xlsxrb/ooxml/reader/listeners/drawing_listeners.rb +11 -4
- data/lib/xlsxrb/ooxml/reader.rb +12 -14
- data/lib/xlsxrb/ooxml/shared_strings_parser.rb +7 -1
- data/lib/xlsxrb/ooxml/styles_parser.rb +39 -9
- data/lib/xlsxrb/ooxml/utils.rb +34 -18
- data/lib/xlsxrb/ooxml/workbook_parser.rb +53 -15
- data/lib/xlsxrb/ooxml/workbook_writer.rb +65 -14
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +319 -79
- data/lib/xlsxrb/ooxml/worksheet_writer.rb +206 -61
- data/lib/xlsxrb/ooxml/writer/features_xml.rb +4 -2
- data/lib/xlsxrb/ooxml/writer.rb +14 -0
- data/lib/xlsxrb/ooxml/zip_reader.rb +109 -25
- data/lib/xlsxrb/stream_row.rb +243 -16
- data/lib/xlsxrb/stream_sheet.rb +414 -15
- data/lib/xlsxrb/stream_writer.rb +213 -17
- data/lib/xlsxrb/style_builder.rb +308 -22
- data/lib/xlsxrb/utils.rb +158 -0
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb/workbook_builder.rb +73 -3
- data/lib/xlsxrb/worksheet_builder.rb +227 -16
- data/lib/xlsxrb.rb +578 -79
- data/sig/generated/xlsxrb/colors.rbs +40 -0
- data/sig/generated/xlsxrb/elements/cell.rbs +113 -8
- data/sig/generated/xlsxrb/elements/column.rbs +3 -2
- data/sig/generated/xlsxrb/elements/coordinate_access.rbs +18 -0
- data/sig/generated/xlsxrb/elements/image.rbs +82 -0
- data/sig/generated/xlsxrb/elements/row.rbs +83 -4
- data/sig/generated/xlsxrb/elements/styles.rbs +79 -0
- data/sig/generated/xlsxrb/elements/types.rbs +43 -0
- data/sig/generated/xlsxrb/elements/workbook.rbs +51 -2
- data/sig/generated/xlsxrb/elements/worksheet.rbs +231 -18
- data/sig/generated/xlsxrb/number_formatter.rbs +132 -0
- data/sig/generated/xlsxrb/ooxml/reader.rbs +6 -0
- data/sig/generated/xlsxrb/ooxml/shared_strings_parser.rbs +2 -0
- data/sig/generated/xlsxrb/ooxml/styles_parser.rbs +5 -2
- data/sig/generated/xlsxrb/ooxml/utils.rbs +17 -8
- data/sig/generated/xlsxrb/ooxml/workbook_parser.rbs +9 -3
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +28 -6
- data/sig/generated/xlsxrb/ooxml/worksheet_writer.rbs +3 -1
- data/sig/generated/xlsxrb/ooxml/writer.rbs +2 -0
- data/sig/generated/xlsxrb/ooxml/zip_reader.rbs +10 -0
- data/sig/generated/xlsxrb/stream_row.rbs +100 -6
- data/sig/generated/xlsxrb/stream_sheet.rbs +247 -13
- data/sig/generated/xlsxrb/stream_writer.rbs +120 -14
- data/sig/generated/xlsxrb/style_builder.rbs +55 -18
- data/sig/generated/xlsxrb/utils.rbs +119 -0
- data/sig/generated/xlsxrb/workbook_builder.rbs +26 -0
- data/sig/generated/xlsxrb/worksheet_builder.rbs +107 -11
- data/sig/generated/xlsxrb.rbs +186 -27
- metadata +11 -1
data/lib/xlsxrb/stream_writer.rb
CHANGED
|
@@ -220,15 +220,30 @@ module Xlsxrb
|
|
|
220
220
|
# @param hidden [Boolean] Whether the row is hidden.
|
|
221
221
|
# @param custom_height [Boolean] Whether to flag as custom height.
|
|
222
222
|
# @param outline_level [Integer, nil] Grouping/outline level (0 - 7).
|
|
223
|
+
# @param collapsed [Boolean] Whether the row is collapsed.
|
|
223
224
|
# @return [void]
|
|
224
225
|
# @api public
|
|
225
|
-
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
226
|
-
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil)
|
|
226
|
+
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?collapsed: bool, ?outline_level: Integer | nil) -> void
|
|
227
|
+
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, collapsed: false, outline_level: nil)
|
|
227
228
|
raise Error, "Sheet '#{@sheet_name}' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
228
229
|
|
|
229
|
-
@writer.row(values, styles: styles, height: height, hidden: hidden, custom_height: custom_height, outline_level: outline_level)
|
|
230
|
+
@writer.row(values, styles: styles, height: height, hidden: hidden, custom_height: custom_height, collapsed: collapsed, outline_level: outline_level)
|
|
231
|
+
end
|
|
232
|
+
alias add_row row
|
|
233
|
+
|
|
234
|
+
# Appends a row to the worksheet and returns self for chaining.
|
|
235
|
+
#
|
|
236
|
+
# @example
|
|
237
|
+
# sheet << ["A", 1] << ["B", 2]
|
|
238
|
+
#
|
|
239
|
+
# @param values [Array, Hash] Row cell values.
|
|
240
|
+
# @return [self]
|
|
241
|
+
# @api public
|
|
242
|
+
#: (Array[untyped] | Hash[untyped, untyped] values) -> self
|
|
243
|
+
def <<(values)
|
|
244
|
+
row(values)
|
|
245
|
+
self
|
|
230
246
|
end
|
|
231
|
-
alias << row
|
|
232
247
|
|
|
233
248
|
# Configures column width and properties.
|
|
234
249
|
#
|
|
@@ -287,7 +302,7 @@ module Xlsxrb
|
|
|
287
302
|
# @param location [String, nil] Destination location / URL (keyword alternative).
|
|
288
303
|
# @return [void]
|
|
289
304
|
# @api public
|
|
290
|
-
#: (String cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
305
|
+
#: (String | Integer cell, ?(String | Elements::Hyperlink)? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
291
306
|
def hyperlink(...)
|
|
292
307
|
raise Error, "Sheet '#{@sheet_name}' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
293
308
|
|
|
@@ -460,6 +475,30 @@ module Xlsxrb
|
|
|
460
475
|
@writer.sparkline_group(...)
|
|
461
476
|
end
|
|
462
477
|
|
|
478
|
+
# Adds a single sparkline to the sheet.
|
|
479
|
+
#
|
|
480
|
+
# @example Add a line sparkline
|
|
481
|
+
# s.add_sparkline(location: "F1", range: "A1:E1")
|
|
482
|
+
#
|
|
483
|
+
# @example Add a column sparkline with high/low markers
|
|
484
|
+
# s.add_sparkline(location: "F2", range: "A2:E2", type: :column, high: true, low: true)
|
|
485
|
+
#
|
|
486
|
+
# @example Add a win/loss sparkline
|
|
487
|
+
# s.add_sparkline(location: "F3", range: "A3:E3", type: :win_loss)
|
|
488
|
+
#
|
|
489
|
+
# @param location [String, nil] Target cell for the sparkline (e.g. "F1").
|
|
490
|
+
# @param range [String, nil] Data range for the sparkline (e.g. "A1:E1").
|
|
491
|
+
# @param type [Symbol, String, nil] Sparkline type (:line, :column, :win_loss / :stacked).
|
|
492
|
+
# @param opts [Hash] Additional sparkline options.
|
|
493
|
+
# @return [void]
|
|
494
|
+
# @api public
|
|
495
|
+
#: (?location: String?, ?range: String?, ?type: (String | Symbol)?, **untyped opts) -> void
|
|
496
|
+
def add_sparkline(...)
|
|
497
|
+
raise Error, "Sheet '#{@sheet_name}' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
498
|
+
|
|
499
|
+
@writer.add_sparkline(...)
|
|
500
|
+
end
|
|
501
|
+
|
|
463
502
|
# Sets workbook-level properties.
|
|
464
503
|
#
|
|
465
504
|
# @param opts [Hash] Workbook property options.
|
|
@@ -554,6 +593,32 @@ module Xlsxrb
|
|
|
554
593
|
|
|
555
594
|
@writer.print_titles(...)
|
|
556
595
|
end
|
|
596
|
+
|
|
597
|
+
# Sets repeating title rows to appear at the top of each printed page.
|
|
598
|
+
#
|
|
599
|
+
# @param first [Integer, String] First row index (0-based) or range string (e.g. "1:2").
|
|
600
|
+
# @param last [Integer, String, nil] Optional last row index (0-based).
|
|
601
|
+
# @return [void]
|
|
602
|
+
# @api public
|
|
603
|
+
#: (Integer | String first, ?(Integer | String)? last) -> void
|
|
604
|
+
def repeat_rows(first, last = nil)
|
|
605
|
+
raise Error, "Sheet '#{@sheet_name}' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
606
|
+
|
|
607
|
+
@writer.repeat_rows(first, last, sheet: @sheet_name)
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
# Sets repeating title columns to appear at the left of each printed page.
|
|
611
|
+
#
|
|
612
|
+
# @param first [Integer, String] First column index (0-based) or column name/range.
|
|
613
|
+
# @param last [Integer, String, nil] Optional last column index/name.
|
|
614
|
+
# @return [void]
|
|
615
|
+
# @api public
|
|
616
|
+
#: (Integer | String first, ?(Integer | String)? last) -> void
|
|
617
|
+
def repeat_columns(first, last = nil)
|
|
618
|
+
raise Error, "Sheet '#{@sheet_name}' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
619
|
+
|
|
620
|
+
@writer.repeat_columns(first, last, sheet: @sheet_name)
|
|
621
|
+
end
|
|
557
622
|
# simplecov:enable
|
|
558
623
|
|
|
559
624
|
# Splits sheet view into panes.
|
|
@@ -829,7 +894,8 @@ module Xlsxrb
|
|
|
829
894
|
@sheet_entry_started = false
|
|
830
895
|
@current_row_buffer = String.new(capacity: 65_536)
|
|
831
896
|
@current_sheet_io = StringIO.new(@current_row_buffer)
|
|
832
|
-
|
|
897
|
+
date1904 = @workbook_properties&.[](:date1904) ? true : false
|
|
898
|
+
@current_row_writer = Ooxml::WorksheetWriter.new(@current_sheet_io, date1904: date1904)
|
|
833
899
|
@current_row_writer.instance_variable_set(:@started, true)
|
|
834
900
|
|
|
835
901
|
@current_columns = []
|
|
@@ -883,7 +949,18 @@ module Xlsxrb
|
|
|
883
949
|
row_buf.clear
|
|
884
950
|
end
|
|
885
951
|
|
|
886
|
-
@
|
|
952
|
+
if @current_columns && !@current_columns.empty? && @style_name_to_id
|
|
953
|
+
@current_columns.each do |col|
|
|
954
|
+
s = col[:style] || col[:style_index]
|
|
955
|
+
if s.is_a?(Symbol) || s.is_a?(String)
|
|
956
|
+
resolved = @style_name_to_id[s] || @style_name_to_id[s.to_s]
|
|
957
|
+
col[:style] = resolved if resolved
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
date1904 = @workbook_properties&.[](:date1904) ? true : false
|
|
963
|
+
@current_row_writer = Ooxml::WorksheetWriter.new(zip_io, date1904: date1904)
|
|
887
964
|
@current_row_writer.start(
|
|
888
965
|
columns: @current_columns,
|
|
889
966
|
sheet_properties: @current_sheet_properties.empty? ? nil : @current_sheet_properties,
|
|
@@ -906,8 +983,8 @@ module Xlsxrb
|
|
|
906
983
|
# @param outline_level [Integer, nil] Grouping/outline level (0 - 7).
|
|
907
984
|
# @return [void]
|
|
908
985
|
# @api public
|
|
909
|
-
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
910
|
-
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil)
|
|
986
|
+
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?collapsed: bool, ?outline_level: Integer | nil) -> void
|
|
987
|
+
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, collapsed: false, outline_level: nil)
|
|
911
988
|
sheet if @current_sheet.nil?
|
|
912
989
|
|
|
913
990
|
row_index = @current_row_index
|
|
@@ -931,36 +1008,60 @@ module Xlsxrb
|
|
|
931
1008
|
raise ArgumentError, "Row contains #{values.length} columns, exceeding Excel limit of 16_384 columns" if @strict_excel_mode && values.length > 16_384
|
|
932
1009
|
|
|
933
1010
|
attrs = nil
|
|
934
|
-
if height || hidden || outline_level
|
|
1011
|
+
if height || hidden || outline_level || collapsed
|
|
935
1012
|
attrs = {}
|
|
936
1013
|
attrs[:height] = height if height
|
|
937
1014
|
attrs[:hidden] = true if hidden
|
|
938
1015
|
attrs[:custom_height] = custom_height || !height.nil?
|
|
1016
|
+
attrs[:collapsed] = true if collapsed
|
|
939
1017
|
attrs[:outline_level] = outline_level if outline_level
|
|
940
1018
|
end
|
|
941
1019
|
|
|
942
1020
|
@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)
|
|
943
1021
|
start_sheet_entry if !@sheet_entry_started && @current_row_buffer.bytesize >= 65_536
|
|
944
1022
|
end
|
|
945
|
-
alias
|
|
1023
|
+
alias add_row row
|
|
1024
|
+
|
|
1025
|
+
# Appends a row to the worksheet and returns self for chaining.
|
|
1026
|
+
#
|
|
1027
|
+
# @example
|
|
1028
|
+
# writer << ["A", 1] << ["B", 2]
|
|
1029
|
+
#
|
|
1030
|
+
# @param values [Array, Hash] Row cell values.
|
|
1031
|
+
# @return [self]
|
|
1032
|
+
# @api public
|
|
1033
|
+
#: (Array[untyped] | Hash[untyped, untyped] values) -> self
|
|
1034
|
+
def <<(values)
|
|
1035
|
+
row(values)
|
|
1036
|
+
self
|
|
1037
|
+
end
|
|
946
1038
|
|
|
947
1039
|
# Sets column formatting and properties for one or multiple columns.
|
|
948
1040
|
#
|
|
949
1041
|
# @param index [Integer, String, Range, Array] Column index (0-based) or letter ("A".."D").
|
|
950
1042
|
# @param width [Float, Integer, nil] Column width in character units (0 - 255).
|
|
951
1043
|
# @param hidden [Boolean] Whether the column is hidden.
|
|
952
|
-
# @param
|
|
953
|
-
# @param outline_level [Integer, nil] Grouping/outline level.
|
|
1044
|
+
# @param style [Integer, Symbol, String, nil] Column style format or index.
|
|
954
1045
|
# @return [void]
|
|
955
1046
|
# @api public
|
|
956
|
-
#: (Integer | String | Range[Integer | String] | Array[Integer | String] index, ?width: Float | Integer | nil, ?hidden: bool, ?custom_width: bool, ?outline_level: Integer | nil) -> void
|
|
957
|
-
def column(index, width: nil, hidden: false, custom_width: false, outline_level: nil)
|
|
1047
|
+
#: (Integer | String | Range[Integer | String] | Array[Integer | String] index, ?width: Float | Integer | nil, ?hidden: bool, ?custom_width: bool, ?outline_level: Integer | nil, ?style: (Integer | Symbol | String)?) -> void
|
|
1048
|
+
def column(index, width: nil, hidden: false, custom_width: false, outline_level: nil, style: nil)
|
|
958
1049
|
raise ArgumentError, "Column width #{width} must be between 0 and 255 characters (Excel limitation)" if @strict_excel_mode && width && (width.negative? || width > 255)
|
|
959
1050
|
|
|
960
1051
|
sheet if @current_sheet.nil?
|
|
961
1052
|
|
|
1053
|
+
style_id = if @style_name_to_id && style
|
|
1054
|
+
@style_name_to_id[style] || @style_name_to_id[style.to_s] || style
|
|
1055
|
+
else
|
|
1056
|
+
style
|
|
1057
|
+
end
|
|
962
1058
|
DslHelpers.normalize_column_indices(index).each do |idx|
|
|
963
|
-
|
|
1059
|
+
entry = { index: idx, width: width, hidden: hidden, custom_width: custom_width || !width.nil?, outline_level: outline_level }
|
|
1060
|
+
if style_id
|
|
1061
|
+
entry[:style] = style_id
|
|
1062
|
+
@current_row_writer&.set_column_style(idx, style_id)
|
|
1063
|
+
end
|
|
1064
|
+
@current_columns << entry
|
|
964
1065
|
end
|
|
965
1066
|
end
|
|
966
1067
|
|
|
@@ -993,9 +1094,18 @@ module Xlsxrb
|
|
|
993
1094
|
# @param location [String, nil] Internal location.
|
|
994
1095
|
# @return [void]
|
|
995
1096
|
# @api public
|
|
996
|
-
#: (String | Integer cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
1097
|
+
#: (String | Integer cell, ?(String | Elements::Hyperlink)? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
997
1098
|
def hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil)
|
|
998
1099
|
sheet if @current_sheet.nil?
|
|
1100
|
+
if url.is_a?(Elements::Hyperlink)
|
|
1101
|
+
link = { cell: cell }
|
|
1102
|
+
link[:url] = url.url if url.url
|
|
1103
|
+
link[:display] = url.display || display if url.display || display
|
|
1104
|
+
link[:tooltip] = url.tooltip || tooltip if url.tooltip || tooltip
|
|
1105
|
+
link[:location] = url.location || location if url.location || location
|
|
1106
|
+
@current_hyperlinks << link
|
|
1107
|
+
return
|
|
1108
|
+
end
|
|
999
1109
|
link = { cell: cell }
|
|
1000
1110
|
link[:url] = url if url
|
|
1001
1111
|
link[:display] = display if display
|
|
@@ -1134,6 +1244,38 @@ module Xlsxrb
|
|
|
1134
1244
|
@current_sparkline_groups << group
|
|
1135
1245
|
end
|
|
1136
1246
|
|
|
1247
|
+
# Adds a single sparkline to the sheet.
|
|
1248
|
+
#
|
|
1249
|
+
# @example Add a line sparkline
|
|
1250
|
+
# writer.add_sparkline(location: "F1", range: "A1:E1")
|
|
1251
|
+
#
|
|
1252
|
+
# @example Add a column sparkline with high/low markers
|
|
1253
|
+
# writer.add_sparkline(location: "F2", range: "A2:E2", type: :column, high: true, low: true)
|
|
1254
|
+
#
|
|
1255
|
+
# @example Add a win/loss sparkline
|
|
1256
|
+
# writer.add_sparkline(location: "F3", range: "A3:E3", type: :win_loss)
|
|
1257
|
+
#
|
|
1258
|
+
# @param location [String, nil] Target cell for the sparkline (e.g. "F1").
|
|
1259
|
+
# @param range [String, nil] Data range for the sparkline (e.g. "A1:E1").
|
|
1260
|
+
# @param type [Symbol, String, nil] Sparkline type (:line, :column, :win_loss / :stacked).
|
|
1261
|
+
# @param opts [Hash] Additional sparkline options.
|
|
1262
|
+
# @return [void]
|
|
1263
|
+
# @api public
|
|
1264
|
+
#: (?location: String?, ?range: String?, ?type: (String | Symbol)?, **untyped opts) -> void
|
|
1265
|
+
def add_sparkline(location: nil, range: nil, type: nil, **opts)
|
|
1266
|
+
loc = location || opts.delete(:location_ref)
|
|
1267
|
+
rng = range || opts.delete(:data_ref) || opts.delete(:data)
|
|
1268
|
+
raise ArgumentError, "Missing required location: parameter for sparkline" unless loc
|
|
1269
|
+
raise ArgumentError, "Missing required range: parameter for sparkline" unless rng
|
|
1270
|
+
|
|
1271
|
+
mapped_type = case type&.to_s
|
|
1272
|
+
when "win_loss" then "stacked"
|
|
1273
|
+
when nil, "" then nil
|
|
1274
|
+
else type.to_s
|
|
1275
|
+
end
|
|
1276
|
+
sparkline_group(sparklines: [{ data_ref: rng.to_s, location_ref: loc.to_s }], type: mapped_type, **opts)
|
|
1277
|
+
end
|
|
1278
|
+
|
|
1137
1279
|
# Merges a range of cells into a single cell.
|
|
1138
1280
|
#
|
|
1139
1281
|
# @param range [String, Hash, nil] Cell range (e.g. "A1:B2") or hash of coordinates.
|
|
@@ -1398,6 +1540,11 @@ module Xlsxrb
|
|
|
1398
1540
|
#: (?rows: String?, ?cols: String?, ?sheet: String?) -> void
|
|
1399
1541
|
def print_titles(rows: nil, cols: nil, sheet: nil)
|
|
1400
1542
|
sheet_name = sheet || @current_sheet || "Sheet1"
|
|
1543
|
+
existing = @defined_names.find { |dn| dn[:name] == "_xlnm.Print_Titles" && dn[:local_sheet_name] == sheet_name }
|
|
1544
|
+
if existing && (rows.nil? || cols.nil?)
|
|
1545
|
+
cols = Regexp.last_match(1).delete("$") if cols.nil? && existing[:value] =~ /'[^']*'!\$([A-Za-z]+:\$[A-Za-z]+)/
|
|
1546
|
+
rows = Regexp.last_match(1).delete("$") if rows.nil? && existing[:value] =~ /'[^']*'!\$([0-9]+:\$[0-9]+)/
|
|
1547
|
+
end
|
|
1401
1548
|
parts = []
|
|
1402
1549
|
parts << "'#{sheet_name}'!$#{cols.sub(":", ":$")}" if cols
|
|
1403
1550
|
parts << "'#{sheet_name}'!$#{rows.sub(":", ":$")}" if rows
|
|
@@ -1406,6 +1553,55 @@ module Xlsxrb
|
|
|
1406
1553
|
defined_name("_xlnm.Print_Titles", value, sheet: sheet_name)
|
|
1407
1554
|
end
|
|
1408
1555
|
|
|
1556
|
+
# Sets repeating title rows for pagination on the current or named sheet.
|
|
1557
|
+
#
|
|
1558
|
+
# @example Repeat first row
|
|
1559
|
+
# stream.repeat_rows(0)
|
|
1560
|
+
#
|
|
1561
|
+
# @param first [Integer, String] First row index (0-based) or range string (e.g. "1:2").
|
|
1562
|
+
# @param last [Integer, String, nil] Optional last row index (0-based).
|
|
1563
|
+
# @param sheet [String, nil] Target sheet name.
|
|
1564
|
+
# @return [void]
|
|
1565
|
+
# @api public
|
|
1566
|
+
#: (Integer | String first, ?(Integer | String)? last, ?sheet: String?) -> void
|
|
1567
|
+
def repeat_rows(first, last = nil, sheet: nil)
|
|
1568
|
+
rows_str = if first.is_a?(String)
|
|
1569
|
+
first.include?(":") ? first : "#{first}:#{last || first}"
|
|
1570
|
+
else
|
|
1571
|
+
last ||= first
|
|
1572
|
+
"#{first + 1}:#{last + 1}"
|
|
1573
|
+
end
|
|
1574
|
+
print_titles(rows: rows_str, sheet: sheet)
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1577
|
+
# Sets repeating title columns for pagination on the current or named sheet.
|
|
1578
|
+
#
|
|
1579
|
+
# @example Repeat columns A through C
|
|
1580
|
+
# stream.repeat_columns("A", "C")
|
|
1581
|
+
#
|
|
1582
|
+
# @param first [Integer, String] First column index (0-based) or column name/range.
|
|
1583
|
+
# @param last [Integer, String, nil] Optional last column index/name.
|
|
1584
|
+
# @param sheet [String, nil] Target sheet name.
|
|
1585
|
+
# @return [void]
|
|
1586
|
+
# @api public
|
|
1587
|
+
#: (Integer | String first, ?(Integer | String)? last, ?sheet: String?) -> void
|
|
1588
|
+
def repeat_columns(first, last = nil, sheet: nil)
|
|
1589
|
+
cols_str = if first.is_a?(String)
|
|
1590
|
+
first.include?(":") ? first : "#{first}:#{last || first}"
|
|
1591
|
+
else
|
|
1592
|
+
first_name = Utils.col_index_to_name(first)
|
|
1593
|
+
last_name = if last.is_a?(Integer)
|
|
1594
|
+
Utils.col_index_to_name(last)
|
|
1595
|
+
elsif last
|
|
1596
|
+
last.to_s
|
|
1597
|
+
else
|
|
1598
|
+
first_name
|
|
1599
|
+
end
|
|
1600
|
+
"#{first_name}:#{last_name}"
|
|
1601
|
+
end
|
|
1602
|
+
print_titles(cols: cols_str, sheet: sheet)
|
|
1603
|
+
end
|
|
1604
|
+
|
|
1409
1605
|
# Sets workbook protection.
|
|
1410
1606
|
#
|
|
1411
1607
|
# @param opts [Hash] Protection options.
|