xlsxwriter 0.0.5 → 0.0.6
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/libxlsxwriter/include/xlsxwriter.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +55 -5
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +6 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +1 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +3 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +7 -2
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +16 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +122 -24
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +236 -48
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/src/chart.c +40 -4
- data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +508 -0
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +100 -3
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +252 -30
- data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +16 -2
- data/ext/xlsxwriter/libxlsxwriter/src/styles.c +54 -7
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +43 -1
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +254 -41
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +381 -65
- data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +16 -7
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
- data/ext/xlsxwriter/workbook.c +9 -6
- data/lib/xlsxwriter/version.rb +1 -1
- metadata +5 -4
@@ -296,6 +296,16 @@ lxw_ct_add_worksheet_name(lxw_content_types *self, const char *name)
|
|
296
296
|
LXW_APP_DOCUMENT "spreadsheetml.worksheet+xml");
|
297
297
|
}
|
298
298
|
|
299
|
+
/*
|
300
|
+
* Add the name of a chartsheet to the ContentTypes overrides.
|
301
|
+
*/
|
302
|
+
void
|
303
|
+
lxw_ct_add_chartsheet_name(lxw_content_types *self, const char *name)
|
304
|
+
{
|
305
|
+
lxw_ct_add_override(self, name,
|
306
|
+
LXW_APP_DOCUMENT "spreadsheetml.chartsheet+xml");
|
307
|
+
}
|
308
|
+
|
299
309
|
/*
|
300
310
|
* Add the name of a chart to the ContentTypes overrides.
|
301
311
|
*/
|
@@ -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);
|
@@ -489,13 +489,40 @@ _drawing_write_client_data(lxw_drawing *self)
|
|
489
489
|
lxw_xml_empty_tag(self->file, "xdr:clientData", NULL);
|
490
490
|
}
|
491
491
|
|
492
|
+
/*
|
493
|
+
* Write the <a:graphicFrameLocks> element.
|
494
|
+
*/
|
495
|
+
STATIC void
|
496
|
+
_drawing_write_a_graphic_frame_locks(lxw_drawing *self)
|
497
|
+
{
|
498
|
+
struct xml_attribute_list attributes;
|
499
|
+
struct xml_attribute *attribute;
|
500
|
+
|
501
|
+
LXW_INIT_ATTRIBUTES();
|
502
|
+
LXW_PUSH_ATTRIBUTES_INT("noGrp", 1);
|
503
|
+
|
504
|
+
lxw_xml_empty_tag(self->file, "a:graphicFrameLocks", &attributes);
|
505
|
+
|
506
|
+
LXW_FREE_ATTRIBUTES();
|
507
|
+
}
|
508
|
+
|
492
509
|
/*
|
493
510
|
* Write the <xdr:cNvGraphicFramePr> element.
|
494
511
|
*/
|
495
512
|
STATIC void
|
496
513
|
_drawing_write_c_nv_graphic_frame_pr(lxw_drawing *self)
|
497
514
|
{
|
498
|
-
|
515
|
+
if (self->embedded) {
|
516
|
+
lxw_xml_empty_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
|
517
|
+
}
|
518
|
+
else {
|
519
|
+
lxw_xml_start_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
|
520
|
+
|
521
|
+
/* Write the a:graphicFrameLocks element. */
|
522
|
+
_drawing_write_a_graphic_frame_locks(self);
|
523
|
+
|
524
|
+
lxw_xml_end_tag(self->file, "xdr:cNvGraphicFramePr");
|
525
|
+
}
|
499
526
|
}
|
500
527
|
|
501
528
|
/*
|
@@ -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.
|
@@ -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");
|
@@ -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
|
*/
|
@@ -164,12 +167,18 @@ STATIC lxw_error
|
|
164
167
|
_write_worksheet_files(lxw_packager *self)
|
165
168
|
{
|
166
169
|
lxw_workbook *workbook = self->workbook;
|
170
|
+
lxw_sheet *sheet;
|
167
171
|
lxw_worksheet *worksheet;
|
168
172
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
169
173
|
uint16_t index = 1;
|
170
174
|
lxw_error err;
|
171
175
|
|
172
|
-
STAILQ_FOREACH(
|
176
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
177
|
+
if (sheet->is_chartsheet)
|
178
|
+
continue;
|
179
|
+
else
|
180
|
+
worksheet = sheet->u.worksheet;
|
181
|
+
|
173
182
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
174
183
|
"xl/worksheets/sheet%d.xml", index++);
|
175
184
|
|
@@ -191,6 +200,43 @@ _write_worksheet_files(lxw_packager *self)
|
|
191
200
|
return LXW_NO_ERROR;
|
192
201
|
}
|
193
202
|
|
203
|
+
/*
|
204
|
+
* Write the chartsheet files.
|
205
|
+
*/
|
206
|
+
STATIC lxw_error
|
207
|
+
_write_chartsheet_files(lxw_packager *self)
|
208
|
+
{
|
209
|
+
lxw_workbook *workbook = self->workbook;
|
210
|
+
lxw_sheet *sheet;
|
211
|
+
lxw_chartsheet *chartsheet;
|
212
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
213
|
+
uint16_t index = 1;
|
214
|
+
lxw_error err;
|
215
|
+
|
216
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
217
|
+
if (sheet->is_chartsheet)
|
218
|
+
chartsheet = sheet->u.chartsheet;
|
219
|
+
else
|
220
|
+
continue;
|
221
|
+
|
222
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
223
|
+
"xl/chartsheets/sheet%d.xml", index++);
|
224
|
+
|
225
|
+
chartsheet->file = lxw_tmpfile(self->tmpdir);
|
226
|
+
if (!chartsheet->file)
|
227
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
228
|
+
|
229
|
+
lxw_chartsheet_assemble_xml_file(chartsheet);
|
230
|
+
|
231
|
+
err = _add_file_to_zip(self, chartsheet->file, sheetname);
|
232
|
+
RETURN_ON_ERROR(err);
|
233
|
+
|
234
|
+
fclose(chartsheet->file);
|
235
|
+
}
|
236
|
+
|
237
|
+
return LXW_NO_ERROR;
|
238
|
+
}
|
239
|
+
|
194
240
|
/*
|
195
241
|
* Write the /xl/media/image?.xml files.
|
196
242
|
*/
|
@@ -198,6 +244,7 @@ STATIC lxw_error
|
|
198
244
|
_write_image_files(lxw_packager *self)
|
199
245
|
{
|
200
246
|
lxw_workbook *workbook = self->workbook;
|
247
|
+
lxw_sheet *sheet;
|
201
248
|
lxw_worksheet *worksheet;
|
202
249
|
lxw_image_options *image;
|
203
250
|
lxw_error err;
|
@@ -206,7 +253,11 @@ _write_image_files(lxw_packager *self)
|
|
206
253
|
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
207
254
|
uint16_t index = 1;
|
208
255
|
|
209
|
-
STAILQ_FOREACH(
|
256
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
257
|
+
if (sheet->is_chartsheet)
|
258
|
+
continue;
|
259
|
+
else
|
260
|
+
worksheet = sheet->u.worksheet;
|
210
261
|
|
211
262
|
if (STAILQ_EMPTY(worksheet->image_data))
|
212
263
|
continue;
|
@@ -216,17 +267,24 @@ _write_image_files(lxw_packager *self)
|
|
216
267
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
217
268
|
"xl/media/image%d.%s", index++, image->extension);
|
218
269
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
270
|
+
if (!image->is_image_buffer) {
|
271
|
+
/* Check that the image file exists and can be opened. */
|
272
|
+
image_stream = fopen(image->filename, "rb");
|
273
|
+
if (!image_stream) {
|
274
|
+
LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
|
275
|
+
"doesn't exist or can't be opened: %s.",
|
276
|
+
image->filename);
|
277
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
278
|
+
}
|
279
|
+
|
280
|
+
err = _add_file_to_zip(self, image_stream, filename);
|
281
|
+
fclose(image_stream);
|
282
|
+
}
|
283
|
+
else {
|
284
|
+
err = _add_buffer_to_zip(self,
|
285
|
+
image->image_buffer,
|
286
|
+
image->image_buffer_size, filename);
|
226
287
|
}
|
227
|
-
|
228
|
-
err = _add_file_to_zip(self, image_stream, filename);
|
229
|
-
fclose(image_stream);
|
230
288
|
|
231
289
|
RETURN_ON_ERROR(err);
|
232
290
|
}
|
@@ -276,13 +334,19 @@ STATIC lxw_error
|
|
276
334
|
_write_drawing_files(lxw_packager *self)
|
277
335
|
{
|
278
336
|
lxw_workbook *workbook = self->workbook;
|
337
|
+
lxw_sheet *sheet;
|
279
338
|
lxw_worksheet *worksheet;
|
280
339
|
lxw_drawing *drawing;
|
281
340
|
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
282
341
|
uint16_t index = 1;
|
283
342
|
lxw_error err;
|
284
343
|
|
285
|
-
STAILQ_FOREACH(
|
344
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
345
|
+
if (sheet->is_chartsheet)
|
346
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
347
|
+
else
|
348
|
+
worksheet = sheet->u.worksheet;
|
349
|
+
|
286
350
|
drawing = worksheet->drawing;
|
287
351
|
|
288
352
|
if (drawing) {
|
@@ -340,7 +404,9 @@ STATIC lxw_error
|
|
340
404
|
_write_app_file(lxw_packager *self)
|
341
405
|
{
|
342
406
|
lxw_workbook *workbook = self->workbook;
|
407
|
+
lxw_sheet *sheet;
|
343
408
|
lxw_worksheet *worksheet;
|
409
|
+
lxw_chartsheet *chartsheet;
|
344
410
|
lxw_defined_name *defined_name;
|
345
411
|
lxw_app *app;
|
346
412
|
uint16_t named_range_count = 0;
|
@@ -361,12 +427,30 @@ _write_app_file(lxw_packager *self)
|
|
361
427
|
goto mem_error;
|
362
428
|
}
|
363
429
|
|
364
|
-
|
430
|
+
if (self->workbook->num_worksheets) {
|
431
|
+
lxw_snprintf(number, LXW_ATTR_32, "%d",
|
432
|
+
self->workbook->num_worksheets);
|
433
|
+
lxw_app_add_heading_pair(app, "Worksheets", number);
|
434
|
+
}
|
435
|
+
|
436
|
+
if (self->workbook->num_chartsheets) {
|
437
|
+
lxw_snprintf(number, LXW_ATTR_32, "%d",
|
438
|
+
self->workbook->num_chartsheets);
|
439
|
+
lxw_app_add_heading_pair(app, "Charts", number);
|
440
|
+
}
|
365
441
|
|
366
|
-
|
442
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
443
|
+
if (!sheet->is_chartsheet) {
|
444
|
+
worksheet = sheet->u.worksheet;
|
445
|
+
lxw_app_add_part_name(app, worksheet->name);
|
446
|
+
}
|
447
|
+
}
|
367
448
|
|
368
|
-
STAILQ_FOREACH(
|
369
|
-
|
449
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
450
|
+
if (sheet->is_chartsheet) {
|
451
|
+
chartsheet = sheet->u.chartsheet;
|
452
|
+
lxw_app_add_part_name(app, chartsheet->name);
|
453
|
+
}
|
370
454
|
}
|
371
455
|
|
372
456
|
/* Add the Named Ranges parts. */
|
@@ -568,9 +652,11 @@ _write_content_types_file(lxw_packager *self)
|
|
568
652
|
{
|
569
653
|
lxw_content_types *content_types = lxw_content_types_new();
|
570
654
|
lxw_workbook *workbook = self->workbook;
|
571
|
-
|
655
|
+
lxw_sheet *sheet;
|
572
656
|
char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
|
573
657
|
uint16_t index = 1;
|
658
|
+
uint16_t worksheet_index = 1;
|
659
|
+
uint16_t chartsheet_index = 1;
|
574
660
|
lxw_error err = LXW_NO_ERROR;
|
575
661
|
|
576
662
|
if (!content_types) {
|
@@ -593,10 +679,17 @@ _write_content_types_file(lxw_packager *self)
|
|
593
679
|
if (workbook->has_bmp)
|
594
680
|
lxw_ct_add_default(content_types, "bmp", "image/bmp");
|
595
681
|
|
596
|
-
STAILQ_FOREACH(
|
597
|
-
|
598
|
-
|
599
|
-
|
682
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
683
|
+
if (sheet->is_chartsheet) {
|
684
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
685
|
+
"/xl/chartsheets/sheet%d.xml", chartsheet_index++);
|
686
|
+
lxw_ct_add_chartsheet_name(content_types, filename);
|
687
|
+
}
|
688
|
+
else {
|
689
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
690
|
+
"/xl/worksheets/sheet%d.xml", worksheet_index++);
|
691
|
+
lxw_ct_add_worksheet_name(content_types, filename);
|
692
|
+
}
|
600
693
|
}
|
601
694
|
|
602
695
|
for (index = 1; index <= self->chart_count; index++) {
|
@@ -637,9 +730,10 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
637
730
|
{
|
638
731
|
lxw_relationships *rels = lxw_relationships_new();
|
639
732
|
lxw_workbook *workbook = self->workbook;
|
640
|
-
|
733
|
+
lxw_sheet *sheet;
|
641
734
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
642
|
-
uint16_t
|
735
|
+
uint16_t worksheet_index = 1;
|
736
|
+
uint16_t chartsheet_index = 1;
|
643
737
|
lxw_error err = LXW_NO_ERROR;
|
644
738
|
|
645
739
|
if (!rels) {
|
@@ -653,10 +747,19 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
653
747
|
goto mem_error;
|
654
748
|
}
|
655
749
|
|
656
|
-
STAILQ_FOREACH(
|
657
|
-
|
658
|
-
|
659
|
-
|
750
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
751
|
+
if (sheet->is_chartsheet) {
|
752
|
+
lxw_snprintf(sheetname,
|
753
|
+
LXW_FILENAME_LENGTH,
|
754
|
+
"chartsheets/sheet%d.xml", chartsheet_index++);
|
755
|
+
lxw_add_document_relationship(rels, "/chartsheet", sheetname);
|
756
|
+
}
|
757
|
+
else {
|
758
|
+
lxw_snprintf(sheetname,
|
759
|
+
LXW_FILENAME_LENGTH,
|
760
|
+
"worksheets/sheet%d.xml", worksheet_index++);
|
761
|
+
lxw_add_document_relationship(rels, "/worksheet", sheetname);
|
762
|
+
}
|
660
763
|
}
|
661
764
|
|
662
765
|
lxw_add_document_relationship(rels, "/theme", "theme/theme1.xml");
|
@@ -688,12 +791,17 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
688
791
|
lxw_relationships *rels;
|
689
792
|
lxw_rel_tuple *rel;
|
690
793
|
lxw_workbook *workbook = self->workbook;
|
794
|
+
lxw_sheet *sheet;
|
691
795
|
lxw_worksheet *worksheet;
|
692
796
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
693
797
|
uint16_t index = 0;
|
694
798
|
lxw_error err;
|
695
799
|
|
696
|
-
STAILQ_FOREACH(
|
800
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
801
|
+
if (sheet->is_chartsheet)
|
802
|
+
continue;
|
803
|
+
else
|
804
|
+
worksheet = sheet->u.worksheet;
|
697
805
|
|
698
806
|
index++;
|
699
807
|
|
@@ -735,6 +843,68 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
735
843
|
return LXW_NO_ERROR;
|
736
844
|
}
|
737
845
|
|
846
|
+
/*
|
847
|
+
* Write the chartsheet .rels files for chartsheets that contain links to
|
848
|
+
* external data such as drawings.
|
849
|
+
*/
|
850
|
+
STATIC lxw_error
|
851
|
+
_write_chartsheet_rels_file(lxw_packager *self)
|
852
|
+
{
|
853
|
+
lxw_relationships *rels;
|
854
|
+
lxw_rel_tuple *rel;
|
855
|
+
lxw_workbook *workbook = self->workbook;
|
856
|
+
lxw_sheet *sheet;
|
857
|
+
lxw_worksheet *worksheet;
|
858
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
859
|
+
uint16_t index = 0;
|
860
|
+
lxw_error err;
|
861
|
+
|
862
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
863
|
+
if (sheet->is_chartsheet)
|
864
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
865
|
+
else
|
866
|
+
continue;
|
867
|
+
|
868
|
+
index++;
|
869
|
+
|
870
|
+
/* TODO. This should never be empty. Put check higher up. */
|
871
|
+
if (STAILQ_EMPTY(worksheet->external_drawing_links))
|
872
|
+
continue;
|
873
|
+
|
874
|
+
rels = lxw_relationships_new();
|
875
|
+
|
876
|
+
rels->file = lxw_tmpfile(self->tmpdir);
|
877
|
+
if (!rels->file) {
|
878
|
+
lxw_free_relationships(rels);
|
879
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
880
|
+
}
|
881
|
+
|
882
|
+
STAILQ_FOREACH(rel, worksheet->external_hyperlinks, list_pointers) {
|
883
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
884
|
+
rel->target_mode);
|
885
|
+
}
|
886
|
+
|
887
|
+
STAILQ_FOREACH(rel, worksheet->external_drawing_links, list_pointers) {
|
888
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
889
|
+
rel->target_mode);
|
890
|
+
}
|
891
|
+
|
892
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
893
|
+
"xl/chartsheets/_rels/sheet%d.xml.rels", index);
|
894
|
+
|
895
|
+
lxw_relationships_assemble_xml_file(rels);
|
896
|
+
|
897
|
+
err = _add_file_to_zip(self, rels->file, sheetname);
|
898
|
+
|
899
|
+
fclose(rels->file);
|
900
|
+
lxw_free_relationships(rels);
|
901
|
+
|
902
|
+
RETURN_ON_ERROR(err);
|
903
|
+
}
|
904
|
+
|
905
|
+
return LXW_NO_ERROR;
|
906
|
+
}
|
907
|
+
|
738
908
|
/*
|
739
909
|
* Write the drawing .rels files for worksheets that contain charts or
|
740
910
|
* drawings.
|
@@ -745,12 +915,17 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
745
915
|
lxw_relationships *rels;
|
746
916
|
lxw_rel_tuple *rel;
|
747
917
|
lxw_workbook *workbook = self->workbook;
|
918
|
+
lxw_sheet *sheet;
|
748
919
|
lxw_worksheet *worksheet;
|
749
920
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
750
921
|
uint16_t index = 1;
|
751
922
|
lxw_error err;
|
752
923
|
|
753
|
-
STAILQ_FOREACH(
|
924
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
925
|
+
if (sheet->is_chartsheet)
|
926
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
927
|
+
else
|
928
|
+
worksheet = sheet->u.worksheet;
|
754
929
|
|
755
930
|
if (STAILQ_EMPTY(worksheet->drawing_links))
|
756
931
|
continue;
|
@@ -895,6 +1070,47 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
895
1070
|
return LXW_NO_ERROR;
|
896
1071
|
}
|
897
1072
|
|
1073
|
+
STATIC lxw_error
|
1074
|
+
_add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
1075
|
+
size_t buffer_size, const char *filename)
|
1076
|
+
{
|
1077
|
+
int16_t error = ZIP_OK;
|
1078
|
+
|
1079
|
+
error = zipOpenNewFileInZip4_64(self->zipfile,
|
1080
|
+
filename,
|
1081
|
+
&self->zipfile_info,
|
1082
|
+
NULL, 0, NULL, 0, NULL,
|
1083
|
+
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
|
1084
|
+
-MAX_WBITS, DEF_MEM_LEVEL,
|
1085
|
+
Z_DEFAULT_STRATEGY, NULL, 0, 0, 0, 0);
|
1086
|
+
|
1087
|
+
if (error != ZIP_OK) {
|
1088
|
+
LXW_ERROR("Error adding member to zipfile");
|
1089
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
error = zipWriteInFileInZip(self->zipfile,
|
1093
|
+
buffer, (unsigned int) buffer_size);
|
1094
|
+
|
1095
|
+
if (error < 0) {
|
1096
|
+
LXW_ERROR("Error in writing member in the zipfile");
|
1097
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
if (error < 0) {
|
1101
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1102
|
+
}
|
1103
|
+
else {
|
1104
|
+
error = zipCloseFileInZip(self->zipfile);
|
1105
|
+
if (error != ZIP_OK) {
|
1106
|
+
LXW_ERROR("Error in closing member in the zipfile");
|
1107
|
+
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
return LXW_NO_ERROR;
|
1112
|
+
}
|
1113
|
+
|
898
1114
|
/*
|
899
1115
|
* Write the xml files that make up the XLXS OPC package.
|
900
1116
|
*/
|
@@ -907,6 +1123,9 @@ lxw_create_package(lxw_packager *self)
|
|
907
1123
|
error = _write_worksheet_files(self);
|
908
1124
|
RETURN_ON_ERROR(error);
|
909
1125
|
|
1126
|
+
error = _write_chartsheet_files(self);
|
1127
|
+
RETURN_ON_ERROR(error);
|
1128
|
+
|
910
1129
|
error = _write_workbook_file(self);
|
911
1130
|
RETURN_ON_ERROR(error);
|
912
1131
|
|
@@ -943,6 +1162,9 @@ lxw_create_package(lxw_packager *self)
|
|
943
1162
|
error = _write_worksheet_rels_file(self);
|
944
1163
|
RETURN_ON_ERROR(error);
|
945
1164
|
|
1165
|
+
error = _write_chartsheet_rels_file(self);
|
1166
|
+
RETURN_ON_ERROR(error);
|
1167
|
+
|
946
1168
|
error = _write_drawing_rels_file(self);
|
947
1169
|
RETURN_ON_ERROR(error);
|
948
1170
|
|