xlsxrb 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/README.md +71 -253
- data/Rakefile +2 -1
- data/benchmark.rb +3 -1
- data/docs/PEER_LIBRARIES.md +121 -0
- data/docs/assets/benchmark_results.svg +144 -0
- data/docs/assets/lsp_autocompletion.png +0 -0
- data/docs/assets/playground_preview.png +0 -0
- data/docs/visual/VisualGallery.md +183 -0
- data/docs/wasm/ruby.wasm +0 -0
- data/lib/xlsxrb/chart_builder.rb +333 -0
- data/lib/xlsxrb/elements/cell.rb +66 -12
- data/lib/xlsxrb/elements/workbook.rb +2 -2
- data/lib/xlsxrb/ooxml/reader/listeners.rb +6450 -0
- data/lib/xlsxrb/ooxml/reader.rb +2 -6438
- data/lib/xlsxrb/ooxml/workbook_writer.rb +297 -236
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +218 -266
- data/lib/xlsxrb/ooxml/worksheet_writer.rb +127 -10
- data/lib/xlsxrb/ooxml/zip_writer.rb +31 -38
- data/lib/xlsxrb/stream_row.rb +34 -8
- data/lib/xlsxrb/stream_sheet.rb +119 -0
- data/lib/xlsxrb/stream_writer.rb +1733 -0
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb/workbook_builder.rb +309 -0
- data/lib/xlsxrb/worksheet_builder.rb +691 -0
- data/lib/xlsxrb.rb +238 -2968
- data/sig/generated/xlsxrb/chart_builder.rbs +269 -0
- data/sig/generated/xlsxrb/elements/cell.rbs +137 -12
- data/sig/generated/xlsxrb/ooxml/reader/listeners.rbs +1074 -0
- data/sig/generated/xlsxrb/ooxml/reader.rbs +0 -1067
- data/sig/generated/xlsxrb/ooxml/workbook_writer.rbs +17 -1
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +18 -4
- data/sig/generated/xlsxrb/ooxml/worksheet_writer.rbs +4 -0
- data/sig/generated/xlsxrb/stream_row.rbs +6 -2
- data/sig/generated/xlsxrb/stream_sheet.rbs +100 -0
- data/sig/generated/xlsxrb/stream_writer.rbs +960 -0
- data/sig/generated/xlsxrb/workbook_builder.rbs +146 -0
- data/sig/generated/xlsxrb/worksheet_builder.rbs +349 -0
- data/sig/generated/xlsxrb.rbs +103 -1563
- metadata +17 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module Xlsxrb
|
|
6
|
+
# Builder for block-style chart definitions.
|
|
7
|
+
#
|
|
8
|
+
# @example Create a chart definition
|
|
9
|
+
# builder = ChartBuilder.new
|
|
10
|
+
# builder.type(:bar)
|
|
11
|
+
# builder.title("Quarterly Sales")
|
|
12
|
+
# builder.series do |s|
|
|
13
|
+
# s.name("2026")
|
|
14
|
+
# s.categories("Sheet1!$A$2:$A$5")
|
|
15
|
+
# s.values("Sheet1!$B$2:$B$5")
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
class ChartBuilder
|
|
20
|
+
# @return [Hash{Symbol => Object}] The configured chart options.
|
|
21
|
+
#: () -> void
|
|
22
|
+
def initialize
|
|
23
|
+
@options = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [Hash{Symbol => Object}]
|
|
27
|
+
#: Hash[Symbol, untyped]
|
|
28
|
+
attr_reader :options
|
|
29
|
+
|
|
30
|
+
# Sets the chart type (e.g. :line, :bar, :pie, :area, :radar, :scatter).
|
|
31
|
+
#
|
|
32
|
+
# @param value [Symbol, String] Chart type.
|
|
33
|
+
# @return [Symbol, String]
|
|
34
|
+
# @api public
|
|
35
|
+
#: (Symbol | String value) -> (Symbol | String)
|
|
36
|
+
def type(value)
|
|
37
|
+
@options[:type] = value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Sets the chart title.
|
|
41
|
+
#
|
|
42
|
+
# @param value [String, Hash, nil] Chart title text or options hash.
|
|
43
|
+
# @return [String, Hash, nil]
|
|
44
|
+
# @api public
|
|
45
|
+
#: (String | Hash[Symbol, untyped] | nil value) -> (String | Hash[Symbol, untyped] | nil)
|
|
46
|
+
def title(value)
|
|
47
|
+
@options[:title] = value
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Adds a data series to the chart.
|
|
51
|
+
#
|
|
52
|
+
# @overload series(value)
|
|
53
|
+
# Adds a pre-built series options hash.
|
|
54
|
+
# @param value [Hash{Symbol => Object}] Series options hash.
|
|
55
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
56
|
+
#
|
|
57
|
+
# @overload series(&block)
|
|
58
|
+
# Configures a series using a block.
|
|
59
|
+
# @yield [series_builder]
|
|
60
|
+
# @yieldparam series_builder [SeriesBuilder]
|
|
61
|
+
# @return [Array<Hash{Symbol => Object}>]
|
|
62
|
+
#
|
|
63
|
+
# @api public
|
|
64
|
+
#: (?Hash[Symbol, untyped]? value) ?{ (SeriesBuilder) -> void } -> Array[Hash[Symbol, untyped]]
|
|
65
|
+
def series(value = nil)
|
|
66
|
+
@options[:series] ||= []
|
|
67
|
+
if block_given?
|
|
68
|
+
sb = SeriesBuilder.new
|
|
69
|
+
yield sb
|
|
70
|
+
@options[:series] << sb.options
|
|
71
|
+
elsif value
|
|
72
|
+
@options[:series] << value
|
|
73
|
+
end
|
|
74
|
+
@options[:series]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Configures the legend property for this chart.
|
|
78
|
+
#
|
|
79
|
+
# @param args [Array] Positional arguments (e.g. position string).
|
|
80
|
+
# @param kwargs [Hash] Keyword arguments for legend styling/layout.
|
|
81
|
+
# @return [Object] The configured legend property.
|
|
82
|
+
# @api public
|
|
83
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
84
|
+
def legend(*args, **kwargs)
|
|
85
|
+
@options[:legend] = kwargs.empty? ? args.first : kwargs
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Configures the plot_area property for this chart.
|
|
89
|
+
#
|
|
90
|
+
# @param args [Array] Positional arguments.
|
|
91
|
+
# @param kwargs [Hash] Keyword arguments for plot area configuration.
|
|
92
|
+
# @return [Object] The configured plot_area property.
|
|
93
|
+
# @api public
|
|
94
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
95
|
+
def plot_area(*args, **kwargs)
|
|
96
|
+
@options[:plot_area] = kwargs.empty? ? args.first : kwargs
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Configures the chart_space property for this chart.
|
|
100
|
+
#
|
|
101
|
+
# @param args [Array] Positional arguments.
|
|
102
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
103
|
+
# @return [Object] The configured chart_space property.
|
|
104
|
+
# @api public
|
|
105
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
106
|
+
def chart_space(*args, **kwargs)
|
|
107
|
+
@options[:chart_space] = kwargs.empty? ? args.first : kwargs
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Configures the style index/id for this chart.
|
|
111
|
+
#
|
|
112
|
+
# @param args [Array] Positional arguments.
|
|
113
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
114
|
+
# @return [Object] The configured style property.
|
|
115
|
+
# @api public
|
|
116
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String | Integer) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String | Integer)
|
|
117
|
+
def style(*args, **kwargs)
|
|
118
|
+
@options[:style] = kwargs.empty? ? args.first : kwargs
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Configures data labels for this chart.
|
|
122
|
+
#
|
|
123
|
+
# @param args [Array] Positional arguments.
|
|
124
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
125
|
+
# @return [Object] The configured data_labels property.
|
|
126
|
+
# @api public
|
|
127
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
128
|
+
def data_labels(*args, **kwargs)
|
|
129
|
+
@options[:data_labels] = kwargs.empty? ? args.first : kwargs
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Configures whether to plot visible cells only.
|
|
133
|
+
#
|
|
134
|
+
# @param args [Array] Positional arguments.
|
|
135
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
136
|
+
# @return [Boolean, String]
|
|
137
|
+
# @api public
|
|
138
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
139
|
+
def plot_visible_only(*args, **kwargs)
|
|
140
|
+
@options[:plot_visible_only] = kwargs.empty? ? args.first : kwargs
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Configures how blank cells are displayed in the chart.
|
|
144
|
+
#
|
|
145
|
+
# @param args [Array] Positional arguments.
|
|
146
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
147
|
+
# @return [String]
|
|
148
|
+
# @api public
|
|
149
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
150
|
+
def display_blanks_as(*args, **kwargs)
|
|
151
|
+
@options[:display_blanks_as] = kwargs.empty? ? args.first : kwargs
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Configures 3D view properties for 3D charts.
|
|
155
|
+
#
|
|
156
|
+
# @param args [Array] Positional arguments.
|
|
157
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
158
|
+
# @return [Object]
|
|
159
|
+
# @api public
|
|
160
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
161
|
+
def view3d(*args, **kwargs)
|
|
162
|
+
@options[:view3d] = kwargs.empty? ? args.first : kwargs
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Configures the category axis properties for this chart.
|
|
166
|
+
#
|
|
167
|
+
# @param args [Array] Positional arguments.
|
|
168
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
169
|
+
# @return [Object]
|
|
170
|
+
# @api public
|
|
171
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
172
|
+
def category_axis(*args, **kwargs)
|
|
173
|
+
@options[:category_axis] = kwargs.empty? ? args.first : kwargs
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Configures the value axis properties for this chart.
|
|
177
|
+
#
|
|
178
|
+
# @param args [Array] Positional arguments.
|
|
179
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
180
|
+
# @return [Object]
|
|
181
|
+
# @api public
|
|
182
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
183
|
+
def value_axis(*args, **kwargs)
|
|
184
|
+
@options[:value_axis] = kwargs.empty? ? args.first : kwargs
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Configures whether to show the legend key in data labels.
|
|
188
|
+
#
|
|
189
|
+
# @param args [Array] Positional arguments.
|
|
190
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
191
|
+
# @return [Boolean, String]
|
|
192
|
+
# @api public
|
|
193
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
194
|
+
def show_legend_key(*args, **kwargs)
|
|
195
|
+
@options[:show_legend_key] = kwargs.empty? ? args.first : kwargs
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Builder for a single series entry in block-style chart definitions.
|
|
199
|
+
#
|
|
200
|
+
# @api public
|
|
201
|
+
class SeriesBuilder
|
|
202
|
+
#: () -> void
|
|
203
|
+
def initialize
|
|
204
|
+
@options = {}
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @return [Hash{Symbol => Object}]
|
|
208
|
+
#: Hash[Symbol, untyped]
|
|
209
|
+
attr_reader :options
|
|
210
|
+
|
|
211
|
+
# Configures categories reference for this series (e.g. "Sheet1!$A$2:$A$10").
|
|
212
|
+
#
|
|
213
|
+
# @param args [Array] Positional arguments.
|
|
214
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
215
|
+
# @return [Object]
|
|
216
|
+
# @api public
|
|
217
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
218
|
+
def categories(*args, **kwargs)
|
|
219
|
+
@options[:categories] = kwargs.empty? ? args.first : kwargs
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Configures values reference for this series (e.g. "Sheet1!$B$2:$B$10").
|
|
223
|
+
#
|
|
224
|
+
# @param args [Array] Positional arguments.
|
|
225
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
226
|
+
# @return [Object]
|
|
227
|
+
# @api public
|
|
228
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
229
|
+
def values(*args, **kwargs)
|
|
230
|
+
@options[:values] = kwargs.empty? ? args.first : kwargs
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Configures the name for this series (e.g. "Total Sales" or cell reference "Sheet1!$B$1").
|
|
234
|
+
#
|
|
235
|
+
# @param args [Array] Positional arguments.
|
|
236
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
237
|
+
# @return [Object]
|
|
238
|
+
# @api public
|
|
239
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
240
|
+
def name(*args, **kwargs)
|
|
241
|
+
@options[:name] = kwargs.empty? ? args.first : kwargs
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Configures data markers for this series.
|
|
245
|
+
#
|
|
246
|
+
# @param args [Array] Positional arguments.
|
|
247
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
248
|
+
# @return [Object]
|
|
249
|
+
# @api public
|
|
250
|
+
#: (*untyped args, **untyped kwargs) -> untyped
|
|
251
|
+
def marker(*args, **kwargs)
|
|
252
|
+
@options[:marker] = kwargs.empty? ? args.first : kwargs
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Configures fill color/pattern for this series.
|
|
256
|
+
#
|
|
257
|
+
# @param args [Array] Positional arguments.
|
|
258
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
259
|
+
# @return [Object]
|
|
260
|
+
# @api public
|
|
261
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
262
|
+
def fill(*args, **kwargs)
|
|
263
|
+
@options[:fill] = kwargs.empty? ? args.first : kwargs
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Configures line color/thickness for this series.
|
|
267
|
+
#
|
|
268
|
+
# @param args [Array] Positional arguments.
|
|
269
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
270
|
+
# @return [Object]
|
|
271
|
+
# @api public
|
|
272
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
273
|
+
def line(*args, **kwargs)
|
|
274
|
+
@options[:line] = kwargs.empty? ? args.first : kwargs
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Configures trendline for this series.
|
|
278
|
+
#
|
|
279
|
+
# @param args [Array] Positional arguments.
|
|
280
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
281
|
+
# @return [Object]
|
|
282
|
+
# @api public
|
|
283
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
284
|
+
def trendline(*args, **kwargs)
|
|
285
|
+
@options[:trendline] = kwargs.empty? ? args.first : kwargs
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Configures data labels for this series.
|
|
289
|
+
#
|
|
290
|
+
# @param args [Array] Positional arguments.
|
|
291
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
292
|
+
# @return [Object]
|
|
293
|
+
# @api public
|
|
294
|
+
#: (*(Hash[Symbol, String | Integer | bool | nil] | String) args, **String | Integer | bool | nil kwargs) -> (Hash[Symbol, String | Integer | bool | nil] | String)
|
|
295
|
+
def data_labels(*args, **kwargs)
|
|
296
|
+
@options[:data_labels] = kwargs.empty? ? args.first : kwargs
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Configures line smoothing for this series.
|
|
300
|
+
#
|
|
301
|
+
# @param args [Array] Positional arguments.
|
|
302
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
303
|
+
# @return [Boolean, String]
|
|
304
|
+
# @api public
|
|
305
|
+
#: (*(bool | String) args, **String | Integer | bool | nil kwargs) -> (bool | String)
|
|
306
|
+
def smooth(*args, **kwargs)
|
|
307
|
+
@options[:smooth] = kwargs.empty? ? args.first : kwargs
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Configures 3D bar/column shape (e.g. "cylinder", "cone", "pyramid").
|
|
311
|
+
#
|
|
312
|
+
# @param args [Array] Positional arguments.
|
|
313
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
314
|
+
# @return [String]
|
|
315
|
+
# @api public
|
|
316
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
317
|
+
def shape(*args, **kwargs)
|
|
318
|
+
@options[:shape] = kwargs.empty? ? args.first : kwargs
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Configures individual series chart type override in combo charts.
|
|
322
|
+
#
|
|
323
|
+
# @param args [Array] Positional arguments.
|
|
324
|
+
# @param kwargs [Hash] Keyword arguments.
|
|
325
|
+
# @return [String]
|
|
326
|
+
# @api public
|
|
327
|
+
#: (*(String) args, **String | Integer | bool | nil kwargs) -> String
|
|
328
|
+
def type(*args, **kwargs)
|
|
329
|
+
@options[:type] = kwargs.empty? ? args.first : kwargs
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
data/lib/xlsxrb/elements/cell.rb
CHANGED
|
@@ -15,7 +15,9 @@ module Xlsxrb
|
|
|
15
15
|
# cell.to_date # Date value
|
|
16
16
|
#
|
|
17
17
|
# @api public
|
|
18
|
-
Cell
|
|
18
|
+
class Cell
|
|
19
|
+
attr_reader :row_index, :column_index, :value, :formula, :style_index, :unmapped_data, :errors
|
|
20
|
+
|
|
19
21
|
# @param row_index [Integer] 0-based row index.
|
|
20
22
|
# @param column_index [Integer] 0-based column index.
|
|
21
23
|
# @param value [Object, nil] The cell's value.
|
|
@@ -23,12 +25,66 @@ module Xlsxrb
|
|
|
23
25
|
# @param style_index [Integer, String, nil] Style identifier.
|
|
24
26
|
# @param unmapped_data [Hash] Additional metadata.
|
|
25
27
|
# @param errors [Array<String>, nil] Validation errors.
|
|
26
|
-
#: (row_index:
|
|
28
|
+
#: (row_index: untyped, column_index: untyped, ?value: untyped, ?formula: (Elements::Formula | String)?, ?style_index: (Integer | String)?, ?unmapped_data: Hash[untyped, untyped], ?errors: Array[String]?) -> void
|
|
27
29
|
def initialize(row_index:, column_index:, value: nil, formula: nil, style_index: nil, unmapped_data: EMPTY_HASH, errors: nil)
|
|
30
|
+
@row_index = row_index
|
|
31
|
+
@column_index = column_index
|
|
32
|
+
@value = value
|
|
33
|
+
@formula = formula
|
|
34
|
+
@style_index = style_index
|
|
35
|
+
@unmapped_data = unmapped_data || EMPTY_HASH
|
|
28
36
|
computed_errors = errors || self.class.validate(row_index, column_index, value)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
@errors = computed_errors.frozen? ? computed_errors : computed_errors.freeze
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.fast_create(row_index, column_index, value, style_index = nil, formula = nil)
|
|
41
|
+
inst = allocate
|
|
42
|
+
inst.instance_variable_set(:@row_index, row_index)
|
|
43
|
+
inst.instance_variable_set(:@column_index, column_index)
|
|
44
|
+
inst.instance_variable_set(:@value, value)
|
|
45
|
+
inst.instance_variable_set(:@formula, formula)
|
|
46
|
+
inst.instance_variable_set(:@style_index, style_index)
|
|
47
|
+
inst.instance_variable_set(:@unmapped_data, EMPTY_HASH)
|
|
48
|
+
inst.instance_variable_set(:@errors, EMPTY_ERRORS)
|
|
49
|
+
inst
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def ==(other)
|
|
53
|
+
other.is_a?(Cell) &&
|
|
54
|
+
row_index == other.row_index &&
|
|
55
|
+
column_index == other.column_index &&
|
|
56
|
+
value == other.value &&
|
|
57
|
+
formula == other.formula &&
|
|
58
|
+
style_index == other.style_index &&
|
|
59
|
+
unmapped_data == other.unmapped_data &&
|
|
60
|
+
errors == other.errors
|
|
61
|
+
end
|
|
62
|
+
alias eql? ==
|
|
63
|
+
|
|
64
|
+
def hash
|
|
65
|
+
[row_index, column_index, value, formula, style_index, unmapped_data, errors].hash
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def deconstruct
|
|
69
|
+
[row_index, column_index, value, formula, style_index, unmapped_data, errors]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def deconstruct_keys(keys)
|
|
73
|
+
h = { row_index: row_index, column_index: column_index, value: value, formula: formula,
|
|
74
|
+
style_index: style_index, unmapped_data: unmapped_data, errors: errors }
|
|
75
|
+
keys ? h.slice(*keys) : h
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def with(**changes)
|
|
79
|
+
self.class.new(
|
|
80
|
+
row_index: changes.fetch(:row_index, row_index),
|
|
81
|
+
column_index: changes.fetch(:column_index, column_index),
|
|
82
|
+
value: changes.fetch(:value, value),
|
|
83
|
+
formula: changes.fetch(:formula, formula),
|
|
84
|
+
style_index: changes.fetch(:style_index, style_index),
|
|
85
|
+
unmapped_data: changes.fetch(:unmapped_data, unmapped_data),
|
|
86
|
+
errors: changes.fetch(:errors, errors)
|
|
87
|
+
)
|
|
32
88
|
end
|
|
33
89
|
|
|
34
90
|
# Returns whether the cell is valid according to OOXML specifications.
|
|
@@ -57,7 +113,8 @@ module Xlsxrb
|
|
|
57
113
|
def [](key)
|
|
58
114
|
case key
|
|
59
115
|
when :value then value
|
|
60
|
-
when :formula
|
|
116
|
+
when :formula
|
|
117
|
+
formula.is_a?(Formula) ? formula.expression : formula
|
|
61
118
|
when :style_index then style_index
|
|
62
119
|
when :ref then ref
|
|
63
120
|
when :column_index then column_index
|
|
@@ -114,9 +171,8 @@ module Xlsxrb
|
|
|
114
171
|
def to_date
|
|
115
172
|
return value if value.is_a?(Date)
|
|
116
173
|
|
|
117
|
-
# Excel epoch is 1899-12-30
|
|
118
174
|
if value.is_a?(Numeric)
|
|
119
|
-
|
|
175
|
+
Ooxml::Utils.serial_to_date(value)
|
|
120
176
|
else
|
|
121
177
|
begin
|
|
122
178
|
Date.parse(value.to_s)
|
|
@@ -135,9 +191,7 @@ module Xlsxrb
|
|
|
135
191
|
return value if value.is_a?(Time)
|
|
136
192
|
|
|
137
193
|
if value.is_a?(Numeric)
|
|
138
|
-
|
|
139
|
-
base_time = Time.utc(1899, 12, 30)
|
|
140
|
-
base_time + (days * 86_400)
|
|
194
|
+
Ooxml::Utils.serial_to_datetime(value)
|
|
141
195
|
else
|
|
142
196
|
begin
|
|
143
197
|
Time.parse(value.to_s)
|
|
@@ -168,7 +222,7 @@ module Xlsxrb
|
|
|
168
222
|
# @param index [Integer] 0-based column index.
|
|
169
223
|
# @return [String] Excel column letter.
|
|
170
224
|
# @api public
|
|
171
|
-
#: (
|
|
225
|
+
#: (untyped index) -> String
|
|
172
226
|
def self.column_letter(index)
|
|
173
227
|
raise ArgumentError, "Column index must be a non-negative Integer, got #{index.inspect}" unless index.is_a?(Integer) && index >= 0
|
|
174
228
|
|
|
@@ -131,10 +131,10 @@ module Xlsxrb
|
|
|
131
131
|
# @example
|
|
132
132
|
# wb.save("output.xlsx")
|
|
133
133
|
#
|
|
134
|
-
# @param filepath [String, IO] Destination file path or IO stream.
|
|
134
|
+
# @param filepath [String, IO, StringIO] Destination file path or IO stream.
|
|
135
135
|
# @return [void]
|
|
136
136
|
# @api public
|
|
137
|
-
#: (
|
|
137
|
+
#: (String | IO | StringIO filepath) -> void
|
|
138
138
|
def save(filepath)
|
|
139
139
|
Xlsxrb.write(filepath, self)
|
|
140
140
|
end
|