fast_excel 0.4.1 → 0.5.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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -7
  3. data/CHANGELOG.md +9 -0
  4. data/Gemfile +1 -1
  5. data/examples/example.rb +2 -0
  6. data/examples/example_date_time.rb +38 -0
  7. data/fast_excel.gemspec +2 -2
  8. data/lib/fast_excel/binding/format.rb +17 -0
  9. data/lib/fast_excel/binding/workbook.rb +39 -17
  10. data/lib/fast_excel/binding/worksheet.rb +57 -13
  11. data/lib/fast_excel/binding.rb +7 -7
  12. data/lib/fast_excel.rb +27 -20
  13. data/libxlsxwriter/.github/FUNDING.yml +1 -0
  14. data/libxlsxwriter/.github/ISSUE_TEMPLATE.md +85 -0
  15. data/libxlsxwriter/.github/PULL_REQUEST_TEMPLATE.md +130 -0
  16. data/libxlsxwriter/.github/workflows/cmake_actions.yml +48 -0
  17. data/libxlsxwriter/.github/workflows/code_style.yml +23 -0
  18. data/libxlsxwriter/.github/workflows/coverity.yml +22 -0
  19. data/libxlsxwriter/.github/workflows/make_actions.yml +52 -0
  20. data/libxlsxwriter/.github/workflows/valgrind.yml +23 -0
  21. data/libxlsxwriter/.github/workflows/windows_build.yml +54 -0
  22. data/libxlsxwriter/.github/workflows/zig_build.yml +22 -0
  23. data/libxlsxwriter/.gitignore +16 -1
  24. data/libxlsxwriter/.indent.pro +24 -0
  25. data/libxlsxwriter/CMakeLists.txt +156 -56
  26. data/libxlsxwriter/CONTRIBUTING.md +2 -2
  27. data/libxlsxwriter/Changes.txt +344 -2
  28. data/libxlsxwriter/LICENSE.txt +66 -8
  29. data/libxlsxwriter/Makefile +151 -54
  30. data/libxlsxwriter/Package.swift +42 -0
  31. data/libxlsxwriter/Readme.md +4 -2
  32. data/libxlsxwriter/build.zig +324 -0
  33. data/libxlsxwriter/build.zig.zon +11 -0
  34. data/libxlsxwriter/cmake/FindMINIZIP.cmake +3 -3
  35. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +6 -0
  36. data/libxlsxwriter/include/xlsxwriter/app.h +2 -1
  37. data/libxlsxwriter/include/xlsxwriter/chart.h +236 -32
  38. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +7 -7
  39. data/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
  40. data/libxlsxwriter/include/xlsxwriter/common.h +111 -50
  41. data/libxlsxwriter/include/xlsxwriter/content_types.h +8 -1
  42. data/libxlsxwriter/include/xlsxwriter/core.h +1 -1
  43. data/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
  44. data/libxlsxwriter/include/xlsxwriter/drawing.h +11 -20
  45. data/libxlsxwriter/include/xlsxwriter/format.h +121 -8
  46. data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  47. data/libxlsxwriter/include/xlsxwriter/metadata.h +49 -0
  48. data/libxlsxwriter/include/xlsxwriter/packager.h +27 -16
  49. data/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
  50. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
  51. data/libxlsxwriter/include/xlsxwriter/styles.h +13 -7
  52. data/libxlsxwriter/include/xlsxwriter/table.h +51 -0
  53. data/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
  54. data/libxlsxwriter/include/xlsxwriter/third_party/emyg_dtoa.h +26 -0
  55. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +27 -25
  56. data/libxlsxwriter/include/xlsxwriter/third_party/md5.h +45 -0
  57. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +155 -153
  58. data/libxlsxwriter/include/xlsxwriter/utility.h +70 -8
  59. data/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
  60. data/libxlsxwriter/include/xlsxwriter/workbook.h +218 -47
  61. data/libxlsxwriter/include/xlsxwriter/worksheet.h +2770 -241
  62. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +12 -8
  63. data/libxlsxwriter/include/xlsxwriter.h +4 -2
  64. data/libxlsxwriter/libxlsxwriter.podspec +8 -5
  65. data/libxlsxwriter/src/Makefile +58 -21
  66. data/libxlsxwriter/src/app.c +5 -2
  67. data/libxlsxwriter/src/chart.c +396 -81
  68. data/libxlsxwriter/src/chartsheet.c +22 -22
  69. data/libxlsxwriter/src/comment.c +443 -0
  70. data/libxlsxwriter/src/content_types.c +40 -1
  71. data/libxlsxwriter/src/core.c +2 -2
  72. data/libxlsxwriter/src/custom.c +1 -1
  73. data/libxlsxwriter/src/drawing.c +160 -40
  74. data/libxlsxwriter/src/format.c +109 -25
  75. data/libxlsxwriter/src/hash_table.c +1 -1
  76. data/libxlsxwriter/src/metadata.c +283 -0
  77. data/libxlsxwriter/src/packager.c +794 -94
  78. data/libxlsxwriter/src/relationships.c +1 -1
  79. data/libxlsxwriter/src/shared_strings.c +2 -4
  80. data/libxlsxwriter/src/styles.c +353 -58
  81. data/libxlsxwriter/src/table.c +304 -0
  82. data/libxlsxwriter/src/theme.c +1 -1
  83. data/libxlsxwriter/src/utility.c +143 -43
  84. data/libxlsxwriter/src/vml.c +1062 -0
  85. data/libxlsxwriter/src/workbook.c +567 -77
  86. data/libxlsxwriter/src/worksheet.c +6668 -1462
  87. data/libxlsxwriter/src/xmlwriter.c +95 -5
  88. data/libxlsxwriter/third_party/dtoa/Makefile +42 -0
  89. data/libxlsxwriter/third_party/dtoa/emyg_dtoa.c +461 -0
  90. data/libxlsxwriter/third_party/dtoa/emyg_dtoa.h +26 -0
  91. data/libxlsxwriter/third_party/md5/Makefile +42 -0
  92. data/libxlsxwriter/third_party/md5/md5.c +291 -0
  93. data/libxlsxwriter/third_party/md5/md5.h +45 -0
  94. data/libxlsxwriter/third_party/minizip/Makefile +3 -8
  95. data/libxlsxwriter/third_party/minizip/Makefile.orig +8 -4
  96. data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +1 -1
  97. data/libxlsxwriter/third_party/minizip/configure.ac +1 -1
  98. data/libxlsxwriter/third_party/minizip/crypt.h +13 -16
  99. data/libxlsxwriter/third_party/minizip/ioapi.c +31 -57
  100. data/libxlsxwriter/third_party/minizip/ioapi.h +31 -23
  101. data/libxlsxwriter/third_party/minizip/iowin32.c +29 -45
  102. data/libxlsxwriter/third_party/minizip/iowin32.h +4 -4
  103. data/libxlsxwriter/third_party/minizip/miniunz.c +29 -56
  104. data/libxlsxwriter/third_party/minizip/minizip.c +38 -49
  105. data/libxlsxwriter/third_party/minizip/mztools.c +1 -7
  106. data/libxlsxwriter/third_party/minizip/unzip.c +202 -342
  107. data/libxlsxwriter/third_party/minizip/unzip.h +74 -74
  108. data/libxlsxwriter/third_party/minizip/zip.c +165 -218
  109. data/libxlsxwriter/third_party/minizip/zip.h +164 -154
  110. data/libxlsxwriter/third_party/tmpfileplus/Makefile +3 -3
  111. data/libxlsxwriter/version.txt +1 -1
  112. data/test/auto_width_test.rb +20 -0
  113. data/test/default_format_test.rb +1 -1
  114. data/test/validations_test.rb +3 -3
  115. data/test/worksheet_test.rb +6 -1
  116. metadata +33 -7
  117. data/libxlsxwriter/.travis.yml +0 -37
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libxlsxwriter
3
3
  *
4
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
4
+ * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
5
  */
6
6
 
7
7
  /**
@@ -57,6 +57,7 @@
57
57
  /* Define the tree.h RB structs for the red-black head types. */
58
58
  RB_HEAD(lxw_worksheet_names, lxw_worksheet_name);
59
59
  RB_HEAD(lxw_chartsheet_names, lxw_chartsheet_name);
60
+ RB_HEAD(lxw_image_md5s, lxw_image_md5);
60
61
 
61
62
  /* Define the queue.h structs for the workbook lists. */
62
63
  STAILQ_HEAD(lxw_sheets, lxw_sheet);
@@ -65,7 +66,7 @@ STAILQ_HEAD(lxw_chartsheets, lxw_chartsheet);
65
66
  STAILQ_HEAD(lxw_charts, lxw_chart);
66
67
  TAILQ_HEAD(lxw_defined_names, lxw_defined_name);
67
68
 
68
- /* TODO */
69
+ /* Struct to hold the 2 sheet types. */
69
70
  typedef struct lxw_sheet {
70
71
  uint8_t is_chartsheet;
71
72
 
@@ -93,6 +94,14 @@ typedef struct lxw_chartsheet_name {
93
94
  RB_ENTRY (lxw_chartsheet_name) tree_pointers;
94
95
  } lxw_chartsheet_name;
95
96
 
97
+ /* Struct to represent an image MD5/ID pair. */
98
+ typedef struct lxw_image_md5 {
99
+ uint32_t id;
100
+ char *md5;
101
+
102
+ RB_ENTRY (lxw_image_md5) tree_pointers;
103
+ } lxw_image_md5;
104
+
96
105
  /* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
97
106
  * warnings and to avoid portability issues with the _unused attribute. */
98
107
  #define LXW_RB_GENERATE_WORKSHEET_NAMES(name, type, field, cmp) \
@@ -117,6 +126,17 @@ typedef struct lxw_chartsheet_name {
117
126
  /* Add unused struct to allow adding a semicolon */ \
118
127
  struct lxw_rb_generate_charsheet_names{int unused;}
119
128
 
129
+ #define LXW_RB_GENERATE_IMAGE_MD5S(name, type, field, cmp) \
130
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
131
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
132
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
133
+ RB_GENERATE_REMOVE(name, type, field, static) \
134
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
135
+ RB_GENERATE_NEXT(name, type, field, static) \
136
+ RB_GENERATE_MINMAX(name, type, field, static) \
137
+ /* Add unused struct to allow adding a semicolon */ \
138
+ struct lxw_rb_generate_image_md5s{int unused;}
139
+
120
140
  /**
121
141
  * @brief Macro to loop over all the worksheets in a workbook.
122
142
  *
@@ -158,39 +178,43 @@ typedef struct lxw_defined_name {
158
178
  } lxw_defined_name;
159
179
 
160
180
  /**
161
- * Workbook document properties.
181
+ * Workbook document properties. Set any unused fields to NULL or 0.
162
182
  */
163
183
  typedef struct lxw_doc_properties {
164
184
  /** The title of the Excel Document. */
165
- char *title;
185
+ const char *title;
166
186
 
167
187
  /** The subject of the Excel Document. */
168
- char *subject;
188
+ const char *subject;
169
189
 
170
190
  /** The author of the Excel Document. */
171
- char *author;
191
+ const char *author;
172
192
 
173
193
  /** The manager field of the Excel Document. */
174
- char *manager;
194
+ const char *manager;
175
195
 
176
196
  /** The company field of the Excel Document. */
177
- char *company;
197
+ const char *company;
178
198
 
179
199
  /** The category of the Excel Document. */
180
- char *category;
200
+ const char *category;
181
201
 
182
202
  /** The keywords of the Excel Document. */
183
- char *keywords;
203
+ const char *keywords;
184
204
 
185
205
  /** The comment field of the Excel Document. */
186
- char *comments;
206
+ const char *comments;
187
207
 
188
208
  /** The status of the Excel Document. */
189
- char *status;
209
+ const char *status;
190
210
 
191
- /** The hyperlink base url of the Excel Document. */
192
- char *hyperlink_base;
211
+ /** The hyperlink base URL of the Excel Document. */
212
+ const char *hyperlink_base;
193
213
 
214
+ /** The file creation date/time shown in Excel. This defaults to the
215
+ * current time and date if set to 0. If you wish to create files that are
216
+ * binary equivalent (for the same input data) then you should set this
217
+ * creation date/time to a known value. */
194
218
  time_t created;
195
219
 
196
220
  } lxw_doc_properties;
@@ -205,7 +229,7 @@ typedef struct lxw_doc_properties {
205
229
  *
206
230
  * - `constant_memory`: This option reduces the amount of data stored in
207
231
  * 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.
232
+ * by default. See the notes below for limitations when this mode is on.
209
233
  *
210
234
  * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior to
211
235
  * assembling the final XLSX file. The temporary files are created in the
@@ -219,24 +243,43 @@ typedef struct lxw_doc_properties {
219
243
  * for more information. This option is off by default.
220
244
  *
221
245
  * [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
- *
246
+
247
+ * - `output_buffer`: Output to a buffer instead of a file. The buffer must be
248
+ * freed manually by calling free(). This option can only be used if filename
249
+ * is NULL.
250
+ *
251
+ * - `output_buffer_size`: Used with output_buffer to get the size of the
252
+ * created buffer. This option can only be used if filename is NULL.
253
+ *
254
+ * @note In `constant_memory` mode each row of in-memory data is written to
255
+ * disk and then freed when a new row is started via one of the
256
+ * `worksheet_write_*()` functions. Therefore, once this option is active data
257
+ * should be written in sequential row by row order. For this reason
258
+ * `worksheet_merge_range()` and some other row based functionality doesn't
259
+ * work in this mode. See @ref ww_mem_constant for more details.
260
+ *
261
+ * @note Also, in `constant_memory` mode the library uses temp file storage
262
+ * for worksheet data. This can lead to an issue on OSes that map the `/tmp`
263
+ * directory into memory since it is possible to consume the "system" memory
264
+ * even though the "process" memory remains constant. In these cases you
265
+ * should use an alternative temp file location by using the `tmpdir` option
266
+ * shown above. See @ref ww_mem_temp for more details.
229
267
  */
230
268
  typedef struct lxw_workbook_options {
231
269
  /** Optimize the workbook to use constant memory for worksheets. */
232
270
  uint8_t constant_memory;
233
271
 
234
272
  /** Directory to use for the temporary files created by libxlsxwriter. */
235
- char *tmpdir;
273
+ const char *tmpdir;
236
274
 
237
275
  /** Allow ZIP64 extensions when creating the xlsx file zip container. */
238
276
  uint8_t use_zip64;
239
277
 
278
+ /** Output buffer to use instead of writing to a file */
279
+ const char **output_buffer;
280
+
281
+ /** Used with output_buffer to get the size of the created buffer */
282
+ size_t *output_buffer_size;
240
283
  } lxw_workbook_options;
241
284
 
242
285
  /**
@@ -254,6 +297,9 @@ typedef struct lxw_workbook {
254
297
  struct lxw_chartsheets *chartsheets;
255
298
  struct lxw_worksheet_names *worksheet_names;
256
299
  struct lxw_chartsheet_names *chartsheet_names;
300
+ struct lxw_image_md5s *image_md5s;
301
+ struct lxw_image_md5s *header_image_md5s;
302
+ struct lxw_image_md5s *background_md5s;
257
303
  struct lxw_charts *charts;
258
304
  struct lxw_charts *ordered_charts;
259
305
  struct lxw_formats *formats;
@@ -271,23 +317,35 @@ typedef struct lxw_workbook {
271
317
  uint16_t first_sheet;
272
318
  uint16_t active_sheet;
273
319
  uint16_t num_xf_formats;
320
+ uint16_t num_dxf_formats;
274
321
  uint16_t num_format_count;
275
322
  uint16_t drawing_count;
323
+ uint16_t comment_count;
276
324
 
277
325
  uint16_t font_count;
278
326
  uint16_t border_count;
279
327
  uint16_t fill_count;
280
328
  uint8_t optimize;
329
+ uint16_t max_url_length;
330
+ uint8_t read_only;
281
331
 
282
332
  uint8_t has_png;
283
333
  uint8_t has_jpeg;
284
334
  uint8_t has_bmp;
335
+ uint8_t has_gif;
336
+ uint8_t has_vml;
337
+ uint8_t has_comments;
338
+ uint8_t has_metadata;
285
339
 
286
340
  lxw_hash_table *used_xf_formats;
341
+ lxw_hash_table *used_dxf_formats;
287
342
 
288
343
  char *vba_project;
344
+ char *vba_project_signature;
289
345
  char *vba_codename;
290
346
 
347
+ lxw_format *default_url_format;
348
+
291
349
  } lxw_workbook;
292
350
 
293
351
 
@@ -331,7 +389,9 @@ lxw_workbook *workbook_new(const char *filename);
331
389
  * @code
332
390
  * lxw_workbook_options options = {.constant_memory = LXW_TRUE,
333
391
  * .tmpdir = "C:\\Temp",
334
- * .use_zip64 = LXW_FALSE};
392
+ * .use_zip64 = LXW_FALSE,
393
+ * .output_buffer = NULL,
394
+ * .output_buffer_size = NULL};
335
395
  *
336
396
  * lxw_workbook *workbook = workbook_new_opt("filename.xlsx", &options);
337
397
  * @endcode
@@ -355,23 +415,30 @@ lxw_workbook *workbook_new(const char *filename);
355
415
  *
356
416
  * [zip64_wiki]: https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64
357
417
  *
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.
363
- *
418
+ * - `output_buffer`: Output to a memory buffer instead of a file. The buffer
419
+ * must be freed manually by calling `free()`. This option can only be used if
420
+ * filename is NULL.
421
+ *
422
+ * - `output_buffer_size`: Used with output_buffer to get the size of the
423
+ * created buffer. This option can only be used if filename is `NULL`.
424
+ *
425
+ * @note In `constant_memory` mode each row of in-memory data is written to
426
+ * disk and then freed when a new row is started via one of the
427
+ * `worksheet_write_*()` functions. Therefore, once this option is active data
428
+ * should be written in sequential row by row order. For this reason
429
+ * `worksheet_merge_range()` and some other row based functionality doesn't
430
+ * work in this mode. See @ref ww_mem_constant for more details.
431
+ *
432
+ * @note Also, in `constant_memory` mode the library uses temp file storage
433
+ * for worksheet data. This can lead to an issue on OSes that map the `/tmp`
434
+ * directory into memory since it is possible to consume the "system" memory
435
+ * even though the "process" memory remains constant. In these cases you
436
+ * should use an alternative temp file location by using the `tmpdir` option
437
+ * shown above. See @ref ww_mem_temp for more details.
364
438
  */
365
439
  lxw_workbook *workbook_new_opt(const char *filename,
366
440
  lxw_workbook_options *options);
367
441
 
368
- /* Deprecated function name for backwards compatibility. */
369
- lxw_workbook *new_workbook(const char *filename);
370
-
371
- /* Deprecated function name for backwards compatibility. */
372
- lxw_workbook *new_workbook_opt(const char *filename,
373
- lxw_workbook_options *options);
374
-
375
442
  /**
376
443
  * @brief Add a new worksheet to a workbook.
377
444
  *
@@ -404,12 +471,15 @@ lxw_workbook *new_workbook_opt(const char *filename,
404
471
  * - The name is less than or equal to 31 UTF-8 characters.
405
472
  * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
406
473
  * - The name doesn't start or end with an apostrophe.
407
- * - The name isn't "History", which is reserved by Excel. (Case insensitive).
408
474
  * - The name isn't already in use. (Case insensitive).
409
475
  *
410
476
  * If any of these errors are encountered the function will return NULL.
411
477
  * You can check for valid name using the `workbook_validate_sheet_name()`
412
478
  * function.
479
+ *
480
+ * @note You should also avoid using the worksheet name "History" (case
481
+ * insensitive) which is reserved in English language versions of
482
+ * Excel. Non-English versions may have restrictions on the equivalent word.
413
483
  */
414
484
  lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
415
485
  const char *sheetname);
@@ -443,13 +513,16 @@ lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
443
513
  * - The name is less than or equal to 31 UTF-8 characters.
444
514
  * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
445
515
  * - The name doesn't start or end with an apostrophe.
446
- * - The name isn't "History", which is reserved by Excel. (Case insensitive).
447
516
  * - The name isn't already in use. (Case insensitive).
448
517
  *
449
518
  * If any of these errors are encountered the function will return NULL.
450
519
  * You can check for valid name using the `workbook_validate_sheet_name()`
451
520
  * function.
452
521
  *
522
+ * @note You should also avoid using the worksheet name "History" (case
523
+ * insensitive) which is reserved in English language versions of
524
+ * Excel. Non-English versions may have restrictions on the equivalent word.
525
+ *
453
526
  * At least one worksheet should be added to a new workbook when creating a
454
527
  * chartsheet in order to provide data for the chart. The @ref worksheet.h
455
528
  * "Worksheet" object is used to write data and configure a worksheet in the
@@ -533,6 +606,8 @@ lxw_format *workbook_default_format(lxw_workbook *workbook);
533
606
  * | #LXW_CHART_COLUMN_STACKED_PERCENT | Column chart - percentage stacked. |
534
607
  * | #LXW_CHART_DOUGHNUT | Doughnut chart. |
535
608
  * | #LXW_CHART_LINE | Line chart. |
609
+ * | #LXW_CHART_LINE_STACKED | Line chart - stacked. |
610
+ * | #LXW_CHART_LINE_STACKED_PERCENT | Line chart - percentage stacked. |
536
611
  * | #LXW_CHART_PIE | Pie chart. |
537
612
  * | #LXW_CHART_SCATTER | Scatter chart. |
538
613
  * | #LXW_CHART_SCATTER_STRAIGHT | Scatter chart - straight. |
@@ -600,10 +675,11 @@ lxw_error workbook_close(lxw_workbook *workbook);
600
675
  * - `keywords`
601
676
  * - `comments`
602
677
  * - `hyperlink_base`
678
+ * - `created`
603
679
  *
604
680
  * The properties are specified via a `lxw_doc_properties` struct. All the
605
- * members are `char *` and they are all optional. An example of how to create
606
- * and pass the properties is:
681
+ * fields are all optional. An example of how to create and pass the
682
+ * properties is:
607
683
  *
608
684
  * @code
609
685
  * // Create a properties structure and set some of the fields.
@@ -625,6 +701,12 @@ lxw_error workbook_close(lxw_workbook *workbook);
625
701
  *
626
702
  * @image html doc_properties.png
627
703
  *
704
+ * The `created` parameter sets the file creation date/time shown in
705
+ * Excel. This defaults to the current time and date if set to 0. If you wish
706
+ * to create files that are binary equivalent (for the same input data) then
707
+ * you should set this creation date/time to a known value using a `time_t`
708
+ * value.
709
+ *
628
710
  */
629
711
  lxw_error workbook_set_properties(lxw_workbook *workbook,
630
712
  lxw_doc_properties *properties);
@@ -777,13 +859,32 @@ lxw_error workbook_set_custom_property_datetime(lxw_workbook *workbook,
777
859
  * @endcode
778
860
  *
779
861
  * The rules for names in Excel are explained in the
780
- * [Microsoft Office
781
- documentation](http://office.microsoft.com/en-001/excel-help/define-and-use-names-in-formulas-HA010147120.aspx).
862
+ * [Microsoft Office documentation](http://office.microsoft.com/en-001/excel-help/define-and-use-names-in-formulas-HA010147120.aspx).
782
863
  *
783
864
  */
784
865
  lxw_error workbook_define_name(lxw_workbook *workbook, const char *name,
785
866
  const char *formula);
786
867
 
868
+ /**
869
+ * @brief Get the default URL format used with `worksheet_write_url()`.
870
+ *
871
+ * @param workbook Pointer to a lxw_workbook instance.
872
+ * @return A lxw_format instance that has hyperlink properties set.
873
+ *
874
+ * This function returns a lxw_format instance that is used for the default
875
+ * blue underline hyperlink in the `worksheet_write_url()` function when a
876
+ * format isn't specified:
877
+ *
878
+ * @code
879
+ * lxw_format *url_format = workbook_get_default_url_format(workbook);
880
+ * @endcode
881
+ *
882
+ * The format is the hyperlink style defined by Excel for the default theme.
883
+ * This format is only ever required when overwriting a string URL with
884
+ * data of a different type. See the example below.
885
+ */
886
+ lxw_format *workbook_get_default_url_format(lxw_workbook *workbook);
887
+
787
888
  /**
788
889
  * @brief Get a worksheet object from its name.
789
890
  *
@@ -834,7 +935,6 @@ lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
834
935
  * - The name is less than or equal to 31 UTF-8 characters.
835
936
  * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
836
937
  * - The name doesn't start or end with an apostrophe.
837
- * - The name isn't "History", which is reserved by Excel. (Case insensitive).
838
938
  * - The name isn't already in use. (Case insensitive, see the note below).
839
939
  *
840
940
  * @code
@@ -845,6 +945,10 @@ lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
845
945
  * `workbook_add_chartsheet()` but it can be explicitly called by the user
846
946
  * beforehand to ensure that the sheet name is valid.
847
947
  *
948
+ * @note You should also avoid using the worksheet name "History" (case
949
+ * insensitive) which is reserved in English language versions of
950
+ * Excel. Non-English versions may have restrictions on the equivalent word.
951
+ *
848
952
  * @note This function does an ASCII lowercase string comparison to determine
849
953
  * if the sheet name is already in use. It doesn't take UTF-8 characters into
850
954
  * account. Thus it would flag "Café" and "café" as a duplicate (just like
@@ -869,13 +973,54 @@ lxw_error workbook_validate_sheet_name(lxw_workbook *workbook,
869
973
  * workbook_add_vba_project(workbook, "vbaProject.bin");
870
974
  * @endcode
871
975
  *
872
- * Only one `vbaProject.bin file` can be added per workbook.
976
+ * Only one `vbaProject.bin` file can be added per workbook. The name doesn't
977
+ * have to be `vbaProject.bin`. Any suitable path/name for an existing VBA bin
978
+ * file will do.
979
+ *
980
+ * Once you add a VBA project had been add to an libxlsxwriter workbook you
981
+ * should ensure that the file extension is `.xlsm` to prevent Excel from
982
+ * giving a warning when it opens the file:
983
+ *
984
+ * @code
985
+ * lxw_workbook *workbook = new_workbook("macro.xlsm");
986
+ * @endcode
987
+ *
988
+ * See also @ref working_with_macros
873
989
  *
874
990
  * @return A #lxw_error.
875
991
  */
876
992
  lxw_error workbook_add_vba_project(lxw_workbook *workbook,
877
993
  const char *filename);
878
994
 
995
+ /**
996
+ * @brief Add a vbaProject binary and a vbaProjectSignature binary to the Excel
997
+ * workbook.
998
+ *
999
+ * @param workbook Pointer to a lxw_workbook instance.
1000
+ * @param vba_project The path/filename of the vbaProject.bin file.
1001
+ * @param signature The path/filename of the vbaProjectSignature.bin file.
1002
+ *
1003
+ * The `%workbook_add_signed_vba_project()` function can be used to add digitally
1004
+ * signed macros or functions to a workbook. The function adds a binary VBA project
1005
+ * file and a binary VBA project signature file that have been extracted from an
1006
+ * existing Excel xlsm file with digitally signed macros:
1007
+ *
1008
+ * @code
1009
+ * workbook_add_signed_vba_project(workbook, "vbaProject.bin", "vbaProjectSignature.bin");
1010
+ * @endcode
1011
+ *
1012
+ * Only one `vbaProject.bin` file can be added per workbook. The name doesn't
1013
+ * have to be `vbaProject.bin`. Any suitable path/name for an existing VBA bin
1014
+ * file will do. The same applies for `vbaProjectSignature.bin`.
1015
+ *
1016
+ * See also @ref working_with_macros
1017
+ *
1018
+ * @return A #lxw_error.
1019
+ */
1020
+ lxw_error workbook_add_signed_vba_project(lxw_workbook *workbook,
1021
+ const char *vba_project,
1022
+ const char *signature);
1023
+
879
1024
  /**
880
1025
  * @brief Set the VBA name for the workbook.
881
1026
  *
@@ -884,21 +1029,47 @@ lxw_error workbook_add_vba_project(lxw_workbook *workbook,
884
1029
  *
885
1030
  * The `workbook_set_vba_name()` function can be used to set the VBA name for
886
1031
  * the workbook. This is sometimes required when a vbaProject macro included
887
- * via `workbook_add_vba_project()` refers to the workbook.
1032
+ * via `workbook_add_vba_project()` refers to the workbook by a name other
1033
+ * than `ThisWorkbook`.
888
1034
  *
889
1035
  * @code
890
1036
  * workbook_set_vba_name(workbook, "MyWorkbook");
891
1037
  * @endcode
892
1038
  *
893
- * The most common Excel VBA name for a workbook is `ThisWorkbook`.
1039
+ * If an Excel VBA name for the workbook isn't specified then libxlsxwriter
1040
+ * will use `ThisWorkbook`.
1041
+ *
1042
+ * See also @ref working_with_macros
894
1043
  *
895
1044
  * @return A #lxw_error.
896
1045
  */
897
1046
  lxw_error workbook_set_vba_name(lxw_workbook *workbook, const char *name);
898
1047
 
1048
+ /**
1049
+ * @brief Add a recommendation to open the file in "read-only" mode.
1050
+ *
1051
+ * @param workbook Pointer to a lxw_workbook instance.
1052
+ *
1053
+ * This function can be used to set the Excel "Read-only Recommended" option
1054
+ * that is available when saving a file. This presents the user of the file
1055
+ * with an option to open it in "read-only" mode. This means that any changes
1056
+ * to the file can't be saved back to the same file and must be saved to a new
1057
+ * file. It can be set as follows:
1058
+ *
1059
+ * @code
1060
+ * workbook_read_only_recommended(workbook);
1061
+ * @endcode
1062
+ *
1063
+ * Which will raise a dialog like the following when opening the file:
1064
+ *
1065
+ * @image html read_only.png
1066
+ */
1067
+ void workbook_read_only_recommended(lxw_workbook *workbook);
1068
+
899
1069
  void lxw_workbook_free(lxw_workbook *workbook);
900
1070
  void lxw_workbook_assemble_xml_file(lxw_workbook *workbook);
901
1071
  void lxw_workbook_set_default_xf_indices(lxw_workbook *workbook);
1072
+ void workbook_unset_default_url_format(lxw_workbook *workbook);
902
1073
 
903
1074
  /* Declarations required for unit testing. */
904
1075
  #ifdef TESTING