fast_excel 0.2.6 → 0.3.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/.dockerignore +2 -0
- data/.gitignore +3 -0
- data/.travis.yml +18 -6
- data/CHANGELOG.md +14 -1
- data/Dockerfile.test +16 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +21 -21
- data/Makefile +13 -2
- data/README.md +148 -38
- data/Rakefile +2 -0
- data/examples/example.rb +3 -3
- data/examples/example_filters.rb +36 -0
- data/examples/example_formula.rb +1 -3
- data/examples/example_hyperlink.rb +20 -0
- data/fast_excel.gemspec +1 -1
- data/lib/fast_excel.rb +36 -12
- data/lib/fast_excel/binding.rb +31 -21
- data/lib/fast_excel/binding/chart.rb +20 -1
- data/lib/fast_excel/binding/workbook.rb +10 -2
- data/lib/fast_excel/binding/worksheet.rb +44 -27
- data/libxlsxwriter/.gitignore +1 -0
- data/libxlsxwriter/.indent.pro +5 -0
- data/libxlsxwriter/CMakeLists.txt +1 -11
- data/libxlsxwriter/CONTRIBUTING.md +1 -1
- data/libxlsxwriter/Changes.txt +84 -0
- data/libxlsxwriter/LICENSE.txt +1 -1
- data/libxlsxwriter/Makefile +7 -5
- data/libxlsxwriter/Readme.md +1 -1
- data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +1 -0
- data/libxlsxwriter/include/xlsxwriter.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/app.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/chart.h +56 -6
- data/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
- data/libxlsxwriter/include/xlsxwriter/common.h +27 -6
- data/libxlsxwriter/include/xlsxwriter/content_types.h +5 -2
- data/libxlsxwriter/include/xlsxwriter/core.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/custom.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/drawing.h +3 -2
- data/libxlsxwriter/include/xlsxwriter/format.h +3 -3
- data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/packager.h +13 -8
- data/libxlsxwriter/include/xlsxwriter/relationships.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/shared_strings.h +5 -3
- data/libxlsxwriter/include/xlsxwriter/styles.h +9 -4
- data/libxlsxwriter/include/xlsxwriter/theme.h +2 -2
- data/libxlsxwriter/include/xlsxwriter/utility.h +26 -2
- data/libxlsxwriter/include/xlsxwriter/workbook.h +232 -55
- data/libxlsxwriter/include/xlsxwriter/worksheet.h +264 -53
- data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +3 -1
- data/libxlsxwriter/libxlsxwriter.podspec +1 -1
- data/libxlsxwriter/src/Makefile +3 -3
- data/libxlsxwriter/src/app.c +2 -2
- data/libxlsxwriter/src/chart.c +41 -5
- data/libxlsxwriter/src/chartsheet.c +508 -0
- data/libxlsxwriter/src/content_types.c +12 -4
- data/libxlsxwriter/src/core.c +2 -2
- data/libxlsxwriter/src/custom.c +2 -2
- data/libxlsxwriter/src/drawing.c +114 -17
- data/libxlsxwriter/src/format.c +3 -3
- data/libxlsxwriter/src/hash_table.c +1 -1
- data/libxlsxwriter/src/packager.c +369 -65
- data/libxlsxwriter/src/relationships.c +2 -2
- data/libxlsxwriter/src/shared_strings.c +18 -4
- data/libxlsxwriter/src/styles.c +56 -9
- data/libxlsxwriter/src/theme.c +2 -2
- data/libxlsxwriter/src/utility.c +53 -6
- data/libxlsxwriter/src/workbook.c +372 -56
- data/libxlsxwriter/src/worksheet.c +425 -76
- data/libxlsxwriter/src/xmlwriter.c +17 -8
- data/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
- data/libxlsxwriter/third_party/minizip/zip.c +2 -0
- data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
- data/libxlsxwriter/version.txt +1 -1
- data/test/tmpfile_test.rb +1 -0
- data/test/validations_test.rb +26 -6
- data/test/worksheet_test.rb +43 -0
- metadata +9 -6
- data/libxlsxwriter/.drone.yml +0 -27
- data/libxlsxwriter/appveyor.yml +0 -65
- data/libxlsxwriter/cmake/FindZLIB.cmake +0 -123
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -25,7 +25,7 @@
|
|
25
25
|
* Create a new content_types object.
|
26
26
|
*/
|
27
27
|
lxw_content_types *
|
28
|
-
lxw_content_types_new()
|
28
|
+
lxw_content_types_new(void)
|
29
29
|
{
|
30
30
|
lxw_content_types *content_types = calloc(1, sizeof(lxw_content_types));
|
31
31
|
GOTO_LABEL_ON_MEM_ERROR(content_types, mem_error);
|
@@ -50,8 +50,6 @@ lxw_content_types_new()
|
|
50
50
|
LXW_APP_DOCUMENT "spreadsheetml.styles+xml");
|
51
51
|
lxw_ct_add_override(content_types, "/xl/theme/theme1.xml",
|
52
52
|
LXW_APP_DOCUMENT "theme+xml");
|
53
|
-
lxw_ct_add_override(content_types, "/xl/workbook.xml",
|
54
|
-
LXW_APP_DOCUMENT "spreadsheetml.sheet.main+xml");
|
55
53
|
|
56
54
|
return content_types;
|
57
55
|
|
@@ -296,6 +294,16 @@ lxw_ct_add_worksheet_name(lxw_content_types *self, const char *name)
|
|
296
294
|
LXW_APP_DOCUMENT "spreadsheetml.worksheet+xml");
|
297
295
|
}
|
298
296
|
|
297
|
+
/*
|
298
|
+
* Add the name of a chartsheet to the ContentTypes overrides.
|
299
|
+
*/
|
300
|
+
void
|
301
|
+
lxw_ct_add_chartsheet_name(lxw_content_types *self, const char *name)
|
302
|
+
{
|
303
|
+
lxw_ct_add_override(self, name,
|
304
|
+
LXW_APP_DOCUMENT "spreadsheetml.chartsheet+xml");
|
305
|
+
}
|
306
|
+
|
299
307
|
/*
|
300
308
|
* Add the name of a chart to the ContentTypes overrides.
|
301
309
|
*/
|
data/libxlsxwriter/src/core.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-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -25,7 +25,7 @@
|
|
25
25
|
* Create a new core object.
|
26
26
|
*/
|
27
27
|
lxw_core *
|
28
|
-
lxw_core_new()
|
28
|
+
lxw_core_new(void)
|
29
29
|
{
|
30
30
|
lxw_core *core = calloc(1, sizeof(lxw_core));
|
31
31
|
GOTO_LABEL_ON_MEM_ERROR(core, mem_error);
|
data/libxlsxwriter/src/custom.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-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -25,7 +25,7 @@
|
|
25
25
|
* Create a new custom object.
|
26
26
|
*/
|
27
27
|
lxw_custom *
|
28
|
-
lxw_custom_new()
|
28
|
+
lxw_custom_new(void)
|
29
29
|
{
|
30
30
|
lxw_custom *custom = calloc(1, sizeof(lxw_custom));
|
31
31
|
GOTO_LABEL_ON_MEM_ERROR(custom, mem_error);
|
data/libxlsxwriter/src/drawing.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-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -27,7 +27,7 @@
|
|
27
27
|
* Create a new drawing collection.
|
28
28
|
*/
|
29
29
|
lxw_drawing *
|
30
|
-
lxw_drawing_new()
|
30
|
+
lxw_drawing_new(void)
|
31
31
|
{
|
32
32
|
lxw_drawing *drawing = calloc(1, sizeof(lxw_drawing));
|
33
33
|
GOTO_LABEL_ON_MEM_ERROR(drawing, mem_error);
|
@@ -225,7 +225,7 @@ _drawing_write_to(lxw_drawing *self, lxw_drawing_coords *coords)
|
|
225
225
|
* Write the <xdr:cNvPr> element.
|
226
226
|
*/
|
227
227
|
STATIC void
|
228
|
-
_drawing_write_c_nv_pr(lxw_drawing *self, char *object_name,
|
228
|
+
_drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint32_t index,
|
229
229
|
lxw_drawing_object *drawing_object)
|
230
230
|
{
|
231
231
|
struct xml_attribute_list attributes;
|
@@ -239,7 +239,7 @@ _drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint16_t index,
|
|
239
239
|
LXW_PUSH_ATTRIBUTES_INT("id", index + 1);
|
240
240
|
LXW_PUSH_ATTRIBUTES_STR("name", name);
|
241
241
|
|
242
|
-
if (drawing_object)
|
242
|
+
if (drawing_object && drawing_object->description)
|
243
243
|
LXW_PUSH_ATTRIBUTES_STR("descr", drawing_object->description);
|
244
244
|
|
245
245
|
lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
|
@@ -282,7 +282,7 @@ _drawing_write_c_nv_pic_pr(lxw_drawing *self)
|
|
282
282
|
* Write the <xdr:nvPicPr> element.
|
283
283
|
*/
|
284
284
|
STATIC void
|
285
|
-
_drawing_write_nv_pic_pr(lxw_drawing *self,
|
285
|
+
_drawing_write_nv_pic_pr(lxw_drawing *self, uint32_t index,
|
286
286
|
lxw_drawing_object *drawing_object)
|
287
287
|
{
|
288
288
|
lxw_xml_start_tag(self->file, "xdr:nvPicPr", NULL);
|
@@ -300,7 +300,7 @@ _drawing_write_nv_pic_pr(lxw_drawing *self, uint16_t index,
|
|
300
300
|
* Write the <a:blip> element.
|
301
301
|
*/
|
302
302
|
STATIC void
|
303
|
-
_drawing_write_a_blip(lxw_drawing *self,
|
303
|
+
_drawing_write_a_blip(lxw_drawing *self, uint32_t index)
|
304
304
|
{
|
305
305
|
struct xml_attribute_list attributes;
|
306
306
|
struct xml_attribute *attribute;
|
@@ -345,7 +345,7 @@ _drawing_write_a_stretch(lxw_drawing *self)
|
|
345
345
|
* Write the <xdr:blipFill> element.
|
346
346
|
*/
|
347
347
|
STATIC void
|
348
|
-
_drawing_write_blip_fill(lxw_drawing *self,
|
348
|
+
_drawing_write_blip_fill(lxw_drawing *self, uint32_t index)
|
349
349
|
{
|
350
350
|
lxw_xml_start_tag(self->file, "xdr:blipFill", NULL);
|
351
351
|
|
@@ -463,7 +463,7 @@ _drawing_write_sp_pr(lxw_drawing *self, lxw_drawing_object *drawing_object)
|
|
463
463
|
* Write the <xdr:pic> element.
|
464
464
|
*/
|
465
465
|
STATIC void
|
466
|
-
_drawing_write_pic(lxw_drawing *self,
|
466
|
+
_drawing_write_pic(lxw_drawing *self, uint32_t index,
|
467
467
|
lxw_drawing_object *drawing_object)
|
468
468
|
{
|
469
469
|
lxw_xml_start_tag(self->file, "xdr:pic", NULL);
|
@@ -489,20 +489,47 @@ _drawing_write_client_data(lxw_drawing *self)
|
|
489
489
|
lxw_xml_empty_tag(self->file, "xdr:clientData", NULL);
|
490
490
|
}
|
491
491
|
|
492
|
+
/*
|
493
|
+
* Write the <a:graphicFrameLocks> element.
|
494
|
+
*/
|
495
|
+
STATIC void
|
496
|
+
_drawing_write_a_graphic_frame_locks(lxw_drawing *self)
|
497
|
+
{
|
498
|
+
struct xml_attribute_list attributes;
|
499
|
+
struct xml_attribute *attribute;
|
500
|
+
|
501
|
+
LXW_INIT_ATTRIBUTES();
|
502
|
+
LXW_PUSH_ATTRIBUTES_INT("noGrp", 1);
|
503
|
+
|
504
|
+
lxw_xml_empty_tag(self->file, "a:graphicFrameLocks", &attributes);
|
505
|
+
|
506
|
+
LXW_FREE_ATTRIBUTES();
|
507
|
+
}
|
508
|
+
|
492
509
|
/*
|
493
510
|
* Write the <xdr:cNvGraphicFramePr> element.
|
494
511
|
*/
|
495
512
|
STATIC void
|
496
513
|
_drawing_write_c_nv_graphic_frame_pr(lxw_drawing *self)
|
497
514
|
{
|
498
|
-
|
515
|
+
if (self->embedded) {
|
516
|
+
lxw_xml_empty_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
|
517
|
+
}
|
518
|
+
else {
|
519
|
+
lxw_xml_start_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
|
520
|
+
|
521
|
+
/* Write the a:graphicFrameLocks element. */
|
522
|
+
_drawing_write_a_graphic_frame_locks(self);
|
523
|
+
|
524
|
+
lxw_xml_end_tag(self->file, "xdr:cNvGraphicFramePr");
|
525
|
+
}
|
499
526
|
}
|
500
527
|
|
501
528
|
/*
|
502
529
|
* Write the <xdr:nvGraphicFramePr> element.
|
503
530
|
*/
|
504
531
|
STATIC void
|
505
|
-
_drawing_write_nv_graphic_frame_pr(lxw_drawing *self,
|
532
|
+
_drawing_write_nv_graphic_frame_pr(lxw_drawing *self, uint32_t index)
|
506
533
|
{
|
507
534
|
lxw_xml_start_tag(self->file, "xdr:nvGraphicFramePr", NULL);
|
508
535
|
|
@@ -572,7 +599,7 @@ _drawing_write_xfrm(lxw_drawing *self)
|
|
572
599
|
* Write the <c:chart> element.
|
573
600
|
*/
|
574
601
|
STATIC void
|
575
|
-
_drawing_write_chart(lxw_drawing *self,
|
602
|
+
_drawing_write_chart(lxw_drawing *self, uint32_t index)
|
576
603
|
{
|
577
604
|
struct xml_attribute_list attributes;
|
578
605
|
struct xml_attribute *attribute;
|
@@ -596,7 +623,7 @@ _drawing_write_chart(lxw_drawing *self, uint16_t index)
|
|
596
623
|
* Write the <a:graphicData> element.
|
597
624
|
*/
|
598
625
|
STATIC void
|
599
|
-
_drawing_write_a_graphic_data(lxw_drawing *self,
|
626
|
+
_drawing_write_a_graphic_data(lxw_drawing *self, uint32_t index)
|
600
627
|
{
|
601
628
|
struct xml_attribute_list attributes;
|
602
629
|
struct xml_attribute *attribute;
|
@@ -619,7 +646,7 @@ _drawing_write_a_graphic_data(lxw_drawing *self, uint16_t index)
|
|
619
646
|
* Write the <a:graphic> element.
|
620
647
|
*/
|
621
648
|
STATIC void
|
622
|
-
_drawing_write_a_graphic(lxw_drawing *self,
|
649
|
+
_drawing_write_a_graphic(lxw_drawing *self, uint32_t index)
|
623
650
|
{
|
624
651
|
|
625
652
|
lxw_xml_start_tag(self->file, "a:graphic", NULL);
|
@@ -634,7 +661,7 @@ _drawing_write_a_graphic(lxw_drawing *self, uint16_t index)
|
|
634
661
|
* Write the <xdr:graphicFrame> element.
|
635
662
|
*/
|
636
663
|
STATIC void
|
637
|
-
_drawing_write_graphic_frame(lxw_drawing *self,
|
664
|
+
_drawing_write_graphic_frame(lxw_drawing *self, uint32_t index)
|
638
665
|
{
|
639
666
|
struct xml_attribute_list attributes;
|
640
667
|
struct xml_attribute *attribute;
|
@@ -662,7 +689,7 @@ _drawing_write_graphic_frame(lxw_drawing *self, uint16_t index)
|
|
662
689
|
* Write the <xdr:twoCellAnchor> element.
|
663
690
|
*/
|
664
691
|
STATIC void
|
665
|
-
_drawing_write_two_cell_anchor(lxw_drawing *self,
|
692
|
+
_drawing_write_two_cell_anchor(lxw_drawing *self, uint32_t index,
|
666
693
|
lxw_drawing_object *drawing_object)
|
667
694
|
{
|
668
695
|
struct xml_attribute_list attributes;
|
@@ -705,6 +732,73 @@ _drawing_write_two_cell_anchor(lxw_drawing *self, uint16_t index,
|
|
705
732
|
LXW_FREE_ATTRIBUTES();
|
706
733
|
}
|
707
734
|
|
735
|
+
/*
|
736
|
+
* Write the <xdr:ext> element.
|
737
|
+
*/
|
738
|
+
STATIC void
|
739
|
+
_drawing_write_ext(lxw_drawing *self, uint32_t cx, uint32_t cy)
|
740
|
+
{
|
741
|
+
struct xml_attribute_list attributes;
|
742
|
+
struct xml_attribute *attribute;
|
743
|
+
|
744
|
+
LXW_INIT_ATTRIBUTES();
|
745
|
+
LXW_PUSH_ATTRIBUTES_INT("cx", cx);
|
746
|
+
LXW_PUSH_ATTRIBUTES_INT("cy", cy);
|
747
|
+
|
748
|
+
lxw_xml_empty_tag(self->file, "xdr:ext", &attributes);
|
749
|
+
|
750
|
+
LXW_FREE_ATTRIBUTES();
|
751
|
+
}
|
752
|
+
|
753
|
+
/*
|
754
|
+
* Write the <xdr:pos> element.
|
755
|
+
*/
|
756
|
+
STATIC void
|
757
|
+
_drawing_write_pos(lxw_drawing *self, int32_t x, int32_t y)
|
758
|
+
{
|
759
|
+
struct xml_attribute_list attributes;
|
760
|
+
struct xml_attribute *attribute;
|
761
|
+
|
762
|
+
LXW_INIT_ATTRIBUTES();
|
763
|
+
LXW_PUSH_ATTRIBUTES_INT("x", x);
|
764
|
+
LXW_PUSH_ATTRIBUTES_INT("y", y);
|
765
|
+
|
766
|
+
lxw_xml_empty_tag(self->file, "xdr:pos", &attributes);
|
767
|
+
|
768
|
+
LXW_FREE_ATTRIBUTES();
|
769
|
+
}
|
770
|
+
|
771
|
+
/*
|
772
|
+
* Write the <xdr:absoluteAnchor> element.
|
773
|
+
*/
|
774
|
+
STATIC void
|
775
|
+
_drawing_write_absolute_anchor(lxw_drawing *self)
|
776
|
+
{
|
777
|
+
lxw_xml_start_tag(self->file, "xdr:absoluteAnchor", NULL);
|
778
|
+
|
779
|
+
if (self->orientation == LXW_LANDSCAPE) {
|
780
|
+
/* Write the xdr:pos element. */
|
781
|
+
_drawing_write_pos(self, 0, 0);
|
782
|
+
|
783
|
+
/* Write the xdr:ext element. */
|
784
|
+
_drawing_write_ext(self, 9308969, 6078325);
|
785
|
+
}
|
786
|
+
else {
|
787
|
+
/* Write the xdr:pos element. */
|
788
|
+
_drawing_write_pos(self, 0, -47625);
|
789
|
+
|
790
|
+
/* Write the xdr:ext element. */
|
791
|
+
_drawing_write_ext(self, 6162675, 6124575);
|
792
|
+
}
|
793
|
+
|
794
|
+
_drawing_write_graphic_frame(self, 1);
|
795
|
+
|
796
|
+
/* Write the xdr:clientData element. */
|
797
|
+
_drawing_write_client_data(self);
|
798
|
+
|
799
|
+
lxw_xml_end_tag(self->file, "xdr:absoluteAnchor");
|
800
|
+
}
|
801
|
+
|
708
802
|
/*****************************************************************************
|
709
803
|
*
|
710
804
|
* XML file assembly functions.
|
@@ -717,7 +811,7 @@ _drawing_write_two_cell_anchor(lxw_drawing *self, uint16_t index,
|
|
717
811
|
void
|
718
812
|
lxw_drawing_assemble_xml_file(lxw_drawing *self)
|
719
813
|
{
|
720
|
-
|
814
|
+
uint32_t index;
|
721
815
|
lxw_drawing_object *drawing_object;
|
722
816
|
|
723
817
|
/* Write the XML declaration. */
|
@@ -733,7 +827,10 @@ lxw_drawing_assemble_xml_file(lxw_drawing *self)
|
|
733
827
|
_drawing_write_two_cell_anchor(self, index, drawing_object);
|
734
828
|
index++;
|
735
829
|
}
|
736
|
-
|
830
|
+
}
|
831
|
+
else {
|
832
|
+
/* Write the xdr:absoluteAnchor element. Mainly for chartsheets. */
|
833
|
+
_drawing_write_absolute_anchor(self);
|
737
834
|
}
|
738
835
|
|
739
836
|
lxw_xml_end_tag(self->file, "xdr:wsDr");
|
data/libxlsxwriter/src/format.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-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
* Create a new format object.
|
22
22
|
*/
|
23
23
|
lxw_format *
|
24
|
-
lxw_format_new()
|
24
|
+
lxw_format_new(void)
|
25
25
|
{
|
26
26
|
lxw_format *format = calloc(1, sizeof(lxw_format));
|
27
27
|
GOTO_LABEL_ON_MEM_ERROR(format, mem_error);
|
@@ -455,7 +455,7 @@ format_set_rotation(lxw_format *self, int16_t angle)
|
|
455
455
|
if (angle == 270) {
|
456
456
|
self->rotation = 255;
|
457
457
|
}
|
458
|
-
else if (angle >= -90
|
458
|
+
else if (angle >= -90 && angle <= 90) {
|
459
459
|
if (angle < 0)
|
460
460
|
angle = -angle + 90;
|
461
461
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
@@ -15,6 +15,9 @@
|
|
15
15
|
STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
|
16
16
|
const char *filename);
|
17
17
|
|
18
|
+
STATIC lxw_error _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
19
|
+
size_t buffer_size, const char *filename);
|
20
|
+
|
18
21
|
/*
|
19
22
|
* Forward declarations.
|
20
23
|
*/
|
@@ -73,7 +76,7 @@ _open_zipfile_win32(const char *filename)
|
|
73
76
|
* Create a new packager object.
|
74
77
|
*/
|
75
78
|
lxw_packager *
|
76
|
-
lxw_packager_new(const char *filename, char *tmpdir)
|
79
|
+
lxw_packager_new(const char *filename, char *tmpdir, uint8_t use_zip64)
|
77
80
|
{
|
78
81
|
lxw_packager *packager = calloc(1, sizeof(lxw_packager));
|
79
82
|
GOTO_LABEL_ON_MEM_ERROR(packager, mem_error);
|
@@ -86,6 +89,7 @@ lxw_packager_new(const char *filename, char *tmpdir)
|
|
86
89
|
GOTO_LABEL_ON_MEM_ERROR(packager->filename, mem_error);
|
87
90
|
|
88
91
|
packager->buffer_size = LXW_ZIP_BUFFER_SIZE;
|
92
|
+
packager->use_zip64 = use_zip64;
|
89
93
|
|
90
94
|
/* Initialize the zip_fileinfo struct to Jan 1 1980 like Excel. */
|
91
95
|
packager->zipfile_info.tmz_date.tm_sec = 0;
|
@@ -164,12 +168,18 @@ STATIC lxw_error
|
|
164
168
|
_write_worksheet_files(lxw_packager *self)
|
165
169
|
{
|
166
170
|
lxw_workbook *workbook = self->workbook;
|
171
|
+
lxw_sheet *sheet;
|
167
172
|
lxw_worksheet *worksheet;
|
168
173
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
169
|
-
|
174
|
+
uint32_t index = 1;
|
170
175
|
lxw_error err;
|
171
176
|
|
172
|
-
STAILQ_FOREACH(
|
177
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
178
|
+
if (sheet->is_chartsheet)
|
179
|
+
continue;
|
180
|
+
else
|
181
|
+
worksheet = sheet->u.worksheet;
|
182
|
+
|
173
183
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
174
184
|
"xl/worksheets/sheet%d.xml", index++);
|
175
185
|
|
@@ -191,6 +201,43 @@ _write_worksheet_files(lxw_packager *self)
|
|
191
201
|
return LXW_NO_ERROR;
|
192
202
|
}
|
193
203
|
|
204
|
+
/*
|
205
|
+
* Write the chartsheet files.
|
206
|
+
*/
|
207
|
+
STATIC lxw_error
|
208
|
+
_write_chartsheet_files(lxw_packager *self)
|
209
|
+
{
|
210
|
+
lxw_workbook *workbook = self->workbook;
|
211
|
+
lxw_sheet *sheet;
|
212
|
+
lxw_chartsheet *chartsheet;
|
213
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
214
|
+
uint32_t index = 1;
|
215
|
+
lxw_error err;
|
216
|
+
|
217
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
218
|
+
if (sheet->is_chartsheet)
|
219
|
+
chartsheet = sheet->u.chartsheet;
|
220
|
+
else
|
221
|
+
continue;
|
222
|
+
|
223
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
224
|
+
"xl/chartsheets/sheet%d.xml", index++);
|
225
|
+
|
226
|
+
chartsheet->file = lxw_tmpfile(self->tmpdir);
|
227
|
+
if (!chartsheet->file)
|
228
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
229
|
+
|
230
|
+
lxw_chartsheet_assemble_xml_file(chartsheet);
|
231
|
+
|
232
|
+
err = _add_file_to_zip(self, chartsheet->file, sheetname);
|
233
|
+
RETURN_ON_ERROR(err);
|
234
|
+
|
235
|
+
fclose(chartsheet->file);
|
236
|
+
}
|
237
|
+
|
238
|
+
return LXW_NO_ERROR;
|
239
|
+
}
|
240
|
+
|
194
241
|
/*
|
195
242
|
* Write the /xl/media/image?.xml files.
|
196
243
|
*/
|
@@ -198,15 +245,20 @@ STATIC lxw_error
|
|
198
245
|
_write_image_files(lxw_packager *self)
|
199
246
|
{
|
200
247
|
lxw_workbook *workbook = self->workbook;
|
248
|
+
lxw_sheet *sheet;
|
201
249
|
lxw_worksheet *worksheet;
|
202
250
|
lxw_image_options *image;
|
203
251
|
lxw_error err;
|
204
252
|
FILE *image_stream;
|
205
253
|
|
206
254
|
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
207
|
-
|
255
|
+
uint32_t index = 1;
|
208
256
|
|
209
|
-
STAILQ_FOREACH(
|
257
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
258
|
+
if (sheet->is_chartsheet)
|
259
|
+
continue;
|
260
|
+
else
|
261
|
+
worksheet = sheet->u.worksheet;
|
210
262
|
|
211
263
|
if (STAILQ_EMPTY(worksheet->image_data))
|
212
264
|
continue;
|
@@ -216,17 +268,24 @@ _write_image_files(lxw_packager *self)
|
|
216
268
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
217
269
|
"xl/media/image%d.%s", index++, image->extension);
|
218
270
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
271
|
+
if (!image->is_image_buffer) {
|
272
|
+
/* Check that the image file exists and can be opened. */
|
273
|
+
image_stream = fopen(image->filename, "rb");
|
274
|
+
if (!image_stream) {
|
275
|
+
LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
|
276
|
+
"doesn't exist or can't be opened: %s.",
|
277
|
+
image->filename);
|
278
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
279
|
+
}
|
280
|
+
|
281
|
+
err = _add_file_to_zip(self, image_stream, filename);
|
282
|
+
fclose(image_stream);
|
283
|
+
}
|
284
|
+
else {
|
285
|
+
err = _add_buffer_to_zip(self,
|
286
|
+
image->image_buffer,
|
287
|
+
image->image_buffer_size, filename);
|
226
288
|
}
|
227
|
-
|
228
|
-
err = _add_file_to_zip(self, image_stream, filename);
|
229
|
-
fclose(image_stream);
|
230
289
|
|
231
290
|
RETURN_ON_ERROR(err);
|
232
291
|
}
|
@@ -235,6 +294,35 @@ _write_image_files(lxw_packager *self)
|
|
235
294
|
return LXW_NO_ERROR;
|
236
295
|
}
|
237
296
|
|
297
|
+
/*
|
298
|
+
* Write the xl/vbaProject.bin file.
|
299
|
+
*/
|
300
|
+
STATIC lxw_error
|
301
|
+
_add_vba_project(lxw_packager *self)
|
302
|
+
{
|
303
|
+
lxw_workbook *workbook = self->workbook;
|
304
|
+
lxw_error err;
|
305
|
+
FILE *image_stream;
|
306
|
+
|
307
|
+
if (!workbook->vba_project)
|
308
|
+
return LXW_NO_ERROR;
|
309
|
+
|
310
|
+
/* Check that the image file exists and can be opened. */
|
311
|
+
image_stream = fopen(workbook->vba_project, "rb");
|
312
|
+
if (!image_stream) {
|
313
|
+
LXW_WARN_FORMAT1("Error adding vbaProject.bin to xlsx file: "
|
314
|
+
"file doesn't exist or can't be opened: %s.",
|
315
|
+
workbook->vba_project);
|
316
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
317
|
+
}
|
318
|
+
|
319
|
+
err = _add_file_to_zip(self, image_stream, "xl/vbaProject.bin");
|
320
|
+
fclose(image_stream);
|
321
|
+
RETURN_ON_ERROR(err);
|
322
|
+
|
323
|
+
return LXW_NO_ERROR;
|
324
|
+
}
|
325
|
+
|
238
326
|
/*
|
239
327
|
* Write the chart files.
|
240
328
|
*/
|
@@ -244,7 +332,7 @@ _write_chart_files(lxw_packager *self)
|
|
244
332
|
lxw_workbook *workbook = self->workbook;
|
245
333
|
lxw_chart *chart;
|
246
334
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
247
|
-
|
335
|
+
uint32_t index = 1;
|
248
336
|
lxw_error err;
|
249
337
|
|
250
338
|
STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
|
@@ -261,14 +349,29 @@ _write_chart_files(lxw_packager *self)
|
|
261
349
|
err = _add_file_to_zip(self, chart->file, sheetname);
|
262
350
|
RETURN_ON_ERROR(err);
|
263
351
|
|
264
|
-
self->chart_count++;
|
265
|
-
|
266
352
|
fclose(chart->file);
|
267
353
|
}
|
268
354
|
|
269
355
|
return LXW_NO_ERROR;
|
270
356
|
}
|
271
357
|
|
358
|
+
/*
|
359
|
+
* Count the chart files.
|
360
|
+
*/
|
361
|
+
uint32_t
|
362
|
+
_get_chart_count(lxw_packager *self)
|
363
|
+
{
|
364
|
+
lxw_workbook *workbook = self->workbook;
|
365
|
+
lxw_chart *chart;
|
366
|
+
uint32_t chart_count = 0;
|
367
|
+
|
368
|
+
STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
|
369
|
+
chart_count++;
|
370
|
+
}
|
371
|
+
|
372
|
+
return chart_count;
|
373
|
+
}
|
374
|
+
|
272
375
|
/*
|
273
376
|
* Write the drawing files.
|
274
377
|
*/
|
@@ -276,13 +379,19 @@ STATIC lxw_error
|
|
276
379
|
_write_drawing_files(lxw_packager *self)
|
277
380
|
{
|
278
381
|
lxw_workbook *workbook = self->workbook;
|
382
|
+
lxw_sheet *sheet;
|
279
383
|
lxw_worksheet *worksheet;
|
280
384
|
lxw_drawing *drawing;
|
281
385
|
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
282
|
-
|
386
|
+
uint32_t index = 1;
|
283
387
|
lxw_error err;
|
284
388
|
|
285
|
-
STAILQ_FOREACH(
|
389
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
390
|
+
if (sheet->is_chartsheet)
|
391
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
392
|
+
else
|
393
|
+
worksheet = sheet->u.worksheet;
|
394
|
+
|
286
395
|
drawing = worksheet->drawing;
|
287
396
|
|
288
397
|
if (drawing) {
|
@@ -298,14 +407,39 @@ _write_drawing_files(lxw_packager *self)
|
|
298
407
|
RETURN_ON_ERROR(err);
|
299
408
|
|
300
409
|
fclose(drawing->file);
|
301
|
-
|
302
|
-
self->drawing_count++;
|
303
410
|
}
|
304
411
|
}
|
305
412
|
|
306
413
|
return LXW_NO_ERROR;
|
307
414
|
}
|
308
415
|
|
416
|
+
/*
|
417
|
+
* Count the drawing files.
|
418
|
+
*/
|
419
|
+
uint32_t
|
420
|
+
_get_drawing_count(lxw_packager *self)
|
421
|
+
{
|
422
|
+
lxw_workbook *workbook = self->workbook;
|
423
|
+
lxw_sheet *sheet;
|
424
|
+
lxw_worksheet *worksheet;
|
425
|
+
lxw_drawing *drawing;
|
426
|
+
uint32_t drawing_count = 0;
|
427
|
+
|
428
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
429
|
+
if (sheet->is_chartsheet)
|
430
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
431
|
+
else
|
432
|
+
worksheet = sheet->u.worksheet;
|
433
|
+
|
434
|
+
drawing = worksheet->drawing;
|
435
|
+
|
436
|
+
if (drawing)
|
437
|
+
drawing_count++;
|
438
|
+
}
|
439
|
+
|
440
|
+
return drawing_count;
|
441
|
+
}
|
442
|
+
|
309
443
|
/*
|
310
444
|
* Write the sharedStrings.xml file.
|
311
445
|
*/
|
@@ -340,10 +474,12 @@ STATIC lxw_error
|
|
340
474
|
_write_app_file(lxw_packager *self)
|
341
475
|
{
|
342
476
|
lxw_workbook *workbook = self->workbook;
|
477
|
+
lxw_sheet *sheet;
|
343
478
|
lxw_worksheet *worksheet;
|
479
|
+
lxw_chartsheet *chartsheet;
|
344
480
|
lxw_defined_name *defined_name;
|
345
481
|
lxw_app *app;
|
346
|
-
|
482
|
+
uint32_t named_range_count = 0;
|
347
483
|
char *autofilter;
|
348
484
|
char *has_range;
|
349
485
|
char number[LXW_ATTR_32] = { 0 };
|
@@ -361,12 +497,30 @@ _write_app_file(lxw_packager *self)
|
|
361
497
|
goto mem_error;
|
362
498
|
}
|
363
499
|
|
364
|
-
|
500
|
+
if (self->workbook->num_worksheets) {
|
501
|
+
lxw_snprintf(number, LXW_ATTR_32, "%d",
|
502
|
+
self->workbook->num_worksheets);
|
503
|
+
lxw_app_add_heading_pair(app, "Worksheets", number);
|
504
|
+
}
|
365
505
|
|
366
|
-
|
506
|
+
if (self->workbook->num_chartsheets) {
|
507
|
+
lxw_snprintf(number, LXW_ATTR_32, "%d",
|
508
|
+
self->workbook->num_chartsheets);
|
509
|
+
lxw_app_add_heading_pair(app, "Charts", number);
|
510
|
+
}
|
367
511
|
|
368
|
-
STAILQ_FOREACH(
|
369
|
-
|
512
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
513
|
+
if (!sheet->is_chartsheet) {
|
514
|
+
worksheet = sheet->u.worksheet;
|
515
|
+
lxw_app_add_part_name(app, worksheet->name);
|
516
|
+
}
|
517
|
+
}
|
518
|
+
|
519
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
520
|
+
if (sheet->is_chartsheet) {
|
521
|
+
chartsheet = sheet->u.chartsheet;
|
522
|
+
lxw_app_add_part_name(app, chartsheet->name);
|
523
|
+
}
|
370
524
|
}
|
371
525
|
|
372
526
|
/* Add the Named Ranges parts. */
|
@@ -568,9 +722,13 @@ _write_content_types_file(lxw_packager *self)
|
|
568
722
|
{
|
569
723
|
lxw_content_types *content_types = lxw_content_types_new();
|
570
724
|
lxw_workbook *workbook = self->workbook;
|
571
|
-
|
725
|
+
lxw_sheet *sheet;
|
572
726
|
char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
|
573
|
-
|
727
|
+
uint32_t index = 1;
|
728
|
+
uint32_t worksheet_index = 1;
|
729
|
+
uint32_t chartsheet_index = 1;
|
730
|
+
uint32_t drawing_count = _get_drawing_count(self);
|
731
|
+
uint32_t chart_count = _get_chart_count(self);
|
574
732
|
lxw_error err = LXW_NO_ERROR;
|
575
733
|
|
576
734
|
if (!content_types) {
|
@@ -593,19 +751,37 @@ _write_content_types_file(lxw_packager *self)
|
|
593
751
|
if (workbook->has_bmp)
|
594
752
|
lxw_ct_add_default(content_types, "bmp", "image/bmp");
|
595
753
|
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
754
|
+
if (workbook->vba_project)
|
755
|
+
lxw_ct_add_default(content_types, "bin",
|
756
|
+
"application/vnd.ms-office.vbaProject");
|
757
|
+
|
758
|
+
if (workbook->vba_project)
|
759
|
+
lxw_ct_add_override(content_types, "/xl/workbook.xml",
|
760
|
+
LXW_APP_MSEXCEL "sheet.macroEnabled.main+xml");
|
761
|
+
else
|
762
|
+
lxw_ct_add_override(content_types, "/xl/workbook.xml",
|
763
|
+
LXW_APP_DOCUMENT "spreadsheetml.sheet.main+xml");
|
764
|
+
|
765
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
766
|
+
if (sheet->is_chartsheet) {
|
767
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
768
|
+
"/xl/chartsheets/sheet%d.xml", chartsheet_index++);
|
769
|
+
lxw_ct_add_chartsheet_name(content_types, filename);
|
770
|
+
}
|
771
|
+
else {
|
772
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
773
|
+
"/xl/worksheets/sheet%d.xml", worksheet_index++);
|
774
|
+
lxw_ct_add_worksheet_name(content_types, filename);
|
775
|
+
}
|
600
776
|
}
|
601
777
|
|
602
|
-
for (index = 1; index <=
|
778
|
+
for (index = 1; index <= chart_count; index++) {
|
603
779
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/chart%d.xml",
|
604
780
|
index);
|
605
781
|
lxw_ct_add_chart_name(content_types, filename);
|
606
782
|
}
|
607
783
|
|
608
|
-
for (index = 1; index <=
|
784
|
+
for (index = 1; index <= drawing_count; index++) {
|
609
785
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
610
786
|
"/xl/drawings/drawing%d.xml", index);
|
611
787
|
lxw_ct_add_drawing_name(content_types, filename);
|
@@ -637,9 +813,10 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
637
813
|
{
|
638
814
|
lxw_relationships *rels = lxw_relationships_new();
|
639
815
|
lxw_workbook *workbook = self->workbook;
|
640
|
-
|
816
|
+
lxw_sheet *sheet;
|
641
817
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
642
|
-
|
818
|
+
uint32_t worksheet_index = 1;
|
819
|
+
uint32_t chartsheet_index = 1;
|
643
820
|
lxw_error err = LXW_NO_ERROR;
|
644
821
|
|
645
822
|
if (!rels) {
|
@@ -653,10 +830,19 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
653
830
|
goto mem_error;
|
654
831
|
}
|
655
832
|
|
656
|
-
STAILQ_FOREACH(
|
657
|
-
|
658
|
-
|
659
|
-
|
833
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
834
|
+
if (sheet->is_chartsheet) {
|
835
|
+
lxw_snprintf(sheetname,
|
836
|
+
LXW_FILENAME_LENGTH,
|
837
|
+
"chartsheets/sheet%d.xml", chartsheet_index++);
|
838
|
+
lxw_add_document_relationship(rels, "/chartsheet", sheetname);
|
839
|
+
}
|
840
|
+
else {
|
841
|
+
lxw_snprintf(sheetname,
|
842
|
+
LXW_FILENAME_LENGTH,
|
843
|
+
"worksheets/sheet%d.xml", worksheet_index++);
|
844
|
+
lxw_add_document_relationship(rels, "/worksheet", sheetname);
|
845
|
+
}
|
660
846
|
}
|
661
847
|
|
662
848
|
lxw_add_document_relationship(rels, "/theme", "theme/theme1.xml");
|
@@ -666,6 +852,10 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
666
852
|
lxw_add_document_relationship(rels, "/sharedStrings",
|
667
853
|
"sharedStrings.xml");
|
668
854
|
|
855
|
+
if (workbook->vba_project)
|
856
|
+
lxw_add_ms_package_relationship(rels, "/vbaProject",
|
857
|
+
"vbaProject.bin");
|
858
|
+
|
669
859
|
lxw_relationships_assemble_xml_file(rels);
|
670
860
|
|
671
861
|
err = _add_file_to_zip(self, rels->file, "xl/_rels/workbook.xml.rels");
|
@@ -688,12 +878,17 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
688
878
|
lxw_relationships *rels;
|
689
879
|
lxw_rel_tuple *rel;
|
690
880
|
lxw_workbook *workbook = self->workbook;
|
881
|
+
lxw_sheet *sheet;
|
691
882
|
lxw_worksheet *worksheet;
|
692
883
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
693
|
-
|
884
|
+
uint32_t index = 0;
|
694
885
|
lxw_error err;
|
695
886
|
|
696
|
-
STAILQ_FOREACH(
|
887
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
888
|
+
if (sheet->is_chartsheet)
|
889
|
+
continue;
|
890
|
+
else
|
891
|
+
worksheet = sheet->u.worksheet;
|
697
892
|
|
698
893
|
index++;
|
699
894
|
|
@@ -735,6 +930,68 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
735
930
|
return LXW_NO_ERROR;
|
736
931
|
}
|
737
932
|
|
933
|
+
/*
|
934
|
+
* Write the chartsheet .rels files for chartsheets that contain links to
|
935
|
+
* external data such as drawings.
|
936
|
+
*/
|
937
|
+
STATIC lxw_error
|
938
|
+
_write_chartsheet_rels_file(lxw_packager *self)
|
939
|
+
{
|
940
|
+
lxw_relationships *rels;
|
941
|
+
lxw_rel_tuple *rel;
|
942
|
+
lxw_workbook *workbook = self->workbook;
|
943
|
+
lxw_sheet *sheet;
|
944
|
+
lxw_worksheet *worksheet;
|
945
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
946
|
+
uint32_t index = 0;
|
947
|
+
lxw_error err;
|
948
|
+
|
949
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
950
|
+
if (sheet->is_chartsheet)
|
951
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
952
|
+
else
|
953
|
+
continue;
|
954
|
+
|
955
|
+
index++;
|
956
|
+
|
957
|
+
/* TODO. This should never be empty. Put check higher up. */
|
958
|
+
if (STAILQ_EMPTY(worksheet->external_drawing_links))
|
959
|
+
continue;
|
960
|
+
|
961
|
+
rels = lxw_relationships_new();
|
962
|
+
|
963
|
+
rels->file = lxw_tmpfile(self->tmpdir);
|
964
|
+
if (!rels->file) {
|
965
|
+
lxw_free_relationships(rels);
|
966
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
967
|
+
}
|
968
|
+
|
969
|
+
STAILQ_FOREACH(rel, worksheet->external_hyperlinks, list_pointers) {
|
970
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
971
|
+
rel->target_mode);
|
972
|
+
}
|
973
|
+
|
974
|
+
STAILQ_FOREACH(rel, worksheet->external_drawing_links, list_pointers) {
|
975
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
976
|
+
rel->target_mode);
|
977
|
+
}
|
978
|
+
|
979
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
980
|
+
"xl/chartsheets/_rels/sheet%d.xml.rels", index);
|
981
|
+
|
982
|
+
lxw_relationships_assemble_xml_file(rels);
|
983
|
+
|
984
|
+
err = _add_file_to_zip(self, rels->file, sheetname);
|
985
|
+
|
986
|
+
fclose(rels->file);
|
987
|
+
lxw_free_relationships(rels);
|
988
|
+
|
989
|
+
RETURN_ON_ERROR(err);
|
990
|
+
}
|
991
|
+
|
992
|
+
return LXW_NO_ERROR;
|
993
|
+
}
|
994
|
+
|
738
995
|
/*
|
739
996
|
* Write the drawing .rels files for worksheets that contain charts or
|
740
997
|
* drawings.
|
@@ -745,12 +1002,17 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
745
1002
|
lxw_relationships *rels;
|
746
1003
|
lxw_rel_tuple *rel;
|
747
1004
|
lxw_workbook *workbook = self->workbook;
|
1005
|
+
lxw_sheet *sheet;
|
748
1006
|
lxw_worksheet *worksheet;
|
749
1007
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
750
|
-
|
1008
|
+
uint32_t index = 1;
|
751
1009
|
lxw_error err;
|
752
1010
|
|
753
|
-
STAILQ_FOREACH(
|
1011
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
1012
|
+
if (sheet->is_chartsheet)
|
1013
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
1014
|
+
else
|
1015
|
+
worksheet = sheet->u.worksheet;
|
754
1016
|
|
755
1017
|
if (STAILQ_EMPTY(worksheet->drawing_links))
|
756
1018
|
continue;
|
@@ -849,7 +1111,8 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
849
1111
|
NULL, 0, NULL, 0, NULL,
|
850
1112
|
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
|
851
1113
|
-MAX_WBITS, DEF_MEM_LEVEL,
|
852
|
-
Z_DEFAULT_STRATEGY, NULL, 0, 0, 0,
|
1114
|
+
Z_DEFAULT_STRATEGY, NULL, 0, 0, 0,
|
1115
|
+
self->use_zip64);
|
853
1116
|
|
854
1117
|
if (error != ZIP_OK) {
|
855
1118
|
LXW_ERROR("Error adding member to zipfile");
|
@@ -881,15 +1144,47 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
881
1144
|
size_read = fread(self->buffer, 1, self->buffer_size, file);
|
882
1145
|
}
|
883
1146
|
|
1147
|
+
error = zipCloseFileInZip(self->zipfile);
|
1148
|
+
if (error != ZIP_OK) {
|
1149
|
+
LXW_ERROR("Error in closing member in the zipfile");
|
1150
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
return LXW_NO_ERROR;
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
STATIC lxw_error
|
1157
|
+
_add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
1158
|
+
size_t buffer_size, const char *filename)
|
1159
|
+
{
|
1160
|
+
int16_t error = ZIP_OK;
|
1161
|
+
|
1162
|
+
error = zipOpenNewFileInZip4_64(self->zipfile,
|
1163
|
+
filename,
|
1164
|
+
&self->zipfile_info,
|
1165
|
+
NULL, 0, NULL, 0, NULL,
|
1166
|
+
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
|
1167
|
+
-MAX_WBITS, DEF_MEM_LEVEL,
|
1168
|
+
Z_DEFAULT_STRATEGY, NULL, 0, 0, 0,
|
1169
|
+
self->use_zip64);
|
1170
|
+
|
1171
|
+
if (error != ZIP_OK) {
|
1172
|
+
LXW_ERROR("Error adding member to zipfile");
|
1173
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
error = zipWriteInFileInZip(self->zipfile,
|
1177
|
+
buffer, (unsigned int) buffer_size);
|
1178
|
+
|
884
1179
|
if (error < 0) {
|
1180
|
+
LXW_ERROR("Error in writing member in the zipfile");
|
885
1181
|
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
886
1182
|
}
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
}
|
1183
|
+
|
1184
|
+
error = zipCloseFileInZip(self->zipfile);
|
1185
|
+
if (error != ZIP_OK) {
|
1186
|
+
LXW_ERROR("Error in closing member in the zipfile");
|
1187
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
893
1188
|
}
|
894
1189
|
|
895
1190
|
return LXW_NO_ERROR;
|
@@ -904,9 +1199,21 @@ lxw_create_package(lxw_packager *self)
|
|
904
1199
|
lxw_error error;
|
905
1200
|
int8_t zip_error;
|
906
1201
|
|
1202
|
+
error = _write_content_types_file(self);
|
1203
|
+
RETURN_ON_ERROR(error);
|
1204
|
+
|
1205
|
+
error = _write_root_rels_file(self);
|
1206
|
+
RETURN_ON_ERROR(error);
|
1207
|
+
|
1208
|
+
error = _write_workbook_rels_file(self);
|
1209
|
+
RETURN_ON_ERROR(error);
|
1210
|
+
|
907
1211
|
error = _write_worksheet_files(self);
|
908
1212
|
RETURN_ON_ERROR(error);
|
909
1213
|
|
1214
|
+
error = _write_chartsheet_files(self);
|
1215
|
+
RETURN_ON_ERROR(error);
|
1216
|
+
|
910
1217
|
error = _write_workbook_file(self);
|
911
1218
|
RETURN_ON_ERROR(error);
|
912
1219
|
|
@@ -919,12 +1226,6 @@ lxw_create_package(lxw_packager *self)
|
|
919
1226
|
error = _write_shared_strings_file(self);
|
920
1227
|
RETURN_ON_ERROR(error);
|
921
1228
|
|
922
|
-
error = _write_app_file(self);
|
923
|
-
RETURN_ON_ERROR(error);
|
924
|
-
|
925
|
-
error = _write_core_file(self);
|
926
|
-
RETURN_ON_ERROR(error);
|
927
|
-
|
928
1229
|
error = _write_custom_file(self);
|
929
1230
|
RETURN_ON_ERROR(error);
|
930
1231
|
|
@@ -934,13 +1235,10 @@ lxw_create_package(lxw_packager *self)
|
|
934
1235
|
error = _write_styles_file(self);
|
935
1236
|
RETURN_ON_ERROR(error);
|
936
1237
|
|
937
|
-
error =
|
938
|
-
RETURN_ON_ERROR(error);
|
939
|
-
|
940
|
-
error = _write_workbook_rels_file(self);
|
1238
|
+
error = _write_worksheet_rels_file(self);
|
941
1239
|
RETURN_ON_ERROR(error);
|
942
1240
|
|
943
|
-
error =
|
1241
|
+
error = _write_chartsheet_rels_file(self);
|
944
1242
|
RETURN_ON_ERROR(error);
|
945
1243
|
|
946
1244
|
error = _write_drawing_rels_file(self);
|
@@ -949,7 +1247,13 @@ lxw_create_package(lxw_packager *self)
|
|
949
1247
|
error = _write_image_files(self);
|
950
1248
|
RETURN_ON_ERROR(error);
|
951
1249
|
|
952
|
-
error =
|
1250
|
+
error = _add_vba_project(self);
|
1251
|
+
RETURN_ON_ERROR(error);
|
1252
|
+
|
1253
|
+
error = _write_core_file(self);
|
1254
|
+
RETURN_ON_ERROR(error);
|
1255
|
+
|
1256
|
+
error = _write_app_file(self);
|
953
1257
|
RETURN_ON_ERROR(error);
|
954
1258
|
|
955
1259
|
zip_error = zipClose(self->zipfile, NULL);
|