fast_excel 0.2.2 → 0.4.0

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.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/.dockerignore +2 -0
  3. data/.gitignore +7 -0
  4. data/.travis.yml +32 -9
  5. data/CHANGELOG.md +36 -1
  6. data/Dockerfile.test +17 -0
  7. data/Gemfile +2 -1
  8. data/Gemfile.lock +33 -24
  9. data/LICENSE +21 -0
  10. data/Makefile +13 -0
  11. data/README.md +177 -40
  12. data/Rakefile +11 -1
  13. data/benchmarks/1k_rows.rb +17 -4
  14. data/benchmarks/20k_rows.rb +4 -0
  15. data/benchmarks/auto_width.rb +37 -0
  16. data/benchmarks/init.rb +14 -2
  17. data/benchmarks/memory.rb +8 -0
  18. data/benchmarks/profiler.rb +27 -0
  19. data/benchmarks/write_value.rb +62 -0
  20. data/examples/example.rb +3 -3
  21. data/examples/example_auto_width.rb +26 -0
  22. data/examples/example_filters.rb +36 -0
  23. data/examples/example_formula.rb +1 -3
  24. data/examples/example_hyperlink.rb +20 -0
  25. data/ext/fast_excel/extconf.rb +3 -0
  26. data/ext/fast_excel/text_width_ext.c +460 -0
  27. data/fast_excel.gemspec +3 -4
  28. data/letters.html +114 -0
  29. data/lib/fast_excel.rb +131 -25
  30. data/lib/fast_excel/binding.rb +33 -21
  31. data/lib/fast_excel/binding/chart.rb +20 -1
  32. data/lib/fast_excel/binding/format.rb +11 -4
  33. data/lib/fast_excel/binding/workbook.rb +10 -2
  34. data/lib/fast_excel/binding/worksheet.rb +44 -27
  35. data/libxlsxwriter/.gitignore +1 -0
  36. data/libxlsxwriter/.indent.pro +8 -0
  37. data/libxlsxwriter/.travis.yml +12 -0
  38. data/libxlsxwriter/CMakeLists.txt +338 -0
  39. data/libxlsxwriter/CONTRIBUTING.md +1 -1
  40. data/libxlsxwriter/Changes.txt +162 -0
  41. data/libxlsxwriter/LICENSE.txt +65 -4
  42. data/libxlsxwriter/Makefile +33 -11
  43. data/libxlsxwriter/Readme.md +3 -1
  44. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +2 -1
  45. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +2 -2
  46. data/libxlsxwriter/include/xlsxwriter.h +2 -2
  47. data/libxlsxwriter/include/xlsxwriter/app.h +2 -2
  48. data/libxlsxwriter/include/xlsxwriter/chart.h +164 -13
  49. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
  50. data/libxlsxwriter/include/xlsxwriter/common.h +35 -6
  51. data/libxlsxwriter/include/xlsxwriter/content_types.h +5 -2
  52. data/libxlsxwriter/include/xlsxwriter/core.h +2 -2
  53. data/libxlsxwriter/include/xlsxwriter/custom.h +2 -2
  54. data/libxlsxwriter/include/xlsxwriter/drawing.h +3 -2
  55. data/libxlsxwriter/include/xlsxwriter/format.h +8 -8
  56. data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  57. data/libxlsxwriter/include/xlsxwriter/packager.h +18 -8
  58. data/libxlsxwriter/include/xlsxwriter/relationships.h +2 -2
  59. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +5 -3
  60. data/libxlsxwriter/include/xlsxwriter/styles.h +10 -5
  61. data/libxlsxwriter/include/xlsxwriter/theme.h +2 -2
  62. data/libxlsxwriter/include/xlsxwriter/utility.h +35 -5
  63. data/libxlsxwriter/include/xlsxwriter/workbook.h +234 -57
  64. data/libxlsxwriter/include/xlsxwriter/worksheet.h +780 -91
  65. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +4 -2
  66. data/libxlsxwriter/libxlsxwriter.podspec +4 -2
  67. data/libxlsxwriter/src/Makefile +31 -6
  68. data/libxlsxwriter/src/app.c +2 -2
  69. data/libxlsxwriter/src/chart.c +116 -23
  70. data/libxlsxwriter/src/chartsheet.c +508 -0
  71. data/libxlsxwriter/src/content_types.c +12 -4
  72. data/libxlsxwriter/src/core.c +11 -11
  73. data/libxlsxwriter/src/custom.c +3 -3
  74. data/libxlsxwriter/src/drawing.c +114 -17
  75. data/libxlsxwriter/src/format.c +5 -5
  76. data/libxlsxwriter/src/hash_table.c +1 -1
  77. data/libxlsxwriter/src/packager.c +378 -61
  78. data/libxlsxwriter/src/relationships.c +2 -2
  79. data/libxlsxwriter/src/shared_strings.c +18 -4
  80. data/libxlsxwriter/src/styles.c +59 -12
  81. data/libxlsxwriter/src/theme.c +2 -2
  82. data/libxlsxwriter/src/utility.c +93 -6
  83. data/libxlsxwriter/src/workbook.c +379 -61
  84. data/libxlsxwriter/src/worksheet.c +1240 -174
  85. data/libxlsxwriter/src/xmlwriter.c +18 -9
  86. data/libxlsxwriter/third_party/minizip/Makefile +6 -1
  87. data/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
  88. data/libxlsxwriter/third_party/minizip/zip.c +2 -0
  89. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
  90. data/libxlsxwriter/version.txt +1 -1
  91. data/test/auto_width_test.rb +19 -0
  92. data/test/date_test.rb +34 -0
  93. data/test/format_test.rb +8 -0
  94. data/test/reopen_test.rb +22 -0
  95. data/test/test_helper.rb +8 -5
  96. data/test/text_width_test.rb +80 -0
  97. data/test/tmpfile_test.rb +1 -0
  98. data/test/validations_test.rb +47 -0
  99. data/test/worksheet_test.rb +44 -1
  100. metadata +33 -9
@@ -0,0 +1,508 @@
1
+ /*****************************************************************************
2
+ * chartsheet - A library for creating Excel XLSX chartsheet files.
3
+ *
4
+ * Used in conjunction with the libxlsxwriter library.
5
+ *
6
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
+ *
8
+ */
9
+
10
+ #include "xlsxwriter/xmlwriter.h"
11
+ #include "xlsxwriter/chartsheet.h"
12
+ #include "xlsxwriter/utility.h"
13
+
14
+ /*
15
+ * Forward declarations.
16
+ */
17
+
18
+ /*****************************************************************************
19
+ *
20
+ * Private functions.
21
+ *
22
+ ****************************************************************************/
23
+
24
+ /*
25
+ * Create a new chartsheet object.
26
+ */
27
+ lxw_chartsheet *
28
+ lxw_chartsheet_new(lxw_worksheet_init_data *init_data)
29
+ {
30
+ lxw_chartsheet *chartsheet = calloc(1, sizeof(lxw_chartsheet));
31
+ GOTO_LABEL_ON_MEM_ERROR(chartsheet, mem_error);
32
+
33
+ /* Use an embedded worksheet instance to write XML records that are
34
+ * shared with worksheet.c. */
35
+ chartsheet->worksheet = lxw_worksheet_new(NULL);
36
+ GOTO_LABEL_ON_MEM_ERROR(chartsheet->worksheet, mem_error);
37
+
38
+ if (init_data) {
39
+ chartsheet->name = init_data->name;
40
+ chartsheet->quoted_name = init_data->quoted_name;
41
+ chartsheet->tmpdir = init_data->tmpdir;
42
+ chartsheet->index = init_data->index;
43
+ chartsheet->hidden = init_data->hidden;
44
+ chartsheet->active_sheet = init_data->active_sheet;
45
+ chartsheet->first_sheet = init_data->first_sheet;
46
+ }
47
+
48
+ chartsheet->worksheet->is_chartsheet = LXW_TRUE;
49
+ chartsheet->worksheet->zoom_scale_normal = LXW_FALSE;
50
+ chartsheet->worksheet->orientation = LXW_LANDSCAPE;
51
+
52
+ return chartsheet;
53
+
54
+ mem_error:
55
+ lxw_chartsheet_free(chartsheet);
56
+ return NULL;
57
+ }
58
+
59
+ /*
60
+ * Free a chartsheet object.
61
+ */
62
+ void
63
+ lxw_chartsheet_free(lxw_chartsheet *chartsheet)
64
+ {
65
+ if (!chartsheet)
66
+ return;
67
+
68
+ lxw_worksheet_free(chartsheet->worksheet);
69
+ free(chartsheet->name);
70
+ free(chartsheet->quoted_name);
71
+ free(chartsheet);
72
+ }
73
+
74
+ /*****************************************************************************
75
+ *
76
+ * XML functions.
77
+ *
78
+ ****************************************************************************/
79
+
80
+ /*
81
+ * Write the XML declaration.
82
+ */
83
+ STATIC void
84
+ _chartsheet_xml_declaration(lxw_chartsheet *self)
85
+ {
86
+ lxw_xml_declaration(self->file);
87
+ }
88
+
89
+ /*
90
+ * Write the <chartsheet> element.
91
+ */
92
+ STATIC void
93
+ _chartsheet_write_chartsheet(lxw_chartsheet *self)
94
+ {
95
+ struct xml_attribute_list attributes;
96
+ struct xml_attribute *attribute;
97
+ char xmlns[] = "http://schemas.openxmlformats.org/"
98
+ "spreadsheetml/2006/main";
99
+ char xmlns_r[] = "http://schemas.openxmlformats.org/"
100
+ "officeDocument/2006/relationships";
101
+
102
+ LXW_INIT_ATTRIBUTES();
103
+ LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
104
+ LXW_PUSH_ATTRIBUTES_STR("xmlns:r", xmlns_r);
105
+
106
+ lxw_xml_start_tag(self->file, "chartsheet", &attributes);
107
+ LXW_FREE_ATTRIBUTES();
108
+ }
109
+
110
+ /*
111
+ * Write the <sheetPr> element.
112
+ */
113
+ STATIC void
114
+ _chartsheet_write_sheet_pr(lxw_chartsheet *self)
115
+ {
116
+ lxw_worksheet_write_sheet_pr(self->worksheet);
117
+ }
118
+
119
+ /*
120
+ * Write the <sheetViews> element.
121
+ */
122
+ STATIC void
123
+ _chartsheet_write_sheet_views(lxw_chartsheet *self)
124
+ {
125
+ lxw_worksheet_write_sheet_views(self->worksheet);
126
+ }
127
+
128
+ /*
129
+ * Write the <pageMargins> element.
130
+ */
131
+ STATIC void
132
+ _chartsheet_write_page_margins(lxw_chartsheet *self)
133
+ {
134
+ lxw_worksheet_write_page_margins(self->worksheet);
135
+ }
136
+
137
+ /*
138
+ * Write the <drawing> elements.
139
+ */
140
+ STATIC void
141
+ _chartsheet_write_drawings(lxw_chartsheet *self)
142
+ {
143
+ lxw_worksheet_write_drawings(self->worksheet);
144
+ }
145
+
146
+ /*
147
+ * Write the <sheetProtection> element.
148
+ */
149
+ STATIC void
150
+ _chartsheet_write_sheet_protection(lxw_chartsheet *self)
151
+ {
152
+ lxw_worksheet_write_sheet_protection(self->worksheet, &self->protection);
153
+ }
154
+
155
+ /*
156
+ * Write the <pageSetup> element.
157
+ */
158
+ STATIC void
159
+ _chartsheet_write_page_setup(lxw_chartsheet *self)
160
+ {
161
+ lxw_worksheet_write_page_setup(self->worksheet);
162
+ }
163
+
164
+ /*
165
+ * Write the <headerFooter> element.
166
+ */
167
+ STATIC void
168
+ _chartsheet_write_header_footer(lxw_chartsheet *self)
169
+ {
170
+ lxw_worksheet_write_header_footer(self->worksheet);
171
+ }
172
+
173
+ /*****************************************************************************
174
+ *
175
+ * XML file assembly functions.
176
+ *
177
+ ****************************************************************************/
178
+
179
+ /*
180
+ * Assemble and write the XML file.
181
+ */
182
+ void
183
+ lxw_chartsheet_assemble_xml_file(lxw_chartsheet *self)
184
+ {
185
+ /* Set the embedded worksheet filehandle to the same as the chartsheet. */
186
+ self->worksheet->file = self->file;
187
+
188
+ /* Write the XML declaration. */
189
+ _chartsheet_xml_declaration(self);
190
+
191
+ /* Write the chartsheet element. */
192
+ _chartsheet_write_chartsheet(self);
193
+
194
+ /* Write the sheetPr element. */
195
+ _chartsheet_write_sheet_pr(self);
196
+
197
+ /* Write the sheetViews element. */
198
+ _chartsheet_write_sheet_views(self);
199
+
200
+ /* Write the sheetProtection element. */
201
+ _chartsheet_write_sheet_protection(self);
202
+
203
+ /* Write the pageMargins element. */
204
+ _chartsheet_write_page_margins(self);
205
+
206
+ /* Write the chartsheet page setup. */
207
+ _chartsheet_write_page_setup(self);
208
+
209
+ /* Write the headerFooter element. */
210
+ _chartsheet_write_header_footer(self);
211
+
212
+ /* Write the drawing element. */
213
+ _chartsheet_write_drawings(self);
214
+
215
+ lxw_xml_end_tag(self->file, "chartsheet");
216
+ }
217
+
218
+ /*****************************************************************************
219
+ *
220
+ * Public functions.
221
+ *
222
+ ****************************************************************************/
223
+ /*
224
+ * Set a chartsheet chart, with options.
225
+ */
226
+ lxw_error
227
+ chartsheet_set_chart_opt(lxw_chartsheet *self,
228
+ lxw_chart *chart, lxw_image_options *user_options)
229
+ {
230
+ lxw_image_options *options;
231
+ lxw_chart_series *series;
232
+
233
+ if (!chart) {
234
+ LXW_WARN("chartsheet_set_chart()/_opt(): chart must be non-NULL.");
235
+ return LXW_ERROR_NULL_PARAMETER_IGNORED;
236
+ }
237
+
238
+ /* Check that the chart isn't being used more than once. */
239
+ if (chart->in_use) {
240
+ LXW_WARN("chartsheet_set_chart()/_opt(): the same chart object "
241
+ "cannot be set for a chartsheet more than once.");
242
+
243
+ return LXW_ERROR_PARAMETER_VALIDATION;
244
+ }
245
+
246
+ /* Check that the chart has a data series. */
247
+ if (STAILQ_EMPTY(chart->series_list)) {
248
+ LXW_WARN("chartsheet_set_chart()/_opt(): chart must have a series.");
249
+
250
+ return LXW_ERROR_PARAMETER_VALIDATION;
251
+ }
252
+
253
+ /* Check that the chart has a 'values' series. */
254
+ STAILQ_FOREACH(series, chart->series_list, list_pointers) {
255
+ if (!series->values->formula && !series->values->sheetname) {
256
+ LXW_WARN("chartsheet_set_chart()/_opt(): chart must have a "
257
+ "'values' series.");
258
+
259
+ return LXW_ERROR_PARAMETER_VALIDATION;
260
+ }
261
+ }
262
+
263
+ /* Create a new object to hold the chart image options. */
264
+ options = calloc(1, sizeof(lxw_image_options));
265
+ RETURN_ON_MEM_ERROR(options, LXW_ERROR_MEMORY_MALLOC_FAILED);
266
+
267
+ if (user_options) {
268
+ options->x_offset = user_options->x_offset;
269
+ options->y_offset = user_options->y_offset;
270
+ options->x_scale = user_options->x_scale;
271
+ options->y_scale = user_options->y_scale;
272
+ }
273
+
274
+ /* TODO. Read defaults from chart. */
275
+ options->width = 480;
276
+ options->height = 288;
277
+
278
+ if (!options->x_scale)
279
+ options->x_scale = 1;
280
+
281
+ if (!options->y_scale)
282
+ options->y_scale = 1;
283
+
284
+ /* Store chart references so they can be ordered in the workbook. */
285
+ options->chart = chart;
286
+
287
+ /* Store the chart data in the embedded worksheet. */
288
+ STAILQ_INSERT_TAIL(self->worksheet->chart_data, options, list_pointers);
289
+
290
+ chart->in_use = LXW_TRUE;
291
+ chart->is_chartsheet = LXW_TRUE;
292
+
293
+ chart->is_protected = self->is_protected;
294
+
295
+ self->chart = chart;
296
+
297
+ return LXW_NO_ERROR;
298
+ }
299
+
300
+ /*
301
+ * Set a chartsheet charts.
302
+ */
303
+ lxw_error
304
+ chartsheet_set_chart(lxw_chartsheet *self, lxw_chart *chart)
305
+ {
306
+ return chartsheet_set_chart_opt(self, chart, NULL);
307
+ }
308
+
309
+ /*
310
+ * Set this chartsheet as a selected worksheet, i.e. the worksheet has its tab
311
+ * highlighted.
312
+ */
313
+ void
314
+ chartsheet_select(lxw_chartsheet *self)
315
+ {
316
+ self->selected = LXW_TRUE;
317
+
318
+ /* Selected worksheet can't be hidden. */
319
+ self->hidden = LXW_FALSE;
320
+ }
321
+
322
+ /*
323
+ * Set this chartsheet as the active worksheet, i.e. the worksheet that is
324
+ * displayed when the workbook is opened. Also set it as selected.
325
+ */
326
+ void
327
+ chartsheet_activate(lxw_chartsheet *self)
328
+ {
329
+ self->worksheet->selected = LXW_TRUE;
330
+ self->worksheet->active = LXW_TRUE;
331
+
332
+ /* Active worksheet can't be hidden. */
333
+ self->worksheet->hidden = LXW_FALSE;
334
+
335
+ *self->active_sheet = self->index;
336
+ }
337
+
338
+ /*
339
+ * Set this chartsheet as the first visible sheet. This is necessary
340
+ * when there are a large number of worksheets and the activated
341
+ * worksheet is not visible on the screen.
342
+ */
343
+ void
344
+ chartsheet_set_first_sheet(lxw_chartsheet *self)
345
+ {
346
+ /* Active worksheet can't be hidden. */
347
+ self->hidden = LXW_FALSE;
348
+
349
+ *self->first_sheet = self->index;
350
+ }
351
+
352
+ /*
353
+ * Hide this chartsheet.
354
+ */
355
+ void
356
+ chartsheet_hide(lxw_chartsheet *self)
357
+ {
358
+ self->hidden = LXW_TRUE;
359
+
360
+ /* A hidden worksheet shouldn't be active or selected. */
361
+ self->selected = LXW_FALSE;
362
+
363
+ /* If this is active_sheet or first_sheet reset the workbook value. */
364
+ if (*self->first_sheet == self->index)
365
+ *self->first_sheet = 0;
366
+
367
+ if (*self->active_sheet == self->index)
368
+ *self->active_sheet = 0;
369
+ }
370
+
371
+ /*
372
+ * Set the color of the chartsheet tab.
373
+ */
374
+ void
375
+ chartsheet_set_tab_color(lxw_chartsheet *self, lxw_color_t color)
376
+ {
377
+ self->worksheet->tab_color = color;
378
+ }
379
+
380
+ /*
381
+ * Set the chartsheet protection flags to prevent modification of chartsheet
382
+ * objects.
383
+ */
384
+ void
385
+ chartsheet_protect(lxw_chartsheet *self, const char *password,
386
+ lxw_protection *options)
387
+ {
388
+ struct lxw_protection *protect = &self->protection;
389
+
390
+ /* Copy any user parameters to the internal structure. */
391
+ if (options) {
392
+ protect->objects = options->no_objects;
393
+ protect->no_content = options->no_content;
394
+ }
395
+ else {
396
+ protect->objects = LXW_FALSE;
397
+ protect->no_content = LXW_FALSE;
398
+ }
399
+
400
+ if (password) {
401
+ uint16_t hash = lxw_hash_password(password);
402
+ lxw_snprintf(protect->hash, 5, "%X", hash);
403
+ }
404
+ else {
405
+ if (protect->objects && protect->no_content)
406
+ return;
407
+ }
408
+
409
+ protect->no_sheet = LXW_TRUE;
410
+ protect->scenarios = LXW_TRUE;
411
+ protect->is_configured = LXW_TRUE;
412
+
413
+ if (self->chart)
414
+ self->chart->is_protected = LXW_TRUE;
415
+ else
416
+ self->is_protected = LXW_TRUE;
417
+ }
418
+
419
+ /*
420
+ * Set the chartsheet zoom factor.
421
+ */
422
+ void
423
+ chartsheet_set_zoom(lxw_chartsheet *self, uint16_t scale)
424
+ {
425
+ /* Confine the scale to Excel"s range */
426
+ if (scale < 10 || scale > 400) {
427
+ LXW_WARN("chartsheet_set_zoom(): "
428
+ "Zoom factor scale outside range: 10 <= zoom <= 400.");
429
+ return;
430
+ }
431
+
432
+ self->worksheet->zoom = scale;
433
+ }
434
+
435
+ /*
436
+ * Set the page orientation as portrait.
437
+ */
438
+ void
439
+ chartsheet_set_portrait(lxw_chartsheet *self)
440
+ {
441
+ worksheet_set_portrait(self->worksheet);
442
+ }
443
+
444
+ /*
445
+ * Set the page orientation as landscape.
446
+ */
447
+ void
448
+ chartsheet_set_landscape(lxw_chartsheet *self)
449
+ {
450
+ worksheet_set_landscape(self->worksheet);
451
+ }
452
+
453
+ /*
454
+ * Set the paper type. Example. 1 = US Letter, 9 = A4
455
+ */
456
+ void
457
+ chartsheet_set_paper(lxw_chartsheet *self, uint8_t paper_size)
458
+ {
459
+ worksheet_set_paper(self->worksheet, paper_size);
460
+ }
461
+
462
+ /*
463
+ * Set all the page margins in inches.
464
+ */
465
+ void
466
+ chartsheet_set_margins(lxw_chartsheet *self, double left, double right,
467
+ double top, double bottom)
468
+ {
469
+ worksheet_set_margins(self->worksheet, left, right, top, bottom);
470
+ }
471
+
472
+ /*
473
+ * Set the page header caption and options.
474
+ */
475
+ lxw_error
476
+ chartsheet_set_header_opt(lxw_chartsheet *self, const char *string,
477
+ lxw_header_footer_options *options)
478
+ {
479
+ return worksheet_set_header_opt(self->worksheet, string, options);
480
+ }
481
+
482
+ /*
483
+ * Set the page footer caption and options.
484
+ */
485
+ lxw_error
486
+ chartsheet_set_footer_opt(lxw_chartsheet *self, const char *string,
487
+ lxw_header_footer_options *options)
488
+ {
489
+ return worksheet_set_footer_opt(self->worksheet, string, options);
490
+ }
491
+
492
+ /*
493
+ * Set the page header caption.
494
+ */
495
+ lxw_error
496
+ chartsheet_set_header(lxw_chartsheet *self, const char *string)
497
+ {
498
+ return chartsheet_set_header_opt(self, string, NULL);
499
+ }
500
+
501
+ /*
502
+ * Set the page footer caption.
503
+ */
504
+ lxw_error
505
+ chartsheet_set_footer(lxw_chartsheet *self, const char *string)
506
+ {
507
+ return chartsheet_set_footer_opt(self, string, NULL);
508
+ }