fast_excel 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -2
  3. data/Makefile +14 -0
  4. data/README.md +7 -2
  5. data/Rakefile +10 -0
  6. data/extconf.rb +0 -0
  7. data/fast_excel.gemspec +3 -1
  8. data/lib/fast_excel/binding.rb +3 -7
  9. data/lib/rubygems_plugin.rb +3 -0
  10. data/libxlsxwriter/.gitignore +49 -0
  11. data/libxlsxwriter/.indent.pro +125 -0
  12. data/libxlsxwriter/.travis.yml +25 -0
  13. data/libxlsxwriter/CONTRIBUTING.md +226 -0
  14. data/libxlsxwriter/Changes.txt +557 -0
  15. data/libxlsxwriter/LICENSE.txt +89 -0
  16. data/libxlsxwriter/Makefile +156 -0
  17. data/libxlsxwriter/Readme.md +78 -0
  18. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +30 -0
  19. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +7 -0
  20. data/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  21. data/libxlsxwriter/include/xlsxwriter/chart.h +3476 -0
  22. data/libxlsxwriter/include/xlsxwriter/common.h +372 -0
  23. data/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  24. data/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  25. data/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  26. data/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  27. data/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  28. data/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  29. data/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  30. data/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  31. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  32. data/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  33. data/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  34. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +214 -0
  35. data/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  36. data/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  37. data/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  38. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  39. data/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  40. data/libxlsxwriter/include/xlsxwriter/workbook.h +757 -0
  41. data/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  42. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  43. data/libxlsxwriter/include/xlsxwriter.h +23 -0
  44. data/libxlsxwriter/lib/.gitignore +0 -0
  45. data/libxlsxwriter/libxlsxwriter.podspec +47 -0
  46. data/libxlsxwriter/src/Makefile +130 -0
  47. data/libxlsxwriter/src/app.c +443 -0
  48. data/libxlsxwriter/src/chart.c +6346 -0
  49. data/libxlsxwriter/src/content_types.c +345 -0
  50. data/libxlsxwriter/src/core.c +293 -0
  51. data/libxlsxwriter/src/custom.c +224 -0
  52. data/libxlsxwriter/src/drawing.c +746 -0
  53. data/libxlsxwriter/src/format.c +729 -0
  54. data/libxlsxwriter/src/hash_table.c +223 -0
  55. data/libxlsxwriter/src/packager.c +948 -0
  56. data/libxlsxwriter/src/relationships.c +245 -0
  57. data/libxlsxwriter/src/shared_strings.c +266 -0
  58. data/libxlsxwriter/src/styles.c +1088 -0
  59. data/libxlsxwriter/src/theme.c +348 -0
  60. data/libxlsxwriter/src/utility.c +515 -0
  61. data/libxlsxwriter/src/workbook.c +1930 -0
  62. data/libxlsxwriter/src/worksheet.c +5022 -0
  63. data/libxlsxwriter/src/xmlwriter.c +355 -0
  64. data/libxlsxwriter/third_party/minizip/Makefile +44 -0
  65. data/libxlsxwriter/third_party/minizip/Makefile.am +45 -0
  66. data/libxlsxwriter/third_party/minizip/Makefile.orig +25 -0
  67. data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +6 -0
  68. data/libxlsxwriter/third_party/minizip/MiniZip64_info.txt +74 -0
  69. data/libxlsxwriter/third_party/minizip/README.txt +5 -0
  70. data/libxlsxwriter/third_party/minizip/configure.ac +32 -0
  71. data/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  72. data/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  73. data/libxlsxwriter/third_party/minizip/ioapi.h +208 -0
  74. data/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  75. data/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  76. data/libxlsxwriter/third_party/minizip/make_vms.com +25 -0
  77. data/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  78. data/libxlsxwriter/third_party/minizip/miniunzip.1 +63 -0
  79. data/libxlsxwriter/third_party/minizip/minizip.1 +46 -0
  80. data/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  81. data/libxlsxwriter/third_party/minizip/minizip.pc.in +12 -0
  82. data/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  83. data/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  84. data/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  85. data/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  86. data/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  87. data/libxlsxwriter/third_party/minizip/zip.h +367 -0
  88. data/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  89. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  90. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  91. data/libxlsxwriter/version.txt +1 -0
  92. metadata +89 -6
  93. data/binaries/libxlsxwriter-alpine.so +0 -0
  94. data/binaries/libxlsxwriter-darwin.dylib +0 -0
  95. data/binaries/libxlsxwriter-glibc.so +0 -0
@@ -0,0 +1,948 @@
1
+ /*****************************************************************************
2
+ * packager - A library for creating Excel XLSX packager files.
3
+ *
4
+ * Used in conjunction with the libxlsxwriter library.
5
+ *
6
+ * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
+ *
8
+ */
9
+
10
+ #include "xlsxwriter/xmlwriter.h"
11
+ #include "xlsxwriter/packager.h"
12
+ #include "xlsxwriter/hash_table.h"
13
+ #include "xlsxwriter/utility.h"
14
+
15
+ STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
16
+ const char *filename);
17
+
18
+ /*
19
+ * Forward declarations.
20
+ */
21
+
22
+ /*****************************************************************************
23
+ *
24
+ * Private functions.
25
+ *
26
+ ****************************************************************************/
27
+ /* Avoid non MSVC definition of _WIN32 in MinGW. */
28
+
29
+ #ifdef __MINGW32__
30
+ #undef _WIN32
31
+ #endif
32
+
33
+ #ifdef _WIN32
34
+
35
+ /* Silence Windows warning with duplicate symbol for SLIST_ENTRY in local
36
+ * queue.h and widows.h. */
37
+ #undef SLIST_ENTRY
38
+
39
+ #include <windows.h>
40
+ #include "../third_party/minizip/iowin32.h"
41
+
42
+ zipFile
43
+ _open_zipfile_win32(const char *filename)
44
+ {
45
+ int n;
46
+ zlib_filefunc64_def filefunc;
47
+
48
+ wchar_t wide_filename[_MAX_PATH + 1] = L"";
49
+
50
+ /* Build a UTF-16 filename for Win32. */
51
+ n = MultiByteToWideChar(CP_UTF8, 0, filename, (int) strlen(filename),
52
+ wide_filename, _MAX_PATH);
53
+
54
+ if (n == 0) {
55
+ LXW_ERROR("MultiByteToWideChar error");
56
+ return NULL;
57
+ }
58
+
59
+ /* Use the native Win32 file handling functions with minizip. */
60
+ fill_win32_filefunc64(&filefunc);
61
+
62
+ return zipOpen2_64(wide_filename, 0, NULL, &filefunc);
63
+ }
64
+
65
+ #endif
66
+
67
+ /*
68
+ * Create a new packager object.
69
+ */
70
+ lxw_packager *
71
+ lxw_packager_new(const char *filename, char *tmpdir)
72
+ {
73
+ lxw_packager *packager = calloc(1, sizeof(lxw_packager));
74
+ GOTO_LABEL_ON_MEM_ERROR(packager, mem_error);
75
+
76
+ packager->buffer = calloc(1, LXW_ZIP_BUFFER_SIZE);
77
+ GOTO_LABEL_ON_MEM_ERROR(packager->buffer, mem_error);
78
+
79
+ packager->filename = lxw_strdup(filename);
80
+ packager->tmpdir = tmpdir;
81
+ GOTO_LABEL_ON_MEM_ERROR(packager->filename, mem_error);
82
+
83
+ packager->buffer_size = LXW_ZIP_BUFFER_SIZE;
84
+
85
+ /* Initialize the zip_fileinfo struct to Jan 1 1980 like Excel. */
86
+ packager->zipfile_info.tmz_date.tm_sec = 0;
87
+ packager->zipfile_info.tmz_date.tm_min = 0;
88
+ packager->zipfile_info.tmz_date.tm_hour = 0;
89
+ packager->zipfile_info.tmz_date.tm_mday = 1;
90
+ packager->zipfile_info.tmz_date.tm_mon = 0;
91
+ packager->zipfile_info.tmz_date.tm_year = 1980;
92
+ packager->zipfile_info.dosDate = 0;
93
+ packager->zipfile_info.internal_fa = 0;
94
+ packager->zipfile_info.external_fa = 0;
95
+
96
+ /* Create a zip container for the xlsx file. */
97
+ #ifdef _WIN32
98
+ packager->zipfile = _open_zipfile_win32(packager->filename);
99
+ #else
100
+ packager->zipfile = zipOpen(packager->filename, 0);
101
+ #endif
102
+
103
+ if (packager->zipfile == NULL)
104
+ goto mem_error;
105
+
106
+ return packager;
107
+
108
+ mem_error:
109
+ lxw_packager_free(packager);
110
+ return NULL;
111
+ }
112
+
113
+ /*
114
+ * Free a packager object.
115
+ */
116
+ void
117
+ lxw_packager_free(lxw_packager *packager)
118
+ {
119
+ if (!packager)
120
+ return;
121
+
122
+ free(packager->buffer);
123
+ free(packager->filename);
124
+ free(packager);
125
+ }
126
+
127
+ /*****************************************************************************
128
+ *
129
+ * File assembly functions.
130
+ *
131
+ ****************************************************************************/
132
+ /*
133
+ * Write the workbook.xml file.
134
+ */
135
+ STATIC lxw_error
136
+ _write_workbook_file(lxw_packager *self)
137
+ {
138
+ lxw_workbook *workbook = self->workbook;
139
+ lxw_error err;
140
+
141
+ workbook->file = lxw_tmpfile(self->tmpdir);
142
+ if (!workbook->file)
143
+ return LXW_ERROR_CREATING_TMPFILE;
144
+
145
+ lxw_workbook_assemble_xml_file(workbook);
146
+
147
+ err = _add_file_to_zip(self, workbook->file, "xl/workbook.xml");
148
+ RETURN_ON_ERROR(err);
149
+
150
+ fclose(workbook->file);
151
+
152
+ return LXW_NO_ERROR;
153
+ }
154
+
155
+ /*
156
+ * Write the worksheet files.
157
+ */
158
+ STATIC lxw_error
159
+ _write_worksheet_files(lxw_packager *self)
160
+ {
161
+ lxw_workbook *workbook = self->workbook;
162
+ lxw_worksheet *worksheet;
163
+ char sheetname[LXW_FILENAME_LENGTH] = { 0 };
164
+ uint16_t index = 1;
165
+ lxw_error err;
166
+
167
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
168
+ lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
169
+ "xl/worksheets/sheet%d.xml", index++);
170
+
171
+ if (worksheet->optimize_row)
172
+ lxw_worksheet_write_single_row(worksheet);
173
+
174
+ worksheet->file = lxw_tmpfile(self->tmpdir);
175
+ if (!worksheet->file)
176
+ return LXW_ERROR_CREATING_TMPFILE;
177
+
178
+ lxw_worksheet_assemble_xml_file(worksheet);
179
+
180
+ err = _add_file_to_zip(self, worksheet->file, sheetname);
181
+ RETURN_ON_ERROR(err);
182
+
183
+ fclose(worksheet->file);
184
+ }
185
+
186
+ return LXW_NO_ERROR;
187
+ }
188
+
189
+ /*
190
+ * Write the /xl/media/image?.xml files.
191
+ */
192
+ STATIC lxw_error
193
+ _write_image_files(lxw_packager *self)
194
+ {
195
+ lxw_workbook *workbook = self->workbook;
196
+ lxw_worksheet *worksheet;
197
+ lxw_image_options *image;
198
+ lxw_error err;
199
+
200
+ char filename[LXW_FILENAME_LENGTH] = { 0 };
201
+ uint16_t index = 1;
202
+
203
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
204
+
205
+ if (STAILQ_EMPTY(worksheet->image_data))
206
+ continue;
207
+
208
+ STAILQ_FOREACH(image, worksheet->image_data, list_pointers) {
209
+
210
+ lxw_snprintf(filename, LXW_FILENAME_LENGTH,
211
+ "xl/media/image%d.%s", index++, image->extension);
212
+
213
+ rewind(image->stream);
214
+
215
+ err = _add_file_to_zip(self, image->stream, filename);
216
+ RETURN_ON_ERROR(err);
217
+
218
+ fclose(image->stream);
219
+ }
220
+ }
221
+
222
+ return LXW_NO_ERROR;
223
+ }
224
+
225
+ /*
226
+ * Write the chart files.
227
+ */
228
+ STATIC lxw_error
229
+ _write_chart_files(lxw_packager *self)
230
+ {
231
+ lxw_workbook *workbook = self->workbook;
232
+ lxw_chart *chart;
233
+ char sheetname[LXW_FILENAME_LENGTH] = { 0 };
234
+ uint16_t index = 1;
235
+ lxw_error err;
236
+
237
+ STAILQ_FOREACH(chart, workbook->ordered_charts, ordered_list_pointers) {
238
+
239
+ lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
240
+ "xl/charts/chart%d.xml", index++);
241
+
242
+ chart->file = lxw_tmpfile(self->tmpdir);
243
+ if (!chart->file)
244
+ return LXW_ERROR_CREATING_TMPFILE;
245
+
246
+ lxw_chart_assemble_xml_file(chart);
247
+
248
+ err = _add_file_to_zip(self, chart->file, sheetname);
249
+ RETURN_ON_ERROR(err);
250
+
251
+ self->chart_count++;
252
+
253
+ fclose(chart->file);
254
+ }
255
+
256
+ return LXW_NO_ERROR;
257
+ }
258
+
259
+ /*
260
+ * Write the drawing files.
261
+ */
262
+ STATIC lxw_error
263
+ _write_drawing_files(lxw_packager *self)
264
+ {
265
+ lxw_workbook *workbook = self->workbook;
266
+ lxw_worksheet *worksheet;
267
+ lxw_drawing *drawing;
268
+ char filename[LXW_FILENAME_LENGTH] = { 0 };
269
+ uint16_t index = 1;
270
+ lxw_error err;
271
+
272
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
273
+ drawing = worksheet->drawing;
274
+
275
+ if (drawing) {
276
+ lxw_snprintf(filename, LXW_FILENAME_LENGTH,
277
+ "xl/drawings/drawing%d.xml", index++);
278
+
279
+ drawing->file = lxw_tmpfile(self->tmpdir);
280
+ if (!drawing->file)
281
+ return LXW_ERROR_CREATING_TMPFILE;
282
+
283
+ lxw_drawing_assemble_xml_file(drawing);
284
+ err = _add_file_to_zip(self, drawing->file, filename);
285
+ RETURN_ON_ERROR(err);
286
+
287
+ fclose(drawing->file);
288
+
289
+ self->drawing_count++;
290
+ }
291
+ }
292
+
293
+ return LXW_NO_ERROR;
294
+ }
295
+
296
+ /*
297
+ * Write the sharedStrings.xml file.
298
+ */
299
+ STATIC lxw_error
300
+ _write_shared_strings_file(lxw_packager *self)
301
+ {
302
+ lxw_sst *sst = self->workbook->sst;
303
+ lxw_error err;
304
+
305
+ /* Skip the sharedStrings file if there are no shared strings. */
306
+ if (!sst->string_count)
307
+ return LXW_NO_ERROR;
308
+
309
+ sst->file = lxw_tmpfile(self->tmpdir);
310
+ if (!sst->file)
311
+ return LXW_ERROR_CREATING_TMPFILE;
312
+
313
+ lxw_sst_assemble_xml_file(sst);
314
+
315
+ err = _add_file_to_zip(self, sst->file, "xl/sharedStrings.xml");
316
+ RETURN_ON_ERROR(err);
317
+
318
+ fclose(sst->file);
319
+
320
+ return LXW_NO_ERROR;
321
+ }
322
+
323
+ /*
324
+ * Write the app.xml file.
325
+ */
326
+ STATIC lxw_error
327
+ _write_app_file(lxw_packager *self)
328
+ {
329
+ lxw_workbook *workbook = self->workbook;
330
+ lxw_worksheet *worksheet;
331
+ lxw_defined_name *defined_name;
332
+ lxw_app *app;
333
+ uint16_t named_range_count = 0;
334
+ char *autofilter;
335
+ char *has_range;
336
+ char number[LXW_ATTR_32] = { 0 };
337
+ lxw_error err = LXW_NO_ERROR;
338
+
339
+ app = lxw_app_new();
340
+ if (!app) {
341
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
342
+ goto mem_error;
343
+ }
344
+
345
+ app->file = lxw_tmpfile(self->tmpdir);
346
+ if (!app->file) {
347
+ err = LXW_ERROR_CREATING_TMPFILE;
348
+ goto mem_error;
349
+ }
350
+
351
+ lxw_snprintf(number, LXW_ATTR_32, "%d", self->workbook->num_sheets);
352
+
353
+ lxw_app_add_heading_pair(app, "Worksheets", number);
354
+
355
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
356
+ lxw_app_add_part_name(app, worksheet->name);
357
+ }
358
+
359
+ /* Add the Named Ranges parts. */
360
+ TAILQ_FOREACH(defined_name, workbook->defined_names, list_pointers) {
361
+
362
+ has_range = strchr(defined_name->formula, '!');
363
+ autofilter = strstr(defined_name->app_name, "_FilterDatabase");
364
+
365
+ /* Only store defined names with ranges (except for autofilters). */
366
+ if (has_range && !autofilter) {
367
+ lxw_app_add_part_name(app, defined_name->app_name);
368
+ named_range_count++;
369
+ }
370
+ }
371
+
372
+ /* Add the Named Range heading pairs. */
373
+ if (named_range_count) {
374
+ lxw_snprintf(number, LXW_ATTR_32, "%d", named_range_count);
375
+ lxw_app_add_heading_pair(app, "Named Ranges", number);
376
+ }
377
+
378
+ /* Set the app/doc properties. */
379
+ app->properties = workbook->properties;
380
+
381
+ lxw_app_assemble_xml_file(app);
382
+
383
+ err = _add_file_to_zip(self, app->file, "docProps/app.xml");
384
+
385
+ fclose(app->file);
386
+
387
+ mem_error:
388
+ lxw_app_free(app);
389
+
390
+ return err;
391
+ }
392
+
393
+ /*
394
+ * Write the core.xml file.
395
+ */
396
+ STATIC lxw_error
397
+ _write_core_file(lxw_packager *self)
398
+ {
399
+ lxw_error err = LXW_NO_ERROR;
400
+ lxw_core *core = lxw_core_new();
401
+
402
+ if (!core) {
403
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
404
+ goto mem_error;
405
+ }
406
+
407
+ core->file = lxw_tmpfile(self->tmpdir);
408
+ if (!core->file) {
409
+ err = LXW_ERROR_CREATING_TMPFILE;
410
+ goto mem_error;
411
+ }
412
+
413
+ core->properties = self->workbook->properties;
414
+
415
+ lxw_core_assemble_xml_file(core);
416
+
417
+ err = _add_file_to_zip(self, core->file, "docProps/core.xml");
418
+
419
+ fclose(core->file);
420
+
421
+ mem_error:
422
+ lxw_core_free(core);
423
+
424
+ return err;
425
+ }
426
+
427
+ /*
428
+ * Write the custom.xml file.
429
+ */
430
+ STATIC lxw_error
431
+ _write_custom_file(lxw_packager *self)
432
+ {
433
+ lxw_custom *custom;
434
+ lxw_error err = LXW_NO_ERROR;
435
+
436
+ if (STAILQ_EMPTY(self->workbook->custom_properties))
437
+ return LXW_NO_ERROR;
438
+
439
+ custom = lxw_custom_new();
440
+ if (!custom) {
441
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
442
+ goto mem_error;
443
+ }
444
+
445
+ custom->file = lxw_tmpfile(self->tmpdir);
446
+ if (!custom->file) {
447
+ err = LXW_ERROR_CREATING_TMPFILE;
448
+ goto mem_error;
449
+ }
450
+
451
+ custom->custom_properties = self->workbook->custom_properties;
452
+
453
+ lxw_custom_assemble_xml_file(custom);
454
+
455
+ err = _add_file_to_zip(self, custom->file, "docProps/custom.xml");
456
+
457
+ fclose(custom->file);
458
+
459
+ mem_error:
460
+ lxw_custom_free(custom);
461
+ return err;
462
+ }
463
+
464
+ /*
465
+ * Write the theme.xml file.
466
+ */
467
+ STATIC lxw_error
468
+ _write_theme_file(lxw_packager *self)
469
+ {
470
+ lxw_error err = LXW_NO_ERROR;
471
+ lxw_theme *theme = lxw_theme_new();
472
+
473
+ if (!theme) {
474
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
475
+ goto mem_error;
476
+ }
477
+
478
+ theme->file = lxw_tmpfile(self->tmpdir);
479
+ if (!theme->file) {
480
+ err = LXW_ERROR_CREATING_TMPFILE;
481
+ goto mem_error;
482
+ }
483
+
484
+ lxw_theme_assemble_xml_file(theme);
485
+
486
+ err = _add_file_to_zip(self, theme->file, "xl/theme/theme1.xml");
487
+
488
+ fclose(theme->file);
489
+
490
+ mem_error:
491
+ lxw_theme_free(theme);
492
+
493
+ return err;
494
+ }
495
+
496
+ /*
497
+ * Write the styles.xml file.
498
+ */
499
+ STATIC lxw_error
500
+ _write_styles_file(lxw_packager *self)
501
+ {
502
+ lxw_styles *styles = lxw_styles_new();
503
+ lxw_hash_element *hash_element;
504
+ lxw_error err = LXW_NO_ERROR;
505
+
506
+ if (!styles) {
507
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
508
+ goto mem_error;
509
+ }
510
+
511
+ /* Copy the unique and in-use formats from the workbook to the styles
512
+ * xf_format list. */
513
+ LXW_FOREACH_ORDERED(hash_element, self->workbook->used_xf_formats) {
514
+ lxw_format *workbook_format = (lxw_format *) hash_element->value;
515
+ lxw_format *style_format = lxw_format_new();
516
+
517
+ if (!style_format) {
518
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
519
+ goto mem_error;
520
+ }
521
+
522
+ memcpy(style_format, workbook_format, sizeof(lxw_format));
523
+ STAILQ_INSERT_TAIL(styles->xf_formats, style_format, list_pointers);
524
+ }
525
+
526
+ styles->font_count = self->workbook->font_count;
527
+ styles->border_count = self->workbook->border_count;
528
+ styles->fill_count = self->workbook->fill_count;
529
+ styles->num_format_count = self->workbook->num_format_count;
530
+ styles->xf_count = self->workbook->used_xf_formats->unique_count;
531
+
532
+ styles->file = lxw_tmpfile(self->tmpdir);
533
+ if (!styles->file) {
534
+ err = LXW_ERROR_CREATING_TMPFILE;
535
+ goto mem_error;
536
+ }
537
+
538
+ lxw_styles_assemble_xml_file(styles);
539
+
540
+ err = _add_file_to_zip(self, styles->file, "xl/styles.xml");
541
+
542
+ fclose(styles->file);
543
+
544
+ mem_error:
545
+ lxw_styles_free(styles);
546
+
547
+ return err;
548
+ }
549
+
550
+ /*
551
+ * Write the ContentTypes.xml file.
552
+ */
553
+ STATIC lxw_error
554
+ _write_content_types_file(lxw_packager *self)
555
+ {
556
+ lxw_content_types *content_types = lxw_content_types_new();
557
+ lxw_workbook *workbook = self->workbook;
558
+ lxw_worksheet *worksheet;
559
+ char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
560
+ uint16_t index = 1;
561
+ lxw_error err = LXW_NO_ERROR;
562
+
563
+ if (!content_types) {
564
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
565
+ goto mem_error;
566
+ }
567
+
568
+ content_types->file = lxw_tmpfile(self->tmpdir);
569
+ if (!content_types->file) {
570
+ err = LXW_ERROR_CREATING_TMPFILE;
571
+ goto mem_error;
572
+ }
573
+
574
+ if (workbook->has_png)
575
+ lxw_ct_add_default(content_types, "png", "image/png");
576
+
577
+ if (workbook->has_jpeg)
578
+ lxw_ct_add_default(content_types, "jpeg", "image/jpeg");
579
+
580
+ if (workbook->has_bmp)
581
+ lxw_ct_add_default(content_types, "bmp", "image/bmp");
582
+
583
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
584
+ lxw_snprintf(filename, LXW_FILENAME_LENGTH,
585
+ "/xl/worksheets/sheet%d.xml", index++);
586
+ lxw_ct_add_worksheet_name(content_types, filename);
587
+ }
588
+
589
+ for (index = 1; index <= self->chart_count; index++) {
590
+ lxw_snprintf(filename, LXW_FILENAME_LENGTH, "/xl/charts/chart%d.xml",
591
+ index);
592
+ lxw_ct_add_chart_name(content_types, filename);
593
+ }
594
+
595
+ for (index = 1; index <= self->drawing_count; index++) {
596
+ lxw_snprintf(filename, LXW_FILENAME_LENGTH,
597
+ "/xl/drawings/drawing%d.xml", index);
598
+ lxw_ct_add_drawing_name(content_types, filename);
599
+ }
600
+
601
+ if (workbook->sst->string_count)
602
+ lxw_ct_add_shared_strings(content_types);
603
+
604
+ if (!STAILQ_EMPTY(self->workbook->custom_properties))
605
+ lxw_ct_add_custom_properties(content_types);
606
+
607
+ lxw_content_types_assemble_xml_file(content_types);
608
+
609
+ err = _add_file_to_zip(self, content_types->file, "[Content_Types].xml");
610
+
611
+ fclose(content_types->file);
612
+
613
+ mem_error:
614
+ lxw_content_types_free(content_types);
615
+
616
+ return err;
617
+ }
618
+
619
+ /*
620
+ * Write the workbook .rels xml file.
621
+ */
622
+ STATIC lxw_error
623
+ _write_workbook_rels_file(lxw_packager *self)
624
+ {
625
+ lxw_relationships *rels = lxw_relationships_new();
626
+ lxw_workbook *workbook = self->workbook;
627
+ lxw_worksheet *worksheet;
628
+ char sheetname[LXW_FILENAME_LENGTH] = { 0 };
629
+ uint16_t index = 1;
630
+ lxw_error err = LXW_NO_ERROR;
631
+
632
+ if (!rels) {
633
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
634
+ goto mem_error;
635
+ }
636
+
637
+ rels->file = lxw_tmpfile(self->tmpdir);
638
+ if (!rels->file) {
639
+ err = LXW_ERROR_CREATING_TMPFILE;
640
+ goto mem_error;
641
+ }
642
+
643
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
644
+ lxw_snprintf(sheetname, LXW_FILENAME_LENGTH, "worksheets/sheet%d.xml",
645
+ index++);
646
+ lxw_add_document_relationship(rels, "/worksheet", sheetname);
647
+ }
648
+
649
+ lxw_add_document_relationship(rels, "/theme", "theme/theme1.xml");
650
+ lxw_add_document_relationship(rels, "/styles", "styles.xml");
651
+
652
+ if (workbook->sst->string_count)
653
+ lxw_add_document_relationship(rels, "/sharedStrings",
654
+ "sharedStrings.xml");
655
+
656
+ lxw_relationships_assemble_xml_file(rels);
657
+
658
+ err = _add_file_to_zip(self, rels->file, "xl/_rels/workbook.xml.rels");
659
+
660
+ fclose(rels->file);
661
+
662
+ mem_error:
663
+ lxw_free_relationships(rels);
664
+
665
+ return err;
666
+ }
667
+
668
+ /*
669
+ * Write the worksheet .rels files for worksheets that contain links to
670
+ * external data such as hyperlinks or drawings.
671
+ */
672
+ STATIC lxw_error
673
+ _write_worksheet_rels_file(lxw_packager *self)
674
+ {
675
+ lxw_relationships *rels;
676
+ lxw_rel_tuple *rel;
677
+ lxw_workbook *workbook = self->workbook;
678
+ lxw_worksheet *worksheet;
679
+ char sheetname[LXW_FILENAME_LENGTH] = { 0 };
680
+ uint16_t index = 0;
681
+ lxw_error err;
682
+
683
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
684
+
685
+ index++;
686
+
687
+ if (STAILQ_EMPTY(worksheet->external_hyperlinks) &&
688
+ STAILQ_EMPTY(worksheet->external_drawing_links))
689
+ continue;
690
+
691
+ rels = lxw_relationships_new();
692
+
693
+ rels->file = lxw_tmpfile(self->tmpdir);
694
+ if (!rels->file) {
695
+ lxw_free_relationships(rels);
696
+ return LXW_ERROR_CREATING_TMPFILE;
697
+ }
698
+
699
+ STAILQ_FOREACH(rel, worksheet->external_hyperlinks, list_pointers) {
700
+ lxw_add_worksheet_relationship(rels, rel->type, rel->target,
701
+ rel->target_mode);
702
+ }
703
+
704
+ STAILQ_FOREACH(rel, worksheet->external_drawing_links, list_pointers) {
705
+ lxw_add_worksheet_relationship(rels, rel->type, rel->target,
706
+ rel->target_mode);
707
+ }
708
+
709
+ lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
710
+ "xl/worksheets/_rels/sheet%d.xml.rels", index);
711
+
712
+ lxw_relationships_assemble_xml_file(rels);
713
+
714
+ err = _add_file_to_zip(self, rels->file, sheetname);
715
+
716
+ fclose(rels->file);
717
+ lxw_free_relationships(rels);
718
+
719
+ RETURN_ON_ERROR(err);
720
+ }
721
+
722
+ return LXW_NO_ERROR;
723
+ }
724
+
725
+ /*
726
+ * Write the drawing .rels files for worksheets that contain charts or
727
+ * drawings.
728
+ */
729
+ STATIC lxw_error
730
+ _write_drawing_rels_file(lxw_packager *self)
731
+ {
732
+ lxw_relationships *rels;
733
+ lxw_rel_tuple *rel;
734
+ lxw_workbook *workbook = self->workbook;
735
+ lxw_worksheet *worksheet;
736
+ char sheetname[LXW_FILENAME_LENGTH] = { 0 };
737
+ uint16_t index = 1;
738
+ lxw_error err;
739
+
740
+ STAILQ_FOREACH(worksheet, workbook->worksheets, list_pointers) {
741
+
742
+ if (STAILQ_EMPTY(worksheet->drawing_links))
743
+ continue;
744
+
745
+ rels = lxw_relationships_new();
746
+
747
+ rels->file = lxw_tmpfile(self->tmpdir);
748
+ if (!rels->file) {
749
+ lxw_free_relationships(rels);
750
+ return LXW_ERROR_CREATING_TMPFILE;
751
+ }
752
+
753
+ STAILQ_FOREACH(rel, worksheet->drawing_links, list_pointers) {
754
+ lxw_add_worksheet_relationship(rels, rel->type, rel->target,
755
+ rel->target_mode);
756
+
757
+ }
758
+
759
+ lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
760
+ "xl/drawings/_rels/drawing%d.xml.rels", index++);
761
+
762
+ lxw_relationships_assemble_xml_file(rels);
763
+
764
+ err = _add_file_to_zip(self, rels->file, sheetname);
765
+
766
+ fclose(rels->file);
767
+ lxw_free_relationships(rels);
768
+
769
+ RETURN_ON_ERROR(err);
770
+ }
771
+
772
+ return LXW_NO_ERROR;
773
+ }
774
+
775
+ /*
776
+ * Write the _rels/.rels xml file.
777
+ */
778
+ STATIC lxw_error
779
+ _write_root_rels_file(lxw_packager *self)
780
+ {
781
+ lxw_relationships *rels = lxw_relationships_new();
782
+ lxw_error err = LXW_NO_ERROR;
783
+
784
+ if (!rels) {
785
+ err = LXW_ERROR_MEMORY_MALLOC_FAILED;
786
+ goto mem_error;
787
+ }
788
+
789
+ rels->file = lxw_tmpfile(self->tmpdir);
790
+ if (!rels->file) {
791
+ err = LXW_ERROR_CREATING_TMPFILE;
792
+ goto mem_error;
793
+ }
794
+
795
+ lxw_add_document_relationship(rels, "/officeDocument", "xl/workbook.xml");
796
+
797
+ lxw_add_package_relationship(rels,
798
+ "/metadata/core-properties",
799
+ "docProps/core.xml");
800
+
801
+ lxw_add_document_relationship(rels,
802
+ "/extended-properties", "docProps/app.xml");
803
+
804
+ if (!STAILQ_EMPTY(self->workbook->custom_properties))
805
+ lxw_add_document_relationship(rels,
806
+ "/custom-properties",
807
+ "docProps/custom.xml");
808
+
809
+ lxw_relationships_assemble_xml_file(rels);
810
+
811
+ err = _add_file_to_zip(self, rels->file, "_rels/.rels");
812
+
813
+ fclose(rels->file);
814
+
815
+ mem_error:
816
+ lxw_free_relationships(rels);
817
+
818
+ return err;
819
+ }
820
+
821
+ /*****************************************************************************
822
+ *
823
+ * Public functions.
824
+ *
825
+ ****************************************************************************/
826
+
827
+ STATIC lxw_error
828
+ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
829
+ {
830
+ int16_t error = ZIP_OK;
831
+ size_t size_read;
832
+
833
+ error = zipOpenNewFileInZip4_64(self->zipfile,
834
+ filename,
835
+ &self->zipfile_info,
836
+ NULL, 0, NULL, 0, NULL,
837
+ Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
838
+ -MAX_WBITS, DEF_MEM_LEVEL,
839
+ Z_DEFAULT_STRATEGY, NULL, 0, 0, 0, 0);
840
+
841
+ if (error != ZIP_OK) {
842
+ LXW_ERROR("Error adding member to zipfile");
843
+ RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
844
+ }
845
+
846
+ fflush(file);
847
+ rewind(file);
848
+
849
+ size_read = fread(self->buffer, 1, self->buffer_size, file);
850
+
851
+ while (size_read) {
852
+
853
+ if (size_read < self->buffer_size) {
854
+ if (feof(file) == 0) {
855
+ LXW_ERROR("Error reading member file data");
856
+ RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
857
+ }
858
+ }
859
+
860
+ error = zipWriteInFileInZip(self->zipfile,
861
+ self->buffer, (unsigned int) size_read);
862
+
863
+ if (error < 0) {
864
+ LXW_ERROR("Error in writing member in the zipfile");
865
+ RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
866
+ }
867
+
868
+ size_read = fread(self->buffer, 1, self->buffer_size, file);
869
+ }
870
+
871
+ if (error < 0) {
872
+ RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
873
+ }
874
+ else {
875
+ error = zipCloseFileInZip(self->zipfile);
876
+ if (error != ZIP_OK) {
877
+ LXW_ERROR("Error in closing member in the zipfile");
878
+ RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
879
+ }
880
+ }
881
+
882
+ return LXW_NO_ERROR;
883
+ }
884
+
885
+ /*
886
+ * Write the xml files that make up the XLXS OPC package.
887
+ */
888
+ lxw_error
889
+ lxw_create_package(lxw_packager *self)
890
+ {
891
+ lxw_error error;
892
+ int8_t zip_error;
893
+
894
+ error = _write_worksheet_files(self);
895
+ RETURN_ON_ERROR(error);
896
+
897
+ error = _write_workbook_file(self);
898
+ RETURN_ON_ERROR(error);
899
+
900
+ error = _write_chart_files(self);
901
+ RETURN_ON_ERROR(error);
902
+
903
+ error = _write_drawing_files(self);
904
+ RETURN_ON_ERROR(error);
905
+
906
+ error = _write_shared_strings_file(self);
907
+ RETURN_ON_ERROR(error);
908
+
909
+ error = _write_app_file(self);
910
+ RETURN_ON_ERROR(error);
911
+
912
+ error = _write_core_file(self);
913
+ RETURN_ON_ERROR(error);
914
+
915
+ error = _write_custom_file(self);
916
+ RETURN_ON_ERROR(error);
917
+
918
+ error = _write_theme_file(self);
919
+ RETURN_ON_ERROR(error);
920
+
921
+ error = _write_styles_file(self);
922
+ RETURN_ON_ERROR(error);
923
+
924
+ error = _write_content_types_file(self);
925
+ RETURN_ON_ERROR(error);
926
+
927
+ error = _write_workbook_rels_file(self);
928
+ RETURN_ON_ERROR(error);
929
+
930
+ error = _write_worksheet_rels_file(self);
931
+ RETURN_ON_ERROR(error);
932
+
933
+ error = _write_drawing_rels_file(self);
934
+ RETURN_ON_ERROR(error);
935
+
936
+ error = _write_image_files(self);
937
+ RETURN_ON_ERROR(error);;
938
+
939
+ error = _write_root_rels_file(self);
940
+ RETURN_ON_ERROR(error);
941
+
942
+ zip_error = zipClose(self->zipfile, NULL);
943
+ if (zip_error) {
944
+ RETURN_ON_ZIP_ERROR(zip_error, LXW_ERROR_ZIP_CLOSE);
945
+ }
946
+
947
+ return LXW_NO_ERROR;
948
+ }