write_xlsx 0.81.1 → 0.83.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/.travis.yml +8 -0
- data/Changes +20 -0
- data/README.md +3 -2
- data/examples/chart_combined.rb +107 -0
- data/examples/chart_data_table.rb +1 -1
- data/examples/chart_pareto.rb +82 -0
- data/lib/write_xlsx/chart.rb +115 -42
- data/lib/write_xlsx/chart/axis.rb +5 -1
- data/lib/write_xlsx/chart/bar.rb +13 -0
- data/lib/write_xlsx/chart/pie.rb +7 -0
- data/lib/write_xlsx/chart/scatter.rb +25 -57
- data/lib/write_xlsx/format.rb +40 -0
- data/lib/write_xlsx/package/app.rb +39 -1
- data/lib/write_xlsx/package/comments.rb +1 -5
- data/lib/write_xlsx/package/content_types.rb +48 -13
- data/lib/write_xlsx/package/core.rb +14 -12
- data/lib/write_xlsx/package/packager.rb +17 -41
- data/lib/write_xlsx/package/styles.rb +215 -256
- data/lib/write_xlsx/package/table.rb +5 -7
- data/lib/write_xlsx/package/xml_writer_simple.rb +2 -0
- data/lib/write_xlsx/sheets.rb +2 -2
- data/lib/write_xlsx/utility.rb +17 -2
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +44 -2
- data/lib/write_xlsx/worksheet.rb +26 -17
- data/lib/write_xlsx/worksheet/page_setup.rb +12 -6
- data/test/chart/test_write_style.rb +2 -2
- data/test/helper.rb +3 -0
- data/test/package/app/test_app01.rb +1 -1
- data/test/package/app/test_app02.rb +1 -1
- data/test/package/app/test_app03.rb +1 -1
- data/test/package/content_types/test_content_types.rb +1 -1
- data/test/package/content_types/test_write_default.rb +1 -1
- data/test/package/content_types/test_write_override.rb +1 -1
- data/test/perl_output/chart_combined.xlsx +0 -0
- data/test/perl_output/chart_pareto.xlsx +0 -0
- data/test/regression/test_button07.rb +5 -2
- data/test/regression/test_button13.rb +34 -0
- data/test/regression/test_button14.rb +31 -0
- data/test/regression/test_chart_column11.rb +45 -0
- data/test/regression/test_chart_column12.rb +45 -0
- data/test/regression/test_chart_combined01.rb +37 -0
- data/test/regression/test_chart_combined02.rb +43 -0
- data/test/regression/test_chart_combined03.rb +45 -0
- data/test/regression/test_chart_combined04.rb +47 -0
- data/test/regression/test_chart_combined05.rb +49 -0
- data/test/regression/test_chart_combined06.rb +49 -0
- data/test/regression/test_chart_combined07.rb +53 -0
- data/test/regression/test_chart_combined08.rb +65 -0
- data/test/regression/test_chart_data_labels24.rb +50 -0
- data/test/regression/test_chart_date05.rb +57 -0
- data/test/regression/test_chart_format20.rb +55 -0
- data/test/regression/test_format11.rb +28 -0
- data/test/regression/test_format12.rb +41 -0
- data/test/regression/test_landscape01.rb +27 -0
- data/test/regression/test_quote_name04.rb +40 -0
- data/test/regression/test_set_start_page01.rb +4 -7
- data/test/regression/test_set_start_page02.rb +33 -0
- data/test/regression/test_set_start_page03.rb +33 -0
- data/test/regression/test_table17.rb +70 -0
- data/test/regression/xlsx_files/chart_column11.xlsx +0 -0
- data/test/regression/xlsx_files/chart_column12.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined01.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined02.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined03.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined04.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined07.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined08.xlsx +0 -0
- data/test/regression/xlsx_files/chart_date05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format20.xlsx +0 -0
- data/test/regression/xlsx_files/format11.xlsx +0 -0
- data/test/regression/xlsx_files/format12.xlsx +0 -0
- data/test/regression/xlsx_files/landscape01.xlsx +0 -0
- data/test/regression/xlsx_files/quote_name04.xlsx +0 -0
- data/test/regression/xlsx_files/set_start_page01.xlsx +0 -0
- data/test/regression/xlsx_files/set_start_page02.xlsx +0 -0
- data/test/regression/xlsx_files/set_start_page03.xlsx +0 -0
- data/test/regression/xlsx_files/table17.xlsx +0 -0
- data/test/test_example_match.rb +172 -0
- data/write_xlsx.gemspec +1 -0
- metadata +106 -3
@@ -136,37 +136,25 @@ def write_shared_strings_file
|
|
136
136
|
# Write the app.xml file.
|
137
137
|
#
|
138
138
|
def write_app_file
|
139
|
-
|
140
|
-
properties = @workbook.doc_properties
|
141
|
-
app = Package::App.new
|
142
|
-
|
143
|
-
FileUtils.mkdir_p("#{@package_dir}/docProps")
|
139
|
+
app = Package::App.new(@workbook)
|
144
140
|
|
145
141
|
# Add the Worksheet heading pairs.
|
146
|
-
app.
|
147
|
-
|
142
|
+
app.add_worksheet_heading_pairs
|
148
143
|
# Add the Chartsheet heading pairs.
|
149
|
-
app.
|
144
|
+
app.add_chartsheet_heading_pairs
|
150
145
|
|
151
146
|
# Add the Worksheet parts.
|
152
|
-
|
153
|
-
each { |sheet| app.add_part_name(sheet.name) }
|
154
|
-
|
147
|
+
app.add_worksheet_part_names
|
155
148
|
# Add the Chartsheet parts.
|
156
|
-
|
157
|
-
each { |sheet| app.add_part_name(sheet.name) }
|
158
|
-
|
149
|
+
app.add_chartsheet_part_names
|
159
150
|
# Add the Named Range heading pairs.
|
160
|
-
|
161
|
-
if range_count != 0
|
162
|
-
app.add_heading_pair([ 'Named Ranges', range_count ])
|
163
|
-
end
|
164
|
-
|
151
|
+
app.add_named_range_heading_pairs
|
165
152
|
# Add the Named Ranges parts.
|
166
|
-
|
153
|
+
app.add_named_ranges_parts
|
167
154
|
|
168
|
-
app.set_properties(
|
155
|
+
app.set_properties(@workbook.doc_properties)
|
169
156
|
|
157
|
+
FileUtils.mkdir_p("#{@package_dir}/docProps")
|
170
158
|
app.set_xml_writer("#{@package_dir}/docProps/app.xml")
|
171
159
|
app.assemble_xml_file
|
172
160
|
end
|
@@ -188,30 +176,18 @@ def write_core_file
|
|
188
176
|
# Write the ContentTypes.xml file.
|
189
177
|
#
|
190
178
|
def write_content_types_file
|
191
|
-
content = Package::ContentTypes.new
|
192
|
-
|
193
|
-
content.add_image_types(@workbook.image_types)
|
194
|
-
@workbook.worksheets.reject { |sheet| sheet.is_chartsheet? }.
|
195
|
-
each_with_index do |sheet, index|
|
196
|
-
content.add_worksheet_name("sheet#{index+1}")
|
197
|
-
end
|
198
|
-
@workbook.worksheets.select { |sheet| sheet.is_chartsheet? }.
|
199
|
-
each_with_index do |sheet, index|
|
200
|
-
content.add_chartsheet_name("sheet#{index+1}")
|
201
|
-
end
|
202
|
-
|
203
|
-
(1 .. @workbook.charts.size).each { |i| content.add_chart_name("chart#{i}") }
|
204
|
-
(1 .. @workbook.drawings.size).each { |i| content.add_drawing_name("drawing#{i}") }
|
179
|
+
content = Package::ContentTypes.new(@workbook)
|
205
180
|
|
181
|
+
content.add_image_types
|
182
|
+
content.add_worksheet_names
|
183
|
+
content.add_chartsheet_names
|
184
|
+
content.add_chart_names
|
185
|
+
content.add_drawing_names
|
206
186
|
content.add_vml_name if @workbook.num_vml_files > 0
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
(1 .. @workbook.num_comment_files).each { |i| content.add_comment_name("comments#{i}") }
|
211
|
-
|
187
|
+
content.add_table_names(@table_count)
|
188
|
+
content.add_comment_names
|
212
189
|
# Add the sharedString rel if there is string data in the workbook.
|
213
190
|
content.add_shared_strings unless @workbook.shared_strings_empty?
|
214
|
-
|
215
191
|
# Add vbaProject if present.
|
216
192
|
content.add_vba_project if @workbook.vba_project
|
217
193
|
|
@@ -26,18 +26,7 @@ def set_xml_writer(filename)
|
|
26
26
|
|
27
27
|
def assemble_xml_file
|
28
28
|
write_xml_declaration do
|
29
|
-
write_style_sheet
|
30
|
-
write_num_fmts
|
31
|
-
write_fonts
|
32
|
-
write_fills
|
33
|
-
write_borders
|
34
|
-
write_cell_style_xfs
|
35
|
-
write_cell_xfs
|
36
|
-
write_cell_styles
|
37
|
-
write_dxfs
|
38
|
-
write_table_styles
|
39
|
-
write_colors
|
40
|
-
end
|
29
|
+
write_style_sheet { write_style_sheet_base }
|
41
30
|
end
|
42
31
|
end
|
43
32
|
|
@@ -71,9 +60,7 @@ def palette_color(index)
|
|
71
60
|
# Write the <styleSheet> element.
|
72
61
|
#
|
73
62
|
def write_style_sheet
|
74
|
-
|
75
|
-
|
76
|
-
attributes = [ ['xmlns', xmlns] ]
|
63
|
+
attributes = [ ['xmlns', XMLWriterSimple::XMLNS] ]
|
77
64
|
|
78
65
|
@writer.tag_elements('styleSheet', attributes) { yield }
|
79
66
|
end
|
@@ -98,57 +85,51 @@ def write_num_fmts
|
|
98
85
|
end
|
99
86
|
end
|
100
87
|
|
88
|
+
FORMAT_CODES = {
|
89
|
+
0 => 'General',
|
90
|
+
1 => '0',
|
91
|
+
2 => '0.00',
|
92
|
+
3 => '#,##0',
|
93
|
+
4 => '#,##0.00',
|
94
|
+
5 => '($#,##0_);($#,##0)',
|
95
|
+
6 => '($#,##0_);[Red]($#,##0)',
|
96
|
+
7 => '($#,##0.00_);($#,##0.00)',
|
97
|
+
8 => '($#,##0.00_);[Red]($#,##0.00)',
|
98
|
+
9 => '0%',
|
99
|
+
10 => '0.00%',
|
100
|
+
11 => '0.00E+00',
|
101
|
+
12 => '# ?/?',
|
102
|
+
13 => '# ??/??',
|
103
|
+
14 => 'm/d/yy',
|
104
|
+
15 => 'd-mmm-yy',
|
105
|
+
16 => 'd-mmm',
|
106
|
+
17 => 'mmm-yy',
|
107
|
+
18 => 'h:mm AM/PM',
|
108
|
+
19 => 'h:mm:ss AM/PM',
|
109
|
+
20 => 'h:mm',
|
110
|
+
21 => 'h:mm:ss',
|
111
|
+
22 => 'm/d/yy h:mm',
|
112
|
+
37 => '(#,##0_);(#,##0)',
|
113
|
+
38 => '(#,##0_);[Red](#,##0)',
|
114
|
+
39 => '(#,##0.00_);(#,##0.00)',
|
115
|
+
40 => '(#,##0.00_);[Red](#,##0.00)',
|
116
|
+
41 => '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
|
117
|
+
42 => '_($* #,##0_);_($* (#,##0);_($* "-"_);_(@_)',
|
118
|
+
43 => '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
|
119
|
+
44 => '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)',
|
120
|
+
45 => 'mm:ss',
|
121
|
+
46 => '[h]:mm:ss',
|
122
|
+
47 => 'mm:ss.0',
|
123
|
+
48 => '##0.0E+0',
|
124
|
+
49 => '@'
|
125
|
+
}
|
126
|
+
|
101
127
|
#
|
102
128
|
# Write the <numFmt> element.
|
103
129
|
#
|
104
130
|
def write_num_fmt(num_fmt_id, format_code)
|
105
|
-
format_codes = {
|
106
|
-
0 => 'General',
|
107
|
-
1 => '0',
|
108
|
-
2 => '0.00',
|
109
|
-
3 => '#,##0',
|
110
|
-
4 => '#,##0.00',
|
111
|
-
5 => '($#,##0_);($#,##0)',
|
112
|
-
6 => '($#,##0_);[Red]($#,##0)',
|
113
|
-
7 => '($#,##0.00_);($#,##0.00)',
|
114
|
-
8 => '($#,##0.00_);[Red]($#,##0.00)',
|
115
|
-
9 => '0%',
|
116
|
-
10 => '0.00%',
|
117
|
-
11 => '0.00E+00',
|
118
|
-
12 => '# ?/?',
|
119
|
-
13 => '# ??/??',
|
120
|
-
14 => 'm/d/yy',
|
121
|
-
15 => 'd-mmm-yy',
|
122
|
-
16 => 'd-mmm',
|
123
|
-
17 => 'mmm-yy',
|
124
|
-
18 => 'h:mm AM/PM',
|
125
|
-
19 => 'h:mm:ss AM/PM',
|
126
|
-
20 => 'h:mm',
|
127
|
-
21 => 'h:mm:ss',
|
128
|
-
22 => 'm/d/yy h:mm',
|
129
|
-
37 => '(#,##0_);(#,##0)',
|
130
|
-
38 => '(#,##0_);[Red](#,##0)',
|
131
|
-
39 => '(#,##0.00_);(#,##0.00)',
|
132
|
-
40 => '(#,##0.00_);[Red](#,##0.00)',
|
133
|
-
41 => '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
|
134
|
-
42 => '_($* #,##0_);_($* (#,##0);_($* "-"_);_(@_)',
|
135
|
-
43 => '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
|
136
|
-
44 => '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)',
|
137
|
-
45 => 'mm:ss',
|
138
|
-
46 => '[h]:mm:ss',
|
139
|
-
47 => 'mm:ss.0',
|
140
|
-
48 => '##0.0E+0',
|
141
|
-
49 => '@'
|
142
|
-
}
|
143
|
-
|
144
131
|
# Set the format code for built-in number formats.
|
145
|
-
if num_fmt_id < 164
|
146
|
-
if format_codes[num_fmt_id]
|
147
|
-
format_code = format_codes[num_fmt_id]
|
148
|
-
else
|
149
|
-
format_code = 'General'
|
150
|
-
end
|
151
|
-
end
|
132
|
+
format_code = FORMAT_CODES[num_fmt_id] || 'General' if num_fmt_id < 164
|
152
133
|
|
153
134
|
attributes = [
|
154
135
|
['numFmtId', num_fmt_id],
|
@@ -163,9 +144,13 @@ def write_num_fmt(num_fmt_id, format_code)
|
|
163
144
|
#
|
164
145
|
def write_fonts
|
165
146
|
write_format_elements('fonts', @font_count) do
|
166
|
-
|
167
|
-
|
168
|
-
|
147
|
+
write_font_base
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def write_font_base
|
152
|
+
@xf_formats.each do |format|
|
153
|
+
format.write_font(@writer, self) if format.has_font?
|
169
154
|
end
|
170
155
|
end
|
171
156
|
|
@@ -182,19 +167,21 @@ def write_color(name, value)
|
|
182
167
|
# Write the <fills> element.
|
183
168
|
#
|
184
169
|
def write_fills
|
185
|
-
|
186
|
-
|
187
|
-
attributes = [ ['count', count] ]
|
170
|
+
attributes = [ ['count', @fill_count] ]
|
188
171
|
|
189
172
|
@writer.tag_elements('fills', attributes) do
|
190
|
-
|
191
|
-
|
192
|
-
|
173
|
+
write_fills_base
|
174
|
+
end
|
175
|
+
end
|
193
176
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
177
|
+
def write_fills_base
|
178
|
+
# Write the default fill element.
|
179
|
+
write_default_fill('none')
|
180
|
+
write_default_fill('gray125')
|
181
|
+
|
182
|
+
# Write the fill elements for format objects that have them.
|
183
|
+
@xf_formats.each do |format|
|
184
|
+
write_fill(format) if format.has_fill?
|
198
185
|
end
|
199
186
|
end
|
200
187
|
|
@@ -207,11 +194,65 @@ def write_default_fill(pattern_type)
|
|
207
194
|
end
|
208
195
|
end
|
209
196
|
|
197
|
+
PATTERNS = %w(
|
198
|
+
none
|
199
|
+
solid
|
200
|
+
mediumGray
|
201
|
+
darkGray
|
202
|
+
lightGray
|
203
|
+
darkHorizontal
|
204
|
+
darkVertical
|
205
|
+
darkDown
|
206
|
+
darkUp
|
207
|
+
darkGrid
|
208
|
+
darkTrellis
|
209
|
+
lightHorizontal
|
210
|
+
lightVertical
|
211
|
+
lightDown
|
212
|
+
lightUp
|
213
|
+
lightGrid
|
214
|
+
lightTrellis
|
215
|
+
gray125
|
216
|
+
gray0625
|
217
|
+
)
|
218
|
+
|
210
219
|
#
|
211
220
|
# Write the <fill> element.
|
212
221
|
#
|
213
222
|
def write_fill(format, dxf_format = nil)
|
214
|
-
|
223
|
+
@writer.tag_elements('fill' ) do
|
224
|
+
write_fill_base(format, dxf_format)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def write_fill_base(format, dxf_format)
|
229
|
+
# The "none" pattern is handled differently for dxf formats.
|
230
|
+
if dxf_format && format.pattern <= 1
|
231
|
+
attributes = []
|
232
|
+
else
|
233
|
+
attributes = [ ['patternType', PATTERNS[format.pattern]] ]
|
234
|
+
end
|
235
|
+
|
236
|
+
@writer.tag_elements('patternFill', attributes) do
|
237
|
+
write_pattern_fill(format, dxf_format)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def write_pattern_fill(format, dxf_format)
|
242
|
+
bg_color, fg_color = bg_and_fg_color(format, dxf_format)
|
243
|
+
|
244
|
+
if fg_color && fg_color != 0
|
245
|
+
@writer.empty_tag('fgColor', [ ['rgb', palette_color(fg_color)] ])
|
246
|
+
end
|
247
|
+
|
248
|
+
if bg_color && bg_color != 0
|
249
|
+
@writer.empty_tag('bgColor', [ ['rgb', palette_color(bg_color)] ])
|
250
|
+
else
|
251
|
+
@writer.empty_tag('bgColor', [ ['indexed', 64] ]) if !dxf_format
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def bg_and_fg_color(format, dxf_format)
|
215
256
|
bg_color = format.bg_color
|
216
257
|
fg_color = format.fg_color
|
217
258
|
|
@@ -222,50 +263,7 @@ def write_fill(format, dxf_format = nil)
|
|
222
263
|
fg_color = format.dxf_fg_color
|
223
264
|
end
|
224
265
|
|
225
|
-
|
226
|
-
none
|
227
|
-
solid
|
228
|
-
mediumGray
|
229
|
-
darkGray
|
230
|
-
lightGray
|
231
|
-
darkHorizontal
|
232
|
-
darkVertical
|
233
|
-
darkDown
|
234
|
-
darkUp
|
235
|
-
darkGrid
|
236
|
-
darkTrellis
|
237
|
-
lightHorizontal
|
238
|
-
lightVertical
|
239
|
-
lightDown
|
240
|
-
lightUp
|
241
|
-
lightGrid
|
242
|
-
lightTrellis
|
243
|
-
gray125
|
244
|
-
gray0625
|
245
|
-
)
|
246
|
-
|
247
|
-
@writer.tag_elements('fill' ) do
|
248
|
-
# The "none" pattern is handled differently for dxf formats.
|
249
|
-
if dxf_format && format.pattern <= 1
|
250
|
-
attributes = []
|
251
|
-
else
|
252
|
-
attributes = [ ['patternType', patterns[format.pattern]] ]
|
253
|
-
end
|
254
|
-
|
255
|
-
@writer.tag_elements('patternFill', attributes) do
|
256
|
-
if fg_color && fg_color != 0
|
257
|
-
fg_color = palette_color(fg_color)
|
258
|
-
@writer.empty_tag('fgColor', [ ['rgb', fg_color] ])
|
259
|
-
end
|
260
|
-
|
261
|
-
if bg_color && bg_color != 0
|
262
|
-
bg_color = palette_color(bg_color)
|
263
|
-
@writer.empty_tag('bgColor', [ ['rgb', bg_color] ])
|
264
|
-
else
|
265
|
-
@writer.empty_tag('bgColor', [ ['indexed', 64] ]) if !dxf_format
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
266
|
+
[bg_color, fg_color]
|
269
267
|
end
|
270
268
|
|
271
269
|
#
|
@@ -273,9 +271,13 @@ def write_fill(format, dxf_format = nil)
|
|
273
271
|
#
|
274
272
|
def write_borders
|
275
273
|
write_format_elements('borders', @border_count) do
|
276
|
-
|
277
|
-
|
278
|
-
|
274
|
+
write_borders_base
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def write_borders_base
|
279
|
+
@xf_formats.each do |format|
|
280
|
+
write_border(format) if format.has_border?
|
279
281
|
end
|
280
282
|
end
|
281
283
|
|
@@ -292,41 +294,52 @@ def write_format_elements(elements, count)
|
|
292
294
|
# Write the <border> element.
|
293
295
|
#
|
294
296
|
def write_border(format, dxf_format = nil)
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
if format.diag_type == 1
|
299
|
-
attributes << ['diagonalUp', 1]
|
300
|
-
elsif format.diag_type == 2
|
301
|
-
attributes << ['diagonalDown', 1]
|
302
|
-
elsif format.diag_type == 3
|
303
|
-
attributes << ['diagonalUp', 1]
|
304
|
-
attributes << ['diagonalDown', 1]
|
297
|
+
# Write the start border tag.
|
298
|
+
@writer.tag_elements('border', format.border_attributes) do
|
299
|
+
write_border_base(format, dxf_format)
|
305
300
|
end
|
301
|
+
end
|
306
302
|
|
307
|
-
|
308
|
-
|
303
|
+
def write_border_base(format, dxf_format)
|
304
|
+
# Write the <border> sub elements.
|
305
|
+
write_border_sub_elements(format)
|
309
306
|
|
310
|
-
#
|
311
|
-
|
312
|
-
|
313
|
-
write_sub_border('
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
# Condition DXF formats don't allow diagonal borders
|
319
|
-
if !dxf_format
|
320
|
-
write_sub_border('diagonal', format.diag_border, format.diag_color)
|
321
|
-
end
|
307
|
+
# Condition DXF formats don't allow diagonal borders
|
308
|
+
if dxf_format
|
309
|
+
write_sub_border('vertical')
|
310
|
+
write_sub_border('horizontal')
|
311
|
+
else
|
312
|
+
# Ensure that a default diag border is set if the diag type is set.
|
313
|
+
format.diag_border = 1 if format.diag_type != 0 && format.diag_border == 0
|
322
314
|
|
323
|
-
|
324
|
-
write_sub_border('vertical')
|
325
|
-
write_sub_border('horizontal')
|
326
|
-
end
|
315
|
+
write_sub_border('diagonal', format.diag_border, format.diag_color)
|
327
316
|
end
|
328
317
|
end
|
329
318
|
|
319
|
+
def write_border_sub_elements(format)
|
320
|
+
write_sub_border('left', format.left, format.left_color)
|
321
|
+
write_sub_border('right', format.right, format.right_color)
|
322
|
+
write_sub_border('top', format.top, format.top_color)
|
323
|
+
write_sub_border('bottom', format.bottom, format.bottom_color)
|
324
|
+
end
|
325
|
+
|
326
|
+
BORDER_STYLES = %w(
|
327
|
+
none
|
328
|
+
thin
|
329
|
+
medium
|
330
|
+
dashed
|
331
|
+
dotted
|
332
|
+
thick
|
333
|
+
double
|
334
|
+
hair
|
335
|
+
mediumDashed
|
336
|
+
dashDot
|
337
|
+
mediumDashDot
|
338
|
+
dashDotDot
|
339
|
+
mediumDashDotDot
|
340
|
+
slantDashDot
|
341
|
+
)
|
342
|
+
|
330
343
|
#
|
331
344
|
# Write the <border> sub elements such as <right>, <top>, etc.
|
332
345
|
#
|
@@ -336,24 +349,7 @@ def write_sub_border(type, style = 0, color = nil)
|
|
336
349
|
return
|
337
350
|
end
|
338
351
|
|
339
|
-
|
340
|
-
none
|
341
|
-
thin
|
342
|
-
medium
|
343
|
-
dashed
|
344
|
-
dotted
|
345
|
-
thick
|
346
|
-
double
|
347
|
-
hair
|
348
|
-
mediumDashed
|
349
|
-
dashDot
|
350
|
-
mediumDashDot
|
351
|
-
dashDotDot
|
352
|
-
mediumDashDotDot
|
353
|
-
slantDashDot
|
354
|
-
)
|
355
|
-
|
356
|
-
attributes = [ [:style, border_styles[style]] ]
|
352
|
+
attributes = [ [:style, BORDER_STYLES[style]] ]
|
357
353
|
|
358
354
|
@writer.tag_elements(type, attributes) do
|
359
355
|
if color != 0
|
@@ -401,16 +397,11 @@ def write_cell_xfs
|
|
401
397
|
# Write the style <xf> element.
|
402
398
|
#
|
403
399
|
def write_style_xf
|
404
|
-
num_fmt_id = 0
|
405
|
-
font_id = 0
|
406
|
-
fill_id = 0
|
407
|
-
border_id = 0
|
408
|
-
|
409
400
|
attributes = [
|
410
|
-
['numFmtId',
|
411
|
-
['fontId',
|
412
|
-
['fillId',
|
413
|
-
['borderId',
|
401
|
+
['numFmtId', 0],
|
402
|
+
['fontId', 0],
|
403
|
+
['fillId', 0],
|
404
|
+
['borderId', 0]
|
414
405
|
]
|
415
406
|
|
416
407
|
@writer.empty_tag('xf', attributes)
|
@@ -418,57 +409,40 @@ def write_style_xf
|
|
418
409
|
|
419
410
|
private
|
420
411
|
|
412
|
+
def write_style_sheet_base
|
413
|
+
write_num_fmts
|
414
|
+
write_fonts
|
415
|
+
write_fills
|
416
|
+
write_borders
|
417
|
+
write_cell_style_xfs
|
418
|
+
write_cell_xfs
|
419
|
+
write_cell_styles
|
420
|
+
write_dxfs
|
421
|
+
write_table_styles
|
422
|
+
write_colors
|
423
|
+
end
|
424
|
+
|
421
425
|
#
|
422
426
|
# Write the <xf> element.
|
423
427
|
#
|
424
428
|
def write_xf(format)
|
425
|
-
has_align = false
|
426
|
-
has_protect = false
|
427
|
-
|
428
|
-
attributes = [
|
429
|
-
['numFmtId', format.num_format_index],
|
430
|
-
['fontId' , format.font_index],
|
431
|
-
['fillId' , format.fill_index],
|
432
|
-
['borderId', format.border_index],
|
433
|
-
['xfId' , 0]
|
434
|
-
]
|
435
|
-
|
436
|
-
attributes << ['applyNumberFormat', 1] if format.num_format_index > 0
|
437
|
-
|
438
|
-
# Add applyFont attribute if XF format uses a font element.
|
439
|
-
attributes << ['applyFont', 1] if format.font_index > 0
|
440
|
-
|
441
|
-
# Add applyFill attribute if XF format uses a fill element.
|
442
|
-
attributes << ['applyFill', 1] if format.fill_index > 0
|
443
|
-
|
444
|
-
# Add applyBorder attribute if XF format uses a border element.
|
445
|
-
attributes << ['applyBorder', 1] if format.border_index > 0
|
446
|
-
|
447
429
|
# Check if XF format has alignment properties set.
|
448
430
|
apply_align, align = format.get_align_properties
|
449
431
|
|
450
|
-
# Check if an alignment sub-element should be written.
|
451
|
-
has_align = true if apply_align && !align.empty?
|
452
|
-
|
453
|
-
# We can also have applyAlignment without a sub-element.
|
454
|
-
attributes << ['applyAlignment', 1] if apply_align
|
455
|
-
|
456
432
|
# Check for cell protection properties.
|
457
433
|
protection = format.get_protection_properties
|
458
434
|
|
459
|
-
if
|
460
|
-
|
461
|
-
has_protect = true
|
462
|
-
end
|
435
|
+
# Check if an alignment sub-element should be written.
|
436
|
+
has_align = apply_align && !align.empty?
|
463
437
|
|
464
438
|
# Write XF with sub-elements if required.
|
465
|
-
if has_align ||
|
466
|
-
@writer.tag_elements('xf',
|
439
|
+
if has_align || protection
|
440
|
+
@writer.tag_elements('xf', format.xf_attributes) do
|
467
441
|
@writer.empty_tag('alignment', align) if has_align
|
468
|
-
@writer.empty_tag('protection', protection) if
|
442
|
+
@writer.empty_tag('protection', protection) if protection
|
469
443
|
end
|
470
444
|
else
|
471
|
-
@writer.empty_tag('xf',
|
445
|
+
@writer.empty_tag('xf', format.xf_attributes)
|
472
446
|
end
|
473
447
|
end
|
474
448
|
|
@@ -488,14 +462,10 @@ def write_cell_styles
|
|
488
462
|
# Write the <cellStyle> element.
|
489
463
|
#
|
490
464
|
def write_cell_style
|
491
|
-
name = 'Normal'
|
492
|
-
xf_id = 0
|
493
|
-
builtin_id = 0
|
494
|
-
|
495
465
|
attributes = [
|
496
|
-
['name',
|
497
|
-
['xfId',
|
498
|
-
['builtinId',
|
466
|
+
['name', 'Normal'],
|
467
|
+
['xfId', 0],
|
468
|
+
['builtinId', 0]
|
499
469
|
]
|
500
470
|
|
501
471
|
@writer.empty_tag('cellStyle', attributes)
|
@@ -505,30 +475,30 @@ def write_cell_style
|
|
505
475
|
# Write the <dxfs> element.
|
506
476
|
#
|
507
477
|
def write_dxfs
|
508
|
-
|
509
|
-
|
510
|
-
count = formats.size
|
478
|
+
attributes = [ ['count', @dxf_formats.count] ]
|
511
479
|
|
512
|
-
|
513
|
-
|
514
|
-
|
480
|
+
if @dxf_formats.empty?
|
481
|
+
@writer.empty_tag('dxfs', attributes)
|
482
|
+
else
|
515
483
|
@writer.tag_elements('dxfs', attributes) do
|
516
484
|
# Write the font elements for format objects that have them.
|
517
485
|
@dxf_formats.each do |format|
|
518
|
-
|
519
|
-
|
486
|
+
write_dxf(format)
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
520
491
|
|
521
|
-
|
522
|
-
|
523
|
-
|
492
|
+
def write_dxf(format)
|
493
|
+
@writer.tag_elements('dxf') do
|
494
|
+
format.write_font(@writer, self, 1) if format.has_dxf_font?
|
524
495
|
|
525
|
-
|
526
|
-
|
527
|
-
end
|
528
|
-
end
|
496
|
+
if format.num_format_index != 0
|
497
|
+
write_num_fmt(format.num_format_index, format.num_format)
|
529
498
|
end
|
530
|
-
|
531
|
-
|
499
|
+
|
500
|
+
write_fill(format, 1) if format.has_dxf_fill?
|
501
|
+
write_border(format, 1) if format.has_dxf_border?
|
532
502
|
end
|
533
503
|
end
|
534
504
|
|
@@ -536,14 +506,10 @@ def write_dxfs
|
|
536
506
|
# Write the <tableStyles> element.
|
537
507
|
#
|
538
508
|
def write_table_styles
|
539
|
-
count = 0
|
540
|
-
default_table_style = 'TableStyleMedium9'
|
541
|
-
default_pivot_style = 'PivotStyleLight16'
|
542
|
-
|
543
509
|
attributes = [
|
544
|
-
['count',
|
545
|
-
['defaultTableStyle',
|
546
|
-
['defaultPivotStyle',
|
510
|
+
['count', 0],
|
511
|
+
['defaultTableStyle', 'TableStyleMedium9'],
|
512
|
+
['defaultPivotStyle', 'PivotStyleLight16']
|
547
513
|
]
|
548
514
|
|
549
515
|
@writer.empty_tag('tableStyles', attributes)
|
@@ -553,8 +519,6 @@ def write_table_styles
|
|
553
519
|
# Write the <colors> element.
|
554
520
|
#
|
555
521
|
def write_colors
|
556
|
-
custom_colors = @custom_colors
|
557
|
-
|
558
522
|
return if @custom_colors.empty?
|
559
523
|
|
560
524
|
@writer.tag_elements( 'colors' ) do
|
@@ -565,16 +529,15 @@ def write_colors
|
|
565
529
|
#
|
566
530
|
# Write the <mruColors> element for the most recently used colours.
|
567
531
|
#
|
568
|
-
def write_mru_colors(
|
569
|
-
custom_colors = args
|
570
|
-
|
532
|
+
def write_mru_colors(custom_colors)
|
571
533
|
# Limit the mruColors to the last 10.
|
572
534
|
count = custom_colors.size
|
535
|
+
# array[-10, 10] returns array which contains last 10 items.
|
573
536
|
custom_colors = custom_colors[-10, 10] if count > 10
|
574
537
|
|
575
538
|
@writer.tag_elements('mruColors') do
|
576
539
|
# Write the custom colors in reverse order.
|
577
|
-
|
540
|
+
custom_colors.reverse.each do |color|
|
578
541
|
write_color('rgb', color)
|
579
542
|
end
|
580
543
|
end
|
@@ -584,9 +547,7 @@ def write_mru_colors(*args)
|
|
584
547
|
# Write the <condense> element.
|
585
548
|
#
|
586
549
|
def write_condense
|
587
|
-
|
588
|
-
|
589
|
-
attributes = [ ['val', val] ]
|
550
|
+
attributes = [ ['val', 0] ]
|
590
551
|
|
591
552
|
@writer.empty_tag('condense', attributes)
|
592
553
|
end
|
@@ -595,9 +556,7 @@ def write_condense
|
|
595
556
|
# Write the <extend> element.
|
596
557
|
#
|
597
558
|
def write_extend
|
598
|
-
|
599
|
-
|
600
|
-
attributes = [ ['val', val] ]
|
559
|
+
attributes = [ ['val', 0] ]
|
601
560
|
|
602
561
|
@writer.empty_tag('extend', attributes)
|
603
562
|
end
|