xlsxrb 0.1.7 → 0.1.9
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 +26 -2
- data/README.md +125 -36
- data/Rakefile +36 -7
- data/benchmark.rb +32 -4
- data/docs/ARCHITECTURE.md +32 -30
- data/docs/DEVELOPMENT.md +11 -3
- data/docs/QUALITY_ASSURANCE.md +3 -4
- data/docs/SPEC_SOURCES.md +7 -1
- data/docs/visual/VisualGallery.md +157 -157
- data/docs/wasm/ruby.wasm +0 -0
- data/lib/ruby_lsp/xlsxrb/addon.rb +1 -1
- data/lib/ruby_lsp/xlsxrb/completion_listener.rb +11 -13
- data/lib/xlsxrb/elements/coordinate_access.rb +101 -0
- data/lib/xlsxrb/elements/row.rb +2 -2
- data/lib/xlsxrb/elements/workbook.rb +20 -2
- data/lib/xlsxrb/elements/worksheet.rb +94 -124
- data/lib/xlsxrb/elements.rb +1 -0
- data/lib/xlsxrb/ooxml/cfb.rb +490 -0
- data/lib/xlsxrb/ooxml/crypto/agile.rb +285 -0
- data/lib/xlsxrb/ooxml/crypto/standard.rb +152 -0
- data/lib/xlsxrb/ooxml/crypto.rb +60 -0
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +21 -15
- data/lib/xlsxrb/stream_row.rb +181 -0
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb.rb +271 -122
- data/sig/generated/xlsxrb/elements/coordinate_access.rbs +70 -0
- data/sig/generated/xlsxrb/elements/worksheet.rbs +119 -14
- data/sig/generated/xlsxrb/ooxml/cfb.rbs +121 -0
- data/sig/generated/xlsxrb/ooxml/crypto/agile.rbs +46 -0
- data/sig/generated/xlsxrb/ooxml/crypto/standard.rbs +28 -0
- data/sig/generated/xlsxrb/ooxml/crypto.rbs +17 -0
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +2 -0
- data/sig/generated/xlsxrb/stream_row.rbs +127 -0
- data/sig/generated/xlsxrb.rbs +135 -71
- data/vendor/sdk_runner/Program.cs +3 -1
- metadata +13 -1
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module Xlsxrb
|
|
6
|
+
# Streaming row implementation that parses cells on-demand / lazily.
|
|
7
|
+
# Provides O(1) memory consumption even for rows with tens of thousands of columns.
|
|
8
|
+
#
|
|
9
|
+
# @example Streaming cells one-by-one (O(1) memory)
|
|
10
|
+
# row.each_cell do |cell|
|
|
11
|
+
# puts "#{cell.ref}: #{cell.value}"
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# @example Random access or array conversion (cached on-demand)
|
|
15
|
+
# cell = row[0]
|
|
16
|
+
# values = row.to_a
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
class StreamRow
|
|
20
|
+
[Enumerable].each { |m| include m }
|
|
21
|
+
|
|
22
|
+
attr_reader :index, :height, :hidden, :custom_height, :outline_level
|
|
23
|
+
|
|
24
|
+
# @param index [Integer] 0-based row index.
|
|
25
|
+
# @param xml_bytes [String] Raw ASCII-8BIT XML bytes.
|
|
26
|
+
# @param from [Integer] Byte offset where cells start.
|
|
27
|
+
# @param to [Integer] Byte offset where cells end.
|
|
28
|
+
# @param shared_strings [Array<String>] Shared strings table.
|
|
29
|
+
# @param height [Float, Integer, nil] Row height in points.
|
|
30
|
+
# @param hidden [Boolean] Whether the row is hidden.
|
|
31
|
+
# @param custom_height [Boolean] Whether custom height is set.
|
|
32
|
+
# @param outline_level [Integer, nil] Grouping/outline level.
|
|
33
|
+
#: (index: Integer, xml_bytes: String, from: Integer, to: Integer, shared_strings: Array[String], ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
|
|
34
|
+
def initialize(index:, xml_bytes:, from:, to:, shared_strings:, height: nil, hidden: false,
|
|
35
|
+
custom_height: false, outline_level: nil)
|
|
36
|
+
@index = index
|
|
37
|
+
@xml = xml_bytes
|
|
38
|
+
@from = from
|
|
39
|
+
@to = to
|
|
40
|
+
@shared_strings = shared_strings
|
|
41
|
+
@height = height
|
|
42
|
+
@hidden = hidden
|
|
43
|
+
@custom_height = custom_height
|
|
44
|
+
@outline_level = outline_level
|
|
45
|
+
@cells_cache = nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Iterate over cells in this streaming row one by one.
|
|
49
|
+
#
|
|
50
|
+
# @yield [cell]
|
|
51
|
+
# @yieldparam cell [Elements::Cell]
|
|
52
|
+
# @return [Enumerator, void]
|
|
53
|
+
# @api public
|
|
54
|
+
#: () { (Elements::Cell) -> void } -> void
|
|
55
|
+
#: () -> Enumerator[Elements::Cell, void]
|
|
56
|
+
def each_cell(&)
|
|
57
|
+
return enum_for(:each_cell) unless block_given?
|
|
58
|
+
|
|
59
|
+
if @cells
|
|
60
|
+
@cells.each(&)
|
|
61
|
+
else
|
|
62
|
+
Ooxml::WorksheetParser.fast_scan_cells_direct(@xml, @from, @to, @shared_strings, { row: @index }, &)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Iterate over cells in this streaming row.
|
|
67
|
+
#
|
|
68
|
+
# @yield [cell]
|
|
69
|
+
# @yieldparam cell [Elements::Cell]
|
|
70
|
+
# @return [Enumerator, void]
|
|
71
|
+
# @api public
|
|
72
|
+
#: () { (Elements::Cell) -> void } -> void
|
|
73
|
+
#: () -> Enumerator[Elements::Cell, void]
|
|
74
|
+
def each(&)
|
|
75
|
+
each_cell(&)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns all cells as an Array. Cached on first access.
|
|
79
|
+
#
|
|
80
|
+
# @return [Array<Elements::Cell>]
|
|
81
|
+
# @api public
|
|
82
|
+
#: () -> Array[Elements::Cell]
|
|
83
|
+
def cells
|
|
84
|
+
@cells ||= each_cell.to_a.freeze
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Access a cell by 0-based column index, or access row attributes via Symbol.
|
|
88
|
+
#
|
|
89
|
+
# @param col_index [Integer, Symbol] Column index or attribute symbol.
|
|
90
|
+
# @return [Elements::Cell, Object, nil]
|
|
91
|
+
# @api public
|
|
92
|
+
#: (Integer | Symbol col_index) -> untyped
|
|
93
|
+
def [](col_index)
|
|
94
|
+
case col_index
|
|
95
|
+
when Symbol
|
|
96
|
+
case col_index
|
|
97
|
+
when :cells then cells
|
|
98
|
+
when :index then index
|
|
99
|
+
when :height then height
|
|
100
|
+
when :hidden then hidden
|
|
101
|
+
when :custom_height then custom_height
|
|
102
|
+
when :outline_level then outline_level
|
|
103
|
+
when :attrs then { height: height, hidden: hidden, custom_height: custom_height, outline_level: outline_level }
|
|
104
|
+
end
|
|
105
|
+
else
|
|
106
|
+
cells[col_index]
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Access a cell by 0-based column index.
|
|
111
|
+
#
|
|
112
|
+
# @param col_index [Integer] 0-based column index.
|
|
113
|
+
# @return [Elements::Cell, nil]
|
|
114
|
+
# @api public
|
|
115
|
+
#: (Integer col_index) -> Elements::Cell?
|
|
116
|
+
def cell_at(col_index)
|
|
117
|
+
cells.find { |c| c.column_index == col_index }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Convert row cells to an Array of raw values (sparse columns get nil).
|
|
121
|
+
#
|
|
122
|
+
# @return [Array<Object>]
|
|
123
|
+
# @api public
|
|
124
|
+
#: () -> Array[untyped]
|
|
125
|
+
def to_a
|
|
126
|
+
return [] if cells.empty?
|
|
127
|
+
|
|
128
|
+
max_col = cells.map(&:column_index).max || 0
|
|
129
|
+
arr = Array.new(max_col + 1)
|
|
130
|
+
cells.each do |cell|
|
|
131
|
+
arr[cell.column_index] = cell.value
|
|
132
|
+
end
|
|
133
|
+
arr
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns cell values as an Array.
|
|
137
|
+
#
|
|
138
|
+
# @return [Array<Object>]
|
|
139
|
+
# @api public
|
|
140
|
+
#: () -> Array[untyped]
|
|
141
|
+
def values
|
|
142
|
+
to_a
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Returns whether the row is valid according to OOXML specifications.
|
|
146
|
+
#
|
|
147
|
+
# @return [Boolean]
|
|
148
|
+
# @api public
|
|
149
|
+
#: () -> bool
|
|
150
|
+
def valid?
|
|
151
|
+
true
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Unmapped metadata for compatibility with Elements::Row.
|
|
155
|
+
#
|
|
156
|
+
# @return [Hash]
|
|
157
|
+
# @api public
|
|
158
|
+
#: () -> Hash[untyped, untyped]
|
|
159
|
+
def unmapped_data
|
|
160
|
+
Elements::EMPTY_HASH
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Validation errors for compatibility with Elements::Row.
|
|
164
|
+
#
|
|
165
|
+
# @return [Array<String>]
|
|
166
|
+
# @api public
|
|
167
|
+
#: () -> Array[String]
|
|
168
|
+
def errors
|
|
169
|
+
Elements::EMPTY_ERRORS
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Human-readable representation.
|
|
173
|
+
#
|
|
174
|
+
# @return [String]
|
|
175
|
+
# @api public
|
|
176
|
+
#: () -> String
|
|
177
|
+
def inspect
|
|
178
|
+
"#<#{self.class.name} index=#{index} height=#{height.inspect} hidden=#{hidden}>"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
data/lib/xlsxrb/version.rb
CHANGED