xlsxtream 2.4.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/xlsxtream.svg)](https://rubygems.org/gems/xlsxtream)
|
4
|
-
[![Build Status](https://travis-ci.org/felixbuenemann/xlsxtream.svg)](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
|