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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.gitignore +3 -0
  4. data/.travis.yml +18 -6
  5. data/CHANGELOG.md +14 -1
  6. data/Dockerfile.test +16 -0
  7. data/Gemfile +1 -1
  8. data/Gemfile.lock +21 -21
  9. data/Makefile +13 -2
  10. data/README.md +148 -38
  11. data/Rakefile +2 -0
  12. data/examples/example.rb +3 -3
  13. data/examples/example_filters.rb +36 -0
  14. data/examples/example_formula.rb +1 -3
  15. data/examples/example_hyperlink.rb +20 -0
  16. data/fast_excel.gemspec +1 -1
  17. data/lib/fast_excel.rb +36 -12
  18. data/lib/fast_excel/binding.rb +31 -21
  19. data/lib/fast_excel/binding/chart.rb +20 -1
  20. data/lib/fast_excel/binding/workbook.rb +10 -2
  21. data/lib/fast_excel/binding/worksheet.rb +44 -27
  22. data/libxlsxwriter/.gitignore +1 -0
  23. data/libxlsxwriter/.indent.pro +5 -0
  24. data/libxlsxwriter/CMakeLists.txt +1 -11
  25. data/libxlsxwriter/CONTRIBUTING.md +1 -1
  26. data/libxlsxwriter/Changes.txt +84 -0
  27. data/libxlsxwriter/LICENSE.txt +1 -1
  28. data/libxlsxwriter/Makefile +7 -5
  29. data/libxlsxwriter/Readme.md +1 -1
  30. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +1 -0
  31. data/libxlsxwriter/include/xlsxwriter.h +2 -2
  32. data/libxlsxwriter/include/xlsxwriter/app.h +2 -2
  33. data/libxlsxwriter/include/xlsxwriter/chart.h +56 -6
  34. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
  35. data/libxlsxwriter/include/xlsxwriter/common.h +27 -6
  36. data/libxlsxwriter/include/xlsxwriter/content_types.h +5 -2
  37. data/libxlsxwriter/include/xlsxwriter/core.h +2 -2
  38. data/libxlsxwriter/include/xlsxwriter/custom.h +2 -2
  39. data/libxlsxwriter/include/xlsxwriter/drawing.h +3 -2
  40. data/libxlsxwriter/include/xlsxwriter/format.h +3 -3
  41. data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  42. data/libxlsxwriter/include/xlsxwriter/packager.h +13 -8
  43. data/libxlsxwriter/include/xlsxwriter/relationships.h +2 -2
  44. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +5 -3
  45. data/libxlsxwriter/include/xlsxwriter/styles.h +9 -4
  46. data/libxlsxwriter/include/xlsxwriter/theme.h +2 -2
  47. data/libxlsxwriter/include/xlsxwriter/utility.h +26 -2
  48. data/libxlsxwriter/include/xlsxwriter/workbook.h +232 -55
  49. data/libxlsxwriter/include/xlsxwriter/worksheet.h +264 -53
  50. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +3 -1
  51. data/libxlsxwriter/libxlsxwriter.podspec +1 -1
  52. data/libxlsxwriter/src/Makefile +3 -3
  53. data/libxlsxwriter/src/app.c +2 -2
  54. data/libxlsxwriter/src/chart.c +41 -5
  55. data/libxlsxwriter/src/chartsheet.c +508 -0
  56. data/libxlsxwriter/src/content_types.c +12 -4
  57. data/libxlsxwriter/src/core.c +2 -2
  58. data/libxlsxwriter/src/custom.c +2 -2
  59. data/libxlsxwriter/src/drawing.c +114 -17
  60. data/libxlsxwriter/src/format.c +3 -3
  61. data/libxlsxwriter/src/hash_table.c +1 -1
  62. data/libxlsxwriter/src/packager.c +369 -65
  63. data/libxlsxwriter/src/relationships.c +2 -2
  64. data/libxlsxwriter/src/shared_strings.c +18 -4
  65. data/libxlsxwriter/src/styles.c +56 -9
  66. data/libxlsxwriter/src/theme.c +2 -2
  67. data/libxlsxwriter/src/utility.c +53 -6
  68. data/libxlsxwriter/src/workbook.c +372 -56
  69. data/libxlsxwriter/src/worksheet.c +425 -76
  70. data/libxlsxwriter/src/xmlwriter.c +17 -8
  71. data/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
  72. data/libxlsxwriter/third_party/minizip/zip.c +2 -0
  73. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
  74. data/libxlsxwriter/version.txt +1 -1
  75. data/test/tmpfile_test.rb +1 -0
  76. data/test/validations_test.rb +26 -6
  77. data/test/worksheet_test.rb +43 -0
  78. metadata +9 -6
  79. data/libxlsxwriter/.drone.yml +0 -27
  80. data/libxlsxwriter/appveyor.yml +0 -65
  81. 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-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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
  */
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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, uint16_t index,
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, uint16_t index,
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, uint16_t index)
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, uint16_t index)
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, uint16_t index,
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
- lxw_xml_empty_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
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, uint16_t index)
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, uint16_t index)
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, uint16_t index)
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, uint16_t index)
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, uint16_t index)
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, uint16_t index,
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
- uint16_t index;
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");
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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 || 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-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
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
- uint16_t index = 1;
174
+ uint32_t index = 1;
170
175
  lxw_error err;
171
176
 
172
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
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
- uint16_t index = 1;
255
+ uint32_t index = 1;
208
256
 
209
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
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
- /* Check that the image file exists and can be opened. */
220
- image_stream = fopen(image->filename, "rb");
221
- if (!image_stream) {
222
- LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
223
- "doesn't exist or can't be opened: %s.",
224
- image->filename);
225
- return LXW_ERROR_CREATING_TMPFILE;
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
- uint16_t index = 1;
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
- uint16_t index = 1;
386
+ uint32_t index = 1;
283
387
  lxw_error err;
284
388
 
285
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
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
- uint16_t named_range_count = 0;
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
- lxw_snprintf(number, LXW_ATTR_32, "%d", self->workbook->num_sheets);
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
- lxw_app_add_heading_pair(app, "Worksheets", number);
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(worksheet, workbook->worksheets, list_pointers) {
369
- lxw_app_add_part_name(app, worksheet->name);
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
- lxw_worksheet *worksheet;
725
+ lxw_sheet *sheet;
572
726
  char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
573
- uint16_t index = 1;
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
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
597
- lxw_snprintf(filename, LXW_FILENAME_LENGTH,
598
- "/xl/worksheets/sheet%d.xml", index++);
599
- lxw_ct_add_worksheet_name(content_types, filename);
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 <= self->chart_count; 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 <= self->drawing_count; 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
- lxw_worksheet *worksheet;
816
+ lxw_sheet *sheet;
641
817
  char sheetname[LXW_FILENAME_LENGTH] = { 0 };
642
- uint16_t index = 1;
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(worksheet, workbook->worksheets, list_pointers) {
657
- lxw_snprintf(sheetname, LXW_FILENAME_LENGTH, "worksheets/sheet%d.xml",
658
- index++);
659
- lxw_add_document_relationship(rels, "/worksheet", sheetname);
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
- uint16_t index = 0;
884
+ uint32_t index = 0;
694
885
  lxw_error err;
695
886
 
696
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
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
- uint16_t index = 1;
1008
+ uint32_t index = 1;
751
1009
  lxw_error err;
752
1010
 
753
- STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
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, 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
- else {
888
- error = zipCloseFileInZip(self->zipfile);
889
- if (error != ZIP_OK) {
890
- LXW_ERROR("Error in closing member in the zipfile");
891
- RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
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 = _write_content_types_file(self);
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 = _write_worksheet_rels_file(self);
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 = _write_root_rels_file(self);
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);