fast_excel 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -1
- data/.travis.yml +12 -12
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +21 -16
- data/Makefile +2 -0
- data/README.md +30 -3
- data/Rakefile +8 -0
- data/benchmarks/1k_rows.rb +17 -4
- data/benchmarks/20k_rows.rb +4 -0
- data/benchmarks/auto_width.rb +37 -0
- data/benchmarks/init.rb +14 -2
- data/benchmarks/memory.rb +8 -0
- data/benchmarks/profiler.rb +27 -0
- data/benchmarks/write_value.rb +62 -0
- data/examples/example_auto_width.rb +26 -0
- data/ext/fast_excel/extconf.rb +3 -0
- data/ext/fast_excel/text_width_ext.c +460 -0
- data/fast_excel.gemspec +2 -3
- data/letters.html +114 -0
- data/lib/fast_excel.rb +79 -13
- data/lib/fast_excel/binding/format.rb +8 -1
- data/test/auto_width_test.rb +19 -0
- data/test/format_test.rb +8 -0
- data/test/text_width_test.rb +80 -0
- data/test/worksheet_test.rb +1 -1
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 26cc6868779b440f2c848e60a68bce2272760255e1c4d4e887edae312d16eb76
|
4
|
+
data.tar.gz: 43e3d4288b2c2bb06685308a4c97b267a563d72c32c4902793dd6d3030cde890
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49fa98254e1c6b147e0edd4262ddd87d5b75410b42b38843ae887bbb98ce9aae6bf6607bdebeec840bca73c98ebc5be1f451ed227d51a147fb6a1c6bd8bd0f67
|
7
|
+
data.tar.gz: 724f6b6e146816061c270899d798faa6ddcbe29e8ce9aba958bc23cb14c3ecdd0e0ce7de686b92b997957c73164a7f83c52f3283499a193eab96670bc9fdecec
|
data/.gitignore
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
.ruby-version
|
2
|
+
.idea/
|
2
3
|
try.c
|
3
4
|
try.rb
|
4
5
|
gen.rb
|
@@ -11,6 +12,6 @@ libxlsxwriter/dev
|
|
11
12
|
libxlsxwriter/docs
|
12
13
|
libxlsxwriter/examples
|
13
14
|
libxlsxwriter/test
|
14
|
-
|
15
|
+
ext/fast_excel/text_width_ext.o
|
15
16
|
ext/fast_excel/Makefile
|
16
17
|
ext/fast_excel/text_width_ext.bundle
|
data/.travis.yml
CHANGED
@@ -3,26 +3,26 @@ language: ruby
|
|
3
3
|
|
4
4
|
matrix:
|
5
5
|
include:
|
6
|
+
# - os: linux
|
7
|
+
# rvm: 2.2.10
|
8
|
+
# - os: osx
|
9
|
+
# rvm: 2.2.10
|
6
10
|
- os: linux
|
7
|
-
rvm: 2.
|
11
|
+
rvm: 2.3.8
|
8
12
|
- os: osx
|
9
|
-
rvm: 2.
|
13
|
+
rvm: 2.3.8
|
10
14
|
- os: linux
|
11
|
-
rvm: 2.
|
15
|
+
rvm: 2.4.5
|
12
16
|
- os: osx
|
13
|
-
rvm: 2.
|
17
|
+
rvm: 2.4.5
|
14
18
|
- os: linux
|
15
|
-
rvm: 2.3
|
19
|
+
rvm: 2.5.3
|
16
20
|
- os: osx
|
17
|
-
rvm: 2.3
|
21
|
+
rvm: 2.5.3
|
18
22
|
- os: linux
|
19
|
-
rvm: 2.
|
23
|
+
rvm: 2.6.0
|
20
24
|
- os: osx
|
21
|
-
rvm: 2.
|
22
|
-
- os: linux
|
23
|
-
rvm: 2.5.0
|
24
|
-
- os: osx
|
25
|
-
rvm: 2.5.0
|
25
|
+
rvm: 2.6.0
|
26
26
|
fast_finish: true
|
27
27
|
|
28
28
|
script:
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -5,7 +5,7 @@ gem 'ffi_gen', require: false
|
|
5
5
|
|
6
6
|
gem 'rake'
|
7
7
|
|
8
|
-
gem 'roo', '2.
|
8
|
+
gem 'roo', '2.8.1', git: 'https://github.com/roo-rb/roo.git', tag: 'v2.8.1'
|
9
9
|
|
10
10
|
gem 'minitest'
|
11
11
|
gem 'minitest-reporters'
|
@@ -13,5 +13,6 @@ gem 'minitest-reporters'
|
|
13
13
|
# For benchmakrs
|
14
14
|
gem 'axlsx', git: 'https://github.com/randym/axlsx.git'
|
15
15
|
gem 'write_xlsx'
|
16
|
+
gem 'xlsxtream'
|
16
17
|
gem 'benchmark-ips'
|
17
18
|
gem 'process_memory', git: 'https://github.com/paxa/process_memory', platforms: :ruby
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/paxa/process_memory
|
3
|
-
revision:
|
3
|
+
revision: 282c75336a4a6b92207cd1eaa57f20887b92601e
|
4
4
|
specs:
|
5
5
|
process_memory (0.1)
|
6
6
|
|
7
7
|
GIT
|
8
8
|
remote: https://github.com/randym/axlsx.git
|
9
|
-
revision:
|
9
|
+
revision: c593a08b2a929dac7aa8dc418b55e26b4c49dc34
|
10
10
|
specs:
|
11
11
|
axlsx (3.0.0.pre)
|
12
12
|
htmlentities (~> 4.3, >= 4.3.4)
|
@@ -16,9 +16,10 @@ GIT
|
|
16
16
|
|
17
17
|
GIT
|
18
18
|
remote: https://github.com/roo-rb/roo.git
|
19
|
-
revision:
|
19
|
+
revision: 5bbda9849ca6deb0ad8020c4476c1ab9ddfd824b
|
20
|
+
tag: v2.8.1
|
20
21
|
specs:
|
21
|
-
roo (2.
|
22
|
+
roo (2.8.1)
|
22
23
|
nokogiri (~> 1)
|
23
24
|
rubyzip (>= 1.2.1, < 2.0.0)
|
24
25
|
|
@@ -28,28 +29,31 @@ GEM
|
|
28
29
|
ansi (1.5.0)
|
29
30
|
benchmark-ips (2.7.2)
|
30
31
|
builder (3.2.3)
|
31
|
-
ffi (1.
|
32
|
+
ffi (1.10.0)
|
32
33
|
ffi_gen (1.2.0)
|
33
34
|
ffi (~> 1.0)
|
34
35
|
htmlentities (4.3.4)
|
35
|
-
mimemagic (0.3.
|
36
|
-
mini_portile2 (2.
|
36
|
+
mimemagic (0.3.3)
|
37
|
+
mini_portile2 (2.4.0)
|
37
38
|
minitest (5.11.3)
|
38
|
-
minitest-reporters (1.
|
39
|
+
minitest-reporters (1.3.6)
|
39
40
|
ansi
|
40
41
|
builder
|
41
42
|
minitest (>= 5.0)
|
42
43
|
ruby-progressbar
|
43
|
-
nokogiri (1.
|
44
|
-
mini_portile2 (~> 2.
|
45
|
-
rake (12.3.
|
46
|
-
ruby-progressbar (1.
|
47
|
-
rubyzip (1.2.
|
48
|
-
write_xlsx (0.85.
|
44
|
+
nokogiri (1.10.1)
|
45
|
+
mini_portile2 (~> 2.4.0)
|
46
|
+
rake (12.3.2)
|
47
|
+
ruby-progressbar (1.10.0)
|
48
|
+
rubyzip (1.2.2)
|
49
|
+
write_xlsx (0.85.5)
|
49
50
|
rubyzip (>= 1.0.0)
|
50
51
|
zip-zip
|
52
|
+
xlsxtream (2.1.0)
|
53
|
+
zip_tricks (~> 4.5)
|
51
54
|
zip-zip (0.3)
|
52
55
|
rubyzip (>= 1.0.0)
|
56
|
+
zip_tricks (4.7.1)
|
53
57
|
|
54
58
|
PLATFORMS
|
55
59
|
ruby
|
@@ -63,8 +67,9 @@ DEPENDENCIES
|
|
63
67
|
minitest-reporters
|
64
68
|
process_memory!
|
65
69
|
rake
|
66
|
-
roo (= 2.
|
70
|
+
roo (= 2.8.1)!
|
67
71
|
write_xlsx
|
72
|
+
xlsxtream
|
68
73
|
|
69
74
|
BUNDLED WITH
|
70
|
-
1.
|
75
|
+
1.17.2
|
data/Makefile
CHANGED
data/README.md
CHANGED
@@ -20,17 +20,19 @@ worksheet.set_column(1, 1, 20, price)
|
|
20
20
|
date_format = workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@")
|
21
21
|
worksheet.set_column(2, 2, 20, date_format)
|
22
22
|
|
23
|
-
worksheet.
|
23
|
+
worksheet.append_row(["message", "price", "date"], bold)
|
24
24
|
|
25
25
|
for i in 1..1000
|
26
|
-
worksheet.
|
26
|
+
worksheet.append_row(["Hello", (rand * 10_000_000).round(2), Time.now])
|
27
27
|
end
|
28
28
|
|
29
|
-
worksheet.
|
29
|
+
worksheet.append_row(["Sum", FastExcel::Formula.new("SUM(B2:B1001)")], bold)
|
30
30
|
|
31
31
|
workbook.close
|
32
32
|
```
|
33
33
|
|
34
|
+
See [more examples](https://github.com/Paxa/fast_excel/tree/master/examples)
|
35
|
+
|
34
36
|
This repository and gem contain sources of [libxlsxwriter](https://github.com/jmcnamara/libxlsxwriter)
|
35
37
|
|
36
38
|
## Benchmarks
|
@@ -69,6 +71,29 @@ Or
|
|
69
71
|
gem install fast_excel
|
70
72
|
```
|
71
73
|
|
74
|
+
## Column Auto Width
|
75
|
+
|
76
|
+
Column authwidth only works for string values, because numbers may have custom formatting
|
77
|
+
|
78
|
+
Enabling column auto widths will slow down writing string values for about 15-25%
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
require 'fast_excel'
|
82
|
+
|
83
|
+
workbook = FastExcel.open(constant_memory: true)
|
84
|
+
|
85
|
+
worksheet = workbook.add_worksheet
|
86
|
+
worksheet.auto_width = true
|
87
|
+
|
88
|
+
worksheet.append_row(["some text", "some longer text for example"])
|
89
|
+
|
90
|
+
content = workbook.read_string
|
91
|
+
File.open('./some_file.xlsx', 'wb') {|f| f.write(content) }
|
92
|
+
```
|
93
|
+
|
94
|
+
![fast_excel_auto_width](https://user-images.githubusercontent.com/26019/51788441-ba981300-21b0-11e9-9611-54dda78effcd.png)
|
95
|
+
|
96
|
+
|
72
97
|
## API
|
73
98
|
|
74
99
|
This gem is FFI binding for libxlsxwriter C library with some syntax sugar. All original functions is avaliable, for example:
|
@@ -93,3 +118,5 @@ Helper Methods:
|
|
93
118
|
* `worksheet.write_row(row_num, array_of_mixed_value, formats = nil)` - write values one by one, detecting type automatically. `formats` can be array, or Format object or nil
|
94
119
|
* `format.font_family` - alias for `format.font_name`
|
95
120
|
* `workbook.default_format.font_size` - set it to 0 if you want to use default font size (that what user set in Excel settings)
|
121
|
+
* `worksheet.write_row(num, values_array, formats = nil)` - Write row of values
|
122
|
+
* `worksheet.append_row(values_array, formats = nil)` - Append row of values ot the bottom of worksheet
|
data/Rakefile
CHANGED
data/benchmarks/1k_rows.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'init'
|
2
2
|
|
3
|
-
HEADERS = ["id", "name", "age", "date"]
|
3
|
+
HEADERS = ["id", "name", "age", "date"].freeze
|
4
4
|
|
5
5
|
DATA = []
|
6
6
|
1000.times do |n|
|
@@ -8,15 +8,15 @@ DATA = []
|
|
8
8
|
end
|
9
9
|
|
10
10
|
Benchmark.ips do |x|
|
11
|
-
x.config(time: 10, warmup:
|
11
|
+
x.config(time: 10, warmup: 40)
|
12
12
|
|
13
13
|
x.report("FastExcel") do
|
14
14
|
workbook = FastExcel.open(constant_memory: true)
|
15
15
|
worksheet = workbook.add_worksheet("benchmark")
|
16
16
|
|
17
17
|
worksheet.write_row(0, HEADERS)
|
18
|
-
DATA.
|
19
|
-
worksheet.
|
18
|
+
DATA.each do |row|
|
19
|
+
worksheet.append_row(row)
|
20
20
|
end
|
21
21
|
workbook.read_string
|
22
22
|
end
|
@@ -55,5 +55,18 @@ Benchmark.ips do |x|
|
|
55
55
|
File.delete(filename)
|
56
56
|
end
|
57
57
|
|
58
|
+
x.report("xlsxtream") do
|
59
|
+
filename = "#{Dir.mktmpdir}/xlsxtream.xlsx"
|
60
|
+
|
61
|
+
Xlsxtream::Workbook.open(filename) do |xlsx|
|
62
|
+
xlsx.write_worksheet do |sheet|
|
63
|
+
sheet << HEADERS
|
64
|
+
DATA.each do |row|
|
65
|
+
sheet << row
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
58
71
|
x.compare!
|
59
72
|
end
|
data/benchmarks/20k_rows.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'init'
|
2
|
+
|
3
|
+
HEADERS = ["id", "name", "age", "date"]
|
4
|
+
|
5
|
+
DATA = []
|
6
|
+
1000.times do |n|
|
7
|
+
DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)]
|
8
|
+
end
|
9
|
+
|
10
|
+
Benchmark.ips do |x|
|
11
|
+
x.config(time: 10, warmup: 2)
|
12
|
+
|
13
|
+
x.report("Normal") do
|
14
|
+
workbook = FastExcel.open(constant_memory: true)
|
15
|
+
worksheet = workbook.add_worksheet("benchmark")
|
16
|
+
|
17
|
+
worksheet.write_row(0, HEADERS)
|
18
|
+
DATA.each_with_index do |row, i|
|
19
|
+
worksheet.write_row(i + 1, row)
|
20
|
+
end
|
21
|
+
workbook.read_string
|
22
|
+
end
|
23
|
+
|
24
|
+
x.report("With auto_width") do
|
25
|
+
workbook = FastExcel.open(constant_memory: true)
|
26
|
+
worksheet = workbook.add_worksheet("benchmark")
|
27
|
+
worksheet.auto_width = true
|
28
|
+
|
29
|
+
worksheet.write_row(0, HEADERS)
|
30
|
+
DATA.each_with_index do |row, i|
|
31
|
+
worksheet.write_row(i + 1, row)
|
32
|
+
end
|
33
|
+
workbook.read_string
|
34
|
+
end
|
35
|
+
|
36
|
+
x.compare!
|
37
|
+
end
|
data/benchmarks/init.rb
CHANGED
@@ -8,10 +8,9 @@ require_relative '../lib/fast_excel'
|
|
8
8
|
require "benchmark/ips"
|
9
9
|
require 'axlsx'
|
10
10
|
require 'write_xlsx'
|
11
|
+
require 'xlsxtream'
|
11
12
|
require 'process_memory'
|
12
13
|
|
13
|
-
require_relative 'init'
|
14
|
-
|
15
14
|
def write_fast_excel_20k
|
16
15
|
workbook = FastExcel.open(constant_memory: true)
|
17
16
|
worksheet = workbook.add_worksheet("benchmark")
|
@@ -57,3 +56,16 @@ def write_axlsx_20k
|
|
57
56
|
File.delete(filename)
|
58
57
|
end
|
59
58
|
end
|
59
|
+
|
60
|
+
def write_xlsxtream_20k
|
61
|
+
filename = "#{Dir.mktmpdir}/xlsxtream.xlsx"
|
62
|
+
|
63
|
+
Xlsxtream::Workbook.open(filename) do |xlsx|
|
64
|
+
xlsx.write_worksheet do |sheet|
|
65
|
+
sheet << HEADERS
|
66
|
+
DATA.each do |row|
|
67
|
+
sheet << row
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/benchmarks/memory.rb
CHANGED
@@ -11,6 +11,7 @@ puts "warm up..."
|
|
11
11
|
write_fast_excel_20k
|
12
12
|
write_axlsx_20k
|
13
13
|
write_xlsx_20k
|
14
|
+
write_xlsxtream_20k
|
14
15
|
|
15
16
|
DATA.clear
|
16
17
|
50_000.times do |n|
|
@@ -47,3 +48,10 @@ sleep 5
|
|
47
48
|
measure_memory("write_xlsx") do
|
48
49
|
write_xlsx_20k
|
49
50
|
end
|
51
|
+
|
52
|
+
GC.start
|
53
|
+
sleep 5
|
54
|
+
|
55
|
+
measure_memory("xlsxtream") do
|
56
|
+
write_xlsxtream_20k
|
57
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative '../lib/fast_excel'
|
2
|
+
require 'ruby-prof'
|
3
|
+
|
4
|
+
DATA = []
|
5
|
+
1000.times do |n|
|
6
|
+
DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)]
|
7
|
+
end
|
8
|
+
|
9
|
+
RubyProf.start
|
10
|
+
|
11
|
+
100.times do
|
12
|
+
workbook = FastExcel.open(constant_memory: true)
|
13
|
+
worksheet = workbook.add_worksheet("benchmark")
|
14
|
+
worksheet.auto_width = true
|
15
|
+
|
16
|
+
DATA.each_with_index do |row, i|
|
17
|
+
worksheet.write_row(i + 1, row)
|
18
|
+
end
|
19
|
+
workbook.read_string
|
20
|
+
|
21
|
+
print '.'
|
22
|
+
end
|
23
|
+
result = RubyProf.stop
|
24
|
+
|
25
|
+
# print a flat profile to text
|
26
|
+
printer = RubyProf::FlatPrinter.new(result)
|
27
|
+
printer.print(STDOUT)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative '../lib/fast_excel'
|
2
|
+
require "benchmark/memory"
|
3
|
+
require "benchmark/ips"
|
4
|
+
|
5
|
+
DATA = []
|
6
|
+
1000.times do |n|
|
7
|
+
DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)]
|
8
|
+
end
|
9
|
+
|
10
|
+
5.times do
|
11
|
+
workbook = FastExcel.open(constant_memory: true)
|
12
|
+
worksheet = workbook.add_worksheet("benchmark")
|
13
|
+
|
14
|
+
DATA.each_with_index do |row, row_num|
|
15
|
+
row.each_with_index do |val, cell_num|
|
16
|
+
worksheet.write_value(row_num + 1, cell_num + 1, val)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
workbook.read_string
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
workbook = FastExcel.open(constant_memory: true)
|
24
|
+
worksheet = workbook.add_worksheet("benchmark")
|
25
|
+
|
26
|
+
DATA.each_with_index do |row, row_num|
|
27
|
+
row.each_with_index do |val, cell_num|
|
28
|
+
worksheet.write_value(row_num + 1, cell_num + 1, val)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
workbook.read_string
|
32
|
+
|
33
|
+
Benchmark.ips do |x|
|
34
|
+
#x.config(time: 10, warmup: 2)
|
35
|
+
|
36
|
+
x.report("Normal") do
|
37
|
+
workbook = FastExcel.open(constant_memory: true)
|
38
|
+
worksheet = workbook.add_worksheet("benchmark")
|
39
|
+
|
40
|
+
DATA.each_with_index do |row, row_num|
|
41
|
+
row.each_with_index do |val, cell_num|
|
42
|
+
worksheet.write_value(row_num + 1, cell_num + 1, val)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
workbook.read_string
|
46
|
+
end
|
47
|
+
|
48
|
+
x.report("Auto-width") do
|
49
|
+
workbook = FastExcel.open(constant_memory: true)
|
50
|
+
worksheet = workbook.add_worksheet("benchmark")
|
51
|
+
worksheet.auto_width = true
|
52
|
+
|
53
|
+
DATA.each_with_index do |row, row_num|
|
54
|
+
row.each_with_index do |val, cell_num|
|
55
|
+
worksheet.write_value(row_num + 1, cell_num + 1, val)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
workbook.read_string
|
59
|
+
end
|
60
|
+
|
61
|
+
x.compare!
|
62
|
+
end
|