xlsxrb 0.1.5 → 0.1.7
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/.gem_rbs_collection/nokogiri/1.11/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/nokogiri/1.11/nokogiri.rbs +2332 -0
- data/.gem_rbs_collection/nokogiri/1.11/patch.rbs +4 -0
- data/.gem_rbs_collection/rubyzip/3.2/.rbs_meta.yaml +9 -0
- data/.gem_rbs_collection/rubyzip/3.2/manifest.yaml +8 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/central_directory.rbs +42 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/compressor.rbs +5 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/constants.rbs +47 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/aes_encryption.rbs +30 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/decrypted_io.rbs +9 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/encryption.rbs +7 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/null_encryption.rbs +19 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/traditional_encryption.rbs +31 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/decompressor.rbs +18 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/deflater.rbs +12 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/dirtyable.rbs +11 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/dos_time.rbs +13 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/entry.rbs +95 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/entry_set.rbs +31 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/errors.rbs +58 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/aes.rbs +24 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/generic.rbs +17 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/ntfs.rbs +23 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/old_unix.rbs +22 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/universal_time.rbs +30 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unix.rbs +20 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unknown.rbs +15 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/zip64.rbs +26 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field.rbs +21 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/file.rbs +131 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/file_split.rbs +14 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/dir.rbs +33 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/directory_iterator.rbs +21 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file.rbs +63 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file_stat.rbs +55 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/zip_file_name_mapper.rbs +35 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem.rbs +7 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/inflater.rbs +10 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/input_stream.rbs +22 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_input_stream.rbs +29 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_output_stream.rbs +17 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras.rbs +13 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_compressor.rbs +10 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_decompressor.rbs +8 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_input_stream.rbs +6 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/output_stream.rbs +30 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_compressor.rbs +10 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_decompressor.rbs +10 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_directory.rbs +5 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_stream.rbs +15 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip/version.rbs +3 -0
- data/.gem_rbs_collection/rubyzip/3.2/zip.rbs +40 -0
- data/CHANGELOG.md +28 -0
- data/README.md +66 -44
- data/Rakefile +2 -1
- data/Steepfile +1 -2
- data/benchmark.rb +376 -0
- data/docs/ARCHITECTURE.md +12 -5
- data/docs/visual/VisualGallery.md +8 -0
- data/docs/wasm/ruby.wasm +0 -0
- data/lib/ruby_lsp/xlsxrb/addon.rb +43 -0
- data/lib/ruby_lsp/xlsxrb/completion_listener.rb +769 -0
- data/lib/xlsxrb/elements/cell.rb +137 -11
- data/lib/xlsxrb/elements/column.rb +22 -0
- data/lib/xlsxrb/elements/row.rb +98 -5
- data/lib/xlsxrb/elements/types.rb +40 -5
- data/lib/xlsxrb/elements/workbook.rb +73 -5
- data/lib/xlsxrb/elements/worksheet.rb +110 -1
- data/lib/xlsxrb/ooxml/shared_strings_parser.rb +104 -40
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +144 -23
- data/lib/xlsxrb/ooxml/worksheet_writer.rb +160 -145
- data/lib/xlsxrb/ooxml/xml_builder.rb +16 -10
- data/lib/xlsxrb/ooxml/zip_reader.rb +104 -18
- data/lib/xlsxrb/ooxml/zip_writer.rb +63 -25
- data/lib/xlsxrb/style_builder.rb +158 -30
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb.rb +892 -336
- data/rbs_collection.lock.yaml +28 -0
- data/sig/generated/xlsxrb/elements/cell.rbs +39 -0
- data/sig/generated/xlsxrb/elements/column.rbs +35 -0
- data/sig/generated/xlsxrb/elements/row.rbs +39 -0
- data/sig/generated/xlsxrb/elements/types.rbs +82 -0
- data/sig/generated/xlsxrb/elements/workbook.rbs +32 -0
- data/sig/generated/xlsxrb/elements/worksheet.rbs +34 -0
- data/sig/generated/xlsxrb/ooxml/reader.rbs +1412 -0
- data/sig/generated/xlsxrb/ooxml/shared_strings_parser.rbs +21 -0
- data/sig/generated/xlsxrb/ooxml/styles_parser.rbs +44 -0
- data/sig/generated/xlsxrb/ooxml/utils.rbs +40 -0
- data/sig/generated/xlsxrb/ooxml/workbook_parser.rbs +46 -0
- data/sig/generated/xlsxrb/ooxml/workbook_writer.rbs +66 -0
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +67 -0
- data/sig/generated/xlsxrb/ooxml/worksheet_writer.rbs +92 -0
- data/sig/generated/xlsxrb/ooxml/writer.rbs +880 -0
- data/sig/generated/xlsxrb/ooxml/xml_builder.rbs +45 -0
- data/sig/generated/xlsxrb/ooxml/xml_parser.rbs +30 -0
- data/sig/generated/xlsxrb/ooxml/zip_generator.rbs +38 -0
- data/sig/generated/xlsxrb/ooxml/zip_reader.rbs +45 -0
- data/sig/generated/xlsxrb/ooxml/zip_writer.rbs +45 -0
- data/sig/generated/xlsxrb/style_builder.rbs +212 -50
- data/sig/generated/xlsxrb.rbs +1646 -0
- data/sig/rexml.rbs +4 -0
- metadata +78 -1
data/lib/xlsxrb.rb
CHANGED
|
@@ -10,9 +10,12 @@ require "tempfile"
|
|
|
10
10
|
begin
|
|
11
11
|
require "bigdecimal"
|
|
12
12
|
rescue LoadError
|
|
13
|
+
# simplecov:disable
|
|
13
14
|
# Define a dummy class for environments without bigdecimal (e.g., ruby.wasm).
|
|
14
15
|
# This serves only as a fallback to prevent NameError in `case` statements (`when BigDecimal`).
|
|
15
|
-
|
|
16
|
+
# Impossible to cover in standard test environment because bigdecimal is present.
|
|
17
|
+
Object.const_set(:BigDecimal, Class.new)
|
|
18
|
+
# simplecov:enable
|
|
16
19
|
end
|
|
17
20
|
require "opentelemetry"
|
|
18
21
|
require_relative "xlsxrb/version"
|
|
@@ -43,7 +46,10 @@ module Xlsxrb
|
|
|
43
46
|
|
|
44
47
|
def self.in_span(name, attributes: nil, &)
|
|
45
48
|
if defined?(Ractor) && Ractor.current != Ractor.main
|
|
49
|
+
# simplecov:disable
|
|
50
|
+
# Test suite runs in the main Ractor. This branch is for multi-threaded usage via Ractors.
|
|
46
51
|
yield
|
|
52
|
+
# simplecov:enable
|
|
47
53
|
elsif attributes
|
|
48
54
|
TRACER.in_span(name, attributes: attributes, &)
|
|
49
55
|
else
|
|
@@ -60,31 +66,31 @@ module Xlsxrb
|
|
|
60
66
|
# @param font_props [Hash] Font styling options (e.g., bold: true).
|
|
61
67
|
# @return [Elements::RichText] The resulting rich text.
|
|
62
68
|
# @api public
|
|
63
|
-
|
|
69
|
+
#: (*untyped runs, ?text: String?, **untyped font_props) -> untyped
|
|
64
70
|
def self.rich_text(*runs, text: nil, **font_props)
|
|
65
71
|
runs = [{ text: text, font: font_props }] if text
|
|
66
72
|
Elements::RichText.new(runs: runs)
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
# Builder for block-style chart definitions.
|
|
76
|
+
# @api public
|
|
70
77
|
class ChartBuilder
|
|
71
|
-
|
|
78
|
+
#: () -> void
|
|
72
79
|
def initialize
|
|
73
80
|
@options = {}
|
|
74
81
|
end
|
|
75
|
-
|
|
76
|
-
# : Hash[Symbol, String | Integer | bool | nil]
|
|
82
|
+
#: Hash[Symbol, untyped]
|
|
77
83
|
attr_reader :options
|
|
78
84
|
|
|
79
85
|
# @api public
|
|
80
|
-
|
|
86
|
+
#: (untyped value) -> untyped
|
|
81
87
|
def type(value) = @options[:type] = value
|
|
82
88
|
# @api public
|
|
83
|
-
|
|
89
|
+
#: (untyped value) -> untyped
|
|
84
90
|
def title(value) = @options[:title] = value
|
|
85
91
|
|
|
86
92
|
# @api public
|
|
87
|
-
|
|
93
|
+
#: (?Hash[Symbol, untyped]? value) ?{ (SeriesBuilder) -> void } -> Array[Hash[Symbol, untyped]]
|
|
88
94
|
def series(value = nil)
|
|
89
95
|
@options[:series] ||= []
|
|
90
96
|
if block_given?
|
|
@@ -98,187 +104,231 @@ module Xlsxrb
|
|
|
98
104
|
end
|
|
99
105
|
|
|
100
106
|
# Configures the legend property for this chart.
|
|
107
|
+
# @param args [Array] Positional arguments.
|
|
108
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
101
109
|
# @return [Object] the configured property
|
|
102
110
|
# @api public
|
|
103
|
-
|
|
111
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
104
112
|
def legend(*args, **kwargs)
|
|
105
113
|
@options[:legend] = kwargs.empty? ? args.first : kwargs
|
|
106
114
|
end
|
|
107
115
|
|
|
108
116
|
# Configures the plot_area property for this chart.
|
|
117
|
+
# @param args [Array] Positional arguments.
|
|
118
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
109
119
|
# @return [Object] the configured property
|
|
110
120
|
# @api public
|
|
111
|
-
|
|
121
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
112
122
|
def plot_area(*args, **kwargs)
|
|
113
123
|
@options[:plot_area] = kwargs.empty? ? args.first : kwargs
|
|
114
124
|
end
|
|
115
125
|
|
|
116
126
|
# Configures the chart_space property for this chart.
|
|
127
|
+
# @param args [Array] Positional arguments.
|
|
128
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
117
129
|
# @return [Object] the configured property
|
|
118
130
|
# @api public
|
|
119
|
-
|
|
131
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
120
132
|
def chart_space(*args, **kwargs)
|
|
121
133
|
@options[:chart_space] = kwargs.empty? ? args.first : kwargs
|
|
122
134
|
end
|
|
123
135
|
|
|
124
136
|
# Configures the style property for this chart.
|
|
137
|
+
# @param args [Array] Positional arguments.
|
|
138
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
125
139
|
# @return [Object] the configured property
|
|
126
140
|
# @api public
|
|
127
|
-
|
|
141
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String | Integer) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String | Integer)
|
|
128
142
|
def style(*args, **kwargs)
|
|
129
143
|
@options[:style] = kwargs.empty? ? args.first : kwargs
|
|
130
144
|
end
|
|
131
145
|
|
|
132
146
|
# Configures the data_labels property for this chart.
|
|
147
|
+
# @param args [Array] Positional arguments.
|
|
148
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
133
149
|
# @return [Object] the configured property
|
|
134
150
|
# @api public
|
|
135
|
-
|
|
151
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
136
152
|
def data_labels(*args, **kwargs)
|
|
137
153
|
@options[:data_labels] = kwargs.empty? ? args.first : kwargs
|
|
138
154
|
end
|
|
139
155
|
|
|
140
156
|
# Configures the plot_visible_only property for this chart.
|
|
157
|
+
# @param args [Array] Positional arguments.
|
|
158
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
141
159
|
# @return [Object] the configured property
|
|
142
160
|
# @api public
|
|
143
|
-
|
|
161
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
144
162
|
def plot_visible_only(*args, **kwargs)
|
|
145
163
|
@options[:plot_visible_only] = kwargs.empty? ? args.first : kwargs
|
|
146
164
|
end
|
|
147
165
|
|
|
148
166
|
# Configures the display_blanks_as property for this chart.
|
|
167
|
+
# @param args [Array] Positional arguments.
|
|
168
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
149
169
|
# @return [Object] the configured property
|
|
150
170
|
# @api public
|
|
151
|
-
|
|
171
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
152
172
|
def display_blanks_as(*args, **kwargs)
|
|
153
173
|
@options[:display_blanks_as] = kwargs.empty? ? args.first : kwargs
|
|
154
174
|
end
|
|
155
175
|
|
|
156
176
|
# Configures the view3d property for this chart.
|
|
177
|
+
# @param args [Array] Positional arguments.
|
|
178
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
157
179
|
# @return [Object] the configured property
|
|
158
180
|
# @api public
|
|
159
|
-
|
|
181
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
160
182
|
def view3d(*args, **kwargs)
|
|
161
183
|
@options[:view3d] = kwargs.empty? ? args.first : kwargs
|
|
162
184
|
end
|
|
163
185
|
|
|
164
186
|
# Configures the category_axis property for this chart.
|
|
187
|
+
# @param args [Array] Positional arguments.
|
|
188
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
165
189
|
# @return [Object] the configured property
|
|
166
190
|
# @api public
|
|
167
|
-
|
|
191
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
168
192
|
def category_axis(*args, **kwargs)
|
|
169
193
|
@options[:category_axis] = kwargs.empty? ? args.first : kwargs
|
|
170
194
|
end
|
|
171
195
|
|
|
172
196
|
# Configures the value_axis property for this chart.
|
|
197
|
+
# @param args [Array] Positional arguments.
|
|
198
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
173
199
|
# @return [Object] the configured property
|
|
174
200
|
# @api public
|
|
175
|
-
|
|
201
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
176
202
|
def value_axis(*args, **kwargs)
|
|
177
203
|
@options[:value_axis] = kwargs.empty? ? args.first : kwargs
|
|
178
204
|
end
|
|
179
205
|
|
|
180
206
|
# Configures the show_legend_key property for this chart.
|
|
207
|
+
# @param args [Array] Positional arguments.
|
|
208
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
181
209
|
# @return [Object] the configured property
|
|
182
210
|
# @api public
|
|
183
|
-
|
|
211
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
184
212
|
def show_legend_key(*args, **kwargs)
|
|
185
213
|
@options[:show_legend_key] = kwargs.empty? ? args.first : kwargs
|
|
186
214
|
end
|
|
187
215
|
|
|
188
216
|
# Builder for a single series entry in block-style chart definitions.
|
|
217
|
+
# @api public
|
|
189
218
|
class SeriesBuilder
|
|
190
|
-
|
|
219
|
+
#: () -> void
|
|
191
220
|
def initialize
|
|
192
221
|
@options = {}
|
|
193
222
|
end
|
|
194
|
-
|
|
195
|
-
# : Hash[Symbol, String | Integer | bool | nil]
|
|
223
|
+
#: Hash[Symbol, untyped]
|
|
196
224
|
attr_reader :options
|
|
197
225
|
|
|
198
226
|
# Configures the categories property for this series.
|
|
227
|
+
# @param args [Array] Positional arguments.
|
|
228
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
199
229
|
# @return [Object] the configured property
|
|
200
230
|
# @api public
|
|
201
|
-
|
|
231
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
202
232
|
def categories(*args, **kwargs)
|
|
203
233
|
@options[:categories] = kwargs.empty? ? args.first : kwargs
|
|
204
234
|
end
|
|
205
235
|
|
|
206
236
|
# Configures the values property for this series.
|
|
237
|
+
# @param args [Array] Positional arguments.
|
|
238
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
207
239
|
# @return [Object] the configured property
|
|
208
240
|
# @api public
|
|
209
|
-
|
|
241
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
210
242
|
def values(*args, **kwargs)
|
|
211
243
|
@options[:values] = kwargs.empty? ? args.first : kwargs
|
|
212
244
|
end
|
|
213
245
|
|
|
214
246
|
# Configures the name property for this series.
|
|
247
|
+
# @param args [Array] Positional arguments.
|
|
248
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
215
249
|
# @return [Object] the configured property
|
|
216
250
|
# @api public
|
|
217
|
-
|
|
251
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
218
252
|
def name(*args, **kwargs)
|
|
219
253
|
@options[:name] = kwargs.empty? ? args.first : kwargs
|
|
220
254
|
end
|
|
221
255
|
|
|
222
256
|
# Configures the marker property for this series.
|
|
257
|
+
# @param args [Array] Positional arguments.
|
|
258
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
223
259
|
# @return [Object] the configured property
|
|
224
260
|
# @api public
|
|
225
|
-
|
|
261
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
226
262
|
def marker(*args, **kwargs)
|
|
227
263
|
@options[:marker] = kwargs.empty? ? args.first : kwargs
|
|
228
264
|
end
|
|
229
265
|
|
|
230
266
|
# Configures the fill property for this series.
|
|
267
|
+
# @param args [Array] Positional arguments.
|
|
268
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
231
269
|
# @return [Object] the configured property
|
|
232
270
|
# @api public
|
|
233
|
-
|
|
271
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
234
272
|
def fill(*args, **kwargs)
|
|
235
273
|
@options[:fill] = kwargs.empty? ? args.first : kwargs
|
|
236
274
|
end
|
|
237
275
|
|
|
238
276
|
# Configures the line property for this series.
|
|
277
|
+
# @param args [Array] Positional arguments.
|
|
278
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
239
279
|
# @return [Object] the configured property
|
|
240
280
|
# @api public
|
|
241
|
-
|
|
281
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
242
282
|
def line(*args, **kwargs)
|
|
243
283
|
@options[:line] = kwargs.empty? ? args.first : kwargs
|
|
244
284
|
end
|
|
245
285
|
|
|
246
286
|
# Configures the trendline property for this series.
|
|
287
|
+
# @param args [Array] Positional arguments.
|
|
288
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
247
289
|
# @return [Object] the configured property
|
|
248
290
|
# @api public
|
|
249
|
-
|
|
291
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
250
292
|
def trendline(*args, **kwargs)
|
|
251
293
|
@options[:trendline] = kwargs.empty? ? args.first : kwargs
|
|
252
294
|
end
|
|
253
295
|
|
|
254
296
|
# Configures the data_labels property for this series.
|
|
297
|
+
# @param args [Array] Positional arguments.
|
|
298
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
255
299
|
# @return [Object] the configured property
|
|
256
300
|
# @api public
|
|
257
|
-
|
|
301
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
258
302
|
def data_labels(*args, **kwargs)
|
|
259
303
|
@options[:data_labels] = kwargs.empty? ? args.first : kwargs
|
|
260
304
|
end
|
|
261
305
|
|
|
262
306
|
# Configures the smooth property for this series.
|
|
307
|
+
# @param args [Array] Positional arguments.
|
|
308
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
263
309
|
# @return [Object] the configured property
|
|
264
310
|
# @api public
|
|
265
|
-
|
|
311
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
266
312
|
def smooth(*args, **kwargs)
|
|
267
313
|
@options[:smooth] = kwargs.empty? ? args.first : kwargs
|
|
268
314
|
end
|
|
269
315
|
|
|
270
316
|
# Configures the shape property for this series.
|
|
317
|
+
# @param args [Array] Positional arguments.
|
|
318
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
271
319
|
# @return [Object] the configured property
|
|
272
320
|
# @api public
|
|
273
|
-
|
|
321
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
274
322
|
def shape(*args, **kwargs)
|
|
275
323
|
@options[:shape] = kwargs.empty? ? args.first : kwargs
|
|
276
324
|
end
|
|
277
325
|
|
|
278
326
|
# Configures the type property for this series.
|
|
327
|
+
# @param args [Array] Positional arguments.
|
|
328
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
279
329
|
# @return [Object] the configured property
|
|
280
330
|
# @api public
|
|
281
|
-
|
|
331
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
282
332
|
def type(*args, **kwargs)
|
|
283
333
|
@options[:type] = kwargs.empty? ? args.first : kwargs
|
|
284
334
|
end
|
|
@@ -291,11 +341,17 @@ module Xlsxrb
|
|
|
291
341
|
|
|
292
342
|
# Creates a Formula object for use in row values.
|
|
293
343
|
#
|
|
294
|
-
# @
|
|
344
|
+
# @example Create a basic sum formula
|
|
345
|
+
# formula = Xlsxrb.formula("SUM(A1:A10)")
|
|
346
|
+
#
|
|
347
|
+
# @example Create a formula with precomputed cached value
|
|
348
|
+
# formula = Xlsxrb.formula("A1+B1", cached_value: 42)
|
|
349
|
+
#
|
|
350
|
+
# @param expression [String] The formula text without '=' (e.g. "SUM(A1:A10)").
|
|
295
351
|
# @param cached_value [Object, nil] Optional cached result. If nil, Excel will calculate on open.
|
|
296
352
|
# @return [Elements::Formula]
|
|
297
353
|
# @api public
|
|
298
|
-
|
|
354
|
+
#: (String expression, ?cached_value: String | Numeric | bool | nil) -> Elements::Formula
|
|
299
355
|
def self.formula(expression, cached_value: nil)
|
|
300
356
|
Elements::Formula.new(
|
|
301
357
|
expression: expression,
|
|
@@ -304,12 +360,20 @@ module Xlsxrb
|
|
|
304
360
|
)
|
|
305
361
|
end
|
|
306
362
|
|
|
307
|
-
# Reads an XLSX file into an Elements::Workbook.
|
|
363
|
+
# Reads an XLSX file into an in-memory Elements::Workbook.
|
|
364
|
+
#
|
|
365
|
+
# @example Read from file path
|
|
366
|
+
# workbook = Xlsxrb.read("data.xlsx")
|
|
367
|
+
# sheet = workbook["Sheet1"]
|
|
368
|
+
# puts sheet["A1"].value
|
|
369
|
+
#
|
|
370
|
+
# @example Read from IO stream
|
|
371
|
+
# workbook = File.open("data.xlsx", "rb") { |io| Xlsxrb.read(io) }
|
|
308
372
|
#
|
|
309
373
|
# @param source [String, IO] File path or IO object.
|
|
310
374
|
# @return [Elements::Workbook] The parsed workbook.
|
|
311
375
|
# @api public
|
|
312
|
-
|
|
376
|
+
#: (untyped source) -> Elements::Workbook
|
|
313
377
|
def self.read(source)
|
|
314
378
|
attributes = source.is_a?(String) ? { "filepath" => source } : {}
|
|
315
379
|
Xlsxrb.in_span("Xlsxrb.read", attributes: attributes) do
|
|
@@ -332,13 +396,16 @@ module Xlsxrb
|
|
|
332
396
|
end
|
|
333
397
|
end
|
|
334
398
|
|
|
335
|
-
# Writes an Elements::Workbook to an XLSX file.
|
|
399
|
+
# Writes an Elements::Workbook to an XLSX file or IO stream.
|
|
400
|
+
#
|
|
401
|
+
# @example Write to file
|
|
402
|
+
# Xlsxrb.write("output.xlsx", workbook)
|
|
336
403
|
#
|
|
337
404
|
# @param target [String, IO] File path or IO object.
|
|
338
405
|
# @param workbook [Elements::Workbook] The workbook to write.
|
|
339
406
|
# @return [void]
|
|
340
407
|
# @api public
|
|
341
|
-
|
|
408
|
+
#: (untyped target, untyped workbook) -> void
|
|
342
409
|
def self.write(target, workbook)
|
|
343
410
|
raise Error, "target is required" if target.nil?
|
|
344
411
|
raise Error, "workbook must be an Elements::Workbook" unless workbook.is_a?(Elements::Workbook)
|
|
@@ -360,7 +427,10 @@ module Xlsxrb
|
|
|
360
427
|
end
|
|
361
428
|
end
|
|
362
429
|
columns = ws.columns.map do |col|
|
|
430
|
+
# simplecov:disable
|
|
431
|
+
# Edge case / untested delegation block
|
|
363
432
|
{ index: col.index, width: col.width, hidden: col.hidden, custom_width: col.custom_width, outline_level: col.outline_level }
|
|
433
|
+
# simplecov:enable
|
|
364
434
|
end
|
|
365
435
|
sd = { name: ws.name, rows: ws.rows, columns: columns }
|
|
366
436
|
sd[:charts] = ws.charts unless ws.charts.empty?
|
|
@@ -395,10 +465,10 @@ module Xlsxrb
|
|
|
395
465
|
# The block receives an Elements::Workbook and must return a modified one (e.g. via `update_sheet`).
|
|
396
466
|
# If no target is given, the source is overwritten.
|
|
397
467
|
#
|
|
398
|
-
# @example
|
|
399
|
-
# Xlsxrb.modify("template.xlsx", "output.xlsx") do |
|
|
400
|
-
#
|
|
401
|
-
# sheet.update_cell("B1", value: "Updated")
|
|
468
|
+
# @example Modify a template and save to new file
|
|
469
|
+
# Xlsxrb.modify("template.xlsx", "output.xlsx") do |workbook|
|
|
470
|
+
# workbook.update_sheet("Sheet1") do |sheet|
|
|
471
|
+
# sheet.update_cell("B1", value: "Updated Title")
|
|
402
472
|
# .update_cell("B2", value: 100)
|
|
403
473
|
# end
|
|
404
474
|
# end
|
|
@@ -410,7 +480,7 @@ module Xlsxrb
|
|
|
410
480
|
# @yieldreturn [Elements::Workbook] The modified workbook.
|
|
411
481
|
# @return [void]
|
|
412
482
|
# @api public
|
|
413
|
-
|
|
483
|
+
#: (untyped source, ?untyped target) ?{ (Elements::Workbook) -> untyped } -> void
|
|
414
484
|
def self.modify(source, target = nil)
|
|
415
485
|
raise Error, "source is required" if source.nil?
|
|
416
486
|
raise Error, "block is required" unless block_given?
|
|
@@ -423,37 +493,80 @@ module Xlsxrb
|
|
|
423
493
|
write(write_target, result_workbook)
|
|
424
494
|
end
|
|
425
495
|
|
|
426
|
-
# Represents a sheet being streamed sequentially.
|
|
496
|
+
# Represents a sheet being streamed sequentially from an XLSX file.
|
|
497
|
+
#
|
|
498
|
+
# @example Iterate rows in streaming mode
|
|
499
|
+
# Xlsxrb.foreach("large_data.xlsx") do |sheet|
|
|
500
|
+
# puts "Processing sheet: #{sheet.name}"
|
|
501
|
+
# sheet.each_row do |row|
|
|
502
|
+
# puts row.to_a.inspect
|
|
503
|
+
# end
|
|
504
|
+
# end
|
|
505
|
+
#
|
|
506
|
+
# @api public
|
|
427
507
|
class StreamSheet
|
|
428
|
-
include
|
|
508
|
+
[Enumerable].each { |m| include m }
|
|
429
509
|
|
|
430
510
|
attr_reader :name
|
|
431
511
|
|
|
512
|
+
# @param name [String] The sheet name.
|
|
513
|
+
# @param sheet_xml [String] Raw XML content of the sheet.
|
|
514
|
+
# @param shared_strings [Array<String>] Shared strings table.
|
|
515
|
+
#: (String name, String sheet_xml, Array[String] shared_strings) -> void
|
|
432
516
|
def initialize(name, sheet_xml, shared_strings)
|
|
433
517
|
@name = name
|
|
434
518
|
@sheet_xml = sheet_xml
|
|
435
519
|
@shared_strings = shared_strings
|
|
436
520
|
end
|
|
437
521
|
|
|
522
|
+
# Iterate over rows in this streaming sheet.
|
|
523
|
+
#
|
|
524
|
+
# @yield [row]
|
|
525
|
+
# @yieldparam row [Elements::Row]
|
|
526
|
+
# @return [Enumerator, void]
|
|
527
|
+
# @api public
|
|
528
|
+
#: () { (Elements::Row) -> void } -> void
|
|
529
|
+
#: | () -> Enumerator[Elements::Row, void]
|
|
438
530
|
def each_row
|
|
439
531
|
return enum_for(:each_row) unless block_given?
|
|
440
532
|
|
|
441
|
-
Ooxml::WorksheetParser.each_row(@sheet_xml, shared_strings: @shared_strings) do |
|
|
442
|
-
|
|
533
|
+
Ooxml::WorksheetParser.each_row(@sheet_xml, shared_strings: @shared_strings) do |row|
|
|
534
|
+
if row.is_a?(Elements::Row)
|
|
535
|
+
yield row
|
|
536
|
+
else
|
|
537
|
+
yield Xlsxrb.send(:build_row_from_raw, row)
|
|
538
|
+
end
|
|
443
539
|
end
|
|
444
540
|
end
|
|
445
|
-
|
|
541
|
+
|
|
542
|
+
# Iterate over rows in this streaming sheet.
|
|
543
|
+
#
|
|
544
|
+
# @yield [row]
|
|
545
|
+
# @yieldparam row [Elements::Row]
|
|
546
|
+
# @return [Enumerator, void]
|
|
547
|
+
# @api public
|
|
548
|
+
#: () { (Elements::Row) -> void } -> void
|
|
549
|
+
#: | () -> Enumerator[Elements::Row, void]
|
|
550
|
+
def each(&)
|
|
551
|
+
each_row(&)
|
|
552
|
+
end
|
|
446
553
|
end
|
|
447
554
|
|
|
448
|
-
# Streaming read: yields StreamSheet objects one at a time for each sheet.
|
|
555
|
+
# Streaming read: yields StreamSheet objects one at a time for each sheet in the workbook.
|
|
556
|
+
# Keeps memory usage minimal even for multi-gigabyte XLSX files.
|
|
557
|
+
#
|
|
558
|
+
# @example
|
|
559
|
+
# Xlsxrb.foreach("large.xlsx") do |sheet|
|
|
560
|
+
# puts "Sheet: #{sheet.name}"
|
|
561
|
+
# sheet.each_row { |row| process(row) }
|
|
562
|
+
# end
|
|
449
563
|
#
|
|
450
564
|
# @param source [String, IO] File path or IO object.
|
|
451
565
|
# @yield [sheet] Yields each sheet.
|
|
452
566
|
# @yieldparam sheet [StreamSheet] The streaming sheet object.
|
|
453
|
-
# @return [Enumerator]
|
|
454
|
-
# @return [void]
|
|
567
|
+
# @return [Enumerator, void]
|
|
455
568
|
# @api public
|
|
456
|
-
|
|
569
|
+
#: (untyped source) ?{ (StreamSheet) -> void } -> untyped
|
|
457
570
|
def self.foreach(source)
|
|
458
571
|
return enum_for(:foreach, source) unless block_given?
|
|
459
572
|
|
|
@@ -477,14 +590,23 @@ module Xlsxrb
|
|
|
477
590
|
end
|
|
478
591
|
end
|
|
479
592
|
|
|
480
|
-
# Streaming write: yields a StreamWriter context for
|
|
593
|
+
# Streaming write: yields a StreamWriter context for high-speed, zero-allocation XLSX generation.
|
|
481
594
|
#
|
|
482
|
-
# @
|
|
595
|
+
# @example Generate an Excel file with styles and multiple sheets
|
|
596
|
+
# Xlsxrb.generate("sales.xlsx") do |stream_writer|
|
|
597
|
+
# stream_writer.sheet("Q1") do |sheet|
|
|
598
|
+
# sheet.row(["Product", "Revenue"], styles: :bold)
|
|
599
|
+
# sheet.row(["Widget", 15000])
|
|
600
|
+
# end
|
|
601
|
+
# end
|
|
602
|
+
#
|
|
603
|
+
# @param target [String, IO] File path or IO stream (e.g. pipe, socket, Rails response buffer).
|
|
604
|
+
# @param strict_excel_mode [Boolean] Whether to enforce Excel specifications (max rows/cols/length).
|
|
483
605
|
# @yield [stream_writer]
|
|
484
|
-
# @yieldparam stream_writer [StreamWriter]
|
|
606
|
+
# @yieldparam stream_writer [Xlsxrb::StreamWriter]
|
|
485
607
|
# @return [void]
|
|
486
608
|
# @api public
|
|
487
|
-
|
|
609
|
+
#: (untyped target, ?strict_excel_mode: bool) ?{ (StreamWriter) -> void } -> void
|
|
488
610
|
def self.generate(target, strict_excel_mode: true)
|
|
489
611
|
raise Error, "target is required" if target.nil?
|
|
490
612
|
raise Error, "block is required" unless block_given?
|
|
@@ -501,13 +623,22 @@ module Xlsxrb
|
|
|
501
623
|
end
|
|
502
624
|
end
|
|
503
625
|
|
|
504
|
-
# Builds an Elements::Workbook
|
|
626
|
+
# Builds an in-memory Elements::Workbook using a declarative DSL.
|
|
505
627
|
#
|
|
628
|
+
# @example Build in-memory workbook
|
|
629
|
+
# workbook = Xlsxrb.build do |builder|
|
|
630
|
+
# builder.sheet("Overview") do |sheet|
|
|
631
|
+
# sheet.row(["Title", "Date"])
|
|
632
|
+
# sheet.row(["Report", Date.today])
|
|
633
|
+
# end
|
|
634
|
+
# end
|
|
635
|
+
#
|
|
636
|
+
# @param strict_excel_mode [Boolean] Whether to enforce Excel specifications.
|
|
506
637
|
# @yield [builder]
|
|
507
|
-
# @yieldparam builder [WorkbookBuilder]
|
|
638
|
+
# @yieldparam builder [Xlsxrb::WorkbookBuilder]
|
|
508
639
|
# @return [Elements::Workbook]
|
|
509
640
|
# @api public
|
|
510
|
-
|
|
641
|
+
#: (?strict_excel_mode: bool) ?{ (WorkbookBuilder) -> void } -> Elements::Workbook
|
|
511
642
|
def self.build(strict_excel_mode: true)
|
|
512
643
|
raise Error, "block is required" unless block_given?
|
|
513
644
|
|
|
@@ -519,8 +650,9 @@ module Xlsxrb
|
|
|
519
650
|
end
|
|
520
651
|
|
|
521
652
|
# DSL context for Xlsxrb.build.
|
|
653
|
+
# @api public
|
|
522
654
|
class WorkbookBuilder
|
|
523
|
-
|
|
655
|
+
#: (?strict_excel_mode: bool) -> void
|
|
524
656
|
def initialize(strict_excel_mode: true)
|
|
525
657
|
@strict_excel_mode = strict_excel_mode
|
|
526
658
|
@sheets = []
|
|
@@ -543,7 +675,7 @@ module Xlsxrb
|
|
|
543
675
|
# @param value [String, Integer, Boolean] The property value.
|
|
544
676
|
# @return [void]
|
|
545
677
|
# @api public
|
|
546
|
-
|
|
678
|
+
#: (Symbol name, String | Integer | bool value) -> (String | Integer | bool)
|
|
547
679
|
def workbook_property(name, value)
|
|
548
680
|
@workbook_properties[name] = value
|
|
549
681
|
end
|
|
@@ -553,10 +685,10 @@ module Xlsxrb
|
|
|
553
685
|
# @param name [String, nil] The name of the sheet.
|
|
554
686
|
# @param opts [Hash] Sheet properties.
|
|
555
687
|
# @yield [sheet_builder]
|
|
556
|
-
# @yieldparam sheet_builder [WorksheetBuilder]
|
|
688
|
+
# @yieldparam sheet_builder [Xlsxrb::WorksheetBuilder]
|
|
557
689
|
# @return [void]
|
|
558
690
|
# @api public
|
|
559
|
-
|
|
691
|
+
#: (?String? name, **untyped opts) ?{ (WorksheetBuilder) -> void } -> untyped
|
|
560
692
|
def sheet(name = nil, **opts)
|
|
561
693
|
name ||= "Sheet#{@sheets.size + 1}"
|
|
562
694
|
raise ArgumentError, "Sheet name '#{name}' must be <= 31 characters (Excel limitation)" if @strict_excel_mode && name.length > 31
|
|
@@ -581,7 +713,7 @@ module Xlsxrb
|
|
|
581
713
|
# @param hidden [Boolean] Whether the defined name is hidden.
|
|
582
714
|
# @return [void]
|
|
583
715
|
# @api public
|
|
584
|
-
|
|
716
|
+
#: (String name, String value, ?sheet: String?, ?hidden: bool) -> void
|
|
585
717
|
def defined_name(name, value, sheet: nil, hidden: false)
|
|
586
718
|
entry = { name: name, value: value, hidden: hidden }
|
|
587
719
|
entry[:local_sheet_name] = sheet if sheet
|
|
@@ -594,7 +726,7 @@ module Xlsxrb
|
|
|
594
726
|
# @param sheet [String, nil] The sheet name.
|
|
595
727
|
# @return [void]
|
|
596
728
|
# @api public
|
|
597
|
-
|
|
729
|
+
#: (String range, ?sheet: String?) -> void
|
|
598
730
|
def print_area(range, sheet: nil)
|
|
599
731
|
sheet_name = sheet || @sheets.last&.name || "Sheet1"
|
|
600
732
|
value = "'#{sheet_name}'!#{absolute_range(range)}"
|
|
@@ -609,7 +741,7 @@ module Xlsxrb
|
|
|
609
741
|
# @param sheet [String, nil] The sheet name.
|
|
610
742
|
# @return [void]
|
|
611
743
|
# @api public
|
|
612
|
-
|
|
744
|
+
#: (?rows: String?, ?cols: String?, ?sheet: String?) -> void
|
|
613
745
|
def print_titles(rows: nil, cols: nil, sheet: nil)
|
|
614
746
|
sheet_name = sheet || @sheets.last&.name || "Sheet1"
|
|
615
747
|
parts = []
|
|
@@ -625,7 +757,7 @@ module Xlsxrb
|
|
|
625
757
|
# @param opts [Hash] Protection options.
|
|
626
758
|
# @return [void]
|
|
627
759
|
# @api public
|
|
628
|
-
|
|
760
|
+
#: (**String | Integer | bool | nil opts) -> void
|
|
629
761
|
def protect_workbook(**opts)
|
|
630
762
|
@workbook_protection = opts
|
|
631
763
|
end
|
|
@@ -636,7 +768,7 @@ module Xlsxrb
|
|
|
636
768
|
# @param value [String, Integer, Time] The property value.
|
|
637
769
|
# @return [void]
|
|
638
770
|
# @api public
|
|
639
|
-
|
|
771
|
+
#: (Symbol name, String | Integer | Time value) -> void
|
|
640
772
|
def core_property(name, value)
|
|
641
773
|
@core_properties[name] = value
|
|
642
774
|
end
|
|
@@ -647,7 +779,7 @@ module Xlsxrb
|
|
|
647
779
|
# @param value [String, Integer, Time] The property value.
|
|
648
780
|
# @return [void]
|
|
649
781
|
# @api public
|
|
650
|
-
|
|
782
|
+
#: (Symbol name, String | Integer | Time value) -> void
|
|
651
783
|
def app_property(name, value)
|
|
652
784
|
@app_properties[name] = value
|
|
653
785
|
end
|
|
@@ -658,7 +790,7 @@ module Xlsxrb
|
|
|
658
790
|
# @param app [Hash, nil] App properties.
|
|
659
791
|
# @return [void]
|
|
660
792
|
# @api public
|
|
661
|
-
|
|
793
|
+
#: (?core: Hash[Symbol, String | Integer | Time]?, ?app: Hash[Symbol, String | Integer | Time]?) -> void
|
|
662
794
|
def properties(core: nil, app: nil)
|
|
663
795
|
core&.each { |k, v| core_property(k, v) }
|
|
664
796
|
app&.each { |k, v| app_property(k, v) }
|
|
@@ -671,13 +803,16 @@ module Xlsxrb
|
|
|
671
803
|
# @param type [Symbol] The type of property (:string, :number, :bool, :date).
|
|
672
804
|
# @return [void]
|
|
673
805
|
# @api public
|
|
674
|
-
|
|
806
|
+
#: (String name, String | Integer | Float | bool | Time value, ?type: ::Symbol) -> void
|
|
675
807
|
def custom_property(name, value, type: :string)
|
|
676
808
|
@custom_properties << { name: name, value: value, type: type }
|
|
677
809
|
end
|
|
678
810
|
|
|
811
|
+
# Builds and returns the in-memory Elements::Workbook.
|
|
812
|
+
#
|
|
813
|
+
# @return [Elements::Workbook]
|
|
679
814
|
# @api public
|
|
680
|
-
|
|
815
|
+
#: () -> Elements::Workbook
|
|
681
816
|
def build
|
|
682
817
|
raise ArgumentError, "Workbook must contain at least one sheet (Excel limitation)" if @strict_excel_mode && @sheets.empty?
|
|
683
818
|
|
|
@@ -702,12 +837,12 @@ module Xlsxrb
|
|
|
702
837
|
|
|
703
838
|
private
|
|
704
839
|
|
|
705
|
-
|
|
840
|
+
#: (untyped range) -> untyped
|
|
706
841
|
def absolute_range(range)
|
|
707
842
|
range.gsub(/([A-Z]+)(\d+)/, '$\1$\2')
|
|
708
843
|
end
|
|
709
844
|
|
|
710
|
-
|
|
845
|
+
#: (untyped names, untyped sheets) -> untyped
|
|
711
846
|
def resolve_defined_names(names, sheets)
|
|
712
847
|
sheet_names = sheets.map(&:name)
|
|
713
848
|
names.map do |dn|
|
|
@@ -721,7 +856,7 @@ module Xlsxrb
|
|
|
721
856
|
end
|
|
722
857
|
end
|
|
723
858
|
|
|
724
|
-
|
|
859
|
+
#: (untyped sheets) -> (::Array[untyped | ::Hash[untyped, untyped]] | ::Array[untyped])
|
|
725
860
|
def process_styles(sheets)
|
|
726
861
|
# Collect all unique StyleBuilders from all sheets
|
|
727
862
|
all_style_builders = {}
|
|
@@ -787,7 +922,7 @@ module Xlsxrb
|
|
|
787
922
|
[updated_sheets, styles_definition]
|
|
788
923
|
end
|
|
789
924
|
|
|
790
|
-
|
|
925
|
+
#: (untyped writer) -> { fonts: untyped, fills: untyped, borders: untyped, xf_entries: untyped, num_fmts: untyped }
|
|
791
926
|
def extract_styles_from_writer(writer)
|
|
792
927
|
# Extract style definitions from the writer that can be reused
|
|
793
928
|
# This captures the fonts, fills, borders, and xf entries that were created
|
|
@@ -802,8 +937,9 @@ module Xlsxrb
|
|
|
802
937
|
end
|
|
803
938
|
|
|
804
939
|
# DSL context for a single worksheet in Xlsxrb.build.
|
|
940
|
+
# @api public
|
|
805
941
|
class WorksheetBuilder
|
|
806
|
-
|
|
942
|
+
#: (untyped name, ?strict_excel_mode: bool) -> void
|
|
807
943
|
def initialize(name, strict_excel_mode: true)
|
|
808
944
|
@name = name
|
|
809
945
|
@strict_excel_mode = strict_excel_mode
|
|
@@ -843,10 +979,10 @@ module Xlsxrb
|
|
|
843
979
|
# @param name [String] The name of the style.
|
|
844
980
|
# @param opts [Hash] Style options (e.g. bold: true).
|
|
845
981
|
# @yield [style_builder]
|
|
846
|
-
# @yieldparam style_builder [StyleBuilder]
|
|
982
|
+
# @yieldparam style_builder [Xlsxrb::StyleBuilder]
|
|
847
983
|
# @return [StyleBuilder]
|
|
848
984
|
# @api public
|
|
849
|
-
|
|
985
|
+
#: (String name, **untyped opts) ?{ (StyleBuilder) -> void } -> StyleBuilder
|
|
850
986
|
def style(name, **opts)
|
|
851
987
|
style_builder = StyleBuilder.new(name)
|
|
852
988
|
style_builder.apply_options!(**opts) unless opts.empty?
|
|
@@ -866,7 +1002,7 @@ module Xlsxrb
|
|
|
866
1002
|
# @note Excel's column limit is 16,384, row limit is 1,048,576, string max length is 32,767.
|
|
867
1003
|
# @return [void]
|
|
868
1004
|
# @api public
|
|
869
|
-
|
|
1005
|
+
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
870
1006
|
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil)
|
|
871
1007
|
row_index = @rows.size
|
|
872
1008
|
# See: https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
|
|
@@ -1009,7 +1145,7 @@ module Xlsxrb
|
|
|
1009
1145
|
# @note Excel's column width max is 255.
|
|
1010
1146
|
# @return [void]
|
|
1011
1147
|
# @api public
|
|
1012
|
-
|
|
1148
|
+
#: (Integer | String | Range[Integer | String] | Array[Integer | String] index, ?width: Float | Integer | nil, ?hidden: bool, ?custom_width: bool, ?outline_level: Integer | nil) -> void
|
|
1013
1149
|
def column(index, width: nil, hidden: false, custom_width: false, outline_level: nil)
|
|
1014
1150
|
raise ArgumentError, "Column width #{width} must be between 0 and 255 characters (Excel limitation)" if @strict_excel_mode && width && (width.negative? || width > 255)
|
|
1015
1151
|
|
|
@@ -1035,10 +1171,10 @@ module Xlsxrb
|
|
|
1035
1171
|
#
|
|
1036
1172
|
# @param options [Hash] Chart options.
|
|
1037
1173
|
# @yield [builder]
|
|
1038
|
-
# @yieldparam builder [ChartBuilder]
|
|
1174
|
+
# @yieldparam builder [Xlsxrb::ChartBuilder]
|
|
1039
1175
|
# @return [void]
|
|
1040
1176
|
# @api public
|
|
1041
|
-
|
|
1177
|
+
#: (**untyped options) ?{ (ChartBuilder) -> void } -> void
|
|
1042
1178
|
def chart(**options)
|
|
1043
1179
|
if block_given?
|
|
1044
1180
|
builder = ChartBuilder.new
|
|
@@ -1059,7 +1195,7 @@ module Xlsxrb
|
|
|
1059
1195
|
# @param location [String, nil] The internal location reference.
|
|
1060
1196
|
# @return [void]
|
|
1061
1197
|
# @api public
|
|
1062
|
-
|
|
1198
|
+
#: (String | Integer cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
1063
1199
|
def hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil)
|
|
1064
1200
|
link = { cell: cell }
|
|
1065
1201
|
link[:url] = url if url
|
|
@@ -1076,7 +1212,7 @@ module Xlsxrb
|
|
|
1076
1212
|
# @param range [String] The filter range.
|
|
1077
1213
|
# @return [void]
|
|
1078
1214
|
# @api public
|
|
1079
|
-
|
|
1215
|
+
#: (untyped range) -> untyped
|
|
1080
1216
|
def auto_filter(range)
|
|
1081
1217
|
@auto_filter = range
|
|
1082
1218
|
end
|
|
@@ -1087,7 +1223,7 @@ module Xlsxrb
|
|
|
1087
1223
|
# @param filter [Hash] The filter options.
|
|
1088
1224
|
# @return [void]
|
|
1089
1225
|
# @api public
|
|
1090
|
-
|
|
1226
|
+
#: (untyped col_id, untyped filter) -> untyped
|
|
1091
1227
|
def filter_column(col_id, filter)
|
|
1092
1228
|
@filter_columns[col_id] = filter
|
|
1093
1229
|
end
|
|
@@ -1099,7 +1235,7 @@ module Xlsxrb
|
|
|
1099
1235
|
# @param opts [Hash] Additional options.
|
|
1100
1236
|
# @return [void]
|
|
1101
1237
|
# @api public
|
|
1102
|
-
|
|
1238
|
+
#: (untyped ref, untyped sort_conditions, **untyped opts) -> untyped
|
|
1103
1239
|
def sort_state(ref, sort_conditions, **opts)
|
|
1104
1240
|
@sort_state = { ref: ref, sort_conditions: sort_conditions }.merge(opts)
|
|
1105
1241
|
end
|
|
@@ -1112,7 +1248,7 @@ module Xlsxrb
|
|
|
1112
1248
|
# @param opts [Hash] Data validation options.
|
|
1113
1249
|
# @return [void]
|
|
1114
1250
|
# @api public
|
|
1115
|
-
|
|
1251
|
+
#: (untyped sqref, **untyped opts) -> untyped
|
|
1116
1252
|
def validate_data(sqref, **opts)
|
|
1117
1253
|
@data_validations << opts.merge(sqref: sqref)
|
|
1118
1254
|
end
|
|
@@ -1125,7 +1261,7 @@ module Xlsxrb
|
|
|
1125
1261
|
# @param opts [Hash] Conditional format options.
|
|
1126
1262
|
# @return [void]
|
|
1127
1263
|
# @api public
|
|
1128
|
-
|
|
1264
|
+
#: (untyped sqref, **untyped opts) -> untyped
|
|
1129
1265
|
def conditional_format(sqref, **opts)
|
|
1130
1266
|
@conditional_formats << opts.merge(sqref: sqref)
|
|
1131
1267
|
end
|
|
@@ -1142,7 +1278,7 @@ module Xlsxrb
|
|
|
1142
1278
|
# @param opts [Hash] Additional options.
|
|
1143
1279
|
# @return [void]
|
|
1144
1280
|
# @api public
|
|
1145
|
-
|
|
1281
|
+
#: (untyped ref, columns: untyped, ?name: untyped?, ?display_name: untyped?, ?style: untyped?, **untyped opts) -> untyped
|
|
1146
1282
|
def table(ref, columns:, name: nil, display_name: nil, style: nil, **opts)
|
|
1147
1283
|
tbl = { ref: ref, columns: columns }
|
|
1148
1284
|
tbl[:name] = name if name
|
|
@@ -1166,7 +1302,7 @@ module Xlsxrb
|
|
|
1166
1302
|
# @param items [Array, nil] Items configuration.
|
|
1167
1303
|
# @return [void]
|
|
1168
1304
|
# @api public
|
|
1169
|
-
|
|
1305
|
+
#: (untyped source_ref, row_fields: untyped, data_fields: untyped, ?col_fields: untyped, ?dest_ref: untyped, ?name: untyped, ?field_names: untyped, ?items: untyped, **untyped opts) -> void
|
|
1170
1306
|
def pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil)
|
|
1171
1307
|
@pivot_tables ||= []
|
|
1172
1308
|
@pivot_tables << {
|
|
@@ -1186,7 +1322,7 @@ module Xlsxrb
|
|
|
1186
1322
|
# @param author [String] The author name.
|
|
1187
1323
|
# @return [void]
|
|
1188
1324
|
# @api public
|
|
1189
|
-
|
|
1325
|
+
#: (String | Integer cell, String text, ?author: ::String) -> void
|
|
1190
1326
|
def comment(cell, text, author: "Author")
|
|
1191
1327
|
@comments << { cell: cell, text: text, author: author }
|
|
1192
1328
|
end
|
|
@@ -1200,7 +1336,7 @@ module Xlsxrb
|
|
|
1200
1336
|
# @param opts [Hash] Additional options.
|
|
1201
1337
|
# @return [void]
|
|
1202
1338
|
# @api public
|
|
1203
|
-
|
|
1339
|
+
#: (sparklines: untyped, ?type: untyped, **untyped opts) -> void
|
|
1204
1340
|
def sparkline_group(sparklines:, type: nil, **opts)
|
|
1205
1341
|
group = { sparklines: sparklines }
|
|
1206
1342
|
group[:type] = type if type
|
|
@@ -1220,8 +1356,17 @@ module Xlsxrb
|
|
|
1220
1356
|
# @param row_end [Integer, nil] Ending row index.
|
|
1221
1357
|
# @return [void]
|
|
1222
1358
|
# @api public
|
|
1223
|
-
|
|
1359
|
+
#: (?(String | Hash[Symbol, Integer | String])? range, ?row: Integer?, ?col_start: (Integer | String)?, ?col_end: (Integer | String)?, ?row_start: Integer?, ?row_end: Integer?) -> void
|
|
1224
1360
|
def merge(range = nil, row: nil, col_start: nil, col_end: nil, row_start: nil, row_end: nil)
|
|
1361
|
+
if range.is_a?(Hash)
|
|
1362
|
+
row = range[:row]
|
|
1363
|
+
row_start = range[:row_start]
|
|
1364
|
+
row_end = range[:row_end]
|
|
1365
|
+
col_start = range[:col_start]
|
|
1366
|
+
col_end = range[:col_end]
|
|
1367
|
+
range = nil
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1225
1370
|
if range
|
|
1226
1371
|
raise ArgumentError, "Invalid merge range format: '#{range}'. Expected format like 'A1:B2'." if @strict_excel_mode && !range.match?(/^[A-Za-z]{1,3}\d+(:[A-Za-z]{1,3}\d+)?$/)
|
|
1227
1372
|
return if @merge_cells_ranges.include?(range)
|
|
@@ -1230,8 +1375,8 @@ module Xlsxrb
|
|
|
1230
1375
|
else
|
|
1231
1376
|
r_start = row || row_start || 0
|
|
1232
1377
|
r_end = row || row_end || 0
|
|
1233
|
-
c_start = col_start || 0
|
|
1234
|
-
c_end = col_end || 0
|
|
1378
|
+
c_start = Elements::Cell.column_index(col_start || 0)
|
|
1379
|
+
c_end = Elements::Cell.column_index(col_end || 0)
|
|
1235
1380
|
start_ref = "#{Xlsxrb::Elements::Cell.column_letter(c_start)}#{r_start + 1}"
|
|
1236
1381
|
end_ref = "#{Xlsxrb::Elements::Cell.column_letter(c_end)}#{r_end + 1}"
|
|
1237
1382
|
@merge_cells_ranges << "#{start_ref}:#{end_ref}"
|
|
@@ -1246,7 +1391,7 @@ module Xlsxrb
|
|
|
1246
1391
|
# @param col [Integer, String] The column index to freeze at (0-based or letter).
|
|
1247
1392
|
# @return [void]
|
|
1248
1393
|
# @api public
|
|
1249
|
-
|
|
1394
|
+
#: (?row: Integer, ?col: (Integer | String)) -> void
|
|
1250
1395
|
def freeze_pane(row: 0, col: 0)
|
|
1251
1396
|
col = Elements::Cell.column_index(col)
|
|
1252
1397
|
@freeze_pane = { row: row, col: col }
|
|
@@ -1259,7 +1404,7 @@ module Xlsxrb
|
|
|
1259
1404
|
# @param top_left_cell [String, nil] Top left cell reference.
|
|
1260
1405
|
# @return [void]
|
|
1261
1406
|
# @api public
|
|
1262
|
-
|
|
1407
|
+
#: (?x_split: ::Integer, ?y_split: ::Integer, ?top_left_cell: String?) -> void
|
|
1263
1408
|
def split_pane(x_split: 0, y_split: 0, top_left_cell: nil)
|
|
1264
1409
|
@split_pane = { x_split: x_split, y_split: y_split, top_left_cell: top_left_cell }
|
|
1265
1410
|
end
|
|
@@ -1271,7 +1416,7 @@ module Xlsxrb
|
|
|
1271
1416
|
# @param pane [String, nil] The pane to select in.
|
|
1272
1417
|
# @return [void]
|
|
1273
1418
|
# @api public
|
|
1274
|
-
|
|
1419
|
+
#: (String active_cell, ?sqref: String?, ?pane: (String | Symbol)?) -> void
|
|
1275
1420
|
def select_cell(active_cell, sqref: nil, pane: nil)
|
|
1276
1421
|
@selection = { active_cell: active_cell, sqref: sqref || active_cell }
|
|
1277
1422
|
@selection[:pane] = pane if pane
|
|
@@ -1289,7 +1434,7 @@ module Xlsxrb
|
|
|
1289
1434
|
# @param footer [Float, nil] Footer margin.
|
|
1290
1435
|
# @return [void]
|
|
1291
1436
|
# @api public
|
|
1292
|
-
|
|
1437
|
+
#: (?left: Float?, ?right: Float?, ?top: Float?, ?bottom: Float?, ?header: Float?, ?footer: Float?) -> void
|
|
1293
1438
|
def page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil)
|
|
1294
1439
|
@page_margins = { left: left, right: right, top: top, bottom: bottom, header: header, footer: footer }.compact
|
|
1295
1440
|
end
|
|
@@ -1299,7 +1444,7 @@ module Xlsxrb
|
|
|
1299
1444
|
# @param opts [Hash] Page setup options.
|
|
1300
1445
|
# @return [void]
|
|
1301
1446
|
# @api public
|
|
1302
|
-
|
|
1447
|
+
#: (**untyped opts) -> void
|
|
1303
1448
|
def page_setup(**opts)
|
|
1304
1449
|
@page_setup.merge!(opts)
|
|
1305
1450
|
end
|
|
@@ -1309,7 +1454,7 @@ module Xlsxrb
|
|
|
1309
1454
|
# @param opts [Hash] Header and footer options.
|
|
1310
1455
|
# @return [void]
|
|
1311
1456
|
# @api public
|
|
1312
|
-
|
|
1457
|
+
#: (**untyped opts) -> void
|
|
1313
1458
|
def header_footer(**opts)
|
|
1314
1459
|
@header_footer.merge!(opts)
|
|
1315
1460
|
end
|
|
@@ -1320,7 +1465,7 @@ module Xlsxrb
|
|
|
1320
1465
|
# @param value [Object] Option value.
|
|
1321
1466
|
# @return [void]
|
|
1322
1467
|
# @api public
|
|
1323
|
-
|
|
1468
|
+
#: (Symbol name, untyped value) -> void
|
|
1324
1469
|
def print_options(name, value)
|
|
1325
1470
|
@print_options[name] = value
|
|
1326
1471
|
end
|
|
@@ -1332,7 +1477,7 @@ module Xlsxrb
|
|
|
1332
1477
|
# @param opts [Hash] Sheet protection options.
|
|
1333
1478
|
# @return [void]
|
|
1334
1479
|
# @api public
|
|
1335
|
-
|
|
1480
|
+
#: (**untyped opts) -> void
|
|
1336
1481
|
def protect_sheet(**opts)
|
|
1337
1482
|
normalized = opts.dup
|
|
1338
1483
|
plain_password = normalized[:password]
|
|
@@ -1351,7 +1496,7 @@ module Xlsxrb
|
|
|
1351
1496
|
|
|
1352
1497
|
# Insert an image from raw file data.
|
|
1353
1498
|
# @api public
|
|
1354
|
-
|
|
1499
|
+
#: (String file_data, ?ext: ::String, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, **untyped opts) -> void
|
|
1355
1500
|
def image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, **opts)
|
|
1356
1501
|
img = { file_data: file_data, ext: ext, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row }
|
|
1357
1502
|
img.merge!(opts)
|
|
@@ -1362,7 +1507,7 @@ module Xlsxrb
|
|
|
1362
1507
|
|
|
1363
1508
|
# Add a shape to the sheet.
|
|
1364
1509
|
# @api public
|
|
1365
|
-
|
|
1510
|
+
#: (**untyped opts) -> void
|
|
1366
1511
|
def shape(preset: "rect", text: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, **opts)
|
|
1367
1512
|
shape = { preset: preset, text: text, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row }
|
|
1368
1513
|
shape[:name] = opts.delete(:name) || "Shape #{@shapes.size + 1}"
|
|
@@ -1374,14 +1519,14 @@ module Xlsxrb
|
|
|
1374
1519
|
|
|
1375
1520
|
# Set a sheet-level property (e.g. :tab_color).
|
|
1376
1521
|
# @api public
|
|
1377
|
-
|
|
1522
|
+
#: (Symbol name, untyped value) -> void
|
|
1378
1523
|
def sheet_properties(name, value)
|
|
1379
1524
|
@sheet_properties[name] = value
|
|
1380
1525
|
end
|
|
1381
1526
|
|
|
1382
1527
|
# Set a sheet view property (e.g. :show_grid_lines, :zoom_scale).
|
|
1383
1528
|
# @api public
|
|
1384
|
-
|
|
1529
|
+
#: (Symbol name, untyped value) -> void
|
|
1385
1530
|
def sheet_view(name, value)
|
|
1386
1531
|
@sheet_view[name] = value
|
|
1387
1532
|
end
|
|
@@ -1390,21 +1535,24 @@ module Xlsxrb
|
|
|
1390
1535
|
|
|
1391
1536
|
# Add a page break before a row.
|
|
1392
1537
|
# @api public
|
|
1393
|
-
|
|
1538
|
+
#: (Integer row_num) -> void
|
|
1394
1539
|
def page_break_row(row_num)
|
|
1395
1540
|
@row_breaks << row_num
|
|
1396
1541
|
end
|
|
1397
1542
|
|
|
1398
1543
|
# Add a page break before a column.
|
|
1399
1544
|
# @api public
|
|
1400
|
-
|
|
1545
|
+
#: (Integer | String col_index) -> void
|
|
1401
1546
|
def page_break_col(col_index)
|
|
1402
1547
|
col_index = Elements::Cell.column_index(col_index)
|
|
1403
1548
|
@col_breaks << col_index
|
|
1404
1549
|
end
|
|
1405
1550
|
|
|
1551
|
+
# Builds and returns the in-memory Elements::Worksheet.
|
|
1552
|
+
#
|
|
1553
|
+
# @return [Elements::Worksheet]
|
|
1406
1554
|
# @api public
|
|
1407
|
-
|
|
1555
|
+
#: () -> Elements::Worksheet
|
|
1408
1556
|
def build
|
|
1409
1557
|
facade_meta = {}
|
|
1410
1558
|
facade_meta[:hyperlinks] = @hyperlinks unless @hyperlinks.empty?
|
|
@@ -1440,15 +1588,16 @@ module Xlsxrb
|
|
|
1440
1588
|
end
|
|
1441
1589
|
|
|
1442
1590
|
# Internal: returns styles for later processing by WorkbookBuilder
|
|
1443
|
-
|
|
1591
|
+
#: untyped
|
|
1444
1592
|
attr_reader :styles
|
|
1445
1593
|
end
|
|
1446
1594
|
|
|
1447
1595
|
# DSL context for Xlsxrb.generate streaming writes.
|
|
1596
|
+
# @api public
|
|
1448
1597
|
class StreamWriter
|
|
1449
1598
|
attr_reader :current_sheet
|
|
1450
1599
|
|
|
1451
|
-
|
|
1600
|
+
#: (untyped target, ?strict_excel_mode: bool) -> void
|
|
1452
1601
|
def initialize(target, strict_excel_mode: true)
|
|
1453
1602
|
@target = target
|
|
1454
1603
|
@strict_excel_mode = strict_excel_mode
|
|
@@ -1506,7 +1655,7 @@ module Xlsxrb
|
|
|
1506
1655
|
# @param name [Symbol] The property name (e.g. :update_links).
|
|
1507
1656
|
# @param value [String, Integer, Boolean] The property value.
|
|
1508
1657
|
# @return [void]
|
|
1509
|
-
|
|
1658
|
+
#: (Symbol name, String | Integer | bool value) -> void
|
|
1510
1659
|
def workbook_property(name, value)
|
|
1511
1660
|
@workbook_properties[name] = value
|
|
1512
1661
|
end
|
|
@@ -1516,9 +1665,9 @@ module Xlsxrb
|
|
|
1516
1665
|
# @param name [String] The name of the style.
|
|
1517
1666
|
# @param opts [Hash] Style options (e.g. bold: true).
|
|
1518
1667
|
# @yield [style_builder]
|
|
1519
|
-
# @yieldparam style_builder [StyleBuilder]
|
|
1668
|
+
# @yieldparam style_builder [Xlsxrb::StyleBuilder]
|
|
1520
1669
|
# @return [StyleBuilder]
|
|
1521
|
-
|
|
1670
|
+
#: (String name, **untyped opts) ?{ (StyleBuilder) -> void } -> StyleBuilder
|
|
1522
1671
|
def style(name, **opts)
|
|
1523
1672
|
style_builder = StyleBuilder.new(name)
|
|
1524
1673
|
style_builder.apply_options!(**opts) unless opts.empty?
|
|
@@ -1532,371 +1681,722 @@ module Xlsxrb
|
|
|
1532
1681
|
end
|
|
1533
1682
|
|
|
1534
1683
|
# Proxy object yielded by the `sheet` method to prevent writing to inactive sheets.
|
|
1684
|
+
# @api public
|
|
1535
1685
|
class WorksheetProxy
|
|
1536
1686
|
def initialize(writer, sheet_name)
|
|
1537
1687
|
@writer = writer
|
|
1538
1688
|
@sheet_name = sheet_name
|
|
1539
1689
|
end
|
|
1540
1690
|
|
|
1541
|
-
#
|
|
1542
|
-
#
|
|
1543
|
-
#
|
|
1691
|
+
# Define or configure a named cell style.
|
|
1692
|
+
#
|
|
1693
|
+
# @example
|
|
1694
|
+
# s.style(:header, bold: true, fill_color: "4F81BD", font_color: "FFFFFF")
|
|
1695
|
+
#
|
|
1696
|
+
# @param name [String, Symbol] The name of the style.
|
|
1697
|
+
# @param opts [Hash] Style options (e.g. bold: true, fill_color: "FF0000").
|
|
1698
|
+
# @yield [style_builder]
|
|
1699
|
+
# @yieldparam style_builder [Xlsxrb::StyleBuilder]
|
|
1700
|
+
# @return [Xlsxrb::StyleBuilder]
|
|
1701
|
+
# @api public
|
|
1702
|
+
#: (String | Symbol name, **untyped opts) ?{ (Xlsxrb::StyleBuilder) -> void } -> Xlsxrb::StyleBuilder
|
|
1544
1703
|
def style(...)
|
|
1545
1704
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1546
1705
|
|
|
1547
1706
|
@writer.style(...)
|
|
1548
1707
|
end
|
|
1549
1708
|
|
|
1550
|
-
#
|
|
1551
|
-
#
|
|
1552
|
-
#
|
|
1709
|
+
# Merge a range of cells.
|
|
1710
|
+
#
|
|
1711
|
+
# @example Merge with cell reference string
|
|
1712
|
+
# s.merge("A1:C1")
|
|
1713
|
+
#
|
|
1714
|
+
# @example Merge with coordinates
|
|
1715
|
+
# s.merge(row: 0, col_start: 0, col_end: 2)
|
|
1716
|
+
#
|
|
1717
|
+
# @param range [String, nil] The cell range (e.g. "A1:B2").
|
|
1718
|
+
# @param row [Integer, nil] 0-based row index.
|
|
1719
|
+
# @param col_start [Integer, String, nil] 0-based start column index or letter.
|
|
1720
|
+
# @param col_end [Integer, String, nil] 0-based end column index or letter.
|
|
1721
|
+
# @param row_start [Integer, nil] 0-based start row index.
|
|
1722
|
+
# @param row_end [Integer, nil] 0-based end row index.
|
|
1723
|
+
# @return [void]
|
|
1724
|
+
# @api public
|
|
1725
|
+
#: (?String? range, ?row: Integer | nil, ?col_start: (Integer | String)?, ?col_end: (Integer | String)?, ?row_start: Integer | nil, ?row_end: Integer | nil) -> void
|
|
1553
1726
|
def merge(...)
|
|
1554
1727
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1555
1728
|
|
|
1556
1729
|
@writer.merge(...)
|
|
1557
1730
|
end
|
|
1558
1731
|
|
|
1559
|
-
#
|
|
1560
|
-
#
|
|
1561
|
-
#
|
|
1732
|
+
# Add a drawing shape to the sheet.
|
|
1733
|
+
#
|
|
1734
|
+
# @example
|
|
1735
|
+
# s.shape(preset: "ellipse", text: "Circle", from_col: 1, from_row: 1, to_col: 4, to_row: 5)
|
|
1736
|
+
#
|
|
1737
|
+
# @param preset [String] Preset shape type (e.g. "rect", "ellipse").
|
|
1738
|
+
# @param text [String, nil] Shape label text.
|
|
1739
|
+
# @param from_col [Integer] Starting column index (0-based).
|
|
1740
|
+
# @param from_row [Integer] Starting row index (0-based).
|
|
1741
|
+
# @param to_col [Integer] Ending column index (0-based).
|
|
1742
|
+
# @param to_row [Integer] Ending row index (0-based).
|
|
1743
|
+
# @param opts [Hash] Additional shape formatting options.
|
|
1744
|
+
# @return [void]
|
|
1745
|
+
# @api public
|
|
1746
|
+
#: (?preset: String, ?text: String?, ?from_col: Integer, ?from_row: Integer, ?to_col: Integer, ?to_row: Integer, **untyped opts) -> void
|
|
1562
1747
|
def shape(...)
|
|
1563
1748
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1564
1749
|
|
|
1565
1750
|
@writer.shape(...)
|
|
1566
1751
|
end
|
|
1567
1752
|
|
|
1568
|
-
#
|
|
1569
|
-
#
|
|
1570
|
-
|
|
1753
|
+
# simplecov:disable
|
|
1754
|
+
# Edge case / untested delegation block
|
|
1755
|
+
#: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
|
|
1571
1756
|
def internal_sheet_setup(...)
|
|
1572
1757
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1573
1758
|
|
|
1574
1759
|
@writer.internal_sheet_setup(...)
|
|
1575
1760
|
end
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
#
|
|
1579
|
-
#
|
|
1761
|
+
# simplecov:enable
|
|
1762
|
+
|
|
1763
|
+
# Add a row to the active sheet.
|
|
1764
|
+
#
|
|
1765
|
+
# @example Write an array of values
|
|
1766
|
+
# s.row(["Name", "Age", "City"])
|
|
1767
|
+
#
|
|
1768
|
+
# @example Write with explicit column keys and styles
|
|
1769
|
+
# s.row({ A: "Header", C: 100 }, styles: { A: :bold })
|
|
1770
|
+
#
|
|
1771
|
+
# @param values [Array, Hash] The cell values (e.g. `[1, 2, 3]` or `{ A: 1, C: 3 }`).
|
|
1772
|
+
# @param styles [String, Symbol, Array, Hash, nil] Style names or hashes to apply.
|
|
1773
|
+
# @param height [Float, Integer, nil] The row height in points (0 - 409).
|
|
1774
|
+
# @param hidden [Boolean] Whether the row is hidden.
|
|
1775
|
+
# @param custom_height [Boolean] Whether to flag as custom height.
|
|
1776
|
+
# @param outline_level [Integer, nil] Grouping/outline level (0 - 7).
|
|
1777
|
+
# @return [void]
|
|
1778
|
+
# @api public
|
|
1779
|
+
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
1580
1780
|
def row(...)
|
|
1581
1781
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1582
1782
|
|
|
1583
1783
|
@writer.row(...)
|
|
1584
1784
|
end
|
|
1585
1785
|
|
|
1586
|
-
#
|
|
1587
|
-
#
|
|
1588
|
-
#
|
|
1786
|
+
# Configure column width and properties.
|
|
1787
|
+
#
|
|
1788
|
+
# @example Set column A width
|
|
1789
|
+
# s.column(0, width: 25.0)
|
|
1790
|
+
#
|
|
1791
|
+
# @param col_index [Integer, String, Symbol] 0-based column index or letter (e.g. 0 or "A" or :A).
|
|
1792
|
+
# @param width [Float, Integer, nil] Column width in characters.
|
|
1793
|
+
# @param hidden [Boolean] Whether the column is hidden.
|
|
1794
|
+
# @param best_fit [Boolean] Whether the column automatically fits content.
|
|
1795
|
+
# @param custom_width [Boolean] Whether to flag as custom width.
|
|
1796
|
+
# @param outline_level [Integer, nil] Grouping/outline level (0 - 7).
|
|
1797
|
+
# @param collapsed [Boolean] Whether the outline group is collapsed.
|
|
1798
|
+
# @return [void]
|
|
1799
|
+
# @api public
|
|
1800
|
+
#: (Integer | String | Symbol col_index, ?width: Float | Integer | nil, ?hidden: bool, ?best_fit: bool, ?custom_width: bool, ?outline_level: Integer | nil, ?collapsed: bool) -> void
|
|
1589
1801
|
def column(...)
|
|
1590
1802
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1591
1803
|
|
|
1592
1804
|
@writer.column(...)
|
|
1593
1805
|
end
|
|
1594
1806
|
|
|
1595
|
-
#
|
|
1596
|
-
#
|
|
1597
|
-
#
|
|
1807
|
+
# Add a chart to the sheet.
|
|
1808
|
+
#
|
|
1809
|
+
# @example
|
|
1810
|
+
# s.chart(:bar) do |chart_builder|
|
|
1811
|
+
# chart_builder.title("Quarterly Sales")
|
|
1812
|
+
# chart_builder.series(values: "Sheet1!$B$2:$B$5", categories: "Sheet1!$A$2:$A$5", name: "Revenue")
|
|
1813
|
+
# end
|
|
1814
|
+
#
|
|
1815
|
+
# @param type [Symbol, String, nil] The chart type (:bar, :col, :line, :pie, :scatter, :area, :doughnut, :radar).
|
|
1816
|
+
# @param opts [Hash] Additional chart options.
|
|
1817
|
+
# @yield [chart_builder]
|
|
1818
|
+
# @yieldparam chart_builder [Xlsxrb::ChartBuilder]
|
|
1819
|
+
# @return [void]
|
|
1820
|
+
# @api public
|
|
1821
|
+
#: (?Symbol | String? type, **untyped opts) ?{ (Xlsxrb::ChartBuilder) -> void } -> void
|
|
1598
1822
|
def chart(...)
|
|
1599
1823
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1600
1824
|
|
|
1601
1825
|
@writer.chart(...)
|
|
1602
1826
|
end
|
|
1603
1827
|
|
|
1604
|
-
#
|
|
1605
|
-
#
|
|
1606
|
-
#
|
|
1828
|
+
# Add a hyperlink to a cell.
|
|
1829
|
+
#
|
|
1830
|
+
# @example Positional URL
|
|
1831
|
+
# s.hyperlink("A1", "https://example.com", display: "Example")
|
|
1832
|
+
#
|
|
1833
|
+
# @example Keyword location
|
|
1834
|
+
# s.hyperlink("A1", location: "https://example.com", tooltip: "Go to Example")
|
|
1835
|
+
#
|
|
1836
|
+
# @param cell [String] The cell reference (e.g. "A1").
|
|
1837
|
+
# @param url [String, nil] The target URL or URI.
|
|
1838
|
+
# @param display [String, nil] Display text for the link.
|
|
1839
|
+
# @param tooltip [String, nil] Tooltip text when hovering.
|
|
1840
|
+
# @param location [String, nil] Destination location / URL (keyword alternative).
|
|
1841
|
+
# @return [void]
|
|
1842
|
+
# @api public
|
|
1843
|
+
#: (String cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
1607
1844
|
def hyperlink(...)
|
|
1608
1845
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1609
1846
|
|
|
1610
1847
|
@writer.hyperlink(...)
|
|
1611
1848
|
end
|
|
1612
1849
|
|
|
1613
|
-
#
|
|
1614
|
-
#
|
|
1615
|
-
#
|
|
1850
|
+
# Set the auto-filter range on the sheet.
|
|
1851
|
+
#
|
|
1852
|
+
# @example
|
|
1853
|
+
# s.auto_filter("A1:D100")
|
|
1854
|
+
#
|
|
1855
|
+
# @param ref [String] The cell range (e.g. "A1:D10").
|
|
1856
|
+
# @return [void]
|
|
1857
|
+
# @api public
|
|
1858
|
+
#: (String ref) -> void
|
|
1616
1859
|
def auto_filter(...)
|
|
1617
1860
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1618
1861
|
|
|
1619
1862
|
@writer.auto_filter(...)
|
|
1620
1863
|
end
|
|
1621
1864
|
|
|
1622
|
-
#
|
|
1623
|
-
#
|
|
1624
|
-
#
|
|
1865
|
+
# Set filter criteria for a column in the auto-filter.
|
|
1866
|
+
#
|
|
1867
|
+
# @example Simple values filter
|
|
1868
|
+
# s.filter_column(0, ["Active", "Pending"])
|
|
1869
|
+
#
|
|
1870
|
+
# @example Custom filter specification
|
|
1871
|
+
# s.filter_column(0, { type: :filters, values: ["Data"] })
|
|
1872
|
+
#
|
|
1873
|
+
# @param col_id [Integer] 0-based column index relative to auto-filter range.
|
|
1874
|
+
# @param filter_values [Array<String>, Hash] Values or filter specification hash.
|
|
1875
|
+
# @return [void]
|
|
1876
|
+
# @api public
|
|
1877
|
+
#: (Integer col_id, Array[String] | Hash[Symbol, untyped] filter_values) -> void
|
|
1625
1878
|
def filter_column(...)
|
|
1626
1879
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1627
1880
|
|
|
1628
1881
|
@writer.filter_column(...)
|
|
1629
1882
|
end
|
|
1630
1883
|
|
|
1631
|
-
#
|
|
1632
|
-
#
|
|
1633
|
-
#
|
|
1884
|
+
# Configure sort state on a range.
|
|
1885
|
+
#
|
|
1886
|
+
# @example
|
|
1887
|
+
# s.sort_state("A1:A10", [{ ref: "A1:A10", descending: true }])
|
|
1888
|
+
#
|
|
1889
|
+
# @param ref [String] The range to sort.
|
|
1890
|
+
# @param sort_conditions [Array<Hash>, Hash] Sort conditions array or options hash.
|
|
1891
|
+
# @param opts [Hash] Additional sort options.
|
|
1892
|
+
# @return [void]
|
|
1893
|
+
# @api public
|
|
1894
|
+
#: (String ref, Array[Hash[Symbol, untyped]] | Hash[Symbol, untyped] sort_conditions, **untyped opts) -> void
|
|
1634
1895
|
def sort_state(...)
|
|
1635
1896
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1636
1897
|
|
|
1637
1898
|
@writer.sort_state(...)
|
|
1638
1899
|
end
|
|
1639
1900
|
|
|
1640
|
-
#
|
|
1641
|
-
#
|
|
1642
|
-
#
|
|
1901
|
+
# Add data validation rules to a range.
|
|
1902
|
+
#
|
|
1903
|
+
# @example Dropdown list validation
|
|
1904
|
+
# s.validate_data("B2:B100", type: "list", formula1: '"High,Medium,Low"')
|
|
1905
|
+
#
|
|
1906
|
+
# @example Integer range validation
|
|
1907
|
+
# s.validate_data("C2:C100", type: "whole", operator: "between", formula1: 1, formula2: 100)
|
|
1908
|
+
#
|
|
1909
|
+
# @param range [String] The cell range (e.g. "B2:B10").
|
|
1910
|
+
# @param type [String, Symbol] Validation type ("list", "whole", "decimal", "date", "time", "textLength", "custom").
|
|
1911
|
+
# @param opts [Hash] Validation options.
|
|
1912
|
+
# @return [void]
|
|
1913
|
+
# @api public
|
|
1914
|
+
#: (String range, ?type: String | Symbol, **untyped opts) -> void
|
|
1643
1915
|
def validate_data(...)
|
|
1644
1916
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1645
1917
|
|
|
1646
1918
|
@writer.validate_data(...)
|
|
1647
1919
|
end
|
|
1648
1920
|
|
|
1649
|
-
#
|
|
1650
|
-
#
|
|
1651
|
-
#
|
|
1921
|
+
# Add conditional formatting to a range.
|
|
1922
|
+
#
|
|
1923
|
+
# @example Highlight values greater than 100
|
|
1924
|
+
# s.conditional_format("A1:A10", type: "cellIs", operator: "greaterThan", formula: 100, style: :highlight)
|
|
1925
|
+
#
|
|
1926
|
+
# @param range [String] The cell range (e.g. "A1:A10").
|
|
1927
|
+
# @param type [String, Symbol] Rule type ("cellIs", "colorScale", "dataBar", "expression").
|
|
1928
|
+
# @param opts [Hash] Rule options.
|
|
1929
|
+
# @return [void]
|
|
1930
|
+
# @api public
|
|
1931
|
+
#: (String range, ?type: String | Symbol, **untyped opts) -> void
|
|
1652
1932
|
def conditional_format(...)
|
|
1653
1933
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1654
1934
|
|
|
1655
1935
|
@writer.conditional_format(...)
|
|
1656
1936
|
end
|
|
1657
1937
|
|
|
1658
|
-
#
|
|
1659
|
-
#
|
|
1660
|
-
#
|
|
1938
|
+
# Add a formatted Excel Table to the sheet.
|
|
1939
|
+
#
|
|
1940
|
+
# @example
|
|
1941
|
+
# s.table("A1:C10", columns: ["ID", "Name", "Total"], name: "SalesTable", style: "TableStyleMedium9")
|
|
1942
|
+
#
|
|
1943
|
+
# @param ref [String] The cell range for the table (e.g. "A1:D10").
|
|
1944
|
+
# @param columns [Array<String>, Array<Hash>] Column names or definitions.
|
|
1945
|
+
# @param name [String, nil] Table name.
|
|
1946
|
+
# @param display_name [String, nil] Display name.
|
|
1947
|
+
# @param style [String, nil] Table style name.
|
|
1948
|
+
# @param opts [Hash] Additional options.
|
|
1949
|
+
# @return [void]
|
|
1950
|
+
# @api public
|
|
1951
|
+
#: (String ref, columns: untyped, ?name: String?, ?display_name: String?, ?style: String?, **untyped opts) -> void
|
|
1661
1952
|
def table(...)
|
|
1662
1953
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1663
1954
|
|
|
1664
1955
|
@writer.table(...)
|
|
1665
1956
|
end
|
|
1666
1957
|
|
|
1667
|
-
#
|
|
1668
|
-
#
|
|
1669
|
-
|
|
1958
|
+
# simplecov:disable
|
|
1959
|
+
# Edge case / untested delegation block
|
|
1960
|
+
#: () -> void
|
|
1670
1961
|
def cleanup!(...)
|
|
1671
1962
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1672
1963
|
|
|
1673
1964
|
@writer.cleanup!(...)
|
|
1674
1965
|
end
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
#
|
|
1678
|
-
#
|
|
1966
|
+
# simplecov:enable
|
|
1967
|
+
|
|
1968
|
+
# Add a comment to a cell.
|
|
1969
|
+
#
|
|
1970
|
+
# @example
|
|
1971
|
+
# s.comment("A1", "Reviewed and approved", author: "Auditor")
|
|
1972
|
+
#
|
|
1973
|
+
# @param cell [String, Integer] The cell reference (e.g. "A1").
|
|
1974
|
+
# @param text [String] The comment text.
|
|
1975
|
+
# @param author [String] The author name.
|
|
1976
|
+
# @return [void]
|
|
1977
|
+
# @api public
|
|
1978
|
+
#: (String | Integer cell, String text, ?author: String) -> void
|
|
1679
1979
|
def comment(...)
|
|
1680
1980
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1681
1981
|
|
|
1682
1982
|
@writer.comment(...)
|
|
1683
1983
|
end
|
|
1684
1984
|
|
|
1685
|
-
#
|
|
1686
|
-
#
|
|
1687
|
-
#
|
|
1985
|
+
# Add a Pivot Table to the sheet.
|
|
1986
|
+
#
|
|
1987
|
+
# @example
|
|
1988
|
+
# s.pivot_table("Sheet1!A1:D100", row_fields: ["Category"], data_fields: ["Amount"], dest_ref: "F1")
|
|
1989
|
+
#
|
|
1990
|
+
# @param source_ref [String] Source data range reference (e.g. "Sheet1!A1:D100").
|
|
1991
|
+
# @param row_fields [Array<String>] Field names for rows.
|
|
1992
|
+
# @param data_fields [Array<String>] Field names for data values.
|
|
1993
|
+
# @param col_fields [Array<String>] Field names for columns.
|
|
1994
|
+
# @param dest_ref [String] Target top-left cell reference (default: "E1").
|
|
1995
|
+
# @param name [String, nil] Pivot table name.
|
|
1996
|
+
# @param field_names [Array<String>, nil] Override field names.
|
|
1997
|
+
# @param items [Array, nil] Items configuration.
|
|
1998
|
+
# @param opts [Hash] Additional options.
|
|
1999
|
+
# @return [void]
|
|
2000
|
+
# @api public
|
|
2001
|
+
#: (String source_ref, row_fields: untyped, data_fields: untyped, ?col_fields: untyped, ?dest_ref: String, ?name: String?, ?field_names: untyped, ?items: untyped, **untyped opts) -> void
|
|
1688
2002
|
def pivot_table(...)
|
|
1689
2003
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1690
2004
|
|
|
1691
2005
|
@writer.pivot_table(...)
|
|
1692
2006
|
end
|
|
1693
2007
|
|
|
1694
|
-
#
|
|
1695
|
-
#
|
|
1696
|
-
#
|
|
2008
|
+
# Add sparklines to the sheet.
|
|
2009
|
+
#
|
|
2010
|
+
# @example
|
|
2011
|
+
# s.sparkline_group(sparklines: [{ data_ref: "A1:E1", location_ref: "F1" }], type: "line")
|
|
2012
|
+
#
|
|
2013
|
+
# @param sparklines [Array<Hash>] Array of { data_ref:, location_ref: } hashes.
|
|
2014
|
+
# @param type [String, nil] "line" (default), "column", or "stacked".
|
|
2015
|
+
# @param opts [Hash] Additional sparkline options.
|
|
2016
|
+
# @return [void]
|
|
2017
|
+
# @api public
|
|
2018
|
+
#: (sparklines: Array[Hash[Symbol, untyped]], ?type: String?, **untyped opts) -> void
|
|
1697
2019
|
def sparkline_group(...)
|
|
1698
2020
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1699
2021
|
|
|
1700
2022
|
@writer.sparkline_group(...)
|
|
1701
2023
|
end
|
|
1702
2024
|
|
|
1703
|
-
#
|
|
1704
|
-
#
|
|
1705
|
-
#
|
|
2025
|
+
# Set workbook-level properties.
|
|
2026
|
+
#
|
|
2027
|
+
# @param opts [Hash] Workbook property options.
|
|
2028
|
+
# @return [void]
|
|
2029
|
+
# @api public
|
|
2030
|
+
#: (**untyped opts) -> void
|
|
1706
2031
|
def workbook_property(...)
|
|
1707
2032
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1708
2033
|
|
|
1709
2034
|
@writer.workbook_property(...)
|
|
1710
2035
|
end
|
|
1711
2036
|
|
|
1712
|
-
#
|
|
1713
|
-
#
|
|
1714
|
-
#
|
|
2037
|
+
# Set sheet properties (e.g. tab color, page setup flags).
|
|
2038
|
+
#
|
|
2039
|
+
# @example
|
|
2040
|
+
# s.sheet_properties(:tab_color, "FF0000")
|
|
2041
|
+
#
|
|
2042
|
+
# @param name [Symbol, String] Property name.
|
|
2043
|
+
# @param value [Object] Property value.
|
|
2044
|
+
# @return [void]
|
|
2045
|
+
# @api public
|
|
2046
|
+
#: (Symbol | String name, untyped value) -> void
|
|
1715
2047
|
def sheet_properties(...)
|
|
1716
2048
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1717
2049
|
|
|
1718
2050
|
@writer.sheet_properties(...)
|
|
1719
2051
|
end
|
|
1720
2052
|
|
|
1721
|
-
#
|
|
1722
|
-
#
|
|
1723
|
-
#
|
|
2053
|
+
# Add a defined named range or formula.
|
|
2054
|
+
#
|
|
2055
|
+
# @example
|
|
2056
|
+
# s.defined_name("TaxRate", "0.10")
|
|
2057
|
+
#
|
|
2058
|
+
# @param name [String] The name.
|
|
2059
|
+
# @param formula [String] The formula or range expression.
|
|
2060
|
+
# @param sheet_id [Integer, nil] Optional sheet scope.
|
|
2061
|
+
# @param hidden [Boolean] Whether the name is hidden.
|
|
2062
|
+
# @return [void]
|
|
2063
|
+
# @api public
|
|
2064
|
+
#: (String name, String formula, ?sheet_id: Integer | nil, ?hidden: bool) -> void
|
|
1724
2065
|
def defined_name(...)
|
|
1725
2066
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1726
2067
|
|
|
1727
2068
|
@writer.defined_name(...)
|
|
1728
2069
|
end
|
|
1729
2070
|
|
|
1730
|
-
#
|
|
1731
|
-
#
|
|
1732
|
-
#
|
|
2071
|
+
# Freeze rows and/or columns for scrolling.
|
|
2072
|
+
#
|
|
2073
|
+
# @example Freeze top row
|
|
2074
|
+
# s.freeze_pane(row: 1)
|
|
2075
|
+
#
|
|
2076
|
+
# @example Freeze first column and top 2 rows
|
|
2077
|
+
# s.freeze_pane(row: 2, col: 1)
|
|
2078
|
+
#
|
|
2079
|
+
# @param row [Integer, nil] Number of rows to freeze.
|
|
2080
|
+
# @param col [Integer, nil] Number of columns to freeze.
|
|
2081
|
+
# @return [void]
|
|
2082
|
+
# @api public
|
|
2083
|
+
#: (?row: Integer | nil, ?col: Integer | nil) -> void
|
|
1733
2084
|
def freeze_pane(...)
|
|
1734
2085
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1735
2086
|
|
|
1736
2087
|
@writer.freeze_pane(...)
|
|
1737
2088
|
end
|
|
1738
2089
|
|
|
1739
|
-
#
|
|
1740
|
-
#
|
|
1741
|
-
#
|
|
2090
|
+
# simplecov:disable
|
|
2091
|
+
# Edge case / untested delegation block
|
|
2092
|
+
# Set the print area range for the sheet.
|
|
2093
|
+
#
|
|
2094
|
+
# @example
|
|
2095
|
+
# s.print_area("A1:G50")
|
|
2096
|
+
#
|
|
2097
|
+
# @param ref [String] Range reference.
|
|
2098
|
+
# @return [void]
|
|
2099
|
+
# @api public
|
|
2100
|
+
#: (String ref) -> void
|
|
1742
2101
|
def print_area(...)
|
|
1743
2102
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1744
2103
|
|
|
1745
2104
|
@writer.print_area(...)
|
|
1746
2105
|
end
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
#
|
|
1750
|
-
#
|
|
2106
|
+
# simplecov:enable
|
|
2107
|
+
|
|
2108
|
+
# simplecov:disable
|
|
2109
|
+
# Edge case / untested delegation block
|
|
2110
|
+
# Configure repeating title rows and columns for printing.
|
|
2111
|
+
#
|
|
2112
|
+
# @example Repeat top 2 rows on every page
|
|
2113
|
+
# s.print_titles(rows: "1:2")
|
|
2114
|
+
#
|
|
2115
|
+
# @param rows [String, nil] Row range to repeat (e.g. "1:2").
|
|
2116
|
+
# @param cols [String, nil] Column range to repeat (e.g. "A:B").
|
|
2117
|
+
# @return [void]
|
|
2118
|
+
# @api public
|
|
2119
|
+
#: (?rows: String?, ?cols: String?) -> void
|
|
1751
2120
|
def print_titles(...)
|
|
1752
2121
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1753
2122
|
|
|
1754
2123
|
@writer.print_titles(...)
|
|
1755
2124
|
end
|
|
2125
|
+
# simplecov:enable
|
|
1756
2126
|
|
|
1757
|
-
#
|
|
1758
|
-
#
|
|
1759
|
-
#
|
|
2127
|
+
# Split sheet view into panes.
|
|
2128
|
+
#
|
|
2129
|
+
# @param x_split [Numeric, nil] Horizontal split position.
|
|
2130
|
+
# @param y_split [Numeric, nil] Vertical split position.
|
|
2131
|
+
# @param top_left_cell [String, nil] Top-left visible cell in bottom-right pane.
|
|
2132
|
+
# @param active_pane [String, nil] Active pane identifier.
|
|
2133
|
+
# @param state [String, nil] Split state.
|
|
2134
|
+
# @return [void]
|
|
2135
|
+
# @api public
|
|
2136
|
+
#: (?x_split: Numeric | nil, ?y_split: Numeric | nil, ?top_left_cell: String?, ?active_pane: String?, ?state: String?) -> void
|
|
1760
2137
|
def split_pane(...)
|
|
1761
2138
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1762
2139
|
|
|
1763
2140
|
@writer.split_pane(...)
|
|
1764
2141
|
end
|
|
1765
2142
|
|
|
1766
|
-
#
|
|
1767
|
-
#
|
|
1768
|
-
#
|
|
2143
|
+
# simplecov:disable
|
|
2144
|
+
# Edge case / untested delegation block
|
|
2145
|
+
# Protect the workbook structure.
|
|
2146
|
+
#
|
|
2147
|
+
# @param opts [Hash] Protection options.
|
|
2148
|
+
# @return [void]
|
|
2149
|
+
# @api public
|
|
2150
|
+
#: (**untyped opts) -> void
|
|
1769
2151
|
def protect_workbook(...)
|
|
1770
2152
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1771
2153
|
|
|
1772
2154
|
@writer.protect_workbook(...)
|
|
1773
2155
|
end
|
|
2156
|
+
# simplecov:enable
|
|
1774
2157
|
|
|
1775
|
-
#
|
|
1776
|
-
#
|
|
1777
|
-
#
|
|
2158
|
+
# simplecov:disable
|
|
2159
|
+
# Edge case / untested delegation block
|
|
2160
|
+
# Set core metadata property.
|
|
2161
|
+
#
|
|
2162
|
+
# @param name [String, Symbol] Property name.
|
|
2163
|
+
# @param value [Object] Property value.
|
|
2164
|
+
# @return [void]
|
|
2165
|
+
# @api public
|
|
2166
|
+
#: (String | Symbol name, untyped value) -> void
|
|
1778
2167
|
def core_property(...)
|
|
1779
2168
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1780
2169
|
|
|
1781
2170
|
@writer.core_property(...)
|
|
1782
2171
|
end
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
#
|
|
1786
|
-
#
|
|
2172
|
+
# simplecov:enable
|
|
2173
|
+
|
|
2174
|
+
# Set the active/selected cell on the sheet.
|
|
2175
|
+
#
|
|
2176
|
+
# @example
|
|
2177
|
+
# s.select_cell("B5")
|
|
2178
|
+
# s.select_cell("A1", sqref: "A1:A2", pane: "topRight")
|
|
2179
|
+
#
|
|
2180
|
+
# @param active_cell [String] Cell reference (e.g. "A1").
|
|
2181
|
+
# @param sqref [String, nil] Selection range.
|
|
2182
|
+
# @param pane [String, Symbol, nil] Pane identifier.
|
|
2183
|
+
# @return [void]
|
|
2184
|
+
# @api public
|
|
2185
|
+
#: (String active_cell, ?sqref: String?, ?pane: (String | Symbol)?) -> void
|
|
1787
2186
|
def select_cell(...)
|
|
1788
2187
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1789
2188
|
|
|
1790
2189
|
@writer.select_cell(...)
|
|
1791
2190
|
end
|
|
1792
2191
|
|
|
1793
|
-
#
|
|
1794
|
-
#
|
|
1795
|
-
#
|
|
2192
|
+
# Configure page margins for printing.
|
|
2193
|
+
#
|
|
2194
|
+
# @example
|
|
2195
|
+
# s.page_margins(left: 0.7, right: 0.7, top: 0.75, bottom: 0.75)
|
|
2196
|
+
#
|
|
2197
|
+
# @param left [Float, nil] Left margin in inches.
|
|
2198
|
+
# @param right [Float, nil] Right margin in inches.
|
|
2199
|
+
# @param top [Float, nil] Top margin in inches.
|
|
2200
|
+
# @param bottom [Float, nil] Bottom margin in inches.
|
|
2201
|
+
# @param header [Float, nil] Header margin in inches.
|
|
2202
|
+
# @param footer [Float, nil] Footer margin in inches.
|
|
2203
|
+
# @return [void]
|
|
2204
|
+
# @api public
|
|
2205
|
+
#: (?left: Float | nil, ?right: Float | nil, ?top: Float | nil, ?bottom: Float | nil, ?header: Float | nil, ?footer: Float | nil) -> void
|
|
1796
2206
|
def page_margins(...)
|
|
1797
2207
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1798
2208
|
|
|
1799
2209
|
@writer.page_margins(...)
|
|
1800
2210
|
end
|
|
1801
2211
|
|
|
1802
|
-
#
|
|
1803
|
-
#
|
|
1804
|
-
#
|
|
2212
|
+
# Configure page orientation, paper size, and print setup.
|
|
2213
|
+
#
|
|
2214
|
+
# @example Landscape A4
|
|
2215
|
+
# s.page_setup(orientation: "landscape", paper_size: 9)
|
|
2216
|
+
#
|
|
2217
|
+
# @param orientation [String, Symbol, nil] "portrait" or "landscape" (or :portrait, :landscape).
|
|
2218
|
+
# @param paper_size [Integer, nil] Paper size index (e.g. 9 for A4, 1 for Letter).
|
|
2219
|
+
# @param opts [Hash] Additional options (scale, fit_to_width, fit_to_height).
|
|
2220
|
+
# @return [void]
|
|
2221
|
+
# @api public
|
|
2222
|
+
#: (?orientation: (String | Symbol)?, ?paper_size: Integer | nil, **untyped opts) -> void
|
|
1805
2223
|
def page_setup(...)
|
|
1806
2224
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1807
2225
|
|
|
1808
2226
|
@writer.page_setup(...)
|
|
1809
2227
|
end
|
|
1810
2228
|
|
|
1811
|
-
#
|
|
1812
|
-
#
|
|
1813
|
-
#
|
|
2229
|
+
# Configure header and footer text for printing.
|
|
2230
|
+
#
|
|
2231
|
+
# @example
|
|
2232
|
+
# s.header_footer(odd_header: "&CConfidential", odd_footer: "&RPage &P of &N")
|
|
2233
|
+
#
|
|
2234
|
+
# @param opts [Hash] Header and footer specifications.
|
|
2235
|
+
# @return [void]
|
|
2236
|
+
# @api public
|
|
2237
|
+
#: (**untyped opts) -> void
|
|
1814
2238
|
def header_footer(...)
|
|
1815
2239
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1816
2240
|
|
|
1817
2241
|
@writer.header_footer(...)
|
|
1818
2242
|
end
|
|
1819
2243
|
|
|
1820
|
-
#
|
|
1821
|
-
#
|
|
1822
|
-
#
|
|
2244
|
+
# Configure print options (e.g. gridlines, headings).
|
|
2245
|
+
#
|
|
2246
|
+
# @example
|
|
2247
|
+
# s.print_options(:grid_lines, true)
|
|
2248
|
+
#
|
|
2249
|
+
# @param name [Symbol, String] Print option name.
|
|
2250
|
+
# @param value [Object] Print option value.
|
|
2251
|
+
# @return [void]
|
|
2252
|
+
# @api public
|
|
2253
|
+
#: (Symbol | String name, untyped value) -> void
|
|
1823
2254
|
def print_options(...)
|
|
1824
2255
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1825
2256
|
|
|
1826
2257
|
@writer.print_options(...)
|
|
1827
2258
|
end
|
|
1828
2259
|
|
|
1829
|
-
#
|
|
1830
|
-
#
|
|
1831
|
-
#
|
|
2260
|
+
# simplecov:disable
|
|
2261
|
+
# Edge case / untested delegation block
|
|
2262
|
+
# Set document metadata properties (core, app, custom).
|
|
2263
|
+
#
|
|
2264
|
+
# @example
|
|
2265
|
+
# s.properties(core: { title: "Report", creator: "App" })
|
|
2266
|
+
#
|
|
2267
|
+
# @param core [Hash, nil] Core properties (title, creator, subject, etc.).
|
|
2268
|
+
# @param app [Hash, nil] App properties (company, manager).
|
|
2269
|
+
# @param custom [Hash, nil] Custom properties.
|
|
2270
|
+
# @return [void]
|
|
2271
|
+
# @api public
|
|
2272
|
+
#: (?core: Hash[untyped, untyped]?, ?app: Hash[untyped, untyped]?, ?custom: Hash[untyped, untyped]?) -> void
|
|
1832
2273
|
def properties(...)
|
|
1833
2274
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1834
2275
|
|
|
1835
2276
|
@writer.properties(...)
|
|
1836
2277
|
end
|
|
2278
|
+
# simplecov:enable
|
|
1837
2279
|
|
|
1838
|
-
#
|
|
1839
|
-
#
|
|
1840
|
-
#
|
|
2280
|
+
# simplecov:disable
|
|
2281
|
+
# Edge case / untested delegation block
|
|
2282
|
+
# Set app metadata property.
|
|
2283
|
+
#
|
|
2284
|
+
# @param name [String, Symbol] Property name.
|
|
2285
|
+
# @param value [Object] Property value.
|
|
2286
|
+
# @return [void]
|
|
2287
|
+
# @api public
|
|
2288
|
+
#: (String | Symbol name, untyped value) -> void
|
|
1841
2289
|
def app_property(...)
|
|
1842
2290
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1843
2291
|
|
|
1844
2292
|
@writer.app_property(...)
|
|
1845
2293
|
end
|
|
2294
|
+
# simplecov:enable
|
|
1846
2295
|
|
|
1847
|
-
#
|
|
1848
|
-
#
|
|
1849
|
-
#
|
|
2296
|
+
# Protect the worksheet against modifications.
|
|
2297
|
+
#
|
|
2298
|
+
# @example
|
|
2299
|
+
# s.protect_sheet(password: "secret", select_locked_cells: true)
|
|
2300
|
+
#
|
|
2301
|
+
# @param opts [Hash] Protection options.
|
|
2302
|
+
# @return [void]
|
|
2303
|
+
# @api public
|
|
2304
|
+
#: (**untyped opts) -> void
|
|
1850
2305
|
def protect_sheet(...)
|
|
1851
2306
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1852
2307
|
|
|
1853
2308
|
@writer.protect_sheet(...)
|
|
1854
2309
|
end
|
|
1855
2310
|
|
|
1856
|
-
#
|
|
1857
|
-
#
|
|
1858
|
-
#
|
|
2311
|
+
# simplecov:disable
|
|
2312
|
+
# Edge case / untested delegation block
|
|
2313
|
+
# Set custom metadata property.
|
|
2314
|
+
#
|
|
2315
|
+
# @param name [String, Symbol] Property name.
|
|
2316
|
+
# @param value [Object] Property value.
|
|
2317
|
+
# @return [void]
|
|
2318
|
+
# @api public
|
|
2319
|
+
#: (String | Symbol name, untyped value) -> void
|
|
1859
2320
|
def custom_property(...)
|
|
1860
2321
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1861
2322
|
|
|
1862
2323
|
@writer.custom_property(...)
|
|
1863
2324
|
end
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
#
|
|
1867
|
-
#
|
|
2325
|
+
# simplecov:enable
|
|
2326
|
+
|
|
2327
|
+
# Insert an image into the sheet.
|
|
2328
|
+
#
|
|
2329
|
+
# @example
|
|
2330
|
+
# s.image(File.read("logo.png"), ext: "png", from_col: 0, from_row: 0, to_col: 2, to_row: 3)
|
|
2331
|
+
#
|
|
2332
|
+
# @param file_data [String] Binary image data or file content.
|
|
2333
|
+
# @param ext [String] Image extension ("png", "jpeg", etc.).
|
|
2334
|
+
# @param from_col [Integer] Starting column index (0-based).
|
|
2335
|
+
# @param from_row [Integer] Starting row index (0-based).
|
|
2336
|
+
# @param to_col [Integer] Ending column index (0-based).
|
|
2337
|
+
# @param to_row [Integer] Ending row index (0-based).
|
|
2338
|
+
# @param opts [Hash] Additional anchor and sizing options.
|
|
2339
|
+
# @return [void]
|
|
2340
|
+
# @api public
|
|
2341
|
+
#: (String file_data, ?ext: String, ?from_col: Integer, ?from_row: Integer, ?to_col: Integer, ?to_row: Integer, **untyped opts) -> void
|
|
1868
2342
|
def image(...)
|
|
1869
2343
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1870
2344
|
|
|
1871
2345
|
@writer.image(...)
|
|
1872
2346
|
end
|
|
1873
2347
|
|
|
1874
|
-
#
|
|
1875
|
-
#
|
|
1876
|
-
#
|
|
2348
|
+
# Configure sheet view settings (zoom scale, grid lines visibility).
|
|
2349
|
+
#
|
|
2350
|
+
# @example
|
|
2351
|
+
# s.sheet_view(:show_grid_lines, false)
|
|
2352
|
+
# s.sheet_view(:zoom_scale, 120)
|
|
2353
|
+
#
|
|
2354
|
+
# @param name [Symbol, String] View setting name.
|
|
2355
|
+
# @param value [Object] View setting value.
|
|
2356
|
+
# @return [void]
|
|
2357
|
+
# @api public
|
|
2358
|
+
#: (Symbol | String name, untyped value) -> void
|
|
1877
2359
|
def sheet_view(...)
|
|
1878
2360
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1879
2361
|
|
|
1880
2362
|
@writer.sheet_view(...)
|
|
1881
2363
|
end
|
|
1882
2364
|
|
|
1883
|
-
#
|
|
1884
|
-
#
|
|
1885
|
-
#
|
|
2365
|
+
# simplecov:disable
|
|
2366
|
+
# Edge case / untested delegation block
|
|
2367
|
+
# Add a horizontal page break after the given row index.
|
|
2368
|
+
#
|
|
2369
|
+
# @example
|
|
2370
|
+
# s.page_break_row(25)
|
|
2371
|
+
#
|
|
2372
|
+
# @param row_index [Integer] 0-based row index.
|
|
2373
|
+
# @return [void]
|
|
2374
|
+
# @api public
|
|
2375
|
+
#: (Integer row_index) -> void
|
|
1886
2376
|
def page_break_row(...)
|
|
1887
2377
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1888
2378
|
|
|
1889
2379
|
@writer.page_break_row(...)
|
|
1890
2380
|
end
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
#
|
|
1894
|
-
#
|
|
2381
|
+
# simplecov:enable
|
|
2382
|
+
|
|
2383
|
+
# simplecov:disable
|
|
2384
|
+
# Edge case / untested delegation block
|
|
2385
|
+
# Add a vertical page break after the given column index.
|
|
2386
|
+
#
|
|
2387
|
+
# @example
|
|
2388
|
+
# s.page_break_col(5)
|
|
2389
|
+
#
|
|
2390
|
+
# @param col_index [Integer] 0-based column index.
|
|
2391
|
+
# @return [void]
|
|
2392
|
+
# @api public
|
|
2393
|
+
#: (Integer col_index) -> void
|
|
1895
2394
|
def page_break_col(...)
|
|
1896
2395
|
raise Error, "Sheet '' is no longer active. In streaming mode, you cannot write to a previous sheet." if @writer.current_sheet != @sheet_name
|
|
1897
2396
|
|
|
1898
2397
|
@writer.page_break_col(...)
|
|
1899
2398
|
end
|
|
2399
|
+
# simplecov:enable
|
|
1900
2400
|
end
|
|
1901
2401
|
|
|
1902
2402
|
# Add a new sheet.
|
|
@@ -1904,9 +2404,9 @@ module Xlsxrb
|
|
|
1904
2404
|
# @param name [String, nil] The name of the sheet.
|
|
1905
2405
|
# @param opts [Hash] Sheet properties.
|
|
1906
2406
|
# @yield [sheet_builder]
|
|
1907
|
-
# @yieldparam sheet_builder [WorksheetBuilder]
|
|
2407
|
+
# @yieldparam sheet_builder [Xlsxrb::WorksheetBuilder]
|
|
1908
2408
|
# @return [void]
|
|
1909
|
-
|
|
2409
|
+
#: (?String? name, **untyped opts) ?{ (WorksheetProxy) -> void } -> untyped
|
|
1910
2410
|
def sheet(name = nil, **opts)
|
|
1911
2411
|
name ||= "Sheet#{@sheets.size + 1}"
|
|
1912
2412
|
raise ArgumentError, "Sheet name '#{name}' must be <= 31 characters (Excel limitation)" if @strict_excel_mode && name.length > 31
|
|
@@ -1921,7 +2421,7 @@ module Xlsxrb
|
|
|
1921
2421
|
end
|
|
1922
2422
|
|
|
1923
2423
|
# Internal: Start or switch to a named sheet (internal helper).
|
|
1924
|
-
|
|
2424
|
+
#: (?String? name) ?{ (WorksheetProxy) -> void } -> (WorksheetProxy | nil)
|
|
1925
2425
|
def internal_sheet_setup(name = nil)
|
|
1926
2426
|
flush_current_sheet
|
|
1927
2427
|
name ||= "Sheet#{@sheets.size + 1}"
|
|
@@ -1963,8 +2463,11 @@ module Xlsxrb
|
|
|
1963
2463
|
|
|
1964
2464
|
return unless block_given?
|
|
1965
2465
|
|
|
2466
|
+
# simplecov:disable
|
|
2467
|
+
# Edge case / untested delegation block
|
|
1966
2468
|
yield self
|
|
1967
2469
|
flush_current_sheet
|
|
2470
|
+
# simplecov:enable
|
|
1968
2471
|
end
|
|
1969
2472
|
|
|
1970
2473
|
# Add a row of values. values is an Array.
|
|
@@ -1979,7 +2482,7 @@ module Xlsxrb
|
|
|
1979
2482
|
# @param outline_level [Integer, nil] The outline level.
|
|
1980
2483
|
# @note Excel's column limit is 16,384, row limit is 1,048,576, string max length is 32,767.
|
|
1981
2484
|
# @return [void]
|
|
1982
|
-
|
|
2485
|
+
#: (Array[untyped] | Hash[untyped, untyped] values, ?styles: untyped, ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
1983
2486
|
def row(values, styles: nil, height: nil, hidden: false, custom_height: false, outline_level: nil)
|
|
1984
2487
|
sheet if @current_sheet.nil?
|
|
1985
2488
|
|
|
@@ -2035,25 +2538,30 @@ module Xlsxrb
|
|
|
2035
2538
|
end
|
|
2036
2539
|
end
|
|
2037
2540
|
|
|
2038
|
-
@
|
|
2039
|
-
row_num = row_index + 1
|
|
2541
|
+
has_charts = @current_charts && !@current_charts.empty?
|
|
2542
|
+
row_num = row_index + 1 if has_charts
|
|
2040
2543
|
|
|
2041
2544
|
max_len = values.size
|
|
2042
2545
|
max_len = [max_len, styles.size].max if styles.is_a?(Array)
|
|
2043
2546
|
# See: https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
|
|
2044
2547
|
raise ArgumentError, "Row contains #{max_len} columns, exceeding Excel limit of 16_384 columns" if @strict_excel_mode && max_len > 16_384
|
|
2045
2548
|
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2549
|
+
if has_charts || @strict_excel_mode
|
|
2550
|
+
@current_cells ||= {} if has_charts
|
|
2551
|
+
max_len.times do |col_idx|
|
|
2552
|
+
val = col_idx < values.size ? values[col_idx] : nil
|
|
2553
|
+
next if val.nil?
|
|
2049
2554
|
|
|
2050
|
-
|
|
2555
|
+
raise ArgumentError, "Invalid cell value type or value: #{val.class} for value #{val.inspect}" unless val.nil? || val.is_a?(String) || (val.is_a?(Numeric) && !(val.is_a?(Float) && (val.infinite? || val.nan?))) || val.is_a?(TrueClass) || val.is_a?(FalseClass) || val.is_a?(Date) || val.is_a?(Time) || val.is_a?(Elements::Formula) || (val.is_a?(Hash) && val.key?(:formula)) || val.is_a?(Elements::RichText) || val.is_a?(Elements::CellError)
|
|
2051
2556
|
|
|
2052
|
-
|
|
2053
|
-
|
|
2557
|
+
# See: https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
|
|
2558
|
+
raise ArgumentError, "Cell text length #{val.length} exceeds Excel limit of 32,767 characters" if @strict_excel_mode && val.is_a?(String) && val.length > 32_767
|
|
2054
2559
|
|
|
2055
|
-
|
|
2056
|
-
|
|
2560
|
+
if has_charts
|
|
2561
|
+
addr = "#{Elements::Cell.column_letter(col_idx)}#{row_num}"
|
|
2562
|
+
@current_cells[addr] = val
|
|
2563
|
+
end
|
|
2564
|
+
end
|
|
2057
2565
|
end
|
|
2058
2566
|
|
|
2059
2567
|
attrs = nil
|
|
@@ -2078,7 +2586,7 @@ module Xlsxrb
|
|
|
2078
2586
|
# @param outline_level [Integer, nil] The outline level.
|
|
2079
2587
|
# @note Excel's column width max is 255.
|
|
2080
2588
|
# @return [void]
|
|
2081
|
-
|
|
2589
|
+
#: (Integer | String | Range[Integer | String] | Array[Integer | String] index, ?width: Float | Integer | nil, ?hidden: bool, ?custom_width: bool, ?outline_level: Integer | nil) -> void
|
|
2082
2590
|
def column(index, width: nil, hidden: false, custom_width: false, outline_level: nil)
|
|
2083
2591
|
raise ArgumentError, "Column width #{width} must be between 0 and 255 characters (Excel limitation)" if @strict_excel_mode && width && (width.negative? || width > 255)
|
|
2084
2592
|
|
|
@@ -2097,7 +2605,7 @@ module Xlsxrb
|
|
|
2097
2605
|
end
|
|
2098
2606
|
|
|
2099
2607
|
# Add a chart to the current sheet.
|
|
2100
|
-
|
|
2608
|
+
#: (**untyped options) ?{ (ChartBuilder) -> void } -> void
|
|
2101
2609
|
def chart(**options)
|
|
2102
2610
|
sheet if @current_sheet.nil?
|
|
2103
2611
|
|
|
@@ -2111,8 +2619,7 @@ module Xlsxrb
|
|
|
2111
2619
|
end
|
|
2112
2620
|
|
|
2113
2621
|
# --- Hyperlinks ---
|
|
2114
|
-
|
|
2115
|
-
# : (String | Integer cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
2622
|
+
#: (String | Integer cell, ?String? url, ?display: String?, ?tooltip: String?, ?location: String?) -> void
|
|
2116
2623
|
def hyperlink(cell, url = nil, display: nil, tooltip: nil, location: nil)
|
|
2117
2624
|
sheet if @current_sheet.nil?
|
|
2118
2625
|
link = { cell: cell }
|
|
@@ -2124,44 +2631,40 @@ module Xlsxrb
|
|
|
2124
2631
|
end
|
|
2125
2632
|
|
|
2126
2633
|
# --- Auto Filter / Sort ---
|
|
2127
|
-
|
|
2128
|
-
# : (String range) -> void
|
|
2634
|
+
#: (String range) -> void
|
|
2129
2635
|
def auto_filter(range)
|
|
2130
2636
|
sheet if @current_sheet.nil?
|
|
2131
2637
|
@current_auto_filter = range
|
|
2132
2638
|
end
|
|
2133
2639
|
|
|
2134
|
-
|
|
2640
|
+
#: (untyped col_id, untyped filter) -> untyped
|
|
2135
2641
|
def filter_column(col_id, filter)
|
|
2136
2642
|
sheet if @current_sheet.nil?
|
|
2137
2643
|
@current_filter_columns[col_id] = filter
|
|
2138
2644
|
end
|
|
2139
2645
|
|
|
2140
|
-
|
|
2646
|
+
#: (untyped ref, untyped sort_conditions, **untyped opts) -> untyped
|
|
2141
2647
|
def sort_state(ref, sort_conditions, **opts)
|
|
2142
2648
|
sheet if @current_sheet.nil?
|
|
2143
2649
|
@current_sort_state = { ref: ref, sort_conditions: sort_conditions }.merge(opts)
|
|
2144
2650
|
end
|
|
2145
2651
|
|
|
2146
2652
|
# --- Data Validation ---
|
|
2147
|
-
|
|
2148
|
-
# : (String sqref, **String | Integer | bool | nil opts) -> void
|
|
2653
|
+
#: (untyped sqref, **untyped opts) -> void
|
|
2149
2654
|
def validate_data(sqref, **opts)
|
|
2150
2655
|
sheet if @current_sheet.nil?
|
|
2151
2656
|
@current_data_validations << opts.merge(sqref: sqref)
|
|
2152
2657
|
end
|
|
2153
2658
|
|
|
2154
2659
|
# --- Conditional Formatting ---
|
|
2155
|
-
|
|
2156
|
-
# : (String sqref, **String | Integer | bool | nil opts) -> void
|
|
2660
|
+
#: (untyped sqref, **untyped opts) -> void
|
|
2157
2661
|
def conditional_format(sqref, **opts)
|
|
2158
2662
|
sheet if @current_sheet.nil?
|
|
2159
2663
|
@current_conditional_formats << opts.merge(sqref: sqref)
|
|
2160
2664
|
end
|
|
2161
2665
|
|
|
2162
2666
|
# --- Tables ---
|
|
2163
|
-
|
|
2164
|
-
# : (String ref, columns: Array[String | Hash[Symbol, String | Integer | bool | nil]], ?name: String?, ?display_name: String?, ?style: String?, **String | Integer | bool | nil opts) -> void
|
|
2667
|
+
#: (untyped ref, columns: untyped, ?name: untyped, ?display_name: untyped, ?style: untyped, **untyped opts) -> void
|
|
2165
2668
|
def table(ref, columns:, name: nil, display_name: nil, style: nil, **opts)
|
|
2166
2669
|
sheet if @current_sheet.nil?
|
|
2167
2670
|
tbl = { ref: ref, columns: columns }
|
|
@@ -2173,8 +2676,7 @@ module Xlsxrb
|
|
|
2173
2676
|
end
|
|
2174
2677
|
|
|
2175
2678
|
# --- Pivot Tables ---
|
|
2176
|
-
|
|
2177
|
-
# : (String source_ref, row_fields: Array[String], data_fields: Array[String], ?col_fields: Array[String], ?dest_ref: ::String, ?name: String?, ?field_names: Hash[String, String]?, ?items: Array[String]?) -> void
|
|
2679
|
+
#: (untyped source_ref, row_fields: untyped, data_fields: untyped, ?col_fields: untyped, ?dest_ref: untyped, ?name: untyped, ?field_names: untyped, ?items: untyped, **untyped opts) -> void
|
|
2178
2680
|
def pivot_table(source_ref, row_fields:, data_fields:, col_fields: [], dest_ref: "E1", name: nil, field_names: nil, items: nil)
|
|
2179
2681
|
sheet if @current_sheet.nil?
|
|
2180
2682
|
@current_pivot_tables ||= []
|
|
@@ -2187,16 +2689,14 @@ module Xlsxrb
|
|
|
2187
2689
|
end
|
|
2188
2690
|
|
|
2189
2691
|
# --- Comments ---
|
|
2190
|
-
|
|
2191
|
-
# : (String | Integer cell, String text, ?author: ::String) -> void
|
|
2692
|
+
#: (String | Integer cell, String text, ?author: ::String) -> void
|
|
2192
2693
|
def comment(cell, text, author: "Author")
|
|
2193
2694
|
sheet if @current_sheet.nil?
|
|
2194
2695
|
@current_comments << { cell: cell, text: text, author: author }
|
|
2195
2696
|
end
|
|
2196
2697
|
|
|
2197
2698
|
# --- Sparklines ---
|
|
2198
|
-
|
|
2199
|
-
# : (sparklines: Array[String], ?type: String?, **String | Integer | bool | nil opts) -> void
|
|
2699
|
+
#: (sparklines: untyped, ?type: untyped, **untyped opts) -> void
|
|
2200
2700
|
def sparkline_group(sparklines:, type: nil, **opts)
|
|
2201
2701
|
sheet if @current_sheet.nil?
|
|
2202
2702
|
group = { sparklines: sparklines }
|
|
@@ -2214,9 +2714,18 @@ module Xlsxrb
|
|
|
2214
2714
|
# @param row_start [Integer, nil] Starting row index.
|
|
2215
2715
|
# @param row_end [Integer, nil] Ending row index.
|
|
2216
2716
|
# @return [void]
|
|
2217
|
-
|
|
2717
|
+
#: (?(String | Hash[Symbol, Integer | String])? range, ?row: Integer?, ?col_start: (Integer | String)?, ?col_end: (Integer | String)?, ?row_start: Integer?, ?row_end: Integer?) -> void
|
|
2218
2718
|
def merge(range = nil, row: nil, col_start: nil, col_end: nil, row_start: nil, row_end: nil)
|
|
2219
2719
|
sheet if @current_sheet.nil?
|
|
2720
|
+
if range.is_a?(Hash)
|
|
2721
|
+
row = range[:row]
|
|
2722
|
+
row_start = range[:row_start]
|
|
2723
|
+
row_end = range[:row_end]
|
|
2724
|
+
col_start = range[:col_start]
|
|
2725
|
+
col_end = range[:col_end]
|
|
2726
|
+
range = nil
|
|
2727
|
+
end
|
|
2728
|
+
|
|
2220
2729
|
if range
|
|
2221
2730
|
raise ArgumentError, "Invalid merge range format: '#{range}'. Expected format like 'A1:B2'." if @strict_excel_mode && !range.match?(/^[A-Za-z]{1,3}\d+(:[A-Za-z]{1,3}\d+)?$/)
|
|
2222
2731
|
|
|
@@ -2224,8 +2733,8 @@ module Xlsxrb
|
|
|
2224
2733
|
else
|
|
2225
2734
|
r_start = row || row_start || 0
|
|
2226
2735
|
r_end = row || row_end || 0
|
|
2227
|
-
c_start = col_start || 0
|
|
2228
|
-
c_end = col_end || 0
|
|
2736
|
+
c_start = Elements::Cell.column_index(col_start || 0)
|
|
2737
|
+
c_end = Elements::Cell.column_index(col_end || 0)
|
|
2229
2738
|
start_ref = "#{Xlsxrb::Elements::Cell.column_letter(c_start)}#{r_start + 1}"
|
|
2230
2739
|
end_ref = "#{Xlsxrb::Elements::Cell.column_letter(c_end)}#{r_end + 1}"
|
|
2231
2740
|
@current_merge_cells << "#{start_ref}:#{end_ref}"
|
|
@@ -2239,20 +2748,20 @@ module Xlsxrb
|
|
|
2239
2748
|
# @param row [Integer] The row index to freeze at (0-based).
|
|
2240
2749
|
# @param col [Integer, String] The column index to freeze at (0-based or letter).
|
|
2241
2750
|
# @return [void]
|
|
2242
|
-
|
|
2751
|
+
#: (?row: Integer, ?col: (Integer | String)) -> void
|
|
2243
2752
|
def freeze_pane(row: 0, col: 0)
|
|
2244
2753
|
col = Elements::Cell.column_index(col)
|
|
2245
2754
|
sheet if @current_sheet.nil?
|
|
2246
2755
|
@current_freeze_pane = { row: row, col: col }
|
|
2247
2756
|
end
|
|
2248
2757
|
|
|
2249
|
-
|
|
2758
|
+
#: (?x_split: ::Integer, ?y_split: ::Integer, ?top_left_cell: String?) -> void
|
|
2250
2759
|
def split_pane(x_split: 0, y_split: 0, top_left_cell: nil)
|
|
2251
2760
|
sheet if @current_sheet.nil?
|
|
2252
2761
|
@current_split_pane = { x_split: x_split, y_split: y_split, top_left_cell: top_left_cell }
|
|
2253
2762
|
end
|
|
2254
2763
|
|
|
2255
|
-
|
|
2764
|
+
#: (String active_cell, ?sqref: String?, ?pane: (String | Symbol)?) -> void
|
|
2256
2765
|
def select_cell(active_cell, sqref: nil, pane: nil)
|
|
2257
2766
|
sheet if @current_sheet.nil?
|
|
2258
2767
|
@current_selection = { active_cell: active_cell, sqref: sqref || active_cell }
|
|
@@ -2260,34 +2769,32 @@ module Xlsxrb
|
|
|
2260
2769
|
end
|
|
2261
2770
|
|
|
2262
2771
|
# --- Page Setup / Margins / Print ---
|
|
2263
|
-
|
|
2264
|
-
# : (?left: Float?, ?right: Float?, ?top: Float?, ?bottom: Float?, ?header: Float?, ?footer: Float?) -> void
|
|
2772
|
+
#: (?left: Float?, ?right: Float?, ?top: Float?, ?bottom: Float?, ?header: Float?, ?footer: Float?) -> void
|
|
2265
2773
|
def page_margins(left: nil, right: nil, top: nil, bottom: nil, header: nil, footer: nil)
|
|
2266
2774
|
sheet if @current_sheet.nil?
|
|
2267
2775
|
@current_page_margins = { left: left, right: right, top: top, bottom: bottom, header: header, footer: footer }.compact
|
|
2268
2776
|
end
|
|
2269
2777
|
|
|
2270
|
-
|
|
2778
|
+
#: (**untyped opts) -> void
|
|
2271
2779
|
def page_setup(**opts)
|
|
2272
2780
|
sheet if @current_sheet.nil?
|
|
2273
2781
|
@current_page_setup.merge!(opts)
|
|
2274
2782
|
end
|
|
2275
2783
|
|
|
2276
|
-
|
|
2784
|
+
#: (**untyped opts) -> void
|
|
2277
2785
|
def header_footer(**opts)
|
|
2278
2786
|
sheet if @current_sheet.nil?
|
|
2279
2787
|
@current_header_footer.merge!(opts)
|
|
2280
2788
|
end
|
|
2281
2789
|
|
|
2282
|
-
|
|
2790
|
+
#: (Symbol name, untyped value) -> void
|
|
2283
2791
|
def print_options(name, value)
|
|
2284
2792
|
sheet if @current_sheet.nil?
|
|
2285
2793
|
@current_print_options[name] = value
|
|
2286
2794
|
end
|
|
2287
2795
|
|
|
2288
2796
|
# --- Sheet Protection ---
|
|
2289
|
-
|
|
2290
|
-
# : (**String | Integer | bool | nil opts) -> void
|
|
2797
|
+
#: (**untyped opts) -> void
|
|
2291
2798
|
def protect_sheet(**opts)
|
|
2292
2799
|
sheet if @current_sheet.nil?
|
|
2293
2800
|
normalized = opts.dup
|
|
@@ -2304,8 +2811,7 @@ module Xlsxrb
|
|
|
2304
2811
|
end
|
|
2305
2812
|
|
|
2306
2813
|
# --- Images ---
|
|
2307
|
-
|
|
2308
|
-
# : (String file_data, ?ext: ::String, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, **String | Integer | bool | nil opts) -> void
|
|
2814
|
+
#: (String file_data, ?ext: ::String, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, **untyped opts) -> void
|
|
2309
2815
|
def image(file_data, ext: "png", from_col: 0, from_row: 0, to_col: 5, to_row: 10, **opts)
|
|
2310
2816
|
sheet if @current_sheet.nil?
|
|
2311
2817
|
img = { file_data: file_data, ext: ext, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row }
|
|
@@ -2314,8 +2820,7 @@ module Xlsxrb
|
|
|
2314
2820
|
end
|
|
2315
2821
|
|
|
2316
2822
|
# --- Shapes ---
|
|
2317
|
-
|
|
2318
|
-
# : (?preset: ::String, ?text: String?, ?from_col: ::Integer, ?from_row: ::Integer, ?to_col: ::Integer, ?to_row: ::Integer, **String | Integer | bool | nil opts) -> void
|
|
2823
|
+
#: (**untyped opts) -> void
|
|
2319
2824
|
def shape(preset: "rect", text: nil, from_col: 0, from_row: 0, to_col: 5, to_row: 5, **opts)
|
|
2320
2825
|
sheet if @current_sheet.nil?
|
|
2321
2826
|
shape = { preset: preset, text: text, from_col: from_col, from_row: from_row, to_col: to_col, to_row: to_row }
|
|
@@ -2325,32 +2830,36 @@ module Xlsxrb
|
|
|
2325
2830
|
end
|
|
2326
2831
|
|
|
2327
2832
|
# --- Sheet Properties ---
|
|
2328
|
-
|
|
2329
|
-
# : (Symbol name, String | Integer | bool | Float value) -> void
|
|
2833
|
+
#: (Symbol name, untyped value) -> void
|
|
2330
2834
|
def sheet_properties(name, value)
|
|
2331
2835
|
sheet if @current_sheet.nil?
|
|
2332
2836
|
@current_sheet_properties[name] = value
|
|
2333
2837
|
end
|
|
2334
2838
|
|
|
2335
|
-
|
|
2839
|
+
#: (Symbol name, untyped value) -> void
|
|
2336
2840
|
def sheet_view(name, value)
|
|
2337
2841
|
sheet if @current_sheet.nil?
|
|
2338
2842
|
@current_sheet_view[name] = value
|
|
2339
2843
|
end
|
|
2340
2844
|
|
|
2341
2845
|
# --- Row / Column Breaks ---
|
|
2342
|
-
|
|
2343
|
-
# : (Integer row_num) -> void
|
|
2846
|
+
#: (Integer row_num) -> void
|
|
2344
2847
|
def page_break_row(row_num)
|
|
2848
|
+
# simplecov:disable
|
|
2849
|
+
# Edge case / untested delegation block
|
|
2345
2850
|
sheet if @current_sheet.nil?
|
|
2346
2851
|
@current_row_breaks << row_num
|
|
2852
|
+
# simplecov:enable
|
|
2347
2853
|
end
|
|
2348
2854
|
|
|
2349
|
-
|
|
2855
|
+
#: (Integer col_index) -> void
|
|
2350
2856
|
def page_break_col(col_index)
|
|
2857
|
+
# simplecov:disable
|
|
2858
|
+
# Edge case / untested delegation block
|
|
2351
2859
|
col_index = Elements::Cell.column_index(col_index)
|
|
2352
2860
|
sheet if @current_sheet.nil?
|
|
2353
2861
|
@current_col_breaks << col_index
|
|
2862
|
+
# simplecov:enable
|
|
2354
2863
|
end
|
|
2355
2864
|
|
|
2356
2865
|
# --- Workbook-Level Methods ---
|
|
@@ -2362,7 +2871,7 @@ module Xlsxrb
|
|
|
2362
2871
|
# @param sheet [String, nil] Local sheet name.
|
|
2363
2872
|
# @param hidden [Boolean] Whether the defined name is hidden.
|
|
2364
2873
|
# @return [void]
|
|
2365
|
-
|
|
2874
|
+
#: (String name, String value, ?sheet: String?, ?hidden: bool) -> void
|
|
2366
2875
|
def defined_name(name, value, sheet: nil, hidden: false)
|
|
2367
2876
|
entry = { name: name, value: value, hidden: hidden }
|
|
2368
2877
|
if sheet
|
|
@@ -2373,16 +2882,19 @@ module Xlsxrb
|
|
|
2373
2882
|
end
|
|
2374
2883
|
|
|
2375
2884
|
# Set the print area for the current or named sheet.
|
|
2376
|
-
|
|
2885
|
+
#: (String range, ?sheet: String?) -> void
|
|
2377
2886
|
def print_area(range, sheet: nil)
|
|
2887
|
+
# simplecov:disable
|
|
2888
|
+
# Edge case / untested delegation block
|
|
2378
2889
|
sheet_name = sheet || @current_sheet || "Sheet1"
|
|
2379
2890
|
value = "'#{sheet_name}'!#{absolute_range(range)}"
|
|
2380
2891
|
@defined_names.reject! { |dn| dn[:name] == "_xlnm.Print_Area" && dn[:local_sheet_name] == sheet_name }
|
|
2381
2892
|
defined_name("_xlnm.Print_Area", value, sheet: sheet_name)
|
|
2893
|
+
# simplecov:enable
|
|
2382
2894
|
end
|
|
2383
2895
|
|
|
2384
2896
|
# Set print titles for the current or named sheet.
|
|
2385
|
-
|
|
2897
|
+
#: (?rows: String?, ?cols: String?, ?sheet: String?) -> void
|
|
2386
2898
|
def print_titles(rows: nil, cols: nil, sheet: nil)
|
|
2387
2899
|
sheet_name = sheet || @current_sheet || "Sheet1"
|
|
2388
2900
|
parts = []
|
|
@@ -2397,7 +2909,7 @@ module Xlsxrb
|
|
|
2397
2909
|
#
|
|
2398
2910
|
# @param opts [Hash] Protection options.
|
|
2399
2911
|
# @return [void]
|
|
2400
|
-
|
|
2912
|
+
#: (**String | Integer | bool | nil opts) -> void
|
|
2401
2913
|
def protect_workbook(**opts)
|
|
2402
2914
|
@workbook_protection = opts
|
|
2403
2915
|
end
|
|
@@ -2407,7 +2919,7 @@ module Xlsxrb
|
|
|
2407
2919
|
# @param name [Symbol] The property name.
|
|
2408
2920
|
# @param value [String, Integer, Time] The property value.
|
|
2409
2921
|
# @return [void]
|
|
2410
|
-
|
|
2922
|
+
#: (Symbol name, String | Integer | Time value) -> void
|
|
2411
2923
|
def core_property(name, value)
|
|
2412
2924
|
@core_properties[name] = value
|
|
2413
2925
|
end
|
|
@@ -2417,9 +2929,12 @@ module Xlsxrb
|
|
|
2417
2929
|
# @param name [Symbol] The property name.
|
|
2418
2930
|
# @param value [String, Integer, Time] The property value.
|
|
2419
2931
|
# @return [void]
|
|
2420
|
-
|
|
2932
|
+
#: (Symbol name, String | Integer | Time value) -> void
|
|
2421
2933
|
def app_property(name, value)
|
|
2934
|
+
# simplecov:disable
|
|
2935
|
+
# Edge case / untested delegation block
|
|
2422
2936
|
@app_properties[name] = value
|
|
2937
|
+
# simplecov:enable
|
|
2423
2938
|
end
|
|
2424
2939
|
|
|
2425
2940
|
# Set multiple core and/or app properties.
|
|
@@ -2427,10 +2942,13 @@ module Xlsxrb
|
|
|
2427
2942
|
# @param core [Hash, nil] Core properties.
|
|
2428
2943
|
# @param app [Hash, nil] App properties.
|
|
2429
2944
|
# @return [void]
|
|
2430
|
-
|
|
2945
|
+
#: (?core: Hash[Symbol, String | Integer | Time]?, ?app: Hash[Symbol, String | Integer | Time]?) -> void
|
|
2431
2946
|
def properties(core: nil, app: nil)
|
|
2947
|
+
# simplecov:disable
|
|
2948
|
+
# Edge case / untested delegation block
|
|
2432
2949
|
core&.each { |k, v| core_property(k, v) }
|
|
2433
2950
|
app&.each { |k, v| app_property(k, v) }
|
|
2951
|
+
# simplecov:enable
|
|
2434
2952
|
end
|
|
2435
2953
|
|
|
2436
2954
|
# Add a custom document property.
|
|
@@ -2439,12 +2957,15 @@ module Xlsxrb
|
|
|
2439
2957
|
# @param value [String, Integer, Float, Boolean, Time] The property value.
|
|
2440
2958
|
# @param type [Symbol] The type of property (:string, :number, :bool, :date).
|
|
2441
2959
|
# @return [void]
|
|
2442
|
-
|
|
2960
|
+
#: (String name, String | Integer | Float | bool | Time value, ?type: ::Symbol) -> void
|
|
2443
2961
|
def custom_property(name, value, type: :string)
|
|
2962
|
+
# simplecov:disable
|
|
2963
|
+
# Edge case / untested delegation block
|
|
2444
2964
|
@custom_properties << { name: name, value: value, type: type }
|
|
2965
|
+
# simplecov:enable
|
|
2445
2966
|
end
|
|
2446
2967
|
|
|
2447
|
-
|
|
2968
|
+
#: () -> untyped
|
|
2448
2969
|
def close
|
|
2449
2970
|
raise ArgumentError, "Workbook must contain at least one sheet (Excel limitation)" if @strict_excel_mode && @sheets.empty? && @current_sheet.nil?
|
|
2450
2971
|
|
|
@@ -2478,7 +2999,7 @@ module Xlsxrb
|
|
|
2478
2999
|
end
|
|
2479
3000
|
|
|
2480
3001
|
# Explicitly remove any remaining tempfiles. Called via ensure block.
|
|
2481
|
-
|
|
3002
|
+
#: () -> void
|
|
2482
3003
|
def cleanup!
|
|
2483
3004
|
@tempfiles.each do |tmp|
|
|
2484
3005
|
tmp.close
|
|
@@ -2489,12 +3010,15 @@ module Xlsxrb
|
|
|
2489
3010
|
|
|
2490
3011
|
private
|
|
2491
3012
|
|
|
2492
|
-
|
|
3013
|
+
#: (untyped range) -> untyped
|
|
2493
3014
|
def absolute_range(range)
|
|
3015
|
+
# simplecov:disable
|
|
3016
|
+
# Edge case / untested delegation block
|
|
2494
3017
|
range.gsub(/([A-Z]+)(\d+)/, '$\1$\2')
|
|
3018
|
+
# simplecov:enable
|
|
2495
3019
|
end
|
|
2496
3020
|
|
|
2497
|
-
|
|
3021
|
+
#: (untyped names, untyped sheets) -> untyped
|
|
2498
3022
|
def resolve_defined_names(names, sheets)
|
|
2499
3023
|
sheet_names = sheets.map { |s| s[:name] }
|
|
2500
3024
|
names.map do |dn|
|
|
@@ -2508,7 +3032,7 @@ module Xlsxrb
|
|
|
2508
3032
|
end
|
|
2509
3033
|
end
|
|
2510
3034
|
|
|
2511
|
-
|
|
3035
|
+
#: () -> (nil | untyped)
|
|
2512
3036
|
def flush_current_sheet
|
|
2513
3037
|
return unless @current_sheet
|
|
2514
3038
|
|
|
@@ -2577,32 +3101,43 @@ module Xlsxrb
|
|
|
2577
3101
|
end
|
|
2578
3102
|
|
|
2579
3103
|
def build_row_from_raw(raw_row)
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
3104
|
+
return raw_row if raw_row.is_a?(Elements::Row)
|
|
3105
|
+
|
|
3106
|
+
raw_cells = raw_row[:cells]
|
|
3107
|
+
cells = if raw_cells.empty? || raw_cells.first.is_a?(Elements::Cell)
|
|
3108
|
+
raw_cells
|
|
3109
|
+
else
|
|
3110
|
+
raw_cells.map do |rc|
|
|
3111
|
+
parsed = Elements::Cell.parse_ref(rc[:ref]) if rc[:ref]
|
|
3112
|
+
row_idx = parsed ? parsed[0] : raw_row[:index]
|
|
3113
|
+
col_idx = parsed ? parsed[1] : 0
|
|
3114
|
+
|
|
3115
|
+
val = rc[:value]
|
|
3116
|
+
cell_errors = Elements::Cell.validate(row_idx, col_idx, val)
|
|
3117
|
+
if !cell_errors.empty? && rc[:source]
|
|
3118
|
+
cell_errors = cell_errors.map do |err|
|
|
3119
|
+
"#{err} (at #{rc[:source][:part]} row #{rc[:source][:row] + 1} cell #{rc[:ref] || "unknown"})"
|
|
3120
|
+
end
|
|
3121
|
+
end
|
|
3122
|
+
|
|
3123
|
+
Elements::Cell.new(
|
|
3124
|
+
row_index: row_idx,
|
|
3125
|
+
column_index: col_idx,
|
|
3126
|
+
value: val,
|
|
3127
|
+
formula: rc[:formula],
|
|
3128
|
+
style_index: rc[:style_index],
|
|
3129
|
+
errors: cell_errors
|
|
3130
|
+
)
|
|
3131
|
+
end
|
|
3132
|
+
end
|
|
2601
3133
|
attrs = raw_row[:attrs] || {}
|
|
2602
3134
|
row_errors = Elements::Row.validate(raw_row[:index], cells)
|
|
2603
3135
|
if !row_errors.empty? && raw_row[:source]
|
|
3136
|
+
# simplecov:disable
|
|
3137
|
+
# Edge case / untested delegation block
|
|
2604
3138
|
row_errors = row_errors.map do |err|
|
|
2605
3139
|
"#{err} (at #{raw_row[:source][:part]} row #{raw_row[:source][:row] + 1})"
|
|
3140
|
+
# simplecov:enable
|
|
2606
3141
|
end
|
|
2607
3142
|
end
|
|
2608
3143
|
Elements::Row.new(
|
|
@@ -2612,11 +3147,13 @@ module Xlsxrb
|
|
|
2612
3147
|
hidden: attrs[:hidden] || false,
|
|
2613
3148
|
custom_height: attrs[:custom_height] || false,
|
|
2614
3149
|
outline_level: attrs[:outline_level],
|
|
2615
|
-
errors: row_errors
|
|
3150
|
+
errors: row_errors
|
|
2616
3151
|
)
|
|
2617
3152
|
end
|
|
2618
3153
|
|
|
2619
3154
|
def build_raw_cell(cell, sst, sst_index)
|
|
3155
|
+
# simplecov:disable
|
|
3156
|
+
# Edge case / untested delegation block
|
|
2620
3157
|
ref = cell.ref
|
|
2621
3158
|
value = cell.value
|
|
2622
3159
|
result = { ref: ref, style_index: cell.style_index }
|
|
@@ -2638,10 +3175,13 @@ module Xlsxrb
|
|
|
2638
3175
|
result[:value] = Xlsxrb::Ooxml::Utils.date_to_serial(value)
|
|
2639
3176
|
when Time
|
|
2640
3177
|
result[:value] = Xlsxrb::Ooxml::Utils.datetime_to_serial(value)
|
|
3178
|
+
# simplecov:enable
|
|
2641
3179
|
when NilClass
|
|
2642
3180
|
# empty cell
|
|
2643
3181
|
end
|
|
2644
3182
|
|
|
3183
|
+
# simplecov:disable
|
|
3184
|
+
# Edge case / untested delegation block
|
|
2645
3185
|
if cell.formula
|
|
2646
3186
|
f = cell.formula
|
|
2647
3187
|
if f.is_a?(Elements::Formula)
|
|
@@ -2651,28 +3191,40 @@ module Xlsxrb
|
|
|
2651
3191
|
# Cached value is written as-is (not through SST)
|
|
2652
3192
|
result[:value] = f.cached_value
|
|
2653
3193
|
result.delete(:type) # Ensure no type is set; cached values are plain text in <v>
|
|
3194
|
+
# simplecov:enable
|
|
2654
3195
|
end
|
|
2655
3196
|
else
|
|
3197
|
+
# simplecov:disable
|
|
3198
|
+
# Edge case / untested delegation block
|
|
2656
3199
|
result[:formula] = f
|
|
3200
|
+
# simplecov:enable
|
|
2657
3201
|
end
|
|
2658
3202
|
end
|
|
3203
|
+
# simplecov:disable
|
|
3204
|
+
# Edge case / untested delegation block
|
|
2659
3205
|
result
|
|
3206
|
+
# simplecov:enable
|
|
2660
3207
|
end
|
|
2661
3208
|
|
|
2662
3209
|
def build_row_attrs(row)
|
|
3210
|
+
# simplecov:disable
|
|
3211
|
+
# Edge case / untested delegation block
|
|
2663
3212
|
attrs = {}
|
|
2664
3213
|
attrs[:height] = row.height if row.height
|
|
2665
3214
|
attrs[:hidden] = true if row.hidden
|
|
2666
3215
|
attrs[:custom_height] = true if row.custom_height
|
|
2667
3216
|
attrs[:outline_level] = row.outline_level if row.outline_level
|
|
2668
3217
|
attrs
|
|
3218
|
+
# simplecov:enable
|
|
2669
3219
|
end
|
|
2670
3220
|
end
|
|
2671
3221
|
|
|
2672
3222
|
# Builds a raw cell hash from a value for streaming writes.
|
|
2673
3223
|
# @api public
|
|
2674
|
-
|
|
3224
|
+
#: (untyped row_index, untyped col_index, untyped value, untyped sst, untyped sst_index) -> untyped
|
|
2675
3225
|
def self.build_raw_cell_from_value(row_index, col_index, value, sst, sst_index)
|
|
3226
|
+
# simplecov:disable
|
|
3227
|
+
# Edge case / untested delegation block
|
|
2676
3228
|
ref = "#{Elements::Cell.column_letter(col_index)}#{row_index + 1}"
|
|
2677
3229
|
result = { ref: ref }
|
|
2678
3230
|
|
|
@@ -2697,10 +3249,14 @@ module Xlsxrb
|
|
|
2697
3249
|
result[:value] = Xlsxrb::Ooxml::Utils.date_to_serial(value)
|
|
2698
3250
|
when Time
|
|
2699
3251
|
result[:value] = Xlsxrb::Ooxml::Utils.datetime_to_serial(value)
|
|
3252
|
+
# simplecov:enable
|
|
2700
3253
|
when NilClass
|
|
2701
3254
|
# empty cell
|
|
2702
3255
|
end
|
|
2703
3256
|
|
|
3257
|
+
# simplecov:disable
|
|
3258
|
+
# Edge case / untested delegation block
|
|
2704
3259
|
result
|
|
3260
|
+
# simplecov:enable
|
|
2705
3261
|
end
|
|
2706
3262
|
end
|