fast_excel 0.4.1 → 0.5.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/test.yml +1 -7
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -1
- data/examples/example.rb +2 -0
- data/examples/example_date_time.rb +38 -0
- data/fast_excel.gemspec +2 -2
- data/lib/fast_excel/binding/format.rb +17 -0
- data/lib/fast_excel/binding/workbook.rb +39 -17
- data/lib/fast_excel/binding/worksheet.rb +57 -13
- data/lib/fast_excel/binding.rb +7 -7
- data/lib/fast_excel.rb +27 -20
- data/libxlsxwriter/.github/FUNDING.yml +1 -0
- data/libxlsxwriter/.github/ISSUE_TEMPLATE.md +85 -0
- data/libxlsxwriter/.github/PULL_REQUEST_TEMPLATE.md +130 -0
- data/libxlsxwriter/.github/workflows/cmake_actions.yml +48 -0
- data/libxlsxwriter/.github/workflows/code_style.yml +23 -0
- data/libxlsxwriter/.github/workflows/coverity.yml +22 -0
- data/libxlsxwriter/.github/workflows/make_actions.yml +52 -0
- data/libxlsxwriter/.github/workflows/valgrind.yml +23 -0
- data/libxlsxwriter/.github/workflows/windows_build.yml +54 -0
- data/libxlsxwriter/.github/workflows/zig_build.yml +22 -0
- data/libxlsxwriter/.gitignore +16 -1
- data/libxlsxwriter/.indent.pro +24 -0
- data/libxlsxwriter/CMakeLists.txt +156 -56
- data/libxlsxwriter/CONTRIBUTING.md +2 -2
- data/libxlsxwriter/Changes.txt +344 -2
- data/libxlsxwriter/LICENSE.txt +66 -8
- data/libxlsxwriter/Makefile +151 -54
- data/libxlsxwriter/Package.swift +42 -0
- data/libxlsxwriter/Readme.md +4 -2
- data/libxlsxwriter/build.zig +324 -0
- data/libxlsxwriter/build.zig.zon +11 -0
- data/libxlsxwriter/cmake/FindMINIZIP.cmake +3 -3
- data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +6 -0
- data/libxlsxwriter/include/xlsxwriter/app.h +2 -1
- data/libxlsxwriter/include/xlsxwriter/chart.h +236 -32
- data/libxlsxwriter/include/xlsxwriter/chartsheet.h +7 -7
- data/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
- data/libxlsxwriter/include/xlsxwriter/common.h +111 -50
- data/libxlsxwriter/include/xlsxwriter/content_types.h +8 -1
- data/libxlsxwriter/include/xlsxwriter/core.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/drawing.h +11 -20
- data/libxlsxwriter/include/xlsxwriter/format.h +121 -8
- data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/metadata.h +49 -0
- data/libxlsxwriter/include/xlsxwriter/packager.h +27 -16
- data/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/styles.h +13 -7
- data/libxlsxwriter/include/xlsxwriter/table.h +51 -0
- data/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/third_party/emyg_dtoa.h +26 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +27 -25
- data/libxlsxwriter/include/xlsxwriter/third_party/md5.h +45 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +155 -153
- data/libxlsxwriter/include/xlsxwriter/utility.h +70 -8
- data/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
- data/libxlsxwriter/include/xlsxwriter/workbook.h +218 -47
- data/libxlsxwriter/include/xlsxwriter/worksheet.h +2770 -241
- data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +12 -8
- data/libxlsxwriter/include/xlsxwriter.h +4 -2
- data/libxlsxwriter/libxlsxwriter.podspec +8 -5
- data/libxlsxwriter/src/Makefile +58 -21
- data/libxlsxwriter/src/app.c +5 -2
- data/libxlsxwriter/src/chart.c +396 -81
- data/libxlsxwriter/src/chartsheet.c +22 -22
- data/libxlsxwriter/src/comment.c +443 -0
- data/libxlsxwriter/src/content_types.c +40 -1
- data/libxlsxwriter/src/core.c +2 -2
- data/libxlsxwriter/src/custom.c +1 -1
- data/libxlsxwriter/src/drawing.c +160 -40
- data/libxlsxwriter/src/format.c +109 -25
- data/libxlsxwriter/src/hash_table.c +1 -1
- data/libxlsxwriter/src/metadata.c +283 -0
- data/libxlsxwriter/src/packager.c +794 -94
- data/libxlsxwriter/src/relationships.c +1 -1
- data/libxlsxwriter/src/shared_strings.c +2 -4
- data/libxlsxwriter/src/styles.c +353 -58
- data/libxlsxwriter/src/table.c +304 -0
- data/libxlsxwriter/src/theme.c +1 -1
- data/libxlsxwriter/src/utility.c +143 -43
- data/libxlsxwriter/src/vml.c +1062 -0
- data/libxlsxwriter/src/workbook.c +567 -77
- data/libxlsxwriter/src/worksheet.c +6668 -1462
- data/libxlsxwriter/src/xmlwriter.c +95 -5
- data/libxlsxwriter/third_party/dtoa/Makefile +42 -0
- data/libxlsxwriter/third_party/dtoa/emyg_dtoa.c +461 -0
- data/libxlsxwriter/third_party/dtoa/emyg_dtoa.h +26 -0
- data/libxlsxwriter/third_party/md5/Makefile +42 -0
- data/libxlsxwriter/third_party/md5/md5.c +291 -0
- data/libxlsxwriter/third_party/md5/md5.h +45 -0
- data/libxlsxwriter/third_party/minizip/Makefile +3 -8
- data/libxlsxwriter/third_party/minizip/Makefile.orig +8 -4
- data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +1 -1
- data/libxlsxwriter/third_party/minizip/configure.ac +1 -1
- data/libxlsxwriter/third_party/minizip/crypt.h +13 -16
- data/libxlsxwriter/third_party/minizip/ioapi.c +31 -57
- data/libxlsxwriter/third_party/minizip/ioapi.h +31 -23
- data/libxlsxwriter/third_party/minizip/iowin32.c +29 -45
- data/libxlsxwriter/third_party/minizip/iowin32.h +4 -4
- data/libxlsxwriter/third_party/minizip/miniunz.c +29 -56
- data/libxlsxwriter/third_party/minizip/minizip.c +38 -49
- data/libxlsxwriter/third_party/minizip/mztools.c +1 -7
- data/libxlsxwriter/third_party/minizip/unzip.c +202 -342
- data/libxlsxwriter/third_party/minizip/unzip.h +74 -74
- data/libxlsxwriter/third_party/minizip/zip.c +165 -218
- data/libxlsxwriter/third_party/minizip/zip.h +164 -154
- data/libxlsxwriter/third_party/tmpfileplus/Makefile +3 -3
- data/libxlsxwriter/version.txt +1 -1
- data/test/auto_width_test.rb +20 -0
- data/test/default_format_test.rb +1 -1
- data/test/validations_test.rb +3 -3
- data/test/worksheet_test.rb +6 -1
- metadata +33 -7
- data/libxlsxwriter/.travis.yml +0 -37
data/libxlsxwriter/src/styles.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -14,7 +14,7 @@
|
|
14
14
|
/*
|
15
15
|
* Forward declarations.
|
16
16
|
*/
|
17
|
-
STATIC void _write_font(lxw_styles *self, lxw_format *format,
|
17
|
+
STATIC void _write_font(lxw_styles *self, lxw_format *format, uint8_t is_dxf,
|
18
18
|
uint8_t is_rich_string);
|
19
19
|
|
20
20
|
/*****************************************************************************
|
@@ -34,9 +34,12 @@ lxw_styles_new(void)
|
|
34
34
|
|
35
35
|
styles->xf_formats = calloc(1, sizeof(struct lxw_formats));
|
36
36
|
GOTO_LABEL_ON_MEM_ERROR(styles->xf_formats, mem_error);
|
37
|
-
|
38
37
|
STAILQ_INIT(styles->xf_formats);
|
39
38
|
|
39
|
+
styles->dxf_formats = calloc(1, sizeof(struct lxw_formats));
|
40
|
+
GOTO_LABEL_ON_MEM_ERROR(styles->dxf_formats, mem_error);
|
41
|
+
STAILQ_INIT(styles->dxf_formats);
|
42
|
+
|
40
43
|
return styles;
|
41
44
|
|
42
45
|
mem_error:
|
@@ -55,7 +58,7 @@ lxw_styles_free(lxw_styles *styles)
|
|
55
58
|
if (!styles)
|
56
59
|
return;
|
57
60
|
|
58
|
-
/* Free the formats in the styles. */
|
61
|
+
/* Free the xf formats in the styles. */
|
59
62
|
if (styles->xf_formats) {
|
60
63
|
while (!STAILQ_EMPTY(styles->xf_formats)) {
|
61
64
|
format = STAILQ_FIRST(styles->xf_formats);
|
@@ -65,6 +68,16 @@ lxw_styles_free(lxw_styles *styles)
|
|
65
68
|
free(styles->xf_formats);
|
66
69
|
}
|
67
70
|
|
71
|
+
/* Free the dxf formats in the styles. */
|
72
|
+
if (styles->dxf_formats) {
|
73
|
+
while (!STAILQ_EMPTY(styles->dxf_formats)) {
|
74
|
+
format = STAILQ_FIRST(styles->dxf_formats);
|
75
|
+
STAILQ_REMOVE_HEAD(styles->dxf_formats, list_pointers);
|
76
|
+
free(format);
|
77
|
+
}
|
78
|
+
free(styles->dxf_formats);
|
79
|
+
}
|
80
|
+
|
68
81
|
free(styles);
|
69
82
|
}
|
70
83
|
|
@@ -72,7 +85,7 @@ lxw_styles_free(lxw_styles *styles)
|
|
72
85
|
* Write the <t> element for rich strings.
|
73
86
|
*/
|
74
87
|
void
|
75
|
-
lxw_styles_write_string_fragment(lxw_styles *self, char *string)
|
88
|
+
lxw_styles_write_string_fragment(lxw_styles *self, const char *string)
|
76
89
|
{
|
77
90
|
struct xml_attribute_list attributes;
|
78
91
|
struct xml_attribute *attribute;
|
@@ -93,7 +106,7 @@ void
|
|
93
106
|
lxw_styles_write_rich_font(lxw_styles *self, lxw_format *format)
|
94
107
|
{
|
95
108
|
|
96
|
-
_write_font(self, format, LXW_TRUE);
|
109
|
+
_write_font(self, format, LXW_FALSE, LXW_TRUE);
|
97
110
|
}
|
98
111
|
|
99
112
|
/*****************************************************************************
|
@@ -136,10 +149,68 @@ _write_num_fmt(lxw_styles *self, uint16_t num_fmt_id, char *format_code)
|
|
136
149
|
{
|
137
150
|
struct xml_attribute_list attributes;
|
138
151
|
struct xml_attribute *attribute;
|
152
|
+
char *format_codes[] = {
|
153
|
+
"General",
|
154
|
+
"0",
|
155
|
+
"0.00",
|
156
|
+
"#,##0",
|
157
|
+
"#,##0.00",
|
158
|
+
"($#,##0_);($#,##0)",
|
159
|
+
"($#,##0_);[Red]($#,##0)",
|
160
|
+
"($#,##0.00_);($#,##0.00)",
|
161
|
+
"($#,##0.00_);[Red]($#,##0.00)",
|
162
|
+
"0%",
|
163
|
+
"0.00%",
|
164
|
+
"0.00E+00",
|
165
|
+
"# ?/?",
|
166
|
+
"# ?" "?/?" "?", /* Split string to avoid unintentional trigraph. */
|
167
|
+
"m/d/yy",
|
168
|
+
"d-mmm-yy",
|
169
|
+
"d-mmm",
|
170
|
+
"mmm-yy",
|
171
|
+
"h:mm AM/PM",
|
172
|
+
"h:mm:ss AM/PM",
|
173
|
+
"h:mm",
|
174
|
+
"h:mm:ss",
|
175
|
+
"m/d/yy h:mm",
|
176
|
+
"General",
|
177
|
+
"General",
|
178
|
+
"General",
|
179
|
+
"General",
|
180
|
+
"General",
|
181
|
+
"General",
|
182
|
+
"General",
|
183
|
+
"General",
|
184
|
+
"General",
|
185
|
+
"General",
|
186
|
+
"General",
|
187
|
+
"General",
|
188
|
+
"General",
|
189
|
+
"General",
|
190
|
+
"(#,##0_);(#,##0)",
|
191
|
+
"(#,##0_);[Red](#,##0)",
|
192
|
+
"(#,##0.00_);(#,##0.00)",
|
193
|
+
"(#,##0.00_);[Red](#,##0.00)",
|
194
|
+
"_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)",
|
195
|
+
"_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(@_)",
|
196
|
+
"_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)",
|
197
|
+
"_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)",
|
198
|
+
"mm:ss",
|
199
|
+
"[h]:mm:ss",
|
200
|
+
"mm:ss.0",
|
201
|
+
"##0.0E+0",
|
202
|
+
"@"
|
203
|
+
};
|
139
204
|
|
140
205
|
LXW_INIT_ATTRIBUTES();
|
141
206
|
LXW_PUSH_ATTRIBUTES_INT("numFmtId", num_fmt_id);
|
142
|
-
|
207
|
+
|
208
|
+
if (num_fmt_id < 50)
|
209
|
+
LXW_PUSH_ATTRIBUTES_STR("formatCode", format_codes[num_fmt_id]);
|
210
|
+
else if (num_fmt_id < 164)
|
211
|
+
LXW_PUSH_ATTRIBUTES_STR("formatCode", "General");
|
212
|
+
else
|
213
|
+
LXW_PUSH_ATTRIBUTES_STR("formatCode", format_code);
|
143
214
|
|
144
215
|
lxw_xml_empty_tag(self->file, "numFmt", &attributes);
|
145
216
|
|
@@ -240,6 +311,23 @@ _write_font_color_rgb(lxw_styles *self, int32_t rgb)
|
|
240
311
|
LXW_FREE_ATTRIBUTES();
|
241
312
|
}
|
242
313
|
|
314
|
+
/*
|
315
|
+
* Write the <color> element for indexed colors.
|
316
|
+
*/
|
317
|
+
STATIC void
|
318
|
+
_write_font_color_indexed(lxw_styles *self, uint8_t index)
|
319
|
+
{
|
320
|
+
struct xml_attribute_list attributes;
|
321
|
+
struct xml_attribute *attribute;
|
322
|
+
|
323
|
+
LXW_INIT_ATTRIBUTES();
|
324
|
+
LXW_PUSH_ATTRIBUTES_INT("indexed", index);
|
325
|
+
|
326
|
+
lxw_xml_empty_tag(self->file, "color", &attributes);
|
327
|
+
|
328
|
+
LXW_FREE_ATTRIBUTES();
|
329
|
+
}
|
330
|
+
|
243
331
|
/*
|
244
332
|
* Write the <name> element.
|
245
333
|
*/
|
@@ -329,11 +417,45 @@ _write_font_underline(lxw_styles *self, uint8_t underline)
|
|
329
417
|
|
330
418
|
}
|
331
419
|
|
420
|
+
/*
|
421
|
+
* Write the font <condense> element.
|
422
|
+
*/
|
423
|
+
STATIC void
|
424
|
+
_write_font_condense(lxw_styles *self)
|
425
|
+
{
|
426
|
+
struct xml_attribute_list attributes;
|
427
|
+
struct xml_attribute *attribute;
|
428
|
+
|
429
|
+
LXW_INIT_ATTRIBUTES();
|
430
|
+
LXW_PUSH_ATTRIBUTES_STR("val", "0");
|
431
|
+
|
432
|
+
lxw_xml_empty_tag(self->file, "condense", &attributes);
|
433
|
+
|
434
|
+
LXW_FREE_ATTRIBUTES();
|
435
|
+
}
|
436
|
+
|
437
|
+
/*
|
438
|
+
* Write the font <extend> element.
|
439
|
+
*/
|
440
|
+
STATIC void
|
441
|
+
_write_font_extend(lxw_styles *self)
|
442
|
+
{
|
443
|
+
struct xml_attribute_list attributes;
|
444
|
+
struct xml_attribute *attribute;
|
445
|
+
|
446
|
+
LXW_INIT_ATTRIBUTES();
|
447
|
+
LXW_PUSH_ATTRIBUTES_STR("val", "0");
|
448
|
+
|
449
|
+
lxw_xml_empty_tag(self->file, "extend", &attributes);
|
450
|
+
|
451
|
+
LXW_FREE_ATTRIBUTES();
|
452
|
+
}
|
453
|
+
|
332
454
|
/*
|
333
455
|
* Write the <vertAlign> font sub-element.
|
334
456
|
*/
|
335
457
|
STATIC void
|
336
|
-
|
458
|
+
_write_font_vert_align(lxw_styles *self, const char *align)
|
337
459
|
{
|
338
460
|
struct xml_attribute_list attributes;
|
339
461
|
struct xml_attribute *attribute;
|
@@ -350,13 +472,20 @@ _write_vert_align(lxw_styles *self, const char *align)
|
|
350
472
|
* Write the <font> element.
|
351
473
|
*/
|
352
474
|
STATIC void
|
353
|
-
_write_font(lxw_styles *self, lxw_format *format, uint8_t
|
475
|
+
_write_font(lxw_styles *self, lxw_format *format, uint8_t is_dxf,
|
476
|
+
uint8_t is_rich_string)
|
354
477
|
{
|
355
478
|
if (is_rich_string)
|
356
479
|
lxw_xml_start_tag(self->file, "rPr", NULL);
|
357
480
|
else
|
358
481
|
lxw_xml_start_tag(self->file, "font", NULL);
|
359
482
|
|
483
|
+
if (format->font_condense)
|
484
|
+
_write_font_condense(self);
|
485
|
+
|
486
|
+
if (format->font_extend)
|
487
|
+
_write_font_extend(self);
|
488
|
+
|
360
489
|
if (format->bold)
|
361
490
|
lxw_xml_empty_tag(self->file, "b", NULL);
|
362
491
|
|
@@ -376,30 +505,41 @@ _write_font(lxw_styles *self, lxw_format *format, uint8_t is_rich_string)
|
|
376
505
|
_write_font_underline(self, format->underline);
|
377
506
|
|
378
507
|
if (format->font_script == LXW_FONT_SUPERSCRIPT)
|
379
|
-
|
508
|
+
_write_font_vert_align(self, "superscript");
|
380
509
|
|
381
510
|
if (format->font_script == LXW_FONT_SUBSCRIPT)
|
382
|
-
|
511
|
+
_write_font_vert_align(self, "subscript");
|
383
512
|
|
384
|
-
if (format->font_size > 0.0)
|
513
|
+
if (!is_dxf && format->font_size > 0.0)
|
385
514
|
_write_font_size(self, format->font_size);
|
386
515
|
|
387
516
|
if (format->theme)
|
388
517
|
_write_font_color_theme(self, format->theme);
|
518
|
+
else if (format->color_indexed)
|
519
|
+
_write_font_color_indexed(self, format->color_indexed);
|
389
520
|
else if (format->font_color != LXW_COLOR_UNSET)
|
390
521
|
_write_font_color_rgb(self, format->font_color);
|
391
|
-
else
|
522
|
+
else if (!is_dxf)
|
392
523
|
_write_font_color_theme(self, LXW_DEFAULT_FONT_THEME);
|
393
524
|
|
394
|
-
|
395
|
-
|
525
|
+
if (!is_dxf) {
|
526
|
+
_write_font_name(self, format->font_name, is_rich_string);
|
527
|
+
_write_font_family(self, format->font_family);
|
396
528
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
529
|
+
/* Only write the scheme element for the default font type if it
|
530
|
+
* is a hyperlink. */
|
531
|
+
if ((!*format->font_name
|
532
|
+
|| strcmp(LXW_DEFAULT_FONT_NAME, format->font_name) == 0)
|
533
|
+
&& !format->hyperlink) {
|
534
|
+
_write_font_scheme(self, format->font_scheme);
|
535
|
+
}
|
536
|
+
}
|
537
|
+
|
538
|
+
if (format->hyperlink) {
|
539
|
+
self->has_hyperlink = LXW_TRUE;
|
540
|
+
|
541
|
+
if (self->hyperlink_font_id == 0)
|
542
|
+
self->hyperlink_font_id = format->font_index;
|
403
543
|
}
|
404
544
|
|
405
545
|
if (is_rich_string)
|
@@ -408,6 +548,22 @@ _write_font(lxw_styles *self, lxw_format *format, uint8_t is_rich_string)
|
|
408
548
|
lxw_xml_end_tag(self->file, "font");
|
409
549
|
}
|
410
550
|
|
551
|
+
/*
|
552
|
+
* Write the <font> element for comments.
|
553
|
+
*/
|
554
|
+
STATIC void
|
555
|
+
_write_comment_font(lxw_styles *self)
|
556
|
+
{
|
557
|
+
lxw_xml_start_tag(self->file, "font", NULL);
|
558
|
+
|
559
|
+
_write_font_size(self, 8);
|
560
|
+
_write_font_color_indexed(self, 81);
|
561
|
+
_write_font_name(self, "Tahoma", LXW_FALSE);
|
562
|
+
_write_font_family(self, 2);
|
563
|
+
|
564
|
+
lxw_xml_end_tag(self->file, "font");
|
565
|
+
}
|
566
|
+
|
411
567
|
/*
|
412
568
|
* Write the <fonts> element.
|
413
569
|
*/
|
@@ -417,17 +573,26 @@ _write_fonts(lxw_styles *self)
|
|
417
573
|
struct xml_attribute_list attributes;
|
418
574
|
struct xml_attribute *attribute;
|
419
575
|
lxw_format *format;
|
576
|
+
uint32_t count;
|
420
577
|
|
421
578
|
LXW_INIT_ATTRIBUTES();
|
422
|
-
|
579
|
+
|
580
|
+
count = self->font_count;
|
581
|
+
if (self->has_comments)
|
582
|
+
count++;
|
583
|
+
|
584
|
+
LXW_PUSH_ATTRIBUTES_INT("count", count);
|
423
585
|
|
424
586
|
lxw_xml_start_tag(self->file, "fonts", &attributes);
|
425
587
|
|
426
588
|
STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
|
427
589
|
if (format->has_font)
|
428
|
-
_write_font(self, format, LXW_FALSE);
|
590
|
+
_write_font(self, format, LXW_FALSE, LXW_FALSE);
|
429
591
|
}
|
430
592
|
|
593
|
+
if (self->has_comments)
|
594
|
+
_write_comment_font(self);
|
595
|
+
|
431
596
|
lxw_xml_end_tag(self->file, "fonts");
|
432
597
|
|
433
598
|
LXW_FREE_ATTRIBUTES();
|
@@ -476,7 +641,7 @@ _write_fg_color(lxw_styles *self, lxw_color_t color)
|
|
476
641
|
* Write the <bgColor> element.
|
477
642
|
*/
|
478
643
|
STATIC void
|
479
|
-
_write_bg_color(lxw_styles *self, lxw_color_t color)
|
644
|
+
_write_bg_color(lxw_styles *self, lxw_color_t color, uint8_t pattern)
|
480
645
|
{
|
481
646
|
struct xml_attribute_list attributes;
|
482
647
|
struct xml_attribute *attribute;
|
@@ -485,15 +650,17 @@ _write_bg_color(lxw_styles *self, lxw_color_t color)
|
|
485
650
|
LXW_INIT_ATTRIBUTES();
|
486
651
|
|
487
652
|
if (color == LXW_COLOR_UNSET) {
|
488
|
-
|
653
|
+
if (pattern <= LXW_PATTERN_SOLID) {
|
654
|
+
LXW_PUSH_ATTRIBUTES_STR("indexed", "64");
|
655
|
+
lxw_xml_empty_tag(self->file, "bgColor", &attributes);
|
656
|
+
}
|
489
657
|
}
|
490
658
|
else {
|
491
659
|
lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
|
492
660
|
LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
|
661
|
+
lxw_xml_empty_tag(self->file, "bgColor", &attributes);
|
493
662
|
}
|
494
663
|
|
495
|
-
lxw_xml_empty_tag(self->file, "bgColor", &attributes);
|
496
|
-
|
497
664
|
LXW_FREE_ATTRIBUTES();
|
498
665
|
}
|
499
666
|
|
@@ -501,7 +668,7 @@ _write_bg_color(lxw_styles *self, lxw_color_t color)
|
|
501
668
|
* Write the <fill> element.
|
502
669
|
*/
|
503
670
|
STATIC void
|
504
|
-
_write_fill(lxw_styles *self, lxw_format *format)
|
671
|
+
_write_fill(lxw_styles *self, lxw_format *format, uint8_t is_dxf)
|
505
672
|
{
|
506
673
|
struct xml_attribute_list attributes;
|
507
674
|
struct xml_attribute *attribute;
|
@@ -532,11 +699,24 @@ _write_fill(lxw_styles *self, lxw_format *format)
|
|
532
699
|
"gray0625",
|
533
700
|
};
|
534
701
|
|
702
|
+
if (is_dxf) {
|
703
|
+
bg_color = format->dxf_bg_color;
|
704
|
+
fg_color = format->dxf_fg_color;
|
705
|
+
}
|
706
|
+
|
535
707
|
LXW_INIT_ATTRIBUTES();
|
536
708
|
|
709
|
+
/* Special handling for pattern only case. */
|
710
|
+
if (!bg_color && !fg_color && pattern) {
|
711
|
+
_write_default_fill(self, patterns[pattern]);
|
712
|
+
LXW_FREE_ATTRIBUTES();
|
713
|
+
return;
|
714
|
+
}
|
715
|
+
|
537
716
|
lxw_xml_start_tag(self->file, "fill", NULL);
|
538
717
|
|
539
|
-
|
718
|
+
/* None/Solid patterns are handled differently for dxf formats. */
|
719
|
+
if (pattern && !(is_dxf && pattern <= LXW_PATTERN_SOLID))
|
540
720
|
LXW_PUSH_ATTRIBUTES_STR("patternType", patterns[pattern]);
|
541
721
|
|
542
722
|
lxw_xml_start_tag(self->file, "patternFill", &attributes);
|
@@ -544,7 +724,7 @@ _write_fill(lxw_styles *self, lxw_format *format)
|
|
544
724
|
if (fg_color != LXW_COLOR_UNSET)
|
545
725
|
_write_fg_color(self, fg_color);
|
546
726
|
|
547
|
-
_write_bg_color(self, bg_color);
|
727
|
+
_write_bg_color(self, bg_color, pattern);
|
548
728
|
|
549
729
|
lxw_xml_end_tag(self->file, "patternFill");
|
550
730
|
lxw_xml_end_tag(self->file, "fill");
|
@@ -573,7 +753,7 @@ _write_fills(lxw_styles *self)
|
|
573
753
|
|
574
754
|
STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
|
575
755
|
if (format->has_fill)
|
576
|
-
_write_fill(self, format);
|
756
|
+
_write_fill(self, format, LXW_FALSE);
|
577
757
|
}
|
578
758
|
|
579
759
|
lxw_xml_end_tag(self->file, "fills");
|
@@ -654,7 +834,7 @@ _write_sub_border(lxw_styles *self, const char *type, uint8_t style,
|
|
654
834
|
* Write the <border> element.
|
655
835
|
*/
|
656
836
|
STATIC void
|
657
|
-
_write_border(lxw_styles *self, lxw_format *format)
|
837
|
+
_write_border(lxw_styles *self, lxw_format *format, uint8_t is_dxf)
|
658
838
|
{
|
659
839
|
struct xml_attribute_list attributes;
|
660
840
|
struct xml_attribute *attribute;
|
@@ -675,7 +855,7 @@ _write_border(lxw_styles *self, lxw_format *format)
|
|
675
855
|
|
676
856
|
/* Ensure that a default diag border is set if the diag type is set. */
|
677
857
|
if (format->diag_type && !format->diag_border) {
|
678
|
-
format->diag_border =
|
858
|
+
format->diag_border = LXW_BORDER_THIN;
|
679
859
|
}
|
680
860
|
|
681
861
|
/* Write the start border tag. */
|
@@ -686,8 +866,16 @@ _write_border(lxw_styles *self, lxw_format *format)
|
|
686
866
|
_write_sub_border(self, "right", format->right, format->right_color);
|
687
867
|
_write_sub_border(self, "top", format->top, format->top_color);
|
688
868
|
_write_sub_border(self, "bottom", format->bottom, format->bottom_color);
|
689
|
-
|
690
|
-
|
869
|
+
|
870
|
+
if (is_dxf) {
|
871
|
+
_write_sub_border(self, "vertical", 0, LXW_COLOR_UNSET);
|
872
|
+
_write_sub_border(self, "horizontal", 0, LXW_COLOR_UNSET);
|
873
|
+
}
|
874
|
+
|
875
|
+
/* Conditional DXF formats don't allow diagonal borders. */
|
876
|
+
if (!is_dxf)
|
877
|
+
_write_sub_border(self, "diagonal",
|
878
|
+
format->diag_border, format->diag_color);
|
691
879
|
|
692
880
|
lxw_xml_end_tag(self->file, "border");
|
693
881
|
|
@@ -711,7 +899,7 @@ _write_borders(lxw_styles *self)
|
|
711
899
|
|
712
900
|
STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
|
713
901
|
if (format->has_border)
|
714
|
-
_write_border(self, format);
|
902
|
+
_write_border(self, format, LXW_FALSE);
|
715
903
|
}
|
716
904
|
|
717
905
|
lxw_xml_end_tag(self->file, "borders");
|
@@ -719,22 +907,70 @@ _write_borders(lxw_styles *self)
|
|
719
907
|
LXW_FREE_ATTRIBUTES();
|
720
908
|
}
|
721
909
|
|
910
|
+
/*
|
911
|
+
* Write the <alignment> element for hyperlinks.
|
912
|
+
*/
|
913
|
+
STATIC void
|
914
|
+
_write_hyperlink_alignment(lxw_styles *self)
|
915
|
+
{
|
916
|
+
struct xml_attribute_list attributes;
|
917
|
+
struct xml_attribute *attribute;
|
918
|
+
|
919
|
+
LXW_INIT_ATTRIBUTES();
|
920
|
+
LXW_PUSH_ATTRIBUTES_STR("vertical", "top");
|
921
|
+
|
922
|
+
lxw_xml_empty_tag(self->file, "alignment", &attributes);
|
923
|
+
|
924
|
+
LXW_FREE_ATTRIBUTES();
|
925
|
+
}
|
926
|
+
|
927
|
+
/*
|
928
|
+
* Write the <protection> element for hyperlinks.
|
929
|
+
*/
|
930
|
+
STATIC void
|
931
|
+
_write_hyperlink_protection(lxw_styles *self)
|
932
|
+
{
|
933
|
+
struct xml_attribute_list attributes;
|
934
|
+
struct xml_attribute *attribute;
|
935
|
+
|
936
|
+
LXW_INIT_ATTRIBUTES();
|
937
|
+
LXW_PUSH_ATTRIBUTES_STR("locked", "0");
|
938
|
+
|
939
|
+
lxw_xml_empty_tag(self->file, "protection", &attributes);
|
940
|
+
|
941
|
+
LXW_FREE_ATTRIBUTES();
|
942
|
+
}
|
943
|
+
|
722
944
|
/*
|
723
945
|
* Write the <xf> element for styles.
|
724
946
|
*/
|
725
947
|
STATIC void
|
726
|
-
_write_style_xf(lxw_styles *self)
|
948
|
+
_write_style_xf(lxw_styles *self, uint8_t has_hyperlink, uint16_t font_id)
|
727
949
|
{
|
728
950
|
struct xml_attribute_list attributes;
|
729
951
|
struct xml_attribute *attribute;
|
730
952
|
|
731
953
|
LXW_INIT_ATTRIBUTES();
|
732
954
|
LXW_PUSH_ATTRIBUTES_STR("numFmtId", "0");
|
733
|
-
|
955
|
+
LXW_PUSH_ATTRIBUTES_INT("fontId", font_id);
|
734
956
|
LXW_PUSH_ATTRIBUTES_STR("fillId", "0");
|
735
957
|
LXW_PUSH_ATTRIBUTES_STR("borderId", "0");
|
736
958
|
|
737
|
-
|
959
|
+
if (has_hyperlink) {
|
960
|
+
LXW_PUSH_ATTRIBUTES_STR("applyNumberFormat", "0");
|
961
|
+
LXW_PUSH_ATTRIBUTES_STR("applyFill", "0");
|
962
|
+
LXW_PUSH_ATTRIBUTES_STR("applyBorder", "0");
|
963
|
+
LXW_PUSH_ATTRIBUTES_STR("applyAlignment", "0");
|
964
|
+
LXW_PUSH_ATTRIBUTES_STR("applyProtection", "0");
|
965
|
+
|
966
|
+
lxw_xml_start_tag(self->file, "xf", &attributes);
|
967
|
+
_write_hyperlink_alignment(self);
|
968
|
+
_write_hyperlink_protection(self);
|
969
|
+
lxw_xml_end_tag(self->file, "xf");
|
970
|
+
}
|
971
|
+
else {
|
972
|
+
lxw_xml_empty_tag(self->file, "xf", &attributes);
|
973
|
+
}
|
738
974
|
|
739
975
|
LXW_FREE_ATTRIBUTES();
|
740
976
|
}
|
@@ -749,10 +985,18 @@ _write_cell_style_xfs(lxw_styles *self)
|
|
749
985
|
struct xml_attribute *attribute;
|
750
986
|
|
751
987
|
LXW_INIT_ATTRIBUTES();
|
752
|
-
|
988
|
+
|
989
|
+
if (self->has_hyperlink)
|
990
|
+
LXW_PUSH_ATTRIBUTES_STR("count", "2");
|
991
|
+
else
|
992
|
+
LXW_PUSH_ATTRIBUTES_STR("count", "1");
|
753
993
|
|
754
994
|
lxw_xml_start_tag(self->file, "cellStyleXfs", &attributes);
|
755
|
-
_write_style_xf(self);
|
995
|
+
_write_style_xf(self, LXW_FALSE, 0);
|
996
|
+
|
997
|
+
if (self->has_hyperlink)
|
998
|
+
_write_style_xf(self, self->has_hyperlink, self->hyperlink_font_id);
|
999
|
+
|
756
1000
|
lxw_xml_end_tag(self->file, "cellStyleXfs");
|
757
1001
|
|
758
1002
|
LXW_FREE_ATTRIBUTES();
|
@@ -936,13 +1180,16 @@ _write_xf(lxw_styles *self, lxw_format *format)
|
|
936
1180
|
LXW_PUSH_ATTRIBUTES_INT("fontId", format->font_index);
|
937
1181
|
LXW_PUSH_ATTRIBUTES_INT("fillId", format->fill_index);
|
938
1182
|
LXW_PUSH_ATTRIBUTES_INT("borderId", format->border_index);
|
939
|
-
|
1183
|
+
LXW_PUSH_ATTRIBUTES_INT("xfId", format->xf_id);
|
1184
|
+
|
1185
|
+
if (format->quote_prefix)
|
1186
|
+
LXW_PUSH_ATTRIBUTES_STR("quotePrefix", "1");
|
940
1187
|
|
941
1188
|
if (format->num_format_index > 0)
|
942
1189
|
LXW_PUSH_ATTRIBUTES_STR("applyNumberFormat", "1");
|
943
1190
|
|
944
1191
|
/* Add applyFont attribute if XF format uses a font element. */
|
945
|
-
if (format->font_index > 0)
|
1192
|
+
if (format->font_index > 0 && !format->hyperlink)
|
946
1193
|
LXW_PUSH_ATTRIBUTES_STR("applyFont", "1");
|
947
1194
|
|
948
1195
|
/* Add applyFill attribute if XF format uses a fill element. */
|
@@ -954,10 +1201,10 @@ _write_xf(lxw_styles *self, lxw_format *format)
|
|
954
1201
|
LXW_PUSH_ATTRIBUTES_STR("applyBorder", "1");
|
955
1202
|
|
956
1203
|
/* We can also have applyAlignment without a sub-element. */
|
957
|
-
if (apply_alignment)
|
1204
|
+
if (apply_alignment || format->hyperlink)
|
958
1205
|
LXW_PUSH_ATTRIBUTES_STR("applyAlignment", "1");
|
959
1206
|
|
960
|
-
if (has_protection)
|
1207
|
+
if (has_protection || format->hyperlink)
|
961
1208
|
LXW_PUSH_ATTRIBUTES_STR("applyProtection", "1");
|
962
1209
|
|
963
1210
|
/* Write XF with sub-elements if required. */
|
@@ -988,14 +1235,27 @@ _write_cell_xfs(lxw_styles *self)
|
|
988
1235
|
struct xml_attribute_list attributes;
|
989
1236
|
struct xml_attribute *attribute;
|
990
1237
|
lxw_format *format;
|
1238
|
+
uint32_t count = self->xf_count;
|
1239
|
+
uint32_t i = 0;
|
1240
|
+
|
1241
|
+
/* If the last format is "font_only" it is for the comment font and
|
1242
|
+
* shouldn't be counted. This is a workaround to get the last object
|
1243
|
+
* in the list since STAILQ_LAST() requires __containerof and isn't
|
1244
|
+
* ANSI compatible. */
|
1245
|
+
STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
|
1246
|
+
i++;
|
1247
|
+
if (i == self->xf_count && format->font_only)
|
1248
|
+
count--;
|
1249
|
+
}
|
991
1250
|
|
992
1251
|
LXW_INIT_ATTRIBUTES();
|
993
|
-
LXW_PUSH_ATTRIBUTES_INT("count",
|
1252
|
+
LXW_PUSH_ATTRIBUTES_INT("count", count);
|
994
1253
|
|
995
1254
|
lxw_xml_start_tag(self->file, "cellXfs", &attributes);
|
996
1255
|
|
997
1256
|
STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
|
998
|
-
|
1257
|
+
if (!format->font_only)
|
1258
|
+
_write_xf(self, format);
|
999
1259
|
}
|
1000
1260
|
|
1001
1261
|
lxw_xml_end_tag(self->file, "cellXfs");
|
@@ -1007,15 +1267,16 @@ _write_cell_xfs(lxw_styles *self)
|
|
1007
1267
|
* Write the <cellStyle> element.
|
1008
1268
|
*/
|
1009
1269
|
STATIC void
|
1010
|
-
_write_cell_style(lxw_styles *self
|
1270
|
+
_write_cell_style(lxw_styles *self, char *name, uint8_t xf_id,
|
1271
|
+
uint8_t builtin_id)
|
1011
1272
|
{
|
1012
1273
|
struct xml_attribute_list attributes;
|
1013
1274
|
struct xml_attribute *attribute;
|
1014
1275
|
|
1015
1276
|
LXW_INIT_ATTRIBUTES();
|
1016
|
-
LXW_PUSH_ATTRIBUTES_STR("name",
|
1017
|
-
|
1018
|
-
|
1277
|
+
LXW_PUSH_ATTRIBUTES_STR("name", name);
|
1278
|
+
LXW_PUSH_ATTRIBUTES_INT("xfId", xf_id);
|
1279
|
+
LXW_PUSH_ATTRIBUTES_INT("builtinId", builtin_id);
|
1019
1280
|
|
1020
1281
|
lxw_xml_empty_tag(self->file, "cellStyle", &attributes);
|
1021
1282
|
|
@@ -1031,10 +1292,19 @@ _write_cell_styles(lxw_styles *self)
|
|
1031
1292
|
struct xml_attribute_list attributes;
|
1032
1293
|
struct xml_attribute *attribute;
|
1033
1294
|
LXW_INIT_ATTRIBUTES();
|
1034
|
-
|
1295
|
+
|
1296
|
+
if (self->has_hyperlink)
|
1297
|
+
LXW_PUSH_ATTRIBUTES_STR("count", "2");
|
1298
|
+
else
|
1299
|
+
LXW_PUSH_ATTRIBUTES_STR("count", "1");
|
1035
1300
|
|
1036
1301
|
lxw_xml_start_tag(self->file, "cellStyles", &attributes);
|
1037
|
-
|
1302
|
+
|
1303
|
+
if (self->has_hyperlink)
|
1304
|
+
_write_cell_style(self, "Hyperlink", 1, 8);
|
1305
|
+
|
1306
|
+
_write_cell_style(self, "Normal", 0, 0);
|
1307
|
+
|
1038
1308
|
lxw_xml_end_tag(self->file, "cellStyles");
|
1039
1309
|
|
1040
1310
|
LXW_FREE_ATTRIBUTES();
|
@@ -1042,18 +1312,46 @@ _write_cell_styles(lxw_styles *self)
|
|
1042
1312
|
|
1043
1313
|
/*
|
1044
1314
|
* Write the <dxfs> element.
|
1315
|
+
*
|
1045
1316
|
*/
|
1046
1317
|
STATIC void
|
1047
1318
|
_write_dxfs(lxw_styles *self)
|
1048
1319
|
{
|
1049
1320
|
struct xml_attribute_list attributes;
|
1050
1321
|
struct xml_attribute *attribute;
|
1322
|
+
lxw_format *format;
|
1323
|
+
uint32_t count = self->dxf_count;
|
1051
1324
|
|
1052
1325
|
LXW_INIT_ATTRIBUTES();
|
1053
|
-
|
1326
|
+
LXW_PUSH_ATTRIBUTES_INT("count", count);
|
1327
|
+
|
1328
|
+
if (count) {
|
1329
|
+
lxw_xml_start_tag(self->file, "dxfs", &attributes);
|
1330
|
+
|
1331
|
+
STAILQ_FOREACH(format, self->dxf_formats, list_pointers) {
|
1332
|
+
lxw_xml_start_tag(self->file, "dxf", NULL);
|
1333
|
+
|
1334
|
+
if (format->has_dxf_font)
|
1335
|
+
_write_font(self, format, LXW_TRUE, LXW_FALSE);
|
1054
1336
|
|
1055
|
-
|
1337
|
+
if (format->num_format_index)
|
1338
|
+
_write_num_fmt(self, format->num_format_index,
|
1339
|
+
format->num_format);
|
1056
1340
|
|
1341
|
+
if (format->has_dxf_fill)
|
1342
|
+
_write_fill(self, format, LXW_TRUE);
|
1343
|
+
|
1344
|
+
if (format->has_dxf_border)
|
1345
|
+
_write_border(self, format, LXW_TRUE);
|
1346
|
+
|
1347
|
+
lxw_xml_end_tag(self->file, "dxf");
|
1348
|
+
}
|
1349
|
+
|
1350
|
+
lxw_xml_end_tag(self->file, "dxfs");
|
1351
|
+
}
|
1352
|
+
else {
|
1353
|
+
lxw_xml_empty_tag(self->file, "dxfs", &attributes);
|
1354
|
+
}
|
1057
1355
|
LXW_FREE_ATTRIBUTES();
|
1058
1356
|
}
|
1059
1357
|
|
@@ -1121,9 +1419,6 @@ lxw_styles_assemble_xml_file(lxw_styles *self)
|
|
1121
1419
|
/* Write the tableStyles element. */
|
1122
1420
|
_write_table_styles(self);
|
1123
1421
|
|
1124
|
-
/* Write the colors element. */
|
1125
|
-
/* _write_colors(self); */
|
1126
|
-
|
1127
1422
|
/* Close the style sheet tag. */
|
1128
1423
|
lxw_xml_end_tag(self->file, "styleSheet");
|
1129
1424
|
}
|