xlsxwriter 0.2.1.pre → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +4 -3
- data/ext/xlsxwriter/chart.c +88 -80
- data/ext/xlsxwriter/chart.h +2 -2
- data/ext/xlsxwriter/chartsheet.c +307 -0
- data/ext/xlsxwriter/chartsheet.h +15 -0
- data/ext/xlsxwriter/common.h +104 -0
- data/ext/xlsxwriter/extconf.rb +8 -8
- data/ext/xlsxwriter/libxlsxwriter/License.txt +24 -2
- data/ext/xlsxwriter/libxlsxwriter/Makefile +46 -12
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +196 -30
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +3 -3
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +24 -5
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +5 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +6 -17
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +20 -6
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +3 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +11 -5
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/md5.h +43 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +42 -3
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +83 -18
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +1519 -109
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +4 -2
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +3 -2
- data/ext/xlsxwriter/libxlsxwriter/src/Makefile +25 -7
- data/ext/xlsxwriter/libxlsxwriter/src/app.c +1 -1
- data/ext/xlsxwriter/libxlsxwriter/src/chart.c +332 -48
- data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +20 -19
- data/ext/xlsxwriter/libxlsxwriter/src/comment.c +443 -0
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +20 -1
- data/ext/xlsxwriter/libxlsxwriter/src/core.c +2 -2
- data/ext/xlsxwriter/libxlsxwriter/src/custom.c +1 -1
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +58 -20
- data/ext/xlsxwriter/libxlsxwriter/src/format.c +98 -25
- data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +1 -1
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +269 -12
- data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +1 -1
- data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +2 -4
- data/ext/xlsxwriter/libxlsxwriter/src/styles.c +334 -48
- data/ext/xlsxwriter/libxlsxwriter/src/theme.c +1 -1
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +71 -8
- data/ext/xlsxwriter/libxlsxwriter/src/vml.c +1032 -0
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +343 -27
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +3759 -478
- data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +81 -2
- data/ext/xlsxwriter/libxlsxwriter/third_party/md5/Makefile +42 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.c +291 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/md5/md5.h +43 -0
- data/ext/xlsxwriter/shared_strings.c +65 -0
- data/ext/xlsxwriter/shared_strings.h +15 -0
- data/ext/xlsxwriter/workbook.c +96 -20
- data/ext/xlsxwriter/worksheet.c +125 -235
- data/ext/xlsxwriter/worksheet.h +2 -1
- data/ext/xlsxwriter/xlsxwriter.c +4 -0
- data/lib/xlsxwriter/rich_string.rb +0 -2
- data/lib/xlsxwriter/version.rb +1 -1
- data/lib/xlsxwriter/worksheet.rb +2 -2
- data/test/{run-test.rb → run_test.rb} +3 -3
- data/test/support/chart_test.rb +3 -3
- data/test/support/with_xlsx_file.rb +4 -2
- data/test/support/xlsx_comparable.rb +40 -26
- data/test/test_array_formula.rb +42 -0
- data/test/test_autofilter.rb +72 -0
- data/test/{test-chart-area.rb → test_chart_area.rb} +2 -2
- data/test/{test-chart-axis.rb → test_chart_axis.rb} +16 -16
- data/test/test_chart_bar.rb +382 -0
- data/test/test_chart_blank.rb +27 -0
- data/test/{test-chart-column.rb → test_chart_column.rb} +2 -2
- data/test/{test-chart-doughnut.rb → test_chart_doughnut.rb} +2 -2
- data/test/{test-chart-legend.rb → test_chart_legend.rb} +2 -2
- data/test/{test-chart-pie.rb → test_chart_pie.rb} +2 -2
- data/test/{test-chart-scatter.rb → test_chart_scatter.rb} +3 -4
- data/test/{test-chart-size.rb → test_chart_size.rb} +2 -2
- data/test/{test-chart-title.rb → test_chart_title.rb} +3 -3
- data/test/test_chartsheet.rb +201 -0
- data/test/{test-data.rb → test_data.rb} +1 -1
- data/test/{test-data-validation.rb → test_data_validation.rb} +23 -24
- data/test/{test-default-row.rb → test_default_row.rb} +1 -1
- data/test/{test-defined-name.rb → test_defined_name.rb} +12 -12
- data/test/{test-escapes.rb → test_escapes.rb} +5 -2
- data/test/{test-fit-to-pages.rb → test_fit_to_pages.rb} +6 -6
- data/test/{test-formatting.rb → test_formatting.rb} +10 -10
- data/test/{test-gridlines.rb → test_gridlines.rb} +3 -3
- data/test/{test-hyperlink.rb → test_hyperlink.rb} +22 -11
- data/test/{test-image.rb → test_image.rb} +6 -4
- data/test/{test-macro.rb → test_macro.rb} +1 -1
- data/test/{test-merge-range.rb → test_merge_range.rb} +1 -1
- data/test/{test-misc.rb → test_misc.rb} +2 -2
- data/test/{test-optimize.rb → test_optimize.rb} +2 -4
- data/test/{test-outline.rb → test_outline.rb} +14 -14
- data/test/{test-page-breaks.rb → test_page_breaks.rb} +2 -2
- data/test/{test-page-setup.rb → test_page_setup.rb} +2 -2
- data/test/{test-panes.rb → test_panes.rb} +1 -1
- data/test/{test-print-area.rb → test_print_area.rb} +3 -3
- data/test/{test-print-options.rb → test_print_options.rb} +7 -7
- data/test/{test-print-scale.rb → test_print_scale.rb} +2 -2
- data/test/{test-properties.rb → test_properties.rb} +2 -2
- data/test/{test-protect.rb → test_protect.rb} +3 -3
- data/test/{test-repeat.rb → test_repeat.rb} +3 -3
- data/test/{test-rich-string.rb → test_rich_string.rb} +5 -9
- data/test/{test-row-col-format.rb → test_row_col_format.rb} +1 -1
- data/test/{test-ruby-worksheet.rb → test_ruby_worksheet.rb} +2 -2
- data/test/{test-set-selection.rb → test_set_selection.rb} +2 -2
- data/test/{test-set-start-page.rb → test_set_start_page.rb} +2 -2
- data/test/{test-simple.rb → test_simple.rb} +10 -10
- data/test/{test-types.rb → test_types.rb} +1 -1
- data/test/{xlsx-func-testcase.rb → xlsx_func_testcase.rb} +1 -0
- metadata +135 -104
- data/test/test-array-formula.rb +0 -35
- data/test/test-autofilter.rb +0 -72
- data/test/test-chart-bar.rb +0 -74
- /data/test/{test-errors.rb → test_errors.rb} +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -27,9 +27,11 @@ lxw_format_new(void)
|
|
27
27
|
GOTO_LABEL_ON_MEM_ERROR(format, mem_error);
|
28
28
|
|
29
29
|
format->xf_format_indices = NULL;
|
30
|
+
format->dxf_format_indices = NULL;
|
30
31
|
|
31
32
|
format->xf_index = LXW_PROPERTY_UNSET;
|
32
33
|
format->dxf_index = LXW_PROPERTY_UNSET;
|
34
|
+
format->xf_id = 0;
|
33
35
|
|
34
36
|
format->font_name[0] = '\0';
|
35
37
|
format->font_scheme[0] = '\0';
|
@@ -42,7 +44,7 @@ lxw_format_new(void)
|
|
42
44
|
format->bold = LXW_FALSE;
|
43
45
|
format->italic = LXW_FALSE;
|
44
46
|
format->font_color = LXW_COLOR_UNSET;
|
45
|
-
format->underline =
|
47
|
+
format->underline = LXW_UNDERLINE_NONE;
|
46
48
|
format->font_strikeout = LXW_FALSE;
|
47
49
|
format->font_outline = LXW_FALSE;
|
48
50
|
format->font_shadow = LXW_FALSE;
|
@@ -51,7 +53,7 @@ lxw_format_new(void)
|
|
51
53
|
format->font_charset = LXW_FALSE;
|
52
54
|
format->font_condense = LXW_FALSE;
|
53
55
|
format->font_extend = LXW_FALSE;
|
54
|
-
format->theme =
|
56
|
+
format->theme = 0;
|
55
57
|
format->hyperlink = LXW_FALSE;
|
56
58
|
|
57
59
|
format->hidden = LXW_FALSE;
|
@@ -116,18 +118,6 @@ lxw_format_free(lxw_format *format)
|
|
116
118
|
format = NULL;
|
117
119
|
}
|
118
120
|
|
119
|
-
/*
|
120
|
-
* Check a user input color.
|
121
|
-
*/
|
122
|
-
lxw_color_t
|
123
|
-
lxw_format_check_color(lxw_color_t color)
|
124
|
-
{
|
125
|
-
if (color == LXW_COLOR_UNSET)
|
126
|
-
return color;
|
127
|
-
else
|
128
|
-
return color & LXW_COLOR_MASK;
|
129
|
-
}
|
130
|
-
|
131
121
|
/*
|
132
122
|
* Check a user input border.
|
133
123
|
*/
|
@@ -160,7 +150,9 @@ _get_format_key(lxw_format *self)
|
|
160
150
|
|
161
151
|
/* Set pointer members to NULL since they aren't part of the comparison. */
|
162
152
|
key->xf_format_indices = NULL;
|
153
|
+
key->dxf_format_indices = NULL;
|
163
154
|
key->num_xf_formats = NULL;
|
155
|
+
key->num_dxf_formats = NULL;
|
164
156
|
key->list_pointers.stqe_next = NULL;
|
165
157
|
|
166
158
|
return key;
|
@@ -182,8 +174,9 @@ lxw_format_get_font_key(lxw_format *self)
|
|
182
174
|
key->font_size = self->font_size;
|
183
175
|
key->bold = self->bold;
|
184
176
|
key->italic = self->italic;
|
185
|
-
key->font_color = self->font_color;
|
186
177
|
key->underline = self->underline;
|
178
|
+
key->theme = self->theme;
|
179
|
+
key->font_color = self->font_color;
|
187
180
|
key->font_strikeout = self->font_strikeout;
|
188
181
|
key->font_outline = self->font_outline;
|
189
182
|
key->font_shadow = self->font_shadow;
|
@@ -296,6 +289,57 @@ lxw_format_get_xf_index(lxw_format *self)
|
|
296
289
|
}
|
297
290
|
}
|
298
291
|
|
292
|
+
/*
|
293
|
+
* Returns the DXF index number used by Excel to identify a format.
|
294
|
+
*/
|
295
|
+
int32_t
|
296
|
+
lxw_format_get_dxf_index(lxw_format *self)
|
297
|
+
{
|
298
|
+
lxw_format *format_key;
|
299
|
+
lxw_format *existing_format;
|
300
|
+
lxw_hash_element *hash_element;
|
301
|
+
lxw_hash_table *formats_hash_table = self->dxf_format_indices;
|
302
|
+
int32_t index;
|
303
|
+
|
304
|
+
/* Note: The formats_hash_table/dxf_format_indices contains the unique and
|
305
|
+
* more importantly the *used* formats in the workbook.
|
306
|
+
*/
|
307
|
+
|
308
|
+
/* Format already has an index number so return it. */
|
309
|
+
if (self->dxf_index != LXW_PROPERTY_UNSET) {
|
310
|
+
return self->dxf_index;
|
311
|
+
}
|
312
|
+
|
313
|
+
/* Otherwise, the format doesn't have an index number so we assign one.
|
314
|
+
* First generate a unique key to identify the format in the hash table.
|
315
|
+
*/
|
316
|
+
format_key = _get_format_key(self);
|
317
|
+
|
318
|
+
/* Return the default format index if the key generation failed. */
|
319
|
+
if (!format_key)
|
320
|
+
return 0;
|
321
|
+
|
322
|
+
/* Look up the format in the hash table. */
|
323
|
+
hash_element =
|
324
|
+
lxw_hash_key_exists(formats_hash_table, format_key,
|
325
|
+
sizeof(lxw_format));
|
326
|
+
|
327
|
+
if (hash_element) {
|
328
|
+
/* Format matches existing format with an index. */
|
329
|
+
free(format_key);
|
330
|
+
existing_format = hash_element->value;
|
331
|
+
return existing_format->dxf_index;
|
332
|
+
}
|
333
|
+
else {
|
334
|
+
/* New format requiring an index. */
|
335
|
+
index = formats_hash_table->unique_count;
|
336
|
+
self->dxf_index = index;
|
337
|
+
lxw_insert_hash_element(formats_hash_table, format_key, self,
|
338
|
+
sizeof(lxw_format));
|
339
|
+
return index;
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
299
343
|
/*
|
300
344
|
* Set the font_name property.
|
301
345
|
*/
|
@@ -322,7 +366,7 @@ format_set_font_size(lxw_format *self, double size)
|
|
322
366
|
void
|
323
367
|
format_set_font_color(lxw_format *self, lxw_color_t color)
|
324
368
|
{
|
325
|
-
self->font_color =
|
369
|
+
self->font_color = color;
|
326
370
|
}
|
327
371
|
|
328
372
|
/*
|
@@ -508,7 +552,7 @@ format_set_pattern(lxw_format *self, uint8_t value)
|
|
508
552
|
void
|
509
553
|
format_set_bg_color(lxw_format *self, lxw_color_t color)
|
510
554
|
{
|
511
|
-
self->bg_color =
|
555
|
+
self->bg_color = color;
|
512
556
|
}
|
513
557
|
|
514
558
|
/*
|
@@ -517,7 +561,7 @@ format_set_bg_color(lxw_format *self, lxw_color_t color)
|
|
517
561
|
void
|
518
562
|
format_set_fg_color(lxw_format *self, lxw_color_t color)
|
519
563
|
{
|
520
|
-
self->fg_color =
|
564
|
+
self->fg_color = color;
|
521
565
|
}
|
522
566
|
|
523
567
|
/*
|
@@ -539,7 +583,6 @@ format_set_border(lxw_format *self, uint8_t style)
|
|
539
583
|
void
|
540
584
|
format_set_border_color(lxw_format *self, lxw_color_t color)
|
541
585
|
{
|
542
|
-
color = lxw_format_check_color(color);
|
543
586
|
self->bottom_color = color;
|
544
587
|
self->top_color = color;
|
545
588
|
self->left_color = color;
|
@@ -561,7 +604,7 @@ format_set_bottom(lxw_format *self, uint8_t style)
|
|
561
604
|
void
|
562
605
|
format_set_bottom_color(lxw_format *self, lxw_color_t color)
|
563
606
|
{
|
564
|
-
self->bottom_color =
|
607
|
+
self->bottom_color = color;
|
565
608
|
}
|
566
609
|
|
567
610
|
/*
|
@@ -579,7 +622,7 @@ format_set_left(lxw_format *self, uint8_t style)
|
|
579
622
|
void
|
580
623
|
format_set_left_color(lxw_format *self, lxw_color_t color)
|
581
624
|
{
|
582
|
-
self->left_color =
|
625
|
+
self->left_color = color;
|
583
626
|
}
|
584
627
|
|
585
628
|
/*
|
@@ -597,7 +640,7 @@ format_set_right(lxw_format *self, uint8_t style)
|
|
597
640
|
void
|
598
641
|
format_set_right_color(lxw_format *self, lxw_color_t color)
|
599
642
|
{
|
600
|
-
self->right_color =
|
643
|
+
self->right_color = color;
|
601
644
|
}
|
602
645
|
|
603
646
|
/*
|
@@ -615,7 +658,7 @@ format_set_top(lxw_format *self, uint8_t style)
|
|
615
658
|
void
|
616
659
|
format_set_top_color(lxw_format *self, lxw_color_t color)
|
617
660
|
{
|
618
|
-
self->top_color =
|
661
|
+
self->top_color = color;
|
619
662
|
}
|
620
663
|
|
621
664
|
/*
|
@@ -634,7 +677,7 @@ format_set_diag_type(lxw_format *self, uint8_t type)
|
|
634
677
|
void
|
635
678
|
format_set_diag_color(lxw_format *self, lxw_color_t color)
|
636
679
|
{
|
637
|
-
self->diag_color =
|
680
|
+
self->diag_color = color;
|
638
681
|
}
|
639
682
|
|
640
683
|
/*
|
@@ -726,3 +769,33 @@ format_set_theme(lxw_format *self, uint8_t value)
|
|
726
769
|
{
|
727
770
|
self->theme = value;
|
728
771
|
}
|
772
|
+
|
773
|
+
/*
|
774
|
+
* Set the color_indexed property.
|
775
|
+
*/
|
776
|
+
void
|
777
|
+
format_set_color_indexed(lxw_format *self, uint8_t value)
|
778
|
+
{
|
779
|
+
self->color_indexed = value;
|
780
|
+
}
|
781
|
+
|
782
|
+
/*
|
783
|
+
* Set the font_only property.
|
784
|
+
*/
|
785
|
+
void
|
786
|
+
format_set_font_only(lxw_format *self)
|
787
|
+
{
|
788
|
+
self->font_only = LXW_TRUE;
|
789
|
+
}
|
790
|
+
|
791
|
+
/*
|
792
|
+
* Set the theme property.
|
793
|
+
*/
|
794
|
+
void
|
795
|
+
format_set_hyperlink(lxw_format *self)
|
796
|
+
{
|
797
|
+
self->hyperlink = LXW_TRUE;
|
798
|
+
self->xf_id = 1;
|
799
|
+
self->underline = LXW_UNDERLINE_SINGLE;
|
800
|
+
self->theme = 10;
|
801
|
+
}
|
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -18,6 +18,10 @@ STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
|
|
18
18
|
STATIC lxw_error _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
19
19
|
size_t buffer_size, const char *filename);
|
20
20
|
|
21
|
+
STATIC lxw_error _write_vml_drawing_rels_file(lxw_packager *self,
|
22
|
+
lxw_worksheet *worksheet,
|
23
|
+
uint32_t index);
|
24
|
+
|
21
25
|
/*
|
22
26
|
* Forward declarations.
|
23
27
|
*/
|
@@ -247,7 +251,7 @@ _write_image_files(lxw_packager *self)
|
|
247
251
|
lxw_workbook *workbook = self->workbook;
|
248
252
|
lxw_sheet *sheet;
|
249
253
|
lxw_worksheet *worksheet;
|
250
|
-
|
254
|
+
lxw_object_properties *object_props;
|
251
255
|
lxw_error err;
|
252
256
|
FILE *image_stream;
|
253
257
|
|
@@ -260,21 +264,25 @@ _write_image_files(lxw_packager *self)
|
|
260
264
|
else
|
261
265
|
worksheet = sheet->u.worksheet;
|
262
266
|
|
263
|
-
if (STAILQ_EMPTY(worksheet->
|
267
|
+
if (STAILQ_EMPTY(worksheet->image_props))
|
264
268
|
continue;
|
265
269
|
|
266
|
-
STAILQ_FOREACH(
|
270
|
+
STAILQ_FOREACH(object_props, worksheet->image_props, list_pointers) {
|
271
|
+
|
272
|
+
if (object_props->is_duplicate)
|
273
|
+
continue;
|
267
274
|
|
268
275
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
269
|
-
"xl/media/image%d.%s", index++,
|
276
|
+
"xl/media/image%d.%s", index++,
|
277
|
+
object_props->extension);
|
270
278
|
|
271
|
-
if (!
|
279
|
+
if (!object_props->is_image_buffer) {
|
272
280
|
/* Check that the image file exists and can be opened. */
|
273
|
-
image_stream =
|
281
|
+
image_stream = lxw_fopen(object_props->filename, "rb");
|
274
282
|
if (!image_stream) {
|
275
283
|
LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
|
276
284
|
"doesn't exist or can't be opened: %s.",
|
277
|
-
|
285
|
+
object_props->filename);
|
278
286
|
return LXW_ERROR_CREATING_TMPFILE;
|
279
287
|
}
|
280
288
|
|
@@ -283,8 +291,9 @@ _write_image_files(lxw_packager *self)
|
|
283
291
|
}
|
284
292
|
else {
|
285
293
|
err = _add_buffer_to_zip(self,
|
286
|
-
|
287
|
-
|
294
|
+
object_props->image_buffer,
|
295
|
+
object_props->image_buffer_size,
|
296
|
+
filename);
|
288
297
|
}
|
289
298
|
|
290
299
|
RETURN_ON_ERROR(err);
|
@@ -308,7 +317,7 @@ _add_vba_project(lxw_packager *self)
|
|
308
317
|
return LXW_NO_ERROR;
|
309
318
|
|
310
319
|
/* Check that the image file exists and can be opened. */
|
311
|
-
image_stream =
|
320
|
+
image_stream = lxw_fopen(workbook->vba_project, "rb");
|
312
321
|
if (!image_stream) {
|
313
322
|
LXW_WARN_FORMAT1("Error adding vbaProject.bin to xlsx file: "
|
314
323
|
"file doesn't exist or can't be opened: %s.",
|
@@ -440,6 +449,164 @@ _get_drawing_count(lxw_packager *self)
|
|
440
449
|
return drawing_count;
|
441
450
|
}
|
442
451
|
|
452
|
+
/*
|
453
|
+
* Write the comment/header VML files.
|
454
|
+
*/
|
455
|
+
STATIC lxw_error
|
456
|
+
_write_vml_files(lxw_packager *self)
|
457
|
+
{
|
458
|
+
lxw_workbook *workbook = self->workbook;
|
459
|
+
lxw_sheet *sheet;
|
460
|
+
lxw_worksheet *worksheet;
|
461
|
+
lxw_vml *vml;
|
462
|
+
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
463
|
+
uint32_t index = 1;
|
464
|
+
lxw_error err;
|
465
|
+
|
466
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
467
|
+
if (sheet->is_chartsheet)
|
468
|
+
continue;
|
469
|
+
else
|
470
|
+
worksheet = sheet->u.worksheet;
|
471
|
+
|
472
|
+
if (!worksheet->has_vml && !worksheet->has_header_vml)
|
473
|
+
continue;
|
474
|
+
|
475
|
+
if (worksheet->has_vml) {
|
476
|
+
|
477
|
+
vml = lxw_vml_new();
|
478
|
+
if (!vml)
|
479
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
480
|
+
|
481
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
482
|
+
"xl/drawings/vmlDrawing%d.vml", index++);
|
483
|
+
|
484
|
+
vml->file = lxw_tmpfile(self->tmpdir);
|
485
|
+
if (!vml->file) {
|
486
|
+
lxw_vml_free(vml);
|
487
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
488
|
+
}
|
489
|
+
|
490
|
+
vml->comment_objs = worksheet->comment_objs;
|
491
|
+
vml->vml_shape_id = worksheet->vml_shape_id;
|
492
|
+
vml->comment_display_default = worksheet->comment_display_default;
|
493
|
+
|
494
|
+
if (worksheet->vml_data_id_str) {
|
495
|
+
vml->vml_data_id_str = worksheet->vml_data_id_str;
|
496
|
+
}
|
497
|
+
else {
|
498
|
+
fclose(vml->file);
|
499
|
+
lxw_vml_free(vml);
|
500
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
501
|
+
}
|
502
|
+
|
503
|
+
lxw_vml_assemble_xml_file(vml);
|
504
|
+
|
505
|
+
err = _add_file_to_zip(self, vml->file, filename);
|
506
|
+
|
507
|
+
fclose(vml->file);
|
508
|
+
lxw_vml_free(vml);
|
509
|
+
|
510
|
+
RETURN_ON_ERROR(err);
|
511
|
+
}
|
512
|
+
|
513
|
+
if (worksheet->has_header_vml) {
|
514
|
+
|
515
|
+
err = _write_vml_drawing_rels_file(self, worksheet, index);
|
516
|
+
RETURN_ON_ERROR(err);
|
517
|
+
|
518
|
+
vml = lxw_vml_new();
|
519
|
+
if (!vml)
|
520
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
521
|
+
|
522
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
523
|
+
"xl/drawings/vmlDrawing%d.vml", index++);
|
524
|
+
|
525
|
+
vml->file = lxw_tmpfile(self->tmpdir);
|
526
|
+
if (!vml->file) {
|
527
|
+
lxw_vml_free(vml);
|
528
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
529
|
+
}
|
530
|
+
|
531
|
+
vml->image_objs = worksheet->header_image_objs;
|
532
|
+
vml->vml_shape_id = worksheet->vml_header_id * 1024;
|
533
|
+
|
534
|
+
if (worksheet->vml_header_id_str) {
|
535
|
+
vml->vml_data_id_str = worksheet->vml_header_id_str;
|
536
|
+
}
|
537
|
+
else {
|
538
|
+
fclose(vml->file);
|
539
|
+
lxw_vml_free(vml);
|
540
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
541
|
+
}
|
542
|
+
|
543
|
+
lxw_vml_assemble_xml_file(vml);
|
544
|
+
|
545
|
+
err = _add_file_to_zip(self, vml->file, filename);
|
546
|
+
|
547
|
+
fclose(vml->file);
|
548
|
+
lxw_vml_free(vml);
|
549
|
+
|
550
|
+
RETURN_ON_ERROR(err);
|
551
|
+
}
|
552
|
+
|
553
|
+
}
|
554
|
+
|
555
|
+
return LXW_NO_ERROR;
|
556
|
+
}
|
557
|
+
|
558
|
+
/*
|
559
|
+
* Write the comment files.
|
560
|
+
*/
|
561
|
+
STATIC lxw_error
|
562
|
+
_write_comment_files(lxw_packager *self)
|
563
|
+
{
|
564
|
+
lxw_workbook *workbook = self->workbook;
|
565
|
+
lxw_sheet *sheet;
|
566
|
+
lxw_worksheet *worksheet;
|
567
|
+
lxw_comment *comment;
|
568
|
+
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
569
|
+
uint32_t index = 1;
|
570
|
+
lxw_error err;
|
571
|
+
|
572
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
573
|
+
if (sheet->is_chartsheet)
|
574
|
+
continue;
|
575
|
+
else
|
576
|
+
worksheet = sheet->u.worksheet;
|
577
|
+
|
578
|
+
if (!worksheet->has_comments)
|
579
|
+
continue;
|
580
|
+
|
581
|
+
comment = lxw_comment_new();
|
582
|
+
if (!comment)
|
583
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
584
|
+
|
585
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
586
|
+
"xl/comments%d.xml", index++);
|
587
|
+
|
588
|
+
comment->file = lxw_tmpfile(self->tmpdir);
|
589
|
+
if (!comment->file) {
|
590
|
+
lxw_comment_free(comment);
|
591
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
592
|
+
}
|
593
|
+
|
594
|
+
comment->comment_objs = worksheet->comment_objs;
|
595
|
+
comment->comment_author = worksheet->comment_author;
|
596
|
+
|
597
|
+
lxw_comment_assemble_xml_file(comment);
|
598
|
+
|
599
|
+
err = _add_file_to_zip(self, comment->file, filename);
|
600
|
+
|
601
|
+
fclose(comment->file);
|
602
|
+
lxw_comment_free(comment);
|
603
|
+
|
604
|
+
RETURN_ON_ERROR(err);
|
605
|
+
}
|
606
|
+
|
607
|
+
return LXW_NO_ERROR;
|
608
|
+
}
|
609
|
+
|
443
610
|
/*
|
444
611
|
* Write the sharedStrings.xml file.
|
445
612
|
*/
|
@@ -690,11 +857,28 @@ _write_styles_file(lxw_packager *self)
|
|
690
857
|
STAILQ_INSERT_TAIL(styles->xf_formats, style_format, list_pointers);
|
691
858
|
}
|
692
859
|
|
860
|
+
/* Copy the unique and in-use dxf formats from the workbook to the styles
|
861
|
+
* dxf_format list. */
|
862
|
+
LXW_FOREACH_ORDERED(hash_element, self->workbook->used_dxf_formats) {
|
863
|
+
lxw_format *workbook_format = (lxw_format *) hash_element->value;
|
864
|
+
lxw_format *style_format = lxw_format_new();
|
865
|
+
|
866
|
+
if (!style_format) {
|
867
|
+
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
868
|
+
goto mem_error;
|
869
|
+
}
|
870
|
+
|
871
|
+
memcpy(style_format, workbook_format, sizeof(lxw_format));
|
872
|
+
STAILQ_INSERT_TAIL(styles->dxf_formats, style_format, list_pointers);
|
873
|
+
}
|
874
|
+
|
693
875
|
styles->font_count = self->workbook->font_count;
|
694
876
|
styles->border_count = self->workbook->border_count;
|
695
877
|
styles->fill_count = self->workbook->fill_count;
|
696
878
|
styles->num_format_count = self->workbook->num_format_count;
|
697
879
|
styles->xf_count = self->workbook->used_xf_formats->unique_count;
|
880
|
+
styles->dxf_count = self->workbook->used_dxf_formats->unique_count;
|
881
|
+
styles->has_comments = self->workbook->has_comments;
|
698
882
|
|
699
883
|
styles->file = lxw_tmpfile(self->tmpdir);
|
700
884
|
if (!styles->file) {
|
@@ -787,6 +971,15 @@ _write_content_types_file(lxw_packager *self)
|
|
787
971
|
lxw_ct_add_drawing_name(content_types, filename);
|
788
972
|
}
|
789
973
|
|
974
|
+
if (workbook->has_vml)
|
975
|
+
lxw_ct_add_vml_name(content_types);
|
976
|
+
|
977
|
+
for (index = 1; index <= workbook->comment_count; index++) {
|
978
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
979
|
+
"/xl/comments%d.xml", index);
|
980
|
+
lxw_ct_add_comment_name(content_types, filename);
|
981
|
+
}
|
982
|
+
|
790
983
|
if (workbook->sst->string_count)
|
791
984
|
lxw_ct_add_shared_strings(content_types);
|
792
985
|
|
@@ -893,7 +1086,10 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
893
1086
|
index++;
|
894
1087
|
|
895
1088
|
if (STAILQ_EMPTY(worksheet->external_hyperlinks) &&
|
896
|
-
STAILQ_EMPTY(worksheet->external_drawing_links)
|
1089
|
+
STAILQ_EMPTY(worksheet->external_drawing_links) &&
|
1090
|
+
!worksheet->external_vml_header_link &&
|
1091
|
+
!worksheet->external_vml_comment_link &&
|
1092
|
+
!worksheet->external_comment_link)
|
897
1093
|
continue;
|
898
1094
|
|
899
1095
|
rels = lxw_relationships_new();
|
@@ -914,6 +1110,21 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
914
1110
|
rel->target_mode);
|
915
1111
|
}
|
916
1112
|
|
1113
|
+
rel = worksheet->external_vml_comment_link;
|
1114
|
+
if (rel)
|
1115
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1116
|
+
rel->target_mode);
|
1117
|
+
|
1118
|
+
rel = worksheet->external_vml_header_link;
|
1119
|
+
if (rel)
|
1120
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1121
|
+
rel->target_mode);
|
1122
|
+
|
1123
|
+
rel = worksheet->external_comment_link;
|
1124
|
+
if (rel)
|
1125
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1126
|
+
rel->target_mode);
|
1127
|
+
|
917
1128
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
918
1129
|
"xl/worksheets/_rels/sheet%d.xml.rels", index);
|
919
1130
|
|
@@ -1047,6 +1258,46 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
1047
1258
|
return LXW_NO_ERROR;
|
1048
1259
|
}
|
1049
1260
|
|
1261
|
+
/*
|
1262
|
+
* Write the vmlDrawing .rels files for worksheets that contain images in
|
1263
|
+
* headers or footers.
|
1264
|
+
*/
|
1265
|
+
STATIC lxw_error
|
1266
|
+
_write_vml_drawing_rels_file(lxw_packager *self, lxw_worksheet *worksheet,
|
1267
|
+
uint32_t index)
|
1268
|
+
{
|
1269
|
+
lxw_relationships *rels;
|
1270
|
+
lxw_rel_tuple *rel;
|
1271
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
1272
|
+
lxw_error err = LXW_NO_ERROR;
|
1273
|
+
|
1274
|
+
rels = lxw_relationships_new();
|
1275
|
+
|
1276
|
+
rels->file = lxw_tmpfile(self->tmpdir);
|
1277
|
+
if (!rels->file) {
|
1278
|
+
lxw_free_relationships(rels);
|
1279
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
1280
|
+
}
|
1281
|
+
|
1282
|
+
STAILQ_FOREACH(rel, worksheet->vml_drawing_links, list_pointers) {
|
1283
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1284
|
+
rel->target_mode);
|
1285
|
+
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
1289
|
+
"xl/drawings/_rels/vmlDrawing%d.vml.rels", index);
|
1290
|
+
|
1291
|
+
lxw_relationships_assemble_xml_file(rels);
|
1292
|
+
|
1293
|
+
err = _add_file_to_zip(self, rels->file, sheetname);
|
1294
|
+
|
1295
|
+
fclose(rels->file);
|
1296
|
+
lxw_free_relationships(rels);
|
1297
|
+
|
1298
|
+
return err;
|
1299
|
+
}
|
1300
|
+
|
1050
1301
|
/*
|
1051
1302
|
* Write the _rels/.rels xml file.
|
1052
1303
|
*/
|
@@ -1223,6 +1474,12 @@ lxw_create_package(lxw_packager *self)
|
|
1223
1474
|
error = _write_drawing_files(self);
|
1224
1475
|
RETURN_ON_ERROR(error);
|
1225
1476
|
|
1477
|
+
error = _write_vml_files(self);
|
1478
|
+
RETURN_ON_ERROR(error);
|
1479
|
+
|
1480
|
+
error = _write_comment_files(self);
|
1481
|
+
RETURN_ON_ERROR(error);
|
1482
|
+
|
1226
1483
|
error = _write_shared_strings_file(self);
|
1227
1484
|
RETURN_ON_ERROR(error);
|
1228
1485
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -145,9 +145,7 @@ _write_si(lxw_sst *self, char *string)
|
|
145
145
|
lxw_xml_start_tag(self->file, "si", NULL);
|
146
146
|
|
147
147
|
/* Look for and escape control chars in the string. */
|
148
|
-
if (
|
149
|
-
"\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"
|
150
|
-
"\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) {
|
148
|
+
if (lxw_has_control_characters(string)) {
|
151
149
|
string = lxw_escape_control_characters(string);
|
152
150
|
escaped_string = LXW_TRUE;
|
153
151
|
}
|