xlsxwriter 0.2.0 → 0.2.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|