xlsxtream 2.0.0 → 2.4.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 +5 -5
- data/.travis.yml +10 -5
- data/CHANGELOG.md +26 -1
- data/README.md +21 -2
- data/lib/xlsxtream.rb +2 -0
- data/lib/xlsxtream/columns.rb +57 -0
- data/lib/xlsxtream/errors.rb +1 -0
- data/lib/xlsxtream/io/directory.rb +1 -0
- data/lib/xlsxtream/io/hash.rb +1 -0
- data/lib/xlsxtream/io/rubyzip.rb +1 -0
- data/lib/xlsxtream/io/stream.rb +1 -0
- data/lib/xlsxtream/io/zip_tricks.rb +2 -1
- data/lib/xlsxtream/row.rb +28 -11
- data/lib/xlsxtream/shared_string_table.rb +1 -0
- data/lib/xlsxtream/version.rb +2 -1
- data/lib/xlsxtream/workbook.rb +46 -22
- data/lib/xlsxtream/worksheet.rb +23 -1
- data/lib/xlsxtream/xml.rb +1 -0
- data/xlsxtream.gemspec +4 -4
- metadata +25 -14
- data/lib/xlsxtream/io/zip_tricks_fibers.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ad3cd850f298db3909ce061876610fdaad2de689675d9b23d6738f8a177f5254
|
4
|
+
data.tar.gz: 5b1002fa1031cd53612735d6732acd43a8b0c086aaccc0f62f9a761583f21c5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bed396c449a050615e3822fc9c76935db6e9c7cb7434bc5a49c4effd76221ed66a023be3cff3859f30d290259c33cf685f8e8a2baaa237d52ae5787b79ee7d67
|
7
|
+
data.tar.gz: 5c31396c6b49b90c7eb9f4fd4a32959ff97eefbe2fa0936833dfc4326954d6e06a267ee4e97ee42faaf8268a2147b3e15edc1ed3341f55794e96f5531afff601
|
data/.travis.yml
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
-
|
3
|
+
os: linux
|
4
|
+
dist: xenial
|
4
5
|
cache: bundler
|
5
6
|
|
6
|
-
before_install:
|
7
|
+
before_install:
|
8
|
+
- gem install bundler -v '~> 1.15' --conservative --minimal-deps
|
7
9
|
|
8
10
|
rvm:
|
9
11
|
- 2.1.10
|
10
|
-
- 2.2.
|
11
|
-
- 2.3.
|
12
|
-
- 2.4.
|
12
|
+
- 2.2.10
|
13
|
+
- 2.3.8
|
14
|
+
- 2.4.10
|
15
|
+
- 2.5.8
|
16
|
+
- 2.6.6
|
17
|
+
- 2.7.1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.4.0 (2020-06-27)
|
4
|
+
|
5
|
+
- Allow writing worksheets without a block using add\_worksheet (#42, #45)
|
6
|
+
- Deprecate calling add\_worksheet with a block, use write\_worksheet instead (#45)
|
7
|
+
- Relax rubyzip development dependency to allow current version (#46)
|
8
|
+
|
9
|
+
## 2.3.0 (2019-11-27)
|
10
|
+
|
11
|
+
- Speed up date / time conversion to OA format (#39)
|
12
|
+
|
13
|
+
## 2.2.0 (2019-11-27)
|
14
|
+
|
15
|
+
- Allow usage with zip\_tricks 5.x gem (#38)
|
16
|
+
|
17
|
+
## 2.1.0 (2018-07-21)
|
18
|
+
|
19
|
+
- New `:columns` option, allowing column widths to be specified (#25)
|
20
|
+
- Fix compatibility with `ruby --enable-frozen-string-literal` (#27)
|
21
|
+
- Support giving the worksheet name as an option to write\_worksheet (#28)
|
22
|
+
|
23
|
+
## 2.0.1 (2018-03-11)
|
24
|
+
|
25
|
+
- Rescue gracefully from invalid dates with auto-format (#22)
|
26
|
+
- Remove unused ZipTricksFibers IO wrapper (#24)
|
27
|
+
|
3
28
|
## 2.0.0 (2017-10-31)
|
4
29
|
|
5
30
|
- Replace RubyZip with ZipTricks as default compressor (#16)
|
@@ -43,7 +68,7 @@
|
|
43
68
|
|
44
69
|
## 0.3.0 (2017-07-12)
|
45
70
|
|
46
|
-
- Add support for auto-formatting
|
71
|
+
- Add support for auto-formatting (#8)
|
47
72
|
|
48
73
|
## 0.2.0 (2017-02-20)
|
49
74
|
|
data/README.md
CHANGED
@@ -61,7 +61,7 @@ end
|
|
61
61
|
# for the workbook or a single worksheet. The SST has to be kept in memory,
|
62
62
|
# so do not use it if you have a huge amount of rows or a little duplication
|
63
63
|
# of content across cells. A single SST is used for the whole workbook.
|
64
|
-
xlsx.write_worksheet('SheetWithSST', use_shared_strings: true) do |sheet|
|
64
|
+
xlsx.write_worksheet(name: 'SheetWithSST', use_shared_strings: true) do |sheet|
|
65
65
|
sheet << ['the', 'same', 'old', 'story']
|
66
66
|
sheet << ['the', 'old', 'same', 'story']
|
67
67
|
sheet << ['old', 'the', 'same', 'story']
|
@@ -72,12 +72,19 @@ end
|
|
72
72
|
# "Number stored as text". Dates and times must be in the ISO-8601 format and
|
73
73
|
# numeric values must contain only numbers and an optional decimal separator.
|
74
74
|
# The strings true and false are detected as boolean values.
|
75
|
-
xlsx.write_worksheet('SheetWithAutoFormat', auto_format: true) do |sheet|
|
75
|
+
xlsx.write_worksheet(name: 'SheetWithAutoFormat', auto_format: true) do |sheet|
|
76
76
|
# these two rows will be identical in the xlsx-output
|
77
77
|
sheet << [true, 11.85, DateTime.parse('2050-01-01T12:00'), Date.parse('1984-01-01')]
|
78
78
|
sheet << ['true', '11.85', '2050-01-01T12:00', '1984-01-01']
|
79
79
|
end
|
80
80
|
|
81
|
+
# You can also create worksheet without a block, using the `add_worksheet` method.
|
82
|
+
# It can be only used sequentially, so remember to manually close the worksheet
|
83
|
+
# when you are done (before opening a new one).
|
84
|
+
worksheet = xls.add_worksheet(name: 'SheetWithoutBlock')
|
85
|
+
worksheet << ['some', 'data']
|
86
|
+
worksheet.close
|
87
|
+
|
81
88
|
# Writes metadata and ZIP archive central directory
|
82
89
|
xlsx.close
|
83
90
|
# Close IO object
|
@@ -90,8 +97,20 @@ Xlsxtream::Workbook.new(io, font: {
|
|
90
97
|
family: 'Roman' # Swiss, Modern, Script, Decorative
|
91
98
|
})
|
92
99
|
|
100
|
+
# Specifying column widths in pixels or characters; 3 column example;
|
101
|
+
# "pixel" widths appear to be *relative* to an assumed 11pt Calibri
|
102
|
+
# font, so if selecting a different font or size (see above), do not
|
103
|
+
# adjust widths to match. Calculate pixel widths for 11pt Calibri.
|
104
|
+
Xlsxtream::Workbook.new(io, columns: [
|
105
|
+
{ width_pixels: 33 },
|
106
|
+
{ width_chars: 7 },
|
107
|
+
{ width_chars: 24 }
|
108
|
+
])
|
109
|
+
# The :columns option can also be given to write_worksheet, so it's
|
110
|
+
# possible to have multiple worksheets with different column widths.
|
93
111
|
```
|
94
112
|
|
113
|
+
|
95
114
|
## Compatibility
|
96
115
|
|
97
116
|
The current version of Xlsxtream requires at least Ruby 2.1.0.
|
data/lib/xlsxtream.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Xlsxtream
|
3
|
+
class Columns
|
4
|
+
|
5
|
+
# Pass an Array of column options Hashes. Symbol Hash keys and associated
|
6
|
+
# values are as follows:
|
7
|
+
#
|
8
|
+
# +width_chars+:: Approximate column with in characters, calculated per
|
9
|
+
# MSDN docs as if using a default 11 point Calibri font
|
10
|
+
# for a 96 DPI target. Specify as an integer.
|
11
|
+
#
|
12
|
+
# +width_pixels+:: Exact with of column in pixels. Specify as a Float.
|
13
|
+
# Overrides +width_chars+ if that is also provided.
|
14
|
+
#
|
15
|
+
def initialize(column_options_array)
|
16
|
+
@columns = column_options_array
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_xml
|
20
|
+
xml = String.new('<cols>')
|
21
|
+
|
22
|
+
@columns.each_with_index do |column, index|
|
23
|
+
width_chars = column[ :width_chars ]
|
24
|
+
width_pixels = column[ :width_pixels ]
|
25
|
+
|
26
|
+
if width_chars.nil? && width_pixels.nil?
|
27
|
+
xml << %Q{<col min="#{index + 1}" max="#{index + 1}"/>}
|
28
|
+
else
|
29
|
+
|
30
|
+
# https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.column.aspx
|
31
|
+
#
|
32
|
+
# Truncate(
|
33
|
+
# [{Number of Characters} * {Maximum Digit Width} + {5 pixel padding}]
|
34
|
+
# /{Maximum Digit Width}*256
|
35
|
+
# )/256
|
36
|
+
#
|
37
|
+
# "Using the Calibri font as an example, the maximum digit width of
|
38
|
+
# 11 point font size is 7 pixels (at 96 dpi)"
|
39
|
+
#
|
40
|
+
# By observation, though, I note that a different spreadsheet-wide
|
41
|
+
# font size selected via the Workbook's ":font => { :size => ... }"
|
42
|
+
# options Hash entry results in Excel, at least, scaling the given
|
43
|
+
# widths in proportion with the requested font size change. We do
|
44
|
+
# not, apparently, need to do that ourselves and run the calculation
|
45
|
+
# based on the reference 11 point -> 7 pixel figure.
|
46
|
+
#
|
47
|
+
width_pixels ||= ((((width_chars * 7.0) + 5) / 7) * 256).truncate() / 256.0
|
48
|
+
|
49
|
+
xml << %Q{<col min="#{index + 1}" max="#{index + 1}" width="#{width_pixels}" customWidth="1"/>}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
xml << '</cols>'
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/xlsxtream/errors.rb
CHANGED
data/lib/xlsxtream/io/hash.rb
CHANGED
data/lib/xlsxtream/io/rubyzip.rb
CHANGED
data/lib/xlsxtream/io/stream.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "zip_tricks"
|
2
3
|
|
3
4
|
module Xlsxtream
|
@@ -8,7 +9,7 @@ module Xlsxtream
|
|
8
9
|
def initialize(body)
|
9
10
|
@streamer = ::ZipTricks::Streamer.new(body)
|
10
11
|
@wf = nil
|
11
|
-
@buffer =
|
12
|
+
@buffer = String.new
|
12
13
|
end
|
13
14
|
|
14
15
|
def <<(data)
|
data/lib/xlsxtream/row.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require "date"
|
3
3
|
require "xlsxtream/xml"
|
4
4
|
|
@@ -27,8 +27,8 @@ module Xlsxtream
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def to_xml
|
30
|
-
column = 'A'
|
31
|
-
xml = %Q{<row r="#{@rownum}">}
|
30
|
+
column = String.new('A')
|
31
|
+
xml = String.new(%Q{<row r="#{@rownum}">})
|
32
32
|
|
33
33
|
@row.each do |value|
|
34
34
|
cid = "#{column}#{@rownum}"
|
@@ -43,10 +43,12 @@ module Xlsxtream
|
|
43
43
|
xml << %Q{<c r="#{cid}" t="n"><v>#{value}</v></c>}
|
44
44
|
when TrueClass, FalseClass
|
45
45
|
xml << %Q{<c r="#{cid}" t="b"><v>#{value ? 1 : 0}</v></c>}
|
46
|
-
when Time
|
46
|
+
when Time
|
47
47
|
xml << %Q{<c r="#{cid}" s="#{TIME_STYLE}"><v>#{time_to_oa_date(value)}</v></c>}
|
48
|
+
when DateTime
|
49
|
+
xml << %Q{<c r="#{cid}" s="#{TIME_STYLE}"><v>#{datetime_to_oa_date(value)}</v></c>}
|
48
50
|
when Date
|
49
|
-
xml << %Q{<c r="#{cid}" s="#{DATE_STYLE}"><v>#{
|
51
|
+
xml << %Q{<c r="#{cid}" s="#{DATE_STYLE}"><v>#{date_to_oa_date(value)}</v></c>}
|
50
52
|
else
|
51
53
|
value = value.to_s
|
52
54
|
|
@@ -77,22 +79,37 @@ module Xlsxtream
|
|
77
79
|
when NUMBER_PATTERN
|
78
80
|
value.include?('.') ? value.to_f : value.to_i
|
79
81
|
when DATE_PATTERN
|
80
|
-
Date.parse(value)
|
82
|
+
Date.parse(value) rescue value
|
81
83
|
when TIME_PATTERN
|
82
|
-
DateTime.parse(value)
|
84
|
+
DateTime.parse(value) rescue value
|
83
85
|
else
|
84
86
|
value
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
|
-
# Converts Time
|
90
|
+
# Converts Time instance to OLE Automation Date
|
89
91
|
def time_to_oa_date(time)
|
90
|
-
time = time.to_time if time.respond_to?(:to_time)
|
91
|
-
|
92
92
|
# Local dates are stored as UTC by truncating the offset:
|
93
93
|
# 1970-01-01 00:00:00 +0200 => 1970-01-01 00:00:00 UTC
|
94
94
|
# This is done because SpreadsheetML is not timezone aware.
|
95
|
-
(time + time.utc_offset)
|
95
|
+
(time.to_f + time.utc_offset) / 86400 + 25569
|
96
|
+
end
|
97
|
+
|
98
|
+
# Converts DateTime instance to OLE Automation Date
|
99
|
+
if RUBY_ENGINE == 'ruby'
|
100
|
+
def datetime_to_oa_date(date)
|
101
|
+
_, jd, df, sf, of = date.marshal_dump
|
102
|
+
jd - 2415019 + (df + of + sf / 1e9) / 86400
|
103
|
+
end
|
104
|
+
else
|
105
|
+
def datetime_to_oa_date(date)
|
106
|
+
date.jd - 2415019 + (date.hour * 3600 + date.sec + date.sec_fraction.to_f) / 86400
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Converts Date instance to OLE Automation Date
|
111
|
+
def date_to_oa_date(date)
|
112
|
+
(date.jd - 2415019).to_f
|
96
113
|
end
|
97
114
|
end
|
98
115
|
end
|
data/lib/xlsxtream/version.rb
CHANGED
data/lib/xlsxtream/workbook.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require "xlsxtream/errors"
|
3
3
|
require "xlsxtream/xml"
|
4
4
|
require "xlsxtream/shared_string_table"
|
@@ -55,29 +55,32 @@ module Xlsxtream
|
|
55
55
|
@io = IO::ZipTricks.new(output)
|
56
56
|
end
|
57
57
|
@sst = SharedStringTable.new
|
58
|
-
@worksheets =
|
58
|
+
@worksheets = []
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
62
|
-
if
|
63
|
-
|
64
|
-
|
61
|
+
def add_worksheet(*args, &block)
|
62
|
+
if block_given?
|
63
|
+
# This method used to be an alias for `write_worksheet`. This was never publicly documented,
|
64
|
+
# but to avoid breaking this private API we keep the old behaviour when called with a block.
|
65
|
+
Kernel.warn "#{caller.first[/.*:\d+:(?=in `)/]} warning: Calling #{self.class}#add_worksheet with a block is deprecated, use #write_worksheet instead."
|
66
|
+
return write_worksheet(*args, &block)
|
65
67
|
end
|
66
|
-
use_sst = options.fetch(:use_shared_strings, @options[:use_shared_strings])
|
67
|
-
auto_format = options.fetch(:auto_format, @options[:auto_format])
|
68
|
-
sst = use_sst ? @sst : nil
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
unless @worksheets.all? { |ws| ws.closed? }
|
70
|
+
fail Error, "Close the current worksheet before adding a new one"
|
71
|
+
end
|
72
|
+
|
73
|
+
build_worksheet(*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
def write_worksheet(*args)
|
77
|
+
worksheet = build_worksheet(*args)
|
73
78
|
|
74
|
-
worksheet = Worksheet.new(@io, :sst => sst, :auto_format => auto_format)
|
75
79
|
yield worksheet if block_given?
|
76
80
|
worksheet.close
|
77
81
|
|
78
82
|
nil
|
79
83
|
end
|
80
|
-
alias_method :add_worksheet, :write_worksheet
|
81
84
|
|
82
85
|
def close
|
83
86
|
write_workbook
|
@@ -92,6 +95,27 @@ module Xlsxtream
|
|
92
95
|
end
|
93
96
|
|
94
97
|
private
|
98
|
+
def build_worksheet(name = nil, options = {})
|
99
|
+
if name.is_a? Hash and options.empty?
|
100
|
+
options = name
|
101
|
+
name = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
use_sst = options.fetch(:use_shared_strings, @options[:use_shared_strings])
|
105
|
+
auto_format = options.fetch(:auto_format, @options[:auto_format])
|
106
|
+
columns = options.fetch(:columns, @options[:columns])
|
107
|
+
sst = use_sst ? @sst : nil
|
108
|
+
|
109
|
+
sheet_id = @worksheets.size + 1
|
110
|
+
name = name || options[:name] || "Sheet#{sheet_id}"
|
111
|
+
|
112
|
+
@io.add_file "xl/worksheets/sheet#{sheet_id}.xml"
|
113
|
+
|
114
|
+
worksheet = Worksheet.new(@io, :id => sheet_id, :name => name, :sst => sst, :auto_format => auto_format, :columns => columns)
|
115
|
+
@worksheets << worksheet
|
116
|
+
|
117
|
+
worksheet
|
118
|
+
end
|
95
119
|
|
96
120
|
def write_root_rels
|
97
121
|
@io.add_file "_rels/.rels"
|
@@ -104,7 +128,7 @@ module Xlsxtream
|
|
104
128
|
end
|
105
129
|
|
106
130
|
def write_workbook
|
107
|
-
rid = "rId0"
|
131
|
+
rid = String.new("rId0")
|
108
132
|
@io.add_file "xl/workbook.xml"
|
109
133
|
@io << XML.header
|
110
134
|
@io << XML.strip(<<-XML)
|
@@ -112,8 +136,8 @@ module Xlsxtream
|
|
112
136
|
<workbookPr date1904="false"/>
|
113
137
|
<sheets>
|
114
138
|
XML
|
115
|
-
@worksheets.each do |
|
116
|
-
@io << %'<sheet name="#{XML.escape_attr name}" sheetId="#{
|
139
|
+
@worksheets.each do |worksheet|
|
140
|
+
@io << %'<sheet name="#{XML.escape_attr worksheet.name}" sheetId="#{worksheet.id}" r:id="#{rid.next!}"/>'
|
117
141
|
end
|
118
142
|
@io << XML.strip(<<-XML)
|
119
143
|
</sheets>
|
@@ -184,12 +208,12 @@ module Xlsxtream
|
|
184
208
|
end
|
185
209
|
|
186
210
|
def write_workbook_rels
|
187
|
-
rid = "rId0"
|
211
|
+
rid = String.new("rId0")
|
188
212
|
@io.add_file "xl/_rels/workbook.xml.rels"
|
189
213
|
@io << XML.header
|
190
214
|
@io << '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
|
191
|
-
@worksheets.each do |
|
192
|
-
@io << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet#{
|
215
|
+
@worksheets.each do |worksheet|
|
216
|
+
@io << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet#{worksheet.id}.xml"/>'
|
193
217
|
end
|
194
218
|
@io << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>'
|
195
219
|
@io << %'<Relationship Id="#{rid.next!}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>' unless @sst.empty?
|
@@ -207,8 +231,8 @@ module Xlsxtream
|
|
207
231
|
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
208
232
|
XML
|
209
233
|
@io << '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>' unless @sst.empty?
|
210
|
-
@worksheets.
|
211
|
-
@io << %'<Override PartName="/xl/worksheets/sheet#{
|
234
|
+
@worksheets.each do |worksheet|
|
235
|
+
@io << %'<Override PartName="/xl/worksheets/sheet#{worksheet.id}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
|
212
236
|
end
|
213
237
|
@io << '</Types>'
|
214
238
|
end
|
data/lib/xlsxtream/worksheet.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require "xlsxtream/xml"
|
3
3
|
require "xlsxtream/row"
|
4
4
|
|
@@ -7,6 +7,7 @@ module Xlsxtream
|
|
7
7
|
def initialize(io, options = {})
|
8
8
|
@io = io
|
9
9
|
@rownum = 1
|
10
|
+
@closed = false
|
10
11
|
@options = options
|
11
12
|
|
12
13
|
write_header
|
@@ -20,6 +21,19 @@ module Xlsxtream
|
|
20
21
|
|
21
22
|
def close
|
22
23
|
write_footer
|
24
|
+
@closed = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def closed?
|
28
|
+
@closed
|
29
|
+
end
|
30
|
+
|
31
|
+
def id
|
32
|
+
@options[:id]
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
@options[:name]
|
23
37
|
end
|
24
38
|
|
25
39
|
private
|
@@ -28,6 +42,14 @@ module Xlsxtream
|
|
28
42
|
@io << XML.header
|
29
43
|
@io << XML.strip(<<-XML)
|
30
44
|
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
45
|
+
XML
|
46
|
+
|
47
|
+
columns = Array(@options[:columns])
|
48
|
+
unless columns.empty?
|
49
|
+
@io << Columns.new(columns).to_xml
|
50
|
+
end
|
51
|
+
|
52
|
+
@io << XML.strip(<<-XML)
|
31
53
|
<sheetData>
|
32
54
|
XML
|
33
55
|
end
|
data/lib/xlsxtream/xml.rb
CHANGED
data/xlsxtream.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'xlsxtream/version'
|
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
spec.required_ruby_version = ">= 2.1.0"
|
22
22
|
|
23
|
-
spec.add_dependency "zip_tricks", "
|
23
|
+
spec.add_dependency "zip_tricks", ">= 4.5", "< 6"
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler", "
|
25
|
+
spec.add_development_dependency "bundler", ">= 1.7", "< 3"
|
26
26
|
spec.add_development_dependency "rake"
|
27
|
-
spec.add_development_dependency "rubyzip", "
|
27
|
+
spec.add_development_dependency "rubyzip", ">= 1.2"
|
28
28
|
spec.add_development_dependency "minitest"
|
29
29
|
spec.add_development_dependency "pry"
|
30
30
|
end
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xlsxtream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Bünemann
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zip_tricks
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.5'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '4.5'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: bundler
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '1.7'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '3'
|
34
43
|
type: :development
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
39
48
|
- !ruby/object:Gem::Version
|
40
49
|
version: '1.7'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '3'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: rake
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,14 +68,14 @@ dependencies:
|
|
56
68
|
name: rubyzip
|
57
69
|
requirement: !ruby/object:Gem::Requirement
|
58
70
|
requirements:
|
59
|
-
- - "
|
71
|
+
- - ">="
|
60
72
|
- !ruby/object:Gem::Version
|
61
73
|
version: '1.2'
|
62
74
|
type: :development
|
63
75
|
prerelease: false
|
64
76
|
version_requirements: !ruby/object:Gem::Requirement
|
65
77
|
requirements:
|
66
|
-
- - "
|
78
|
+
- - ">="
|
67
79
|
- !ruby/object:Gem::Version
|
68
80
|
version: '1.2'
|
69
81
|
- !ruby/object:Gem::Dependency
|
@@ -112,13 +124,13 @@ files:
|
|
112
124
|
- bin/console
|
113
125
|
- bin/setup
|
114
126
|
- lib/xlsxtream.rb
|
127
|
+
- lib/xlsxtream/columns.rb
|
115
128
|
- lib/xlsxtream/errors.rb
|
116
129
|
- lib/xlsxtream/io/directory.rb
|
117
130
|
- lib/xlsxtream/io/hash.rb
|
118
131
|
- lib/xlsxtream/io/rubyzip.rb
|
119
132
|
- lib/xlsxtream/io/stream.rb
|
120
133
|
- lib/xlsxtream/io/zip_tricks.rb
|
121
|
-
- lib/xlsxtream/io/zip_tricks_fibers.rb
|
122
134
|
- lib/xlsxtream/row.rb
|
123
135
|
- lib/xlsxtream/shared_string_table.rb
|
124
136
|
- lib/xlsxtream/version.rb
|
@@ -130,7 +142,7 @@ homepage: https://github.com/felixbuenemann/xlsxtream
|
|
130
142
|
licenses:
|
131
143
|
- MIT
|
132
144
|
metadata: {}
|
133
|
-
post_install_message:
|
145
|
+
post_install_message:
|
134
146
|
rdoc_options: []
|
135
147
|
require_paths:
|
136
148
|
- lib
|
@@ -145,9 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
157
|
- !ruby/object:Gem::Version
|
146
158
|
version: '0'
|
147
159
|
requirements: []
|
148
|
-
|
149
|
-
|
150
|
-
signing_key:
|
160
|
+
rubygems_version: 3.1.2
|
161
|
+
signing_key:
|
151
162
|
specification_version: 4
|
152
163
|
summary: Xlsxtream is a streaming XLSX spreadsheet writer
|
153
164
|
test_files: []
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require "zip_tricks"
|
2
|
-
|
3
|
-
module Xlsxtream
|
4
|
-
module IO
|
5
|
-
class ZipTricksFibers
|
6
|
-
def initialize(body)
|
7
|
-
@streamer = ::ZipTricks::Streamer.new(body)
|
8
|
-
@wf = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def <<(data)
|
12
|
-
@wf.resume(data)
|
13
|
-
self
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_file(path)
|
17
|
-
@wf.resume(:__close__) if @wf
|
18
|
-
|
19
|
-
@wf = Fiber.new do | bytes_or_close_sym |
|
20
|
-
@streamer.write_deflated_file(path) do |write_sink|
|
21
|
-
loop do
|
22
|
-
break if bytes_or_close_sym == :__close__
|
23
|
-
write_sink << bytes_or_close_sym
|
24
|
-
bytes_or_close_sym = Fiber.yield
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def close
|
31
|
-
@wf.resume(:__close__) if @wf
|
32
|
-
@streamer.close
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|