xlsxwriter 0.2.0 → 0.2.1.pre

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5952e238ec4dc55988d50bacd80e39132daca19f62ad8c6191705b240ad40cf1
4
- data.tar.gz: '05824be3c90e0ebbf3a44df01034b3d300191ea8712cb7e4d24643aa68b0beef'
3
+ metadata.gz: 258446b7479b3f3677923a46fe56f3206d313a81776e797bf4232e08bbaa1926
4
+ data.tar.gz: '029fd9139e2047cbbd7e248f324c517c09383fa332f02edd83dabaf75c328886'
5
5
  SHA512:
6
- metadata.gz: b3733fc664a8e74657d194268b3b653a28bb886078fe92a35cdbcfefc1665d47add6117b35598726db1159caca7b983db0358f6e0c28be27a2a6d503b06fea81
7
- data.tar.gz: 630f607d92e91c348b0a126f121242fcafd81bece774f642363b272c721c5d10d4a12ac8213290c7fbef1b8b4519f745c7ee6b5c364cc19a84fe26af256f8411
6
+ metadata.gz: 356595ae4d443af888c87a9402727dae8438db5ee666fe75887762a3140d905e9473d7e9c63967c6cd94c92c7cc643696d9a044658691d8164c0464ed9b50a32
7
+ data.tar.gz: 96d899fd65b2b01a7ffb64f38749b71baa849786fc7a5cd61fecbafbae245aa2b7aff3d5e9b852694ad70a1bb399517a1ba8611b12ab52b8f5c8a33998f850f1
@@ -7,6 +7,13 @@ VALUE cChart;
7
7
  VALUE cChartSeries;
8
8
  VALUE cChartAxis;
9
9
 
10
+ #define DEF_PROP_SETTER(type, field, value, ptr_field) VALUE type ## _set_ ## field ## _ (VALUE self, VALUE val) { \
11
+ struct type *ptr; \
12
+ Data_Get_Struct(self, struct type, ptr); \
13
+ type ## _set_ ## field (ptr->ptr_field, value); \
14
+ return val; \
15
+ }
16
+
10
17
 
11
18
  VALUE
12
19
  chart_alloc(VALUE klass) {
@@ -233,38 +240,24 @@ chart_legend_delete_series_(VALUE self, VALUE series) {
233
240
  return self;
234
241
  }
235
242
 
236
- /* call-seq: chart.style=(style) -> style
243
+ /* Document-method: XlsxWriter::Workbook::Chart#style=
244
+ *
245
+ * call-seq: chart.style=(style) -> style
237
246
  *
238
247
  * Sets the chart +style+ (integer from 1 to 48, default is 2).
239
248
  */
240
- VALUE
241
- chart_set_style_(VALUE self, VALUE style) {
242
- struct chart *ptr;
243
- Data_Get_Struct(self, struct chart, ptr);
244
-
245
- chart_set_style(ptr->chart, NUM2INT(rb_check_to_int(style)));
246
- return style;
247
- }
248
-
249
- /* :nodoc: */
250
- VALUE
251
- chart_set_rotation_(VALUE self, VALUE rotation) {
252
- struct chart *ptr;
253
- Data_Get_Struct(self, struct chart, ptr);
249
+ DEF_PROP_SETTER(chart, style, NUM2INT(rb_check_to_int(val)), chart)
254
250
 
255
- chart_set_rotation(ptr->chart, NUM2UINT(rb_check_to_int(rotation)));
256
- return rotation;
257
- }
258
251
 
259
- /* :nodoc: */
260
- VALUE
261
- chart_set_hole_size_(VALUE self, VALUE size) {
262
- struct chart *ptr;
263
- Data_Get_Struct(self, struct chart, ptr);
252
+ /* Document-method: XlsxWriter::Workbook::Chart#rotation=
253
+ *
254
+ */
255
+ DEF_PROP_SETTER(chart, rotation, NUM2UINT(rb_check_to_int(val)), chart)
264
256
 
265
- chart_set_hole_size(ptr->chart, NUM2UINT(rb_check_to_int(size)));
266
- return size;
267
- }
257
+ /* Document-method: XlsxWriter::Workbook::Chart#hole_size=
258
+ *
259
+ */
260
+ DEF_PROP_SETTER(chart, hole_size, NUM2UINT(rb_check_to_int(val)), chart)
268
261
 
269
262
 
270
263
  /* :nodoc: */
@@ -302,18 +295,79 @@ chart_set_axis_id_2_(VALUE self, VALUE val) {
302
295
  }
303
296
 
304
297
 
305
- /* call-seq: axis.name=(name) -> name
298
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#name=
299
+ *
300
+ * call-seq: axis.name=(name) -> name
306
301
  *
307
302
  * Sets the chart axis +name+.
308
303
  */
309
- VALUE
310
- chart_axis_set_name_(VALUE self, VALUE val) {
311
- struct chart_axis *ptr;
312
- Data_Get_Struct(self, struct chart_axis, ptr);
304
+ DEF_PROP_SETTER(chart_axis, name, StringValueCStr(val), axis)
313
305
 
314
- chart_axis_set_name(ptr->axis, StringValueCStr(val));
315
- return val;
316
- }
306
+ /* Document-method XlsxWriter::Workbook::Chart::Axis#interval_unit=
307
+ *
308
+ */
309
+ DEF_PROP_SETTER(chart_axis, interval_unit, NUM2UINT(rb_check_to_int(val)), axis)
310
+
311
+ /* Document-method XlsxWriter::Workbook::Chart::Axis#interval_tick=
312
+ *
313
+ */
314
+ DEF_PROP_SETTER(chart_axis, interval_tick, NUM2UINT(rb_check_to_int(val)), axis)
315
+
316
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#max=
317
+ *
318
+ * call-seq: axis.max=(value) -> value
319
+ *
320
+ * Sets the chart axis +max+ value.
321
+ */
322
+ DEF_PROP_SETTER(chart_axis, max, NUM2DBL(rb_check_to_float(val)), axis)
323
+
324
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#min=
325
+ *
326
+ * call-seq: axis.min=(value) -> value
327
+ *
328
+ * Sets the chart axis +min+ value.
329
+ */
330
+ DEF_PROP_SETTER(chart_axis, min, NUM2DBL(rb_check_to_float(val)), axis)
331
+
332
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#major_tick_mark=
333
+ *
334
+ */
335
+ DEF_PROP_SETTER(chart_axis, major_tick_mark, NUM2UINT(rb_check_to_int(val)), axis)
336
+
337
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#minor_tick_mark=
338
+ *
339
+ */
340
+ DEF_PROP_SETTER(chart_axis, minor_tick_mark, NUM2UINT(rb_check_to_int(val)), axis)
341
+
342
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#major_unit=
343
+ *
344
+ */
345
+ DEF_PROP_SETTER(chart_axis, major_unit, NUM2DBL(rb_check_to_float(val)), axis)
346
+
347
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#minor_unit=
348
+ *
349
+ */
350
+ DEF_PROP_SETTER(chart_axis, minor_unit, NUM2DBL(rb_check_to_float(val)), axis)
351
+
352
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#label_align=
353
+ *
354
+ */
355
+ DEF_PROP_SETTER(chart_axis, label_align, NUM2UINT(rb_check_to_int(val)), axis)
356
+
357
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#label_position=
358
+ *
359
+ */
360
+ DEF_PROP_SETTER(chart_axis, label_position, NUM2DBL(rb_check_to_float(val)), axis)
361
+
362
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#log_base=
363
+ *
364
+ */
365
+ DEF_PROP_SETTER(chart_axis, log_base, NUM2DBL(rb_check_to_float(val)), axis)
366
+
367
+ /* Document-method: XlsxWriter::Workbook::Chart::Axis#num_format=
368
+ *
369
+ */
370
+ DEF_PROP_SETTER(chart_axis, num_format, StringValueCStr(val), axis)
317
371
 
318
372
  /* call-seq:
319
373
  * axis.set_name_range(name, cell) -> self
@@ -392,6 +446,38 @@ chart_axis_set_fill_(VALUE self, VALUE opts) {
392
446
  return self;
393
447
  }
394
448
 
449
+ /* Document-method XlsxWriter::Workbook::Chart::Axis#position=
450
+ *
451
+ */
452
+ DEF_PROP_SETTER(chart_axis, position, NUM2UINT(rb_check_to_int(val)), axis)
453
+
454
+ /* call-seq: axis.reverse = true
455
+ *
456
+ * Interpret axis values/categories in reverse order.
457
+ */
458
+ VALUE
459
+ chart_axis_set_reverse_(VALUE self, VALUE p) {
460
+ struct chart_axis *ptr;
461
+ if (RTEST(p)) {
462
+ Data_Get_Struct(self, struct chart_axis, ptr);
463
+
464
+ chart_axis_set_reverse(ptr->axis);
465
+ }
466
+ return p;
467
+ }
468
+
469
+ VALUE
470
+ chart_axis_set_source_linked_(VALUE self, VALUE val) {
471
+ struct chart_axis *ptr;
472
+
473
+ Data_Get_Struct(self, struct chart_axis, ptr);
474
+
475
+ ptr->axis->source_linked = NUM2UINT(rb_check_to_int(val));
476
+
477
+ return val;
478
+ }
479
+
480
+
395
481
  /* call-seq:
396
482
  * series.set_categories(sheetname, range)
397
483
  * series.set_categories(sheetname, cell_from, cell_to)
@@ -433,18 +519,13 @@ chart_series_set_values_(int argc, VALUE *argv, VALUE self) {
433
519
  return self;
434
520
  }
435
521
 
436
- /* call-seq: series.name=(name) -> name
522
+ /* Document-method: XlsxWriter::Workbook::Chart::Series#name=
523
+ *
524
+ * call-seq: series.name=(name) -> name
437
525
  *
438
526
  * Set chart series name.
439
527
  */
440
- VALUE
441
- chart_series_set_name_(VALUE self, VALUE name) {
442
- struct chart_series *ptr;
443
- Data_Get_Struct(self, struct chart_series, ptr);
444
-
445
- chart_series_set_name(ptr->series, StringValueCStr(name));
446
- return name;
447
- }
528
+ DEF_PROP_SETTER(chart_series, name, StringValueCStr(val), series)
448
529
 
449
530
  /* call-seq:
450
531
  * series.set_name_range(name, cell) -> self
@@ -465,6 +546,17 @@ chart_series_set_name_range_(int argc, VALUE *argv, VALUE self) {
465
546
  return self;
466
547
  }
467
548
 
549
+ VALUE
550
+ chart_series_set_invert_if_negative_(VALUE self, VALUE p) {
551
+ struct chart_series *ptr;
552
+ if (RTEST(p)) {
553
+ Data_Get_Struct(self, struct chart_series, ptr);
554
+
555
+ chart_series_set_invert_if_negative(ptr->series);
556
+ }
557
+ return p;
558
+ }
559
+
468
560
 
469
561
  #define SET_PROP(prop, vres) { \
470
562
  val = rb_hash_aref(opts, ID2SYM(rb_intern(#prop))); \
@@ -552,11 +644,26 @@ void init_xlsxwriter_chart() {
552
644
  rb_define_method(cChartAxis, "initialize", chart_axis_init, 2);
553
645
 
554
646
  rb_define_method(cChartAxis, "name=", chart_axis_set_name_, 1);
647
+ rb_define_method(cChartAxis, "interval_unit=", chart_axis_set_interval_unit_, 1);
648
+ rb_define_method(cChartAxis, "interval_tick=", chart_axis_set_interval_tick_, 1);
649
+ rb_define_method(cChartAxis, "max=", chart_axis_set_max_, 1);
650
+ rb_define_method(cChartAxis, "min=", chart_axis_set_min_, 1);
651
+ rb_define_method(cChartAxis, "major_tick_mark=", chart_axis_set_major_tick_mark_, 1);
652
+ rb_define_method(cChartAxis, "minor_tick_mark=", chart_axis_set_minor_tick_mark_, 1);
653
+ rb_define_method(cChartAxis, "major_unit=", chart_axis_set_major_unit_, 1);
654
+ rb_define_method(cChartAxis, "minor_unit=", chart_axis_set_minor_unit_, 1);
655
+ rb_define_method(cChartAxis, "label_align=", chart_axis_set_label_align_, 1);
656
+ rb_define_method(cChartAxis, "label_position=", chart_axis_set_label_position_, 1);
657
+ rb_define_method(cChartAxis, "log_base=", chart_axis_set_log_base_, 1);
658
+ rb_define_method(cChartAxis, "num_format=", chart_axis_set_num_format_, 1);
555
659
  rb_define_method(cChartAxis, "set_name_range", chart_axis_set_name_range_, -1);
556
660
  rb_define_method(cChartAxis, "set_name_font", chart_axis_set_name_font_, 1);
557
661
  rb_define_method(cChartAxis, "set_num_font", chart_axis_set_num_font_, 1);
558
662
  rb_define_method(cChartAxis, "set_line", chart_axis_set_line_, 1);
559
663
  rb_define_method(cChartAxis, "set_fill", chart_axis_set_fill_, 1);
664
+ rb_define_method(cChartAxis, "position=", chart_axis_set_position_, 1);
665
+ rb_define_method(cChartAxis, "reverse=", chart_axis_set_reverse_, 1);
666
+ rb_define_method(cChartAxis, "source_linked=", chart_axis_set_source_linked_, 1);
560
667
 
561
668
  rb_define_alloc_func(cChartSeries, chart_series_alloc);
562
669
  rb_define_method(cChartSeries, "initialize", chart_series_init, -1);
@@ -565,6 +672,7 @@ void init_xlsxwriter_chart() {
565
672
  rb_define_method(cChartSeries, "set_values", chart_series_set_values_, -1);
566
673
  rb_define_method(cChartSeries, "name=", chart_series_set_name_, 1);
567
674
  rb_define_method(cChartSeries, "set_name_range", chart_series_set_name_range_, -1);
675
+ rb_define_method(cChartSeries, "invert_if_negative=", chart_series_set_invert_if_negative_, 1);
568
676
 
569
677
  #define MAP_CHART_CONST(name) rb_define_const(cChart, #name, INT2NUM(LXW_CHART_##name))
570
678
  MAP_CHART_CONST(NONE);
@@ -602,7 +710,25 @@ void init_xlsxwriter_chart() {
602
710
  MAP_CHART_CONST(AXIS_LABEL_ALIGN_CENTER);
603
711
  MAP_CHART_CONST(AXIS_LABEL_ALIGN_LEFT);
604
712
  MAP_CHART_CONST(AXIS_LABEL_ALIGN_RIGHT);
605
-
606
-
607
713
  #undef MAP_CHART_CONST
714
+
715
+ #define MAP_CHART_AXIS_CONST(name) rb_define_const(cChartAxis, #name, INT2NUM(LXW_CHART_AXIS_##name))
716
+ MAP_CHART_AXIS_CONST(LABEL_ALIGN_CENTER);
717
+ MAP_CHART_AXIS_CONST(LABEL_ALIGN_LEFT);
718
+ MAP_CHART_AXIS_CONST(LABEL_ALIGN_RIGHT);
719
+
720
+ MAP_CHART_AXIS_CONST(LABEL_POSITION_NEXT_TO);
721
+ MAP_CHART_AXIS_CONST(LABEL_POSITION_HIGH);
722
+ MAP_CHART_AXIS_CONST(LABEL_POSITION_LOW);
723
+ MAP_CHART_AXIS_CONST(LABEL_POSITION_NONE);
724
+
725
+ MAP_CHART_AXIS_CONST(POSITION_BETWEEN);
726
+ MAP_CHART_AXIS_CONST(POSITION_ON_TICK);
727
+
728
+ MAP_CHART_AXIS_CONST(TICK_MARK_DEFAULT);
729
+ MAP_CHART_AXIS_CONST(TICK_MARK_NONE);
730
+ MAP_CHART_AXIS_CONST(TICK_MARK_INSIDE);
731
+ MAP_CHART_AXIS_CONST(TICK_MARK_OUTSIDE);
732
+ MAP_CHART_AXIS_CONST(TICK_MARK_CROSSING);
733
+ #undef MAP_CHART_AXIS_CONST
608
734
  }
@@ -18,6 +18,6 @@
18
18
  #include "xlsxwriter/format.h"
19
19
  #include "xlsxwriter/utility.h"
20
20
 
21
- #define LXW_VERSION "0.8.6"
21
+ #define LXW_VERSION "0.8.7"
22
22
 
23
23
  #endif /* __LXW_XLSXWRITER_H__ */
@@ -68,13 +68,22 @@ typedef enum lxw_error {
68
68
  /** Error reading a tmpfile. */
69
69
  LXW_ERROR_READING_TMPFILE,
70
70
 
71
- /** Zlib error with a file operation while creating xlsx file. */
71
+ /** Zip generic error ZIP_ERRNO while creating the xlsx file. */
72
72
  LXW_ERROR_ZIP_FILE_OPERATION,
73
73
 
74
- /** Zlib error when adding sub file to xlsx file. */
74
+ /** Zip error ZIP_PARAMERROR while creating the xlsx file. */
75
+ LXW_ERROR_ZIP_PARAMETER_ERROR,
76
+
77
+ /** Zip error ZIP_BADZIPFILE (use_zip64 option may be required). */
78
+ LXW_ERROR_ZIP_BAD_ZIP_FILE,
79
+
80
+ /** Zip error ZIP_INTERNALERROR while creating the xlsx file. */
81
+ LXW_ERROR_ZIP_INTERNAL_ERROR,
82
+
83
+ /** File error or unknown zip error when adding sub file to xlsx file. */
75
84
  LXW_ERROR_ZIP_FILE_ADD,
76
85
 
77
- /** Zlib error when closing xlsx file. */
86
+ /** Unknown zip error when closing xlsx file. */
78
87
  LXW_ERROR_ZIP_CLOSE,
79
88
 
80
89
  /** NULL function parameter ignored. */
@@ -86,12 +95,18 @@ typedef enum lxw_error {
86
95
  /** Worksheet name exceeds Excel's limit of 31 characters. */
87
96
  LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED,
88
97
 
89
- /** Worksheet name contains invalid Excel character: '[]:*?/\\' */
98
+ /** Worksheet name cannot contain invalid characters: '[ ] : * ? / \\' */
90
99
  LXW_ERROR_INVALID_SHEETNAME_CHARACTER,
91
100
 
101
+ /** Worksheet name cannot start or end with an apostrophe. */
102
+ LXW_ERROR_SHEETNAME_START_END_APOSTROPHE,
103
+
92
104
  /** Worksheet name is already in use. */
93
105
  LXW_ERROR_SHEETNAME_ALREADY_USED,
94
106
 
107
+ /** Worksheet name 'History' is reserved by Excel. */
108
+ LXW_ERROR_SHEETNAME_RESERVED,
109
+
95
110
  /** Parameter exceeds Excel's limit of 32 characters. */
96
111
  LXW_ERROR_32_STRING_LENGTH_EXCEEDED,
97
112
 
@@ -17,6 +17,7 @@
17
17
 
18
18
  #define LXW_APP_PACKAGE "application/vnd.openxmlformats-package."
19
19
  #define LXW_APP_DOCUMENT "application/vnd.openxmlformats-officedocument."
20
+ #define LXW_APP_MSEXCEL "application/vnd.ms-excel."
20
21
 
21
22
  /*
22
23
  * Struct to represent a content_types.
@@ -32,11 +32,17 @@
32
32
 
33
33
  #define LXW_ZIP_BUFFER_SIZE (16384)
34
34
 
35
- /* If zlib returns Z_ERRNO then errno is set and we can trap that. Otherwise
36
- * return a default libxlsxwriter error. */
35
+ /* If zip returns a ZIP_XXX error then errno is set and we can trap that in
36
+ * workbook.c. Otherwise return a default libxlsxwriter error. */
37
37
  #define RETURN_ON_ZIP_ERROR(err, default_err) \
38
- if (err == Z_ERRNO) \
38
+ if (err == ZIP_ERRNO) \
39
39
  return LXW_ERROR_ZIP_FILE_OPERATION; \
40
+ else if (err == ZIP_PARAMERROR) \
41
+ return LXW_ERROR_ZIP_PARAMETER_ERROR; \
42
+ else if (err == ZIP_BADZIPFILE) \
43
+ return LXW_ERROR_ZIP_BAD_ZIP_FILE; \
44
+ else if (err == ZIP_INTERNALERROR) \
45
+ return LXW_ERROR_ZIP_INTERNAL_ERROR; \
40
46
  else \
41
47
  return default_err;
42
48
 
@@ -54,6 +60,7 @@ typedef struct lxw_packager {
54
60
  char *filename;
55
61
  char *buffer;
56
62
  char *tmpdir;
63
+ uint8_t use_zip64;
57
64
 
58
65
  } lxw_packager;
59
66
 
@@ -64,7 +71,8 @@ extern "C" {
64
71
  #endif
65
72
  /* *INDENT-ON* */
66
73
 
67
- lxw_packager *lxw_packager_new(const char *filename, char *tmpdir);
74
+ lxw_packager *lxw_packager_new(const char *filename, char *tmpdir,
75
+ uint8_t use_zip64);
68
76
  void lxw_packager_free(lxw_packager *packager);
69
77
  lxw_error lxw_create_package(lxw_packager *self);
70
78
 
@@ -17,6 +17,7 @@
17
17
  #define __LXW_UTILITY_H__
18
18
 
19
19
  #include <stdint.h>
20
+ #include <strings.h>
20
21
  #include "common.h"
21
22
  #include "xmlwriter.h"
22
23
 
@@ -166,6 +167,13 @@ size_t lxw_utf8_strlen(const char *str);
166
167
 
167
168
  void lxw_str_tolower(char *str);
168
169
 
170
+ /* Define a portable version of strcasecmp(). */
171
+ #ifdef _MSC_VER
172
+ #define lxw_strcasecmp _stricmp
173
+ #else
174
+ #define lxw_strcasecmp strcasecmp
175
+ #endif
176
+
169
177
  FILE *lxw_tmpfile(char *tmpdir);
170
178
 
171
179
  /* Use a user defined function to format doubles in sprintf or else a simple
@@ -203,27 +203,40 @@ typedef struct lxw_doc_properties {
203
203
  *
204
204
  * The following properties are supported:
205
205
  *
206
- * - `constant_memory`: Reduces the amount of data stored in memory so that
207
- * large files can be written efficiently.
206
+ * - `constant_memory`: This option reduces the amount of data stored in
207
+ * memory so that large files can be written efficiently. This option is off
208
+ * by default. See the note below for limitations when this mode is on.
208
209
  *
209
- * @note In this mode a row of data is written and then discarded when a
210
- * cell in a new row is added via one of the `worksheet_write_*()`
211
- * functions. Therefore, once this option is active, data should be written in
212
- * sequential row order. For this reason the `worksheet_merge_range()`
213
- * doesn't work in this mode. See also @ref ww_mem_constant.
214
- *
215
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
216
- * to assembling the final XLSX file. The temporary files are created in the
210
+ * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior to
211
+ * assembling the final XLSX file. The temporary files are created in the
217
212
  * system's temp directory. If the default temporary directory isn't
218
213
  * accessible to your application, or doesn't contain enough space, you can
219
214
  * specify an alternative location using the `tmpdir` option.
215
+ *
216
+ * - `use_zip64`: Make the zip library use ZIP64 extensions when writing very
217
+ * large xlsx files to allow the zip container, or individual XML files
218
+ * within it, to be greater than 4 GB. See [ZIP64 on Wikipedia][zip64_wiki]
219
+ * for more information. This option is off by default.
220
+ *
221
+ * [zip64_wiki]: https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64
222
+ *
223
+ * @note In `constant_memory` mode a row of data is written and then discarded
224
+ * when a cell in a new row is added via one of the `worksheet_write_*()`
225
+ * functions. Therefore, once this option is active, data should be written in
226
+ * sequential row order. For this reason the `worksheet_merge_range()` doesn't
227
+ * work in this mode. See also @ref ww_mem_constant.
228
+ *
220
229
  */
221
230
  typedef struct lxw_workbook_options {
222
- /** Optimize the workbook to use constant memory for worksheets */
231
+ /** Optimize the workbook to use constant memory for worksheets. */
223
232
  uint8_t constant_memory;
224
233
 
225
234
  /** Directory to use for the temporary files created by libxlsxwriter. */
226
235
  char *tmpdir;
236
+
237
+ /** Allow ZIP64 extensions when creating the xlsx file zip container. */
238
+ uint8_t use_zip64;
239
+
227
240
  } lxw_workbook_options;
228
241
 
229
242
  /**
@@ -272,6 +285,9 @@ typedef struct lxw_workbook {
272
285
 
273
286
  lxw_hash_table *used_xf_formats;
274
287
 
288
+ char *vba_project;
289
+ char *vba_codename;
290
+
275
291
  } lxw_workbook;
276
292
 
277
293
 
@@ -313,30 +329,37 @@ lxw_workbook *workbook_new(const char *filename);
313
329
  * additional options to be set.
314
330
  *
315
331
  * @code
316
- * lxw_workbook_options options = {.constant_memory = 1,
317
- * .tmpdir = "C:\\Temp"};
332
+ * lxw_workbook_options options = {.constant_memory = LXW_TRUE,
333
+ * .tmpdir = "C:\\Temp",
334
+ * .use_zip64 = LXW_FALSE};
318
335
  *
319
336
  * lxw_workbook *workbook = workbook_new_opt("filename.xlsx", &options);
320
337
  * @endcode
321
338
  *
322
339
  * The options that can be set via #lxw_workbook_options are:
323
340
  *
324
- * - `constant_memory`: Reduces the amount of data stored in memory so that
325
- * large files can be written efficiently.
326
- *
327
- * @note In this mode a row of data is written and then discarded when a
328
- * cell in a new row is added via one of the `worksheet_write_*()`
329
- * functions. Therefore, once this option is active, data should be written in
330
- * sequential row order. For this reason the `worksheet_merge_range()`
331
- * doesn't work in this mode. See also @ref ww_mem_constant.
341
+ * - `constant_memory`: This option reduces the amount of data stored in
342
+ * memory so that large files can be written efficiently. This option is off
343
+ * by default. See the note below for limitations when this mode is on.
332
344
  *
333
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
334
- * to assembling the final XLSX file. The temporary files are created in the
345
+ * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior to
346
+ * assembling the final XLSX file. The temporary files are created in the
335
347
  * system's temp directory. If the default temporary directory isn't
336
348
  * accessible to your application, or doesn't contain enough space, you can
337
- * specify an alternative location using the `tmpdir` option.*
349
+ * specify an alternative location using the `tmpdir` option.
350
+ *
351
+ * - `use_zip64`: Make the zip library use ZIP64 extensions when writing very
352
+ * large xlsx files to allow the zip container, or individual XML files
353
+ * within it, to be greater than 4 GB. See [ZIP64 on Wikipedia][zip64_wiki]
354
+ * for more information. This option is off by default.
355
+ *
356
+ * [zip64_wiki]: https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64
338
357
  *
339
- * See @ref working_with_memory for more details.
358
+ * @note In `constant_memory` mode a row of data is written and then discarded
359
+ * when a cell in a new row is added via one of the `worksheet_write_*()`
360
+ * functions. Therefore, once this option is active, data should be written in
361
+ * sequential row order. For this reason the `worksheet_merge_range()` doesn't
362
+ * work in this mode. See also @ref ww_mem_constant.
340
363
  *
341
364
  */
342
365
  lxw_workbook *workbook_new_opt(const char *filename,
@@ -376,14 +399,17 @@ lxw_workbook *new_workbook_opt(const char *filename,
376
399
  *
377
400
  * @image html workbook02.png
378
401
  *
379
- * The worksheet name must be a valid Excel worksheet name, i.e. it must be
380
- * less than 32 character and it cannot contain any of the characters:
402
+ * The worksheet name must be a valid Excel worksheet name, i.e:
381
403
  *
382
- * / \ [ ] : * ?
383
- *
384
- * In addition, you cannot use the same, case insensitive, `sheetname` for more
385
- * than one worksheet, or chartsheet.
404
+ * - The name is less than or equal to 31 UTF-8 characters.
405
+ * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
406
+ * - The name doesn't start or end with an apostrophe.
407
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
408
+ * - The name isn't already in use. (Case insensitive).
386
409
  *
410
+ * If any of these errors are encountered the function will return NULL.
411
+ * You can check for valid name using the `workbook_validate_sheet_name()`
412
+ * function.
387
413
  */
388
414
  lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
389
415
  const char *sheetname);
@@ -412,13 +438,17 @@ lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
412
438
  *
413
439
  * @endcode
414
440
  *
415
- * The chartsheet name must be a valid Excel worksheet name, i.e. it must be
416
- * less than 32 character and it cannot contain any of the characters:
441
+ * The chartsheet name must be a valid Excel worksheet name, i.e.:
417
442
  *
418
- * / \ [ ] : * ?
443
+ * - The name is less than or equal to 31 UTF-8 characters.
444
+ * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
445
+ * - The name doesn't start or end with an apostrophe.
446
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
447
+ * - The name isn't already in use. (Case insensitive).
419
448
  *
420
- * In addition, you cannot use the same, case insensitive, `sheetname` for more
421
- * than one chartsheet, or worksheet.
449
+ * If any of these errors are encountered the function will return NULL.
450
+ * You can check for valid name using the `workbook_validate_sheet_name()`
451
+ * function.
422
452
  *
423
453
  * At least one worksheet should be added to a new workbook when creating a
424
454
  * chartsheet in order to provide data for the chart. The @ref worksheet.h
@@ -797,7 +827,9 @@ lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
797
827
  *
798
828
  * - The name is less than or equal to 31 UTF-8 characters.
799
829
  * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
800
- * - The name isn't already in use.
830
+ * - The name doesn't start or end with an apostrophe.
831
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
832
+ * - The name isn't already in use. (Case insensitive, see the note below).
801
833
  *
802
834
  * @code
803
835
  * lxw_error err = workbook_validate_sheet_name(workbook, "Foglio");
@@ -807,10 +839,73 @@ lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
807
839
  * `workbook_add_chartsheet()` but it can be explicitly called by the user
808
840
  * beforehand to ensure that the sheet name is valid.
809
841
  *
842
+ * @note This function does an ASCII lowercase string comparison to determine
843
+ * if the sheet name is already in use. It doesn't take UTF-8 characters into
844
+ * account. Thus it would flag "Café" and "café" as a duplicate (just like
845
+ * Excel) but it wouldn't catch "CAFÉ". If you need a full UTF-8 case
846
+ * insensitive check you should use a third party library to implement it.
847
+ *
810
848
  */
811
849
  lxw_error workbook_validate_sheet_name(lxw_workbook *workbook,
812
850
  const char *sheetname);
813
851
 
852
+ /**
853
+ * @brief Add a vbaProject binary to the Excel workbook.
854
+ *
855
+ * @param workbook Pointer to a lxw_workbook instance.
856
+ * @param filename The path/filename of the vbaProject.bin file.
857
+ *
858
+ * The `%workbook_add_vba_project()` function can be used to add macros or
859
+ * functions to a workbook using a binary VBA project file that has been
860
+ * extracted from an existing Excel xlsm file:
861
+ *
862
+ * @code
863
+ * workbook_add_vba_project(workbook, "vbaProject.bin");
864
+ * @endcode
865
+ *
866
+ * Only one `vbaProject.bin file` can be added per workbook. The name doesn't
867
+ * have to be `vbaProject.bin`. Any suitable path/name for an existing VBA bin
868
+ * file will do.
869
+ *
870
+ * Once you add a VBA project had been add to an libxlsxwriter workbook you
871
+ * should ensure that the file extension is `.xlsm` to prevent Excel from
872
+ * giving a warning when it opens the file:
873
+ *
874
+ * @code
875
+ * lxw_workbook *workbook = new_workbook("macro.xlsm");
876
+ * @endcode
877
+ *
878
+ * See also @ref working_with_macros
879
+ *
880
+ * @return A #lxw_error.
881
+ */
882
+ lxw_error workbook_add_vba_project(lxw_workbook *workbook,
883
+ const char *filename);
884
+
885
+ /**
886
+ * @brief Set the VBA name for the workbook.
887
+ *
888
+ * @param workbook Pointer to a lxw_workbook instance.
889
+ * @param name Name of the workbook used by VBA.
890
+ *
891
+ * The `workbook_set_vba_name()` function can be used to set the VBA name for
892
+ * the workbook. This is sometimes required when a vbaProject macro included
893
+ * via `workbook_add_vba_project()` refers to the workbook by a name other
894
+ * than `ThisWorkbook`.
895
+ *
896
+ * @code
897
+ * workbook_set_vba_name(workbook, "MyWorkbook");
898
+ * @endcode
899
+ *
900
+ * If an Excel VBA name for the workbook isn't specified then libxlsxwriter
901
+ * will use `ThisWorkbook`.
902
+ *
903
+ * See also @ref working_with_macros
904
+ *
905
+ * @return A #lxw_error.
906
+ */
907
+ lxw_error workbook_set_vba_name(lxw_workbook *workbook, const char *name);
908
+
814
909
  void lxw_workbook_free(lxw_workbook *workbook);
815
910
  void lxw_workbook_assemble_xml_file(lxw_workbook *workbook);
816
911
  void lxw_workbook_set_default_xf_indices(lxw_workbook *workbook);