axlsx_styler 0.1.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +23 -0
- data/README.md +50 -26
- data/Rakefile +18 -4
- data/lib/axlsx_styler.rb +4 -23
- data/lib/axlsx_styler/axlsx_cell.rb +32 -30
- data/lib/axlsx_styler/axlsx_package.rb +17 -0
- data/lib/axlsx_styler/axlsx_styles.rb +36 -0
- data/lib/axlsx_styler/axlsx_workbook.rb +26 -43
- data/lib/axlsx_styler/axlsx_worksheet.rb +34 -17
- data/lib/axlsx_styler/version.rb +1 -1
- data/test/dummy_app/Rakefile +7 -0
- data/test/dummy_app/app/assets/config/manifest.js +3 -0
- data/test/dummy_app/app/assets/javascripts/application.js +0 -0
- data/test/dummy_app/app/assets/stylesheets/application.css +3 -0
- data/test/dummy_app/app/controllers/application_controller.rb +3 -0
- data/test/dummy_app/app/controllers/spreadsheets_controller.rb +7 -0
- data/test/dummy_app/app/models/application_record.rb +3 -0
- data/test/dummy_app/app/views/layouts/application.html.erb +14 -0
- data/{examples/colors_and_borders.rb → test/dummy_app/app/views/spreadsheets/test.xlsx.axlsx} +2 -7
- data/test/dummy_app/config.ru +4 -0
- data/test/dummy_app/config/application.rb +56 -0
- data/test/dummy_app/config/boot.rb +10 -0
- data/test/dummy_app/config/database.yml +25 -0
- data/test/dummy_app/config/environment.rb +5 -0
- data/test/dummy_app/config/environments/development.rb +30 -0
- data/test/dummy_app/config/environments/production.rb +60 -0
- data/test/dummy_app/config/environments/test.rb +41 -0
- data/test/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy_app/config/initializers/inflections.rb +10 -0
- data/test/dummy_app/config/initializers/mime_types.rb +5 -0
- data/test/dummy_app/config/initializers/secret_token.rb +11 -0
- data/test/dummy_app/config/initializers/session_store.rb +8 -0
- data/test/dummy_app/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy_app/config/locales/en.yml +5 -0
- data/test/dummy_app/config/routes.rb +3 -0
- data/test/dummy_app/config/secrets.yml +22 -0
- data/test/dummy_app/db/schema.rb +15 -0
- data/test/dummy_app/db/test.sqlite3 +0 -0
- data/test/dummy_app/log/test.log +1004 -0
- data/test/helper_methods.rb +12 -0
- data/test/integration/application_test.rb +18 -0
- data/test/test_helper.rb +31 -4
- data/test/unit/borders_test.rb +127 -0
- data/test/unit/examples_test.rb +20 -0
- data/test/unit/merge_styles_test.rb +56 -0
- data/test/unit/regresssions_test.rb +44 -0
- data/test/unit/serialize_test.rb +34 -0
- data/test/unit/to_stream_test.rb +34 -0
- metadata +152 -47
- data/.gitignore +0 -24
- data/Gemfile +0 -4
- data/axlsx_styler.gemspec +0 -36
- data/examples/vanilla_axlsx.md +0 -70
- data/spreadsheet.png +0 -0
- data/test/cell_test.rb +0 -14
- data/test/integration_test.rb +0 -234
- data/test/workbook_test.rb +0 -10
data/.gitignore
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
18
|
-
*.bundle
|
19
|
-
*.so
|
20
|
-
*.o
|
21
|
-
*.a
|
22
|
-
mkmf.log
|
23
|
-
*.xlsx
|
24
|
-
*.xlsx#
|
data/Gemfile
DELETED
data/axlsx_styler.gemspec
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'axlsx_styler/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'axlsx_styler'
|
8
|
-
spec.version = AxlsxStyler::VERSION
|
9
|
-
spec.authors = ['Anton Sakovich']
|
10
|
-
spec.email = ['sakovias@gmail.com']
|
11
|
-
spec.summary = %q(This gem allows to separate data from styles when using Axlsx gem.)
|
12
|
-
spec.description = %q(
|
13
|
-
Axlsx gem is an excellent tool to build Excel worksheets. The sheets are
|
14
|
-
created row-by-row and styles are immediately added to each cell when a
|
15
|
-
row is created. This gem allows to follow an alternative route: fill out
|
16
|
-
a spreadsheet with data and apply styles later. Styles can be added
|
17
|
-
to individual cells as well as to ranges of cells. As a bonus, this gem
|
18
|
-
also simplifies drawing borders around groups of cells.
|
19
|
-
)
|
20
|
-
spec.homepage = 'https://github.com/sakovias/axlsx_styler'
|
21
|
-
spec.license = 'MIT'
|
22
|
-
|
23
|
-
spec.files = `git ls-files -z`.split("\x0")
|
24
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
26
|
-
spec.require_paths = ['lib']
|
27
|
-
spec.required_ruby_version = '>= 1.9.3'
|
28
|
-
|
29
|
-
spec.add_dependency 'axlsx', '~> 2.0'
|
30
|
-
spec.add_dependency 'activesupport', '>= 3.1'
|
31
|
-
|
32
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
33
|
-
spec.add_development_dependency 'rake', '~> 0.9'
|
34
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
35
|
-
spec.add_development_dependency 'awesome_print', '~> 1.6'
|
36
|
-
end
|
data/examples/vanilla_axlsx.md
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
This gem is supposed to make styling spreadsheets easier.
|
2
|
-
|
3
|
-
Here's how the [example from the README](../README.md) compares to that implemented with plain `axlsx`.
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
require 'axlsx'
|
7
|
-
axlsx = Axlsx::Package.new
|
8
|
-
wb = axlsx.workbook
|
9
|
-
border_color = '000000'
|
10
|
-
wb.add_worksheet do |sheet|
|
11
|
-
# top row
|
12
|
-
header_hash = { b: true, bg_color: '95AFBA' }
|
13
|
-
top_left_corner = wb.styles.add_style header_hash.merge({
|
14
|
-
border: { style: :thin, color: border_color, edges: [:top, :left, :bottom] }
|
15
|
-
})
|
16
|
-
top_edge = wb.styles.add_style header_hash.merge({
|
17
|
-
border: { style: :thin, color: border_color, edges: [:top, :bottom] }
|
18
|
-
})
|
19
|
-
top_right_corner = wb.styles.add_style header_hash.merge({
|
20
|
-
border: { style: :thin, color: border_color, edges: [:top, :right, :bottom] }
|
21
|
-
})
|
22
|
-
sheet.add_row
|
23
|
-
sheet.add_row(["", "Product", "Category", "Price"],
|
24
|
-
style: [ nil, top_left_corner, top_edge, top_right_corner ]
|
25
|
-
)
|
26
|
-
|
27
|
-
# middle rows
|
28
|
-
color_hash = { bg_color: 'E2F89C' }
|
29
|
-
left_edge = wb.styles.add_style color_hash.merge(
|
30
|
-
b: true,
|
31
|
-
border: {
|
32
|
-
style: :thin, color: border_color, edges: [:left]
|
33
|
-
}
|
34
|
-
)
|
35
|
-
inner = wb.styles.add_style color_hash
|
36
|
-
right_edge = wb.styles.add_style color_hash.merge(
|
37
|
-
alignment: { horizontal: :left },
|
38
|
-
border: {
|
39
|
-
style: :thin, color: border_color, edges: [:right]
|
40
|
-
}
|
41
|
-
)
|
42
|
-
sheet.add_row(
|
43
|
-
["", "Butter", "Dairy", 4.99],
|
44
|
-
style: [nil, left_edge, inner, right_edge]
|
45
|
-
)
|
46
|
-
sheet.add_row(
|
47
|
-
["", "Bread", "Baked Goods", 3.45],
|
48
|
-
style: [nil, left_edge, inner, right_edge]
|
49
|
-
)
|
50
|
-
|
51
|
-
# last row
|
52
|
-
bottom_left_corner = wb.styles.add_style color_hash.merge({
|
53
|
-
b: true,
|
54
|
-
border: { style: :thin, color: border_color, edges: [:left, :bottom] }
|
55
|
-
})
|
56
|
-
bottom_edge = wb.styles.add_style color_hash.merge({
|
57
|
-
border: { style: :thin, color: border_color, edges: [:bottom] }
|
58
|
-
})
|
59
|
-
bottom_right_corner = wb.styles.add_style color_hash.merge({
|
60
|
-
alignment: { horizontal: :left },
|
61
|
-
border: { style: :thin, color: border_color, edges: [:right, :bottom] }
|
62
|
-
})
|
63
|
-
sheet.add_row(["", "Broccoli", "Produce", 2.99],
|
64
|
-
style: [nil, bottom_left_corner, bottom_edge, bottom_right_corner]
|
65
|
-
)
|
66
|
-
|
67
|
-
sheet.column_widths 5, 20, 20, 20
|
68
|
-
end
|
69
|
-
axlsx.serialize "grocery.xlsx"
|
70
|
-
```
|
data/spreadsheet.png
DELETED
Binary file
|
data/test/cell_test.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class CellTest < MiniTest::Test
|
4
|
-
def test_can_add_style
|
5
|
-
p = Axlsx::Package.new
|
6
|
-
wb = p.workbook
|
7
|
-
sheet = wb.add_worksheet
|
8
|
-
row = sheet.add_row ["x", "y"]
|
9
|
-
cell = row.cells.first
|
10
|
-
|
11
|
-
cell.add_style b: true
|
12
|
-
assert_equal({ b: true }, cell.raw_style)
|
13
|
-
end
|
14
|
-
end
|
data/test/integration_test.rb
DELETED
@@ -1,234 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class IntegrationTest < MiniTest::Test
|
4
|
-
def setup
|
5
|
-
@axlsx = Axlsx::Package.new
|
6
|
-
@workbook = @axlsx.workbook
|
7
|
-
end
|
8
|
-
|
9
|
-
# Save to a file using Axlsx::Package#serialize
|
10
|
-
def serialize(filename)
|
11
|
-
@axlsx.serialize File.expand_path("../../tmp/#{filename}.xlsx", __FILE__)
|
12
|
-
assert_equal true, @workbook.styles_applied
|
13
|
-
end
|
14
|
-
|
15
|
-
# Save to a file by getting contents from stream
|
16
|
-
def to_stream(filename)
|
17
|
-
File.open(File.expand_path("../../tmp/#{filename}.xlsx", __FILE__), 'w') do |f|
|
18
|
-
f.write @axlsx.to_stream.read
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# New functionality as of 0.1.5 (serialize)
|
23
|
-
def test_works_without_apply_styles_serialize
|
24
|
-
filename = 'without_apply_styles_serialize'
|
25
|
-
assert_equal nil, @workbook.styles_applied
|
26
|
-
@workbook.add_worksheet do |sheet|
|
27
|
-
sheet.add_row ['A1', 'B1']
|
28
|
-
sheet.add_style 'A1:B1', b: true
|
29
|
-
end
|
30
|
-
serialize(filename)
|
31
|
-
assert_equal 1, @workbook.style_index.count
|
32
|
-
end
|
33
|
-
|
34
|
-
# New functionality as of 0.1.5 (to_stream)
|
35
|
-
def test_works_without_apply_styles_to_stream
|
36
|
-
filename = 'without_apply_styles_to_stream'
|
37
|
-
assert_equal nil, @workbook.styles_applied
|
38
|
-
@workbook.add_worksheet do |sheet|
|
39
|
-
sheet.add_row ['A1', 'B1']
|
40
|
-
sheet.add_style 'A1:B1', b: true
|
41
|
-
end
|
42
|
-
to_stream(filename)
|
43
|
-
assert_equal 1, @workbook.style_index.count
|
44
|
-
end
|
45
|
-
|
46
|
-
# Backwards compatibility with pre 0.1.5 (serialize)
|
47
|
-
def test_works_with_apply_styles_serialize
|
48
|
-
filename = 'with_apply_styles_serialize'
|
49
|
-
assert_equal nil, @workbook.styles_applied
|
50
|
-
@workbook.add_worksheet do |sheet|
|
51
|
-
sheet.add_row ['A1', 'B1']
|
52
|
-
sheet.add_style 'A1:B1', b: true
|
53
|
-
end
|
54
|
-
@workbook.apply_styles # important for backwards compatibility
|
55
|
-
assert_equal 1, @workbook.style_index.count
|
56
|
-
serialize(filename)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Backwards compatibility with pre 0.1.5 (to_stream)
|
60
|
-
def test_works_with_apply_styles_to_stream
|
61
|
-
filename = 'with_apply_styles_to_stream'
|
62
|
-
assert_equal nil, @workbook.styles_applied
|
63
|
-
@workbook.add_worksheet do |sheet|
|
64
|
-
sheet.add_row ['A1', 'B1']
|
65
|
-
sheet.add_style 'A1:B1', b: true
|
66
|
-
end
|
67
|
-
@workbook.apply_styles # important for backwards compatibility
|
68
|
-
assert_equal 1, @workbook.style_index.count
|
69
|
-
to_stream(filename)
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_table_with_borders
|
73
|
-
filename = 'borders_test'
|
74
|
-
@workbook.add_worksheet do |sheet|
|
75
|
-
sheet.add_row
|
76
|
-
sheet.add_row ['', 'Product', 'Category', 'Price']
|
77
|
-
sheet.add_row ['', 'Butter', 'Dairy', 4.99]
|
78
|
-
sheet.add_row ['', 'Bread', 'Baked Goods', 3.45]
|
79
|
-
sheet.add_row ['', 'Broccoli', 'Produce', 2.99]
|
80
|
-
sheet.add_row ['', 'Pizza', 'Frozen Foods', 4.99]
|
81
|
-
sheet.column_widths 5, 20, 20, 20
|
82
|
-
|
83
|
-
sheet.add_style 'B2:D2', b: true
|
84
|
-
sheet.add_style 'B2:B6', b: true
|
85
|
-
sheet.add_style 'B2:D2', bg_color: '95AFBA'
|
86
|
-
sheet.add_style 'B3:D6', bg_color: 'E2F89C'
|
87
|
-
sheet.add_style 'D3:D6', alignment: { horizontal: :left }
|
88
|
-
sheet.add_border 'B2:D6'
|
89
|
-
sheet.add_border 'B3:D3', [:top]
|
90
|
-
sheet.add_border 'B3:D3', edges: [:bottom], style: :medium
|
91
|
-
sheet.add_border 'B3:D3', edges: [:bottom], style: :medium, color: '32f332'
|
92
|
-
end
|
93
|
-
serialize(filename)
|
94
|
-
assert_equal 12, @workbook.style_index.count
|
95
|
-
assert_equal 12 + 2, @workbook.style_index.keys.max
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_duplicate_borders
|
99
|
-
filename = 'duplicate_borders_test'
|
100
|
-
@workbook.add_worksheet do |sheet|
|
101
|
-
sheet.add_row
|
102
|
-
sheet.add_row ['', 'B2', 'C2', 'D2']
|
103
|
-
sheet.add_row ['', 'B3', 'C3', 'D3']
|
104
|
-
sheet.add_row ['', 'B4', 'C4', 'D4']
|
105
|
-
|
106
|
-
sheet.add_border 'B2:D4'
|
107
|
-
sheet.add_border 'B2:D4'
|
108
|
-
end
|
109
|
-
serialize(filename)
|
110
|
-
assert_equal 8, @workbook.style_index.count
|
111
|
-
assert_equal 8, @workbook.styled_cells.count
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_multiple_style_borders_on_same_sells
|
115
|
-
filename = 'multiple_style_borders'
|
116
|
-
@workbook.add_worksheet do |sheet|
|
117
|
-
sheet.add_row
|
118
|
-
sheet.add_row ['', 'B2', 'C2', 'D2']
|
119
|
-
sheet.add_row ['', 'B3', 'C3', 'D3']
|
120
|
-
|
121
|
-
sheet.add_border 'B2:D3', :all
|
122
|
-
sheet.add_border 'B2:D2', edges: [:bottom], style: :thick, color: 'ff0000'
|
123
|
-
end
|
124
|
-
serialize(filename)
|
125
|
-
assert_equal 6, @workbook.style_index.count
|
126
|
-
assert_equal 6, @workbook.styled_cells.count
|
127
|
-
|
128
|
-
b2_cell_style = {
|
129
|
-
border: {
|
130
|
-
style: :thick,
|
131
|
-
color: 'ff0000',
|
132
|
-
edges: [:bottom, :left, :top]
|
133
|
-
}
|
134
|
-
}
|
135
|
-
assert_equal b2_cell_style, @workbook.style_index
|
136
|
-
.find { |_, v| v[:border][:edges] == [:bottom, :left, :top] }[1]
|
137
|
-
|
138
|
-
d3_cell_style = {
|
139
|
-
border: {
|
140
|
-
style: :thin,
|
141
|
-
color: '000000',
|
142
|
-
edges: [:bottom, :right]
|
143
|
-
}
|
144
|
-
}
|
145
|
-
assert_equal d3_cell_style, @workbook.style_index
|
146
|
-
.find { |_, v| v[:border][:edges] == [:bottom, :right] }[1]
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_table_with_num_fmt
|
150
|
-
filename = 'num_fmt_test'
|
151
|
-
t = Time.now
|
152
|
-
day = 24 * 60 * 60
|
153
|
-
@workbook.add_worksheet do |sheet|
|
154
|
-
sheet.add_row %w(Date Count Percent)
|
155
|
-
sheet.add_row [t - 2 * day, 2, 2.to_f.round(2) / 11]
|
156
|
-
sheet.add_row [t - 1 * day, 3, 3.to_f.round(2) / 11]
|
157
|
-
sheet.add_row [t, 6, 6.to_f.round(2) / 11]
|
158
|
-
|
159
|
-
sheet.add_style 'A1:B1', b: true
|
160
|
-
sheet.add_style 'A2:A4', format_code: 'YYYY-MM-DD hh:mm:ss'
|
161
|
-
end
|
162
|
-
serialize(filename)
|
163
|
-
assert_equal 2, @workbook.style_index.count
|
164
|
-
assert_equal 2 + 2, @workbook.style_index.keys.max
|
165
|
-
assert_equal 5, @workbook.styled_cells.count
|
166
|
-
end
|
167
|
-
|
168
|
-
def test_duplicate_styles
|
169
|
-
filename = 'duplicate_styles'
|
170
|
-
@workbook.add_worksheet do |sheet|
|
171
|
-
sheet.add_row %w(Index City)
|
172
|
-
sheet.add_row [1, 'Ottawa']
|
173
|
-
sheet.add_row [2, 'Boston']
|
174
|
-
|
175
|
-
sheet.add_border 'A1:B1', [:bottom]
|
176
|
-
sheet.add_border 'A1:B1', [:bottom]
|
177
|
-
sheet.add_style 'A1:A3', b: true
|
178
|
-
sheet.add_style 'A1:A3', b: true
|
179
|
-
end
|
180
|
-
serialize(filename)
|
181
|
-
assert_equal 4, @workbook.styled_cells.count
|
182
|
-
assert_equal 3, @workbook.style_index.count
|
183
|
-
end
|
184
|
-
|
185
|
-
def test_multiple_named_styles
|
186
|
-
filename = 'multiple_named_styles'
|
187
|
-
bold_blue = { b: true, fg_color: '0000FF' }
|
188
|
-
large = { sz: 16 }
|
189
|
-
red = { fg_color: 'FF0000' }
|
190
|
-
@workbook.add_worksheet do |sheet|
|
191
|
-
sheet.add_row %w(Index City)
|
192
|
-
sheet.add_row [1, 'Ottawa']
|
193
|
-
sheet.add_row [2, 'Boston']
|
194
|
-
|
195
|
-
sheet.add_style 'A1:B1', bold_blue, large
|
196
|
-
sheet.add_style 'A1:A3', red
|
197
|
-
end
|
198
|
-
serialize(filename)
|
199
|
-
assert_equal 4, @workbook.styled_cells.count
|
200
|
-
assert_equal 3, @workbook.style_index.count
|
201
|
-
end
|
202
|
-
|
203
|
-
# Overriding borders (part 1)
|
204
|
-
def test_mixed_borders_1
|
205
|
-
@filename = 'mixed_borders_1'
|
206
|
-
@workbook.add_worksheet do |sheet|
|
207
|
-
sheet.add_row
|
208
|
-
sheet.add_row ['', '1', '2', '3']
|
209
|
-
sheet.add_row ['', '4', '5', '6']
|
210
|
-
sheet.add_row ['', '7', '8', '9']
|
211
|
-
sheet.add_style 'B2:D4', border: { style: :thin, color: '000000' }
|
212
|
-
sheet.add_border 'C3:D4', style: :medium
|
213
|
-
end
|
214
|
-
@workbook.apply_styles
|
215
|
-
assert_equal 9, @workbook.styled_cells.count
|
216
|
-
assert_equal 2, @workbook.style_index.count
|
217
|
-
end
|
218
|
-
|
219
|
-
# Overriding borders (part 2)
|
220
|
-
def test_mixed_borders
|
221
|
-
@filename = 'mixed_borders_2'
|
222
|
-
@workbook.add_worksheet do |sheet|
|
223
|
-
sheet.add_row
|
224
|
-
sheet.add_row ['', '1', '2', '3']
|
225
|
-
sheet.add_row ['', '4', '5', '6']
|
226
|
-
sheet.add_row ['', '7', '8', '9']
|
227
|
-
sheet.add_border 'B2:D4', style: :medium
|
228
|
-
sheet.add_style 'D2:D4', border: { style: :thin, color: '000000' }
|
229
|
-
end
|
230
|
-
@workbook.apply_styles
|
231
|
-
assert_equal 8, @workbook.styled_cells.count
|
232
|
-
assert_equal 6, @workbook.style_index.count
|
233
|
-
end
|
234
|
-
end
|
data/test/workbook_test.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
class WorkbookTest < MiniTest::Test
|
2
|
-
def test_adding_styled_cells
|
3
|
-
p = Axlsx::Package.new
|
4
|
-
wb = p.workbook
|
5
|
-
wb.add_styled_cell 'Cell 1'
|
6
|
-
wb.add_styled_cell 'Cell 2'
|
7
|
-
assert_equal ['Cell 1', 'Cell 2'].to_set, wb.styled_cells
|
8
|
-
assert_equal nil, wb.styles_applied
|
9
|
-
end
|
10
|
-
end
|