xlsxrb 0.1.6 → 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/CHANGELOG.md +10 -0
- data/README.md +27 -12
- data/Steepfile +1 -0
- 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 +98 -4
- data/lib/xlsxrb/elements/column.rb +22 -0
- data/lib/xlsxrb/elements/row.rb +81 -1
- data/lib/xlsxrb/elements/types.rb +36 -5
- data/lib/xlsxrb/elements/workbook.rb +73 -5
- data/lib/xlsxrb/elements/worksheet.rb +110 -1
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb.rb +530 -181
- data/sig/generated/xlsxrb/elements/cell.rbs +10 -1
- data/sig/generated/xlsxrb/elements/column.rbs +5 -0
- data/sig/generated/xlsxrb/elements/row.rbs +8 -1
- data/sig/generated/xlsxrb/elements/types.rbs +13 -5
- data/sig/generated/xlsxrb/elements/workbook.rbs +8 -1
- data/sig/generated/xlsxrb/elements/worksheet.rbs +7 -0
- data/sig/generated/xlsxrb.rbs +606 -236
- metadata +3 -1
|
@@ -5,15 +5,33 @@
|
|
|
5
5
|
module Xlsxrb
|
|
6
6
|
module Elements
|
|
7
7
|
# Represents a single worksheet in a workbook.
|
|
8
|
+
#
|
|
9
|
+
# @example Access cells and rows
|
|
10
|
+
# sheet = workbook.sheet(0)
|
|
11
|
+
# cell = sheet["A1"]
|
|
12
|
+
# sheet.each_row { |row| puts row.to_a.inspect }
|
|
13
|
+
#
|
|
14
|
+
# @api public
|
|
8
15
|
Worksheet = Data.define(:name, :rows, :columns, :charts, :unmapped_data, :errors) do
|
|
9
16
|
include Enumerable
|
|
10
17
|
|
|
18
|
+
# @param name [String] The worksheet name (max 31 characters).
|
|
19
|
+
# @param rows [Array<Elements::Row>] Rows in the sheet.
|
|
20
|
+
# @param columns [Array<Elements::Column>] Column definitions.
|
|
21
|
+
# @param charts [Array<Hash>] Charts in the sheet.
|
|
22
|
+
# @param unmapped_data [Hash] Additional metadata for round-tripping.
|
|
23
|
+
# @param errors [Array<String>, nil] Validation errors.
|
|
24
|
+
#: (name: String, ?rows: Array[Elements::Row], ?columns: Array[Elements::Column], ?charts: Array[Hash[Symbol, untyped]], ?unmapped_data: Hash[untyped, untyped], ?errors: Array[String]?) -> void
|
|
11
25
|
def initialize(name:, rows: [], columns: [], charts: [], unmapped_data: {}, errors: nil)
|
|
12
26
|
computed_errors = errors || self.class.validate(name, rows)
|
|
13
27
|
super(name: name, rows: rows.freeze, columns: columns.freeze, charts: charts.freeze,
|
|
14
28
|
unmapped_data: unmapped_data, errors: computed_errors.freeze)
|
|
15
29
|
end
|
|
16
30
|
|
|
31
|
+
# Returns a Hash mapping Excel cell references (e.g. "A1") to Cell objects.
|
|
32
|
+
#
|
|
33
|
+
# @return [Hash<String, Elements::Cell>]
|
|
34
|
+
#: () -> Hash[String, Elements::Cell]
|
|
17
35
|
def cells_hash
|
|
18
36
|
h = {}
|
|
19
37
|
rows.each do |r|
|
|
@@ -25,51 +43,131 @@ module Xlsxrb
|
|
|
25
43
|
h
|
|
26
44
|
end
|
|
27
45
|
|
|
46
|
+
# Returns all cells ordered by row and column index.
|
|
47
|
+
#
|
|
48
|
+
# @return [Array<Elements::Cell>]
|
|
49
|
+
# @api public
|
|
50
|
+
#: () -> Array[Elements::Cell]
|
|
28
51
|
def cells
|
|
29
52
|
# Ensure ordered traversal
|
|
30
53
|
cells_hash.values.sort_by { |c| [c.row_index, c.column_index] }
|
|
31
54
|
end
|
|
32
55
|
|
|
56
|
+
# Access a cell by its Excel-style reference (e.g. "A1").
|
|
57
|
+
#
|
|
58
|
+
# @example
|
|
59
|
+
# sheet["A1"] #=> #<Elements::Cell value="Hello">
|
|
60
|
+
#
|
|
61
|
+
# @param ref [String, Symbol] Cell reference (e.g. "A1" or :A1).
|
|
62
|
+
# @return [Elements::Cell, nil]
|
|
63
|
+
# @api public
|
|
64
|
+
#: (String | Symbol ref) -> Elements::Cell?
|
|
33
65
|
def [](ref)
|
|
34
66
|
cells_hash[ref.to_s.upcase]
|
|
35
67
|
end
|
|
36
68
|
|
|
69
|
+
# Iterate over cells in the worksheet.
|
|
70
|
+
#
|
|
71
|
+
# @example
|
|
72
|
+
# sheet.each do |cell|
|
|
73
|
+
# puts cell.value
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# @yield [cell]
|
|
77
|
+
# @yieldparam cell [Elements::Cell]
|
|
78
|
+
# @return [Enumerator, void]
|
|
79
|
+
# @api public
|
|
80
|
+
#: () { (Elements::Cell) -> void } -> void
|
|
81
|
+
#: | () -> Enumerator[Elements::Cell, void]
|
|
37
82
|
def each(&)
|
|
38
83
|
return to_enum(:each) unless block_given?
|
|
39
84
|
|
|
40
85
|
cells.each(&)
|
|
41
86
|
end
|
|
42
87
|
|
|
88
|
+
# Iterate over cells in the worksheet.
|
|
89
|
+
#
|
|
90
|
+
# @example
|
|
91
|
+
# sheet.each_cell do |cell|
|
|
92
|
+
# puts "#{cell.ref}: #{cell.value}"
|
|
93
|
+
# end
|
|
94
|
+
#
|
|
95
|
+
# @yield [cell]
|
|
96
|
+
# @yieldparam cell [Elements::Cell]
|
|
97
|
+
# @return [Enumerator, void]
|
|
98
|
+
# @api public
|
|
99
|
+
#: () { (Elements::Cell) -> void } -> void
|
|
100
|
+
#: | () -> Enumerator[Elements::Cell, void]
|
|
43
101
|
def each_cell(&)
|
|
44
102
|
return to_enum(:each_cell) unless block_given?
|
|
45
103
|
|
|
46
104
|
cells.each(&)
|
|
47
105
|
end
|
|
48
106
|
|
|
107
|
+
# Iterate over rows in the worksheet.
|
|
108
|
+
#
|
|
109
|
+
# @example
|
|
110
|
+
# sheet.each_row do |row|
|
|
111
|
+
# puts "Row #{row.index}: #{row.to_a.inspect}"
|
|
112
|
+
# end
|
|
113
|
+
#
|
|
114
|
+
# @yield [row]
|
|
115
|
+
# @yieldparam row [Elements::Row]
|
|
116
|
+
# @return [Enumerator, void]
|
|
117
|
+
# @api public
|
|
118
|
+
#: () { (Elements::Row) -> void } -> void
|
|
119
|
+
#: | () -> Enumerator[Elements::Row, void]
|
|
49
120
|
def each_row(&)
|
|
50
121
|
return to_enum(:each_row) unless block_given?
|
|
51
122
|
|
|
52
123
|
rows.each(&)
|
|
53
124
|
end
|
|
54
125
|
|
|
126
|
+
# Returns whether the worksheet is valid according to OOXML specifications.
|
|
127
|
+
#
|
|
128
|
+
# @return [Boolean]
|
|
129
|
+
#: () -> bool
|
|
55
130
|
def valid?
|
|
56
131
|
errors.empty?
|
|
57
132
|
end
|
|
58
133
|
|
|
59
134
|
# Returns the row at the given 0-based index, or nil.
|
|
135
|
+
#
|
|
136
|
+
# @param index [Integer] 0-based row index.
|
|
137
|
+
# @return [Elements::Row, nil]
|
|
138
|
+
# @api public
|
|
139
|
+
#: (Integer index) -> Elements::Row?
|
|
60
140
|
def row_at(index)
|
|
61
141
|
rows.find { |r| r.index == index }
|
|
62
142
|
end
|
|
63
143
|
|
|
144
|
+
# Returns the first row in the sheet, or nil.
|
|
145
|
+
#
|
|
146
|
+
# @return [Elements::Row, nil]
|
|
147
|
+
# @api public
|
|
148
|
+
#: () -> Elements::Row?
|
|
64
149
|
def first_row
|
|
65
150
|
rows.min_by(&:index)
|
|
66
151
|
end
|
|
67
152
|
|
|
153
|
+
# Returns the last row in the sheet, or nil.
|
|
154
|
+
#
|
|
155
|
+
# @return [Elements::Row, nil]
|
|
156
|
+
# @api public
|
|
157
|
+
#: () -> Elements::Row?
|
|
68
158
|
def last_row
|
|
69
159
|
rows.max_by(&:index)
|
|
70
160
|
end
|
|
71
161
|
|
|
72
|
-
# Returns cell value at Excel-style reference (e.g. "A1").
|
|
162
|
+
# Returns the raw cell value at the given Excel-style reference (e.g. "A1").
|
|
163
|
+
#
|
|
164
|
+
# @example
|
|
165
|
+
# sheet.cell_value("A1") #=> "Sales Report"
|
|
166
|
+
#
|
|
167
|
+
# @param ref [String] Cell reference (e.g. "A1").
|
|
168
|
+
# @return [Object, nil]
|
|
169
|
+
# @api public
|
|
170
|
+
#: (String ref) -> untyped
|
|
73
171
|
def cell_value(ref)
|
|
74
172
|
parsed = Cell.parse_ref(ref)
|
|
75
173
|
return nil unless parsed
|
|
@@ -84,11 +182,16 @@ module Xlsxrb
|
|
|
84
182
|
|
|
85
183
|
# Returns a new Worksheet with the specified cell updated.
|
|
86
184
|
#
|
|
185
|
+
# @example
|
|
186
|
+
# new_sheet = sheet.update_cell("B1", value: "Updated")
|
|
187
|
+
#
|
|
87
188
|
# @param ref [String] The cell reference (e.g. "B1").
|
|
88
189
|
# @param value [Object] The new cell value.
|
|
89
190
|
# @param style_index [Integer, String, nil] Optional new style index.
|
|
90
191
|
# @param formula [Elements::Formula, nil] Optional new formula.
|
|
91
192
|
# @return [Worksheet] A new Worksheet instance.
|
|
193
|
+
# @api public
|
|
194
|
+
#: (String ref, ?value: untyped, ?style_index: Integer | String | nil, ?formula: Elements::Formula?) -> Elements::Worksheet
|
|
92
195
|
def update_cell(ref, value: nil, style_index: nil, formula: nil)
|
|
93
196
|
parsed = Cell.parse_ref(ref)
|
|
94
197
|
raise ArgumentError, "invalid cell reference: #{ref}" unless parsed
|
|
@@ -124,6 +227,12 @@ module Xlsxrb
|
|
|
124
227
|
with(rows: new_rows)
|
|
125
228
|
end
|
|
126
229
|
|
|
230
|
+
# Validates worksheet name and rows against OOXML limits.
|
|
231
|
+
#
|
|
232
|
+
# @param name [String]
|
|
233
|
+
# @param rows [Array<Elements::Row>]
|
|
234
|
+
# @return [Array<String>] List of errors.
|
|
235
|
+
#: (untyped name, untyped rows) -> Array[String]
|
|
127
236
|
def self.validate(name, rows)
|
|
128
237
|
errs = []
|
|
129
238
|
if name.nil? || !name.is_a?(String) || name.empty?
|
data/lib/xlsxrb/version.rb
CHANGED