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 +4 -4
- data/ext/xlsxwriter/chart.c +171 -45
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +19 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +1 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +12 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +8 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +132 -37
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +30 -4
- data/ext/xlsxwriter/libxlsxwriter/src/Makefile +2 -2
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +0 -2
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +12 -12
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +73 -23
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +9 -4
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +117 -14
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +31 -6
- data/ext/xlsxwriter/workbook.c +52 -8
- data/ext/xlsxwriter/worksheet.c +68 -0
- data/lib/xlsxwriter/version.rb +1 -1
- data/test/support/chart_test.rb +17 -0
- data/test/test-chart-area.rb +41 -7
- data/test/test-chart-axis.rb +427 -55
- data/test/test-chart-bar.rb +48 -10
- data/test/test-image.rb +15 -0
- data/test/test-macro.rb +20 -0
- data/test/xlsx-func-testcase.rb +2 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz: '
|
3
|
+
metadata.gz: 258446b7479b3f3677923a46fe56f3206d313a81776e797bf4232e08bbaa1926
|
4
|
+
data.tar.gz: '029fd9139e2047cbbd7e248f324c517c09383fa332f02edd83dabaf75c328886'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 356595ae4d443af888c87a9402727dae8438db5ee666fe75887762a3140d905e9473d7e9c63967c6cd94c92c7cc643696d9a044658691d8164c0464ed9b50a32
|
7
|
+
data.tar.gz: 96d899fd65b2b01a7ffb64f38749b71baa849786fc7a5cd61fecbafbae245aa2b7aff3d5e9b852694ad70a1bb399517a1ba8611b12ab52b8f5c8a33998f850f1
|
data/ext/xlsxwriter/chart.c
CHANGED
@@ -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
|
-
/*
|
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
|
-
|
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
|
-
/*
|
260
|
-
|
261
|
-
|
262
|
-
|
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
|
-
|
266
|
-
|
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
|
-
/*
|
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
|
-
|
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
|
-
|
315
|
-
|
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
|
-
/*
|
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
|
-
|
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
|
}
|
@@ -68,13 +68,22 @@ typedef enum lxw_error {
|
|
68
68
|
/** Error reading a tmpfile. */
|
69
69
|
LXW_ERROR_READING_TMPFILE,
|
70
70
|
|
71
|
-
/**
|
71
|
+
/** Zip generic error ZIP_ERRNO while creating the xlsx file. */
|
72
72
|
LXW_ERROR_ZIP_FILE_OPERATION,
|
73
73
|
|
74
|
-
/**
|
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
|
-
/**
|
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
|
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
|
|
@@ -32,11 +32,17 @@
|
|
32
32
|
|
33
33
|
#define LXW_ZIP_BUFFER_SIZE (16384)
|
34
34
|
|
35
|
-
/* If
|
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 ==
|
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`:
|
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
|
-
*
|
210
|
-
*
|
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 =
|
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`:
|
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
|
-
*
|
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
|
-
*
|
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
|
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
|
-
*
|
385
|
-
*
|
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
|
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
|
-
*
|
421
|
-
*
|
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
|
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);
|