xlsxtream 2.4.0 → 3.0.0
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/.github/workflows/ci.yml +27 -0
- data/CHANGELOG.md +9 -0
- data/README.md +22 -23
- data/lib/xlsxtream/version.rb +1 -1
- data/lib/xlsxtream/workbook.rb +35 -52
- data/lib/xlsxtream/zip_kit_writer.rb +74 -0
- data/xlsxtream.gemspec +2 -2
- metadata +11 -15
- data/.travis.yml +0 -17
- data/lib/xlsxtream/io/directory.rb +0 -28
- data/lib/xlsxtream/io/hash.rb +0 -47
- data/lib/xlsxtream/io/rubyzip.rb +0 -31
- data/lib/xlsxtream/io/stream.rb +0 -26
- data/lib/xlsxtream/io/zip_tricks.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e14836ad11f003e4019482eaf41eaf3a9ff76cb2dd61936a38b295e3b8e95b1a
|
4
|
+
data.tar.gz: 1603a0f3563d7c1f433ccaea41f73afca61603165d02d3c6b984225fecbb4cce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e196498e8816bd269ad49f09fb47774b19518b3add9f4b466be2bb919b87bae5d48539209357f3fa124671586352b5b473af49b7175349d83066db2bbc10e17f
|
7
|
+
data.tar.gz: 86f3dd5355883938d09c38f2c20d8840c650be9bea551916c3b1290994060d89df7acb1b984f86c2c80c2596ce037b927e7f1d66ffd2ca8a3a706a4e112141de
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
|
6
|
+
env:
|
7
|
+
BUNDLE_PATH: vendor/bundle
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
name: Tests
|
12
|
+
runs-on: ubuntu-22.04
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
ruby:
|
16
|
+
- '2.6'
|
17
|
+
- '3.2'
|
18
|
+
steps:
|
19
|
+
- name: Checkout
|
20
|
+
uses: actions/checkout@v4
|
21
|
+
- name: Setup Ruby
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
25
|
+
bundler-cache: true
|
26
|
+
- name: "Tests"
|
27
|
+
run: bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.0.0 (2024-12-28)
|
4
|
+
|
5
|
+
- Change dependency from zip\_tricks to zip\_kit (#57)
|
6
|
+
- Switch from Travis-CI to Github Actions (#58)
|
7
|
+
- Allow ZipKit streamer to be passed in as output destination (#59)
|
8
|
+
- Remove IO wrappers and leave just the ZIP output wrapper (#59)
|
9
|
+
- Ensure the gem can use the ZipKit Rails streaming helper for output (#59)
|
10
|
+
- Drop support for Ruby < 2.6.0 (required for zip\_kit gem)
|
11
|
+
|
3
12
|
## 2.4.0 (2020-06-27)
|
4
13
|
|
5
14
|
- Allow writing worksheets without a block using add\_worksheet (#42, #45)
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Xlsxtream
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/xlsxtream)
|
4
|
-
[](https://travis-ci.org/felixbuenemann/xlsxtream)
|
5
4
|
|
6
5
|
Xlsxtream is a streaming writer for XLSX spreadsheets. It supports multiple worksheets and optional string
|
7
6
|
deduplication via a shared string table (SST). Its purpose is to replace CSV for large exports, because using
|
@@ -10,7 +9,7 @@ low memory usage.
|
|
10
9
|
|
11
10
|
Xlsxtream does not support formatting, charts, comments and a myriad of
|
12
11
|
other [OOXML](https://en.wikipedia.org/wiki/Office_Open_XML) features. If you are looking for a
|
13
|
-
fully featured solution take a look at [
|
12
|
+
fully featured solution take a look at [caxslx](https://github.com/caxlsx/caxlsx).
|
14
13
|
|
15
14
|
Xlsxtream supports writing to files or IO-like objects, data is flushed as the ZIP compressor sees fit.
|
16
15
|
|
@@ -33,7 +32,7 @@ Or install it yourself as:
|
|
33
32
|
## Usage
|
34
33
|
|
35
34
|
```ruby
|
36
|
-
# Creates a new workbook and
|
35
|
+
# Creates a new workbook file, write and close it at the end of the block
|
37
36
|
Xlsxtream::Workbook.open('my_data.xlsx') do |xlsx|
|
38
37
|
xlsx.write_worksheet 'Sheet1' do |sheet|
|
39
38
|
# Boolean, Date, Time, DateTime and Numeric are properly mapped
|
@@ -108,36 +107,36 @@ Xlsxtream::Workbook.new(io, columns: [
|
|
108
107
|
])
|
109
108
|
# The :columns option can also be given to write_worksheet, so it's
|
110
109
|
# possible to have multiple worksheets with different column widths.
|
111
|
-
```
|
112
|
-
|
113
|
-
|
114
|
-
## Compatibility
|
115
|
-
|
116
|
-
The current version of Xlsxtream requires at least Ruby 2.1.0.
|
117
110
|
|
118
|
-
If you are using an older Ruby version you can use the following in your Gemfile:
|
119
111
|
|
120
|
-
|
121
|
-
|
112
|
+
# Output from Rails (will stream without buffering)
|
113
|
+
class ReportsController < ApplicationController
|
114
|
+
include ZipKit::RailsStreaming
|
115
|
+
EXCEL_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
116
|
+
|
117
|
+
def download
|
118
|
+
zip_kit_stream(filename: "report.xlsx", type: EXCEL_CONTENT_TYPE) do |zip_kit_streamer|
|
119
|
+
Xlsxtream::Workbook.open(zip_kit_streamer) do |xlsx|
|
120
|
+
xlsx.write_worksheet 'Sheet1' do |sheet|
|
121
|
+
# Boolean, Date, Time, DateTime and Numeric are properly mapped
|
122
|
+
sheet << [true, Date.today, 'hello', 'world', 42, 3.14159265359, 42**13]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
122
128
|
```
|
123
129
|
|
124
|
-
|
125
|
-
* The last version with support for Ruby 1.9.2 is 1.3.2.
|
130
|
+
## Compatibility
|
126
131
|
|
127
|
-
|
132
|
+
The current version of Xlsxtream requires at least Ruby 2.6
|
128
133
|
|
129
|
-
If you are
|
134
|
+
If you are using an older Ruby version you can use the following in your Gemfile:
|
130
135
|
|
131
136
|
```ruby
|
132
|
-
|
133
|
-
Xlsxtream::Workbook.new(io, io_wrapper: MyCustomIOWrapper)
|
134
|
-
# New code with IO wrapper instance
|
135
|
-
io_wrapper = MyCustomIOWrapper.new(io)
|
136
|
-
Xlsxtream::Workbook.new(io_wrapper)
|
137
|
+
gem 'xlsxtream', '< 3'
|
137
138
|
```
|
138
139
|
|
139
|
-
Every IO-like object that responds to `:add_file` is treated as an IO wrapper.
|
140
|
-
|
141
140
|
## Development
|
142
141
|
|
143
142
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/xlsxtream/version.rb
CHANGED
data/lib/xlsxtream/workbook.rb
CHANGED
@@ -3,7 +3,7 @@ require "xlsxtream/errors"
|
|
3
3
|
require "xlsxtream/xml"
|
4
4
|
require "xlsxtream/shared_string_table"
|
5
5
|
require "xlsxtream/worksheet"
|
6
|
-
require "xlsxtream/
|
6
|
+
require "xlsxtream/zip_kit_writer"
|
7
7
|
|
8
8
|
module Xlsxtream
|
9
9
|
class Workbook
|
@@ -35,25 +35,8 @@ module Xlsxtream
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def initialize(output, options = {})
|
38
|
-
|
39
|
-
fail Error, "Xlsxtream::Workbook.new output cannot be nil"
|
40
|
-
end
|
38
|
+
@writer = ZipKitWriter.with_output_to(output)
|
41
39
|
@options = options
|
42
|
-
if options[:io_wrapper]
|
43
|
-
fail Deprecation,
|
44
|
-
"The Xlsxtream::Workbook.new :io_wrapper option is deprecated. "\
|
45
|
-
"Please pass an IO wrapper instance as the first argument instead."
|
46
|
-
end
|
47
|
-
if output.is_a?(String) || !output.respond_to?(:<<)
|
48
|
-
@file = File.open(output, 'wb')
|
49
|
-
@io = IO::ZipTricks.new(@file)
|
50
|
-
elsif output.respond_to? :add_file
|
51
|
-
@file = nil
|
52
|
-
@io = output
|
53
|
-
else
|
54
|
-
@file = nil
|
55
|
-
@io = IO::ZipTricks.new(output)
|
56
|
-
end
|
57
40
|
@sst = SharedStringTable.new
|
58
41
|
@worksheets = []
|
59
42
|
end
|
@@ -89,8 +72,8 @@ module Xlsxtream
|
|
89
72
|
write_workbook_rels
|
90
73
|
write_root_rels
|
91
74
|
write_content_types
|
92
|
-
@
|
93
|
-
|
75
|
+
@writer.close
|
76
|
+
|
94
77
|
nil
|
95
78
|
end
|
96
79
|
|
@@ -109,18 +92,18 @@ module Xlsxtream
|
|
109
92
|
sheet_id = @worksheets.size + 1
|
110
93
|
name = name || options[:name] || "Sheet#{sheet_id}"
|
111
94
|
|
112
|
-
@
|
95
|
+
@writer.add_file "xl/worksheets/sheet#{sheet_id}.xml"
|
113
96
|
|
114
|
-
worksheet = Worksheet.new(@
|
97
|
+
worksheet = Worksheet.new(@writer, :id => sheet_id, :name => name, :sst => sst, :auto_format => auto_format, :columns => columns)
|
115
98
|
@worksheets << worksheet
|
116
99
|
|
117
100
|
worksheet
|
118
101
|
end
|
119
102
|
|
120
103
|
def write_root_rels
|
121
|
-
@
|
122
|
-
@
|
123
|
-
@
|
104
|
+
@writer.add_file "_rels/.rels"
|
105
|
+
@writer << XML.header
|
106
|
+
@writer << XML.strip(<<-XML)
|
124
107
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
125
108
|
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
|
126
109
|
</Relationships>
|
@@ -129,17 +112,17 @@ module Xlsxtream
|
|
129
112
|
|
130
113
|
def write_workbook
|
131
114
|
rid = String.new("rId0")
|
132
|
-
@
|
133
|
-
@
|
134
|
-
@
|
115
|
+
@writer.add_file "xl/workbook.xml"
|
116
|
+
@writer << XML.header
|
117
|
+
@writer << XML.strip(<<-XML)
|
135
118
|
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
136
119
|
<workbookPr date1904="false"/>
|
137
120
|
<sheets>
|
138
121
|
XML
|
139
122
|
@worksheets.each do |worksheet|
|
140
|
-
@
|
123
|
+
@writer << %'<sheet name="#{XML.escape_attr worksheet.name}" sheetId="#{worksheet.id}" r:id="#{rid.next!}"/>'
|
141
124
|
end
|
142
|
-
@
|
125
|
+
@writer << XML.strip(<<-XML)
|
143
126
|
</sheets>
|
144
127
|
</workbook>
|
145
128
|
XML
|
@@ -154,9 +137,9 @@ module Xlsxtream
|
|
154
137
|
"Invalid font family #{font_family}, must be one of "\
|
155
138
|
+ FONT_FAMILY_IDS.keys.map(&:inspect).join(', ')
|
156
139
|
|
157
|
-
@
|
158
|
-
@
|
159
|
-
@
|
140
|
+
@writer.add_file "xl/styles.xml"
|
141
|
+
@writer << XML.header
|
142
|
+
@writer << XML.strip(<<-XML)
|
160
143
|
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
161
144
|
<numFmts count="2">
|
162
145
|
<numFmt numFmtId="164" formatCode="yyyy\\-mm\\-dd"/>
|
@@ -198,43 +181,43 @@ module Xlsxtream
|
|
198
181
|
end
|
199
182
|
|
200
183
|
def write_sst
|
201
|
-
@
|
202
|
-
@
|
203
|
-
@
|
184
|
+
@writer.add_file "xl/sharedStrings.xml"
|
185
|
+
@writer << XML.header
|
186
|
+
@writer << %'<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="#{@sst.references}" uniqueCount="#{@sst.size}">'
|
204
187
|
@sst.each_key do |string|
|
205
|
-
@
|
188
|
+
@writer << "<si><t>#{XML.escape_value string}</t></si>"
|
206
189
|
end
|
207
|
-
@
|
190
|
+
@writer << '</sst>'
|
208
191
|
end
|
209
192
|
|
210
193
|
def write_workbook_rels
|
211
194
|
rid = String.new("rId0")
|
212
|
-
@
|
213
|
-
@
|
214
|
-
@
|
195
|
+
@writer.add_file "xl/_rels/workbook.xml.rels"
|
196
|
+
@writer << XML.header
|
197
|
+
@writer << '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
215
198
|
@worksheets.each do |worksheet|
|
216
|
-
@
|
199
|
+
@writer << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet#{worksheet.id}.xml"/>'
|
217
200
|
end
|
218
|
-
@
|
219
|
-
@
|
220
|
-
@
|
201
|
+
@writer << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>'
|
202
|
+
@writer << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>' unless @sst.empty?
|
203
|
+
@writer << '</Relationships>'
|
221
204
|
end
|
222
205
|
|
223
206
|
def write_content_types
|
224
|
-
@
|
225
|
-
@
|
226
|
-
@
|
207
|
+
@writer.add_file "[Content_Types].xml"
|
208
|
+
@writer << XML.header
|
209
|
+
@writer << XML.strip(<<-XML)
|
227
210
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
228
211
|
<Default Extension="xml" ContentType="application/xml"/>
|
229
212
|
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
230
213
|
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
231
214
|
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
232
215
|
XML
|
233
|
-
@
|
216
|
+
@writer << '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>' unless @sst.empty?
|
234
217
|
@worksheets.each do |worksheet|
|
235
|
-
@
|
218
|
+
@writer << %'<Override PartName="/xl/worksheets/sheet#{worksheet.id}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
|
236
219
|
end
|
237
|
-
@
|
220
|
+
@writer << '</Types>'
|
238
221
|
end
|
239
222
|
end
|
240
223
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "zip_kit"
|
3
|
+
|
4
|
+
module Xlsxtream
|
5
|
+
class ZipKitWriter
|
6
|
+
BUFFER_SIZE = 64 * 1024
|
7
|
+
|
8
|
+
def self.with_output_to(output)
|
9
|
+
if output.is_a?(self)
|
10
|
+
output
|
11
|
+
elsif output.is_a?(ZipKit::Streamer)
|
12
|
+
# If this is a Streamer which has already been initialized, it is likely that the streamer
|
13
|
+
# was initialized with a Streamer.open block - it will close itself. This allows xslxstream
|
14
|
+
# to be used with zip_kit_stream and other cases where the Streamer is managed externally
|
15
|
+
new(output, close: [])
|
16
|
+
elsif output.is_a?(String)
|
17
|
+
file = File.open(output, 'wb')
|
18
|
+
streamer = ZipKit::Streamer.new(file)
|
19
|
+
# First the Streamer needs to be closed (to write out the central directory), then the file
|
20
|
+
new(streamer, close: [streamer, file])
|
21
|
+
elsif output.respond_to?(:<<) || output.respond_to?(:write)
|
22
|
+
streamer = ZipKit::Streamer.new(output)
|
23
|
+
new(streamer, close: [streamer])
|
24
|
+
else
|
25
|
+
error = <<~MSG
|
26
|
+
An `output` object must be one of:
|
27
|
+
|
28
|
+
* A String containing a path to a file ("workbook.xslx")
|
29
|
+
* A ZipKit::Streamer
|
30
|
+
* An IO-like object responding to #<< or #write
|
31
|
+
|
32
|
+
but it was a #{output.class}
|
33
|
+
MSG
|
34
|
+
raise ArgumentError, error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(streamer, close: [])
|
39
|
+
@streamer = streamer
|
40
|
+
@currently_writing_file_inside_zip = nil
|
41
|
+
@buffer = String.new
|
42
|
+
@close = close
|
43
|
+
end
|
44
|
+
|
45
|
+
def <<(data)
|
46
|
+
@buffer << data
|
47
|
+
flush_buffer if @buffer.size >= BUFFER_SIZE
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_file(path)
|
52
|
+
flush_file
|
53
|
+
@currently_writing_file_inside_zip = @streamer.write_deflated_file(path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def close
|
57
|
+
flush_file
|
58
|
+
@close.each(&:close)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def flush_buffer
|
64
|
+
@currently_writing_file_inside_zip << @buffer
|
65
|
+
@buffer.clear
|
66
|
+
end
|
67
|
+
|
68
|
+
def flush_file
|
69
|
+
return unless @currently_writing_file_inside_zip
|
70
|
+
flush_buffer if @buffer.size > 0
|
71
|
+
@currently_writing_file_inside_zip.close
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/xlsxtream.gemspec
CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.bindir = "exe"
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
-
spec.required_ruby_version = ">= 2.
|
21
|
+
spec.required_ruby_version = ">= 2.6.0"
|
22
22
|
|
23
|
-
spec.add_dependency "
|
23
|
+
spec.add_dependency "zip_kit", ">= 6.2", "< 7"
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler", ">= 1.7", "< 3"
|
26
26
|
spec.add_development_dependency "rake"
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xlsxtream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Bünemann
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: zip_kit
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.2'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '6.2'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: bundler
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,8 +114,8 @@ executables: []
|
|
114
114
|
extensions: []
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
|
+
- ".github/workflows/ci.yml"
|
117
118
|
- ".gitignore"
|
118
|
-
- ".travis.yml"
|
119
119
|
- CHANGELOG.md
|
120
120
|
- Gemfile
|
121
121
|
- LICENSE.txt
|
@@ -126,17 +126,13 @@ files:
|
|
126
126
|
- lib/xlsxtream.rb
|
127
127
|
- lib/xlsxtream/columns.rb
|
128
128
|
- lib/xlsxtream/errors.rb
|
129
|
-
- lib/xlsxtream/io/directory.rb
|
130
|
-
- lib/xlsxtream/io/hash.rb
|
131
|
-
- lib/xlsxtream/io/rubyzip.rb
|
132
|
-
- lib/xlsxtream/io/stream.rb
|
133
|
-
- lib/xlsxtream/io/zip_tricks.rb
|
134
129
|
- lib/xlsxtream/row.rb
|
135
130
|
- lib/xlsxtream/shared_string_table.rb
|
136
131
|
- lib/xlsxtream/version.rb
|
137
132
|
- lib/xlsxtream/workbook.rb
|
138
133
|
- lib/xlsxtream/worksheet.rb
|
139
134
|
- lib/xlsxtream/xml.rb
|
135
|
+
- lib/xlsxtream/zip_kit_writer.rb
|
140
136
|
- xlsxtream.gemspec
|
141
137
|
homepage: https://github.com/felixbuenemann/xlsxtream
|
142
138
|
licenses:
|
@@ -150,14 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
150
146
|
requirements:
|
151
147
|
- - ">="
|
152
148
|
- !ruby/object:Gem::Version
|
153
|
-
version: 2.
|
149
|
+
version: 2.6.0
|
154
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
151
|
requirements:
|
156
152
|
- - ">="
|
157
153
|
- !ruby/object:Gem::Version
|
158
154
|
version: '0'
|
159
155
|
requirements: []
|
160
|
-
rubygems_version: 3.
|
156
|
+
rubygems_version: 3.4.19
|
161
157
|
signing_key:
|
162
158
|
specification_version: 4
|
163
159
|
summary: Xlsxtream is a streaming XLSX spreadsheet writer
|
data/.travis.yml
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "pathname"
|
3
|
-
|
4
|
-
module Xlsxtream
|
5
|
-
module IO
|
6
|
-
class Directory
|
7
|
-
def initialize(path)
|
8
|
-
@path = Pathname(path)
|
9
|
-
@file = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def <<(data)
|
13
|
-
@file << data
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_file(path)
|
17
|
-
close
|
18
|
-
file_path = @path + path
|
19
|
-
file_path.parent.mkpath
|
20
|
-
@file = file_path.open("wb")
|
21
|
-
end
|
22
|
-
|
23
|
-
def close
|
24
|
-
@file.close if @file
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/xlsxtream/io/hash.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Xlsxtream
|
3
|
-
module IO
|
4
|
-
class Hash
|
5
|
-
def initialize(stream)
|
6
|
-
@stream = stream
|
7
|
-
@hash = {}
|
8
|
-
@path = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def <<(data)
|
12
|
-
@stream << data
|
13
|
-
end
|
14
|
-
|
15
|
-
def add_file(path)
|
16
|
-
close
|
17
|
-
@path = path
|
18
|
-
@hash[@path] = [@stream.tell]
|
19
|
-
end
|
20
|
-
|
21
|
-
def close
|
22
|
-
@hash[@path] << @stream.tell if @path
|
23
|
-
end
|
24
|
-
|
25
|
-
def fetch(path)
|
26
|
-
old = @stream.tell
|
27
|
-
from, to = @hash.fetch(path)
|
28
|
-
size = to - from
|
29
|
-
@stream.seek(from)
|
30
|
-
data = @stream.read(size)
|
31
|
-
@stream.seek(old)
|
32
|
-
data
|
33
|
-
end
|
34
|
-
|
35
|
-
def [](path)
|
36
|
-
fetch(path)
|
37
|
-
rescue KeyError
|
38
|
-
nil
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_h
|
42
|
-
::Hash[@hash.keys.map {|path| [path, fetch(path)] }]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
data/lib/xlsxtream/io/rubyzip.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "zip"
|
3
|
-
require "xlsxtream/errors"
|
4
|
-
|
5
|
-
module Xlsxtream
|
6
|
-
module IO
|
7
|
-
class RubyZip
|
8
|
-
def initialize(io)
|
9
|
-
unless io.respond_to? :pos and io.respond_to? :pos=
|
10
|
-
raise Error, 'IO is not seekable'
|
11
|
-
end
|
12
|
-
io.binmode if io.respond_to? :binmode
|
13
|
-
stream = true
|
14
|
-
@zos = Zip::OutputStream.new(io, stream)
|
15
|
-
end
|
16
|
-
|
17
|
-
def <<(data)
|
18
|
-
@zos << data
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_file(path)
|
22
|
-
@zos.put_next_entry path
|
23
|
-
end
|
24
|
-
|
25
|
-
def close
|
26
|
-
os = @zos.close_buffer
|
27
|
-
os.flush if os.respond_to? :flush
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/xlsxtream/io/stream.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Xlsxtream
|
3
|
-
module IO
|
4
|
-
class Stream
|
5
|
-
def initialize(stream)
|
6
|
-
@stream = stream
|
7
|
-
@path = nil
|
8
|
-
end
|
9
|
-
|
10
|
-
def <<(data)
|
11
|
-
@stream << data
|
12
|
-
end
|
13
|
-
|
14
|
-
def add_file(path)
|
15
|
-
close
|
16
|
-
@path = path
|
17
|
-
@stream << "#@path\n"
|
18
|
-
end
|
19
|
-
|
20
|
-
def close
|
21
|
-
@stream << "\n" if @path
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "zip_tricks"
|
3
|
-
|
4
|
-
module Xlsxtream
|
5
|
-
module IO
|
6
|
-
class ZipTricks
|
7
|
-
BUFFER_SIZE = 64 * 1024
|
8
|
-
|
9
|
-
def initialize(body)
|
10
|
-
@streamer = ::ZipTricks::Streamer.new(body)
|
11
|
-
@wf = nil
|
12
|
-
@buffer = String.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def <<(data)
|
16
|
-
@buffer << data
|
17
|
-
flush_buffer if @buffer.size >= BUFFER_SIZE
|
18
|
-
self
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_file(path)
|
22
|
-
flush_file
|
23
|
-
@wf = @streamer.write_deflated_file(path)
|
24
|
-
end
|
25
|
-
|
26
|
-
def close
|
27
|
-
flush_file
|
28
|
-
@streamer.close
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def flush_buffer
|
34
|
-
@wf << @buffer
|
35
|
-
@buffer.clear
|
36
|
-
end
|
37
|
-
|
38
|
-
def flush_file
|
39
|
-
return unless @wf
|
40
|
-
flush_buffer if @buffer.size > 0
|
41
|
-
@wf.close
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|