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
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libxlsxwriter
3
3
  *
4
- * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
4
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
5
  */
6
6
 
7
7
  /**
@@ -46,6 +46,7 @@
46
46
  #include <errno.h>
47
47
 
48
48
  #include "worksheet.h"
49
+ #include "chartsheet.h"
49
50
  #include "chart.h"
50
51
  #include "shared_strings.h"
51
52
  #include "hash_table.h"
@@ -55,12 +56,27 @@
55
56
 
56
57
  /* Define the tree.h RB structs for the red-black head types. */
57
58
  RB_HEAD(lxw_worksheet_names, lxw_worksheet_name);
59
+ RB_HEAD(lxw_chartsheet_names, lxw_chartsheet_name);
58
60
 
59
61
  /* Define the queue.h structs for the workbook lists. */
62
+ STAILQ_HEAD(lxw_sheets, lxw_sheet);
60
63
  STAILQ_HEAD(lxw_worksheets, lxw_worksheet);
64
+ STAILQ_HEAD(lxw_chartsheets, lxw_chartsheet);
61
65
  STAILQ_HEAD(lxw_charts, lxw_chart);
62
66
  TAILQ_HEAD(lxw_defined_names, lxw_defined_name);
63
67
 
68
+ /* TODO */
69
+ typedef struct lxw_sheet {
70
+ uint8_t is_chartsheet;
71
+
72
+ union {
73
+ lxw_worksheet *worksheet;
74
+ lxw_chartsheet *chartsheet;
75
+ } u;
76
+
77
+ STAILQ_ENTRY (lxw_sheet) list_pointers;
78
+ } lxw_sheet;
79
+
64
80
  /* Struct to represent a worksheet name/pointer pair. */
65
81
  typedef struct lxw_worksheet_name {
66
82
  const char *name;
@@ -69,18 +85,37 @@ typedef struct lxw_worksheet_name {
69
85
  RB_ENTRY (lxw_worksheet_name) tree_pointers;
70
86
  } lxw_worksheet_name;
71
87
 
88
+ /* Struct to represent a chartsheet name/pointer pair. */
89
+ typedef struct lxw_chartsheet_name {
90
+ const char *name;
91
+ lxw_chartsheet *chartsheet;
92
+
93
+ RB_ENTRY (lxw_chartsheet_name) tree_pointers;
94
+ } lxw_chartsheet_name;
95
+
72
96
  /* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
73
97
  * warnings and to avoid portability issues with the _unused attribute. */
74
- #define LXW_RB_GENERATE_NAMES(name, type, field, cmp) \
75
- RB_GENERATE_INSERT_COLOR(name, type, field, static) \
76
- RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
77
- RB_GENERATE_INSERT(name, type, field, cmp, static) \
78
- RB_GENERATE_REMOVE(name, type, field, static) \
79
- RB_GENERATE_FIND(name, type, field, cmp, static) \
80
- RB_GENERATE_NEXT(name, type, field, static) \
81
- RB_GENERATE_MINMAX(name, type, field, static) \
82
- /* Add unused struct to allow adding a semicolon */ \
83
- struct lxw_rb_generate_names{int unused;}
98
+ #define LXW_RB_GENERATE_WORKSHEET_NAMES(name, type, field, cmp) \
99
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
100
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
101
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
102
+ RB_GENERATE_REMOVE(name, type, field, static) \
103
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
104
+ RB_GENERATE_NEXT(name, type, field, static) \
105
+ RB_GENERATE_MINMAX(name, type, field, static) \
106
+ /* Add unused struct to allow adding a semicolon */ \
107
+ struct lxw_rb_generate_worksheet_names{int unused;}
108
+
109
+ #define LXW_RB_GENERATE_CHARTSHEET_NAMES(name, type, field, cmp) \
110
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
111
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
112
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
113
+ RB_GENERATE_REMOVE(name, type, field, static) \
114
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
115
+ RB_GENERATE_NEXT(name, type, field, static) \
116
+ RB_GENERATE_MINMAX(name, type, field, static) \
117
+ /* Add unused struct to allow adding a semicolon */ \
118
+ struct lxw_rb_generate_charsheet_names{int unused;}
84
119
 
85
120
  /**
86
121
  * @brief Macro to loop over all the worksheets in a workbook.
@@ -168,27 +203,40 @@ typedef struct lxw_doc_properties {
168
203
  *
169
204
  * The following properties are supported:
170
205
  *
171
- * - `constant_memory`: Reduces the amount of data stored in memory so that
172
- * large files can be written efficiently.
173
- *
174
- * @note In this mode a row of data is written and then discarded when a
175
- * cell in a new row is added via one of the `worksheet_write_*()`
176
- * functions. Therefore, once this option is active, data should be written in
177
- * sequential row order. For this reason the `worksheet_merge_range()`
178
- * doesn't work in this mode. See also @ref ww_mem_constant.
206
+ * - `constant_memory`: This option reduces the amount of data stored in
207
+ * memory so that large files can be written efficiently. This option is off
208
+ * by default. See the note below for limitations when this mode is on.
179
209
  *
180
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
181
- * to assembling the final XLSX file. The temporary files are created in the
210
+ * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior to
211
+ * assembling the final XLSX file. The temporary files are created in the
182
212
  * system's temp directory. If the default temporary directory isn't
183
213
  * accessible to your application, or doesn't contain enough space, you can
184
- * specify an alternative location using the `tempdir` option.
214
+ * specify an alternative location using the `tmpdir` option.
215
+ *
216
+ * - `use_zip64`: Make the zip library use ZIP64 extensions when writing very
217
+ * large xlsx files to allow the zip container, or individual XML files
218
+ * within it, to be greater than 4 GB. See [ZIP64 on Wikipedia][zip64_wiki]
219
+ * for more information. This option is off by default.
220
+ *
221
+ * [zip64_wiki]: https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64
222
+ *
223
+ * @note In `constant_memory` mode a row of data is written and then discarded
224
+ * when a cell in a new row is added via one of the `worksheet_write_*()`
225
+ * functions. Therefore, once this option is active, data should be written in
226
+ * sequential row order. For this reason the `worksheet_merge_range()` doesn't
227
+ * work in this mode. See also @ref ww_mem_constant.
228
+ *
185
229
  */
186
230
  typedef struct lxw_workbook_options {
187
- /** Optimize the workbook to use constant memory for worksheets */
231
+ /** Optimize the workbook to use constant memory for worksheets. */
188
232
  uint8_t constant_memory;
189
233
 
190
234
  /** Directory to use for the temporary files created by libxlsxwriter. */
191
235
  char *tmpdir;
236
+
237
+ /** Allow ZIP64 extensions when creating the xlsx file zip container. */
238
+ uint8_t use_zip64;
239
+
192
240
  } lxw_workbook_options;
193
241
 
194
242
  /**
@@ -201,8 +249,11 @@ typedef struct lxw_workbook_options {
201
249
  typedef struct lxw_workbook {
202
250
 
203
251
  FILE *file;
252
+ struct lxw_sheets *sheets;
204
253
  struct lxw_worksheets *worksheets;
254
+ struct lxw_chartsheets *chartsheets;
205
255
  struct lxw_worksheet_names *worksheet_names;
256
+ struct lxw_chartsheet_names *chartsheet_names;
206
257
  struct lxw_charts *charts;
207
258
  struct lxw_charts *ordered_charts;
208
259
  struct lxw_formats *formats;
@@ -215,6 +266,8 @@ typedef struct lxw_workbook {
215
266
  lxw_workbook_options options;
216
267
 
217
268
  uint16_t num_sheets;
269
+ uint16_t num_worksheets;
270
+ uint16_t num_chartsheets;
218
271
  uint16_t first_sheet;
219
272
  uint16_t active_sheet;
220
273
  uint16_t num_xf_formats;
@@ -232,6 +285,9 @@ typedef struct lxw_workbook {
232
285
 
233
286
  lxw_hash_table *used_xf_formats;
234
287
 
288
+ char *vba_project;
289
+ char *vba_codename;
290
+
235
291
  } lxw_workbook;
236
292
 
237
293
 
@@ -273,30 +329,37 @@ lxw_workbook *workbook_new(const char *filename);
273
329
  * additional options to be set.
274
330
  *
275
331
  * @code
276
- * lxw_workbook_options options = {.constant_memory = 1,
277
- * .tmpdir = "C:\\Temp"};
332
+ * lxw_workbook_options options = {.constant_memory = LXW_TRUE,
333
+ * .tmpdir = "C:\\Temp",
334
+ * .use_zip64 = LXW_FALSE};
278
335
  *
279
336
  * lxw_workbook *workbook = workbook_new_opt("filename.xlsx", &options);
280
337
  * @endcode
281
338
  *
282
339
  * The options that can be set via #lxw_workbook_options are:
283
340
  *
284
- * - `constant_memory`: Reduces the amount of data stored in memory so that
285
- * large files can be written efficiently.
286
- *
287
- * @note In this mode a row of data is written and then discarded when a
288
- * cell in a new row is added via one of the `worksheet_write_*()`
289
- * functions. Therefore, once this option is active, data should be written in
290
- * sequential row order. For this reason the `worksheet_merge_range()`
291
- * doesn't work in this mode. See also @ref ww_mem_constant.
341
+ * - `constant_memory`: This option reduces the amount of data stored in
342
+ * memory so that large files can be written efficiently. This option is off
343
+ * by default. See the note below for limitations when this mode is on.
292
344
  *
293
- * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior
294
- * to assembling the final XLSX file. The temporary files are created in the
345
+ * - `tmpdir`: libxlsxwriter stores workbook data in temporary files prior to
346
+ * assembling the final XLSX file. The temporary files are created in the
295
347
  * system's temp directory. If the default temporary directory isn't
296
348
  * accessible to your application, or doesn't contain enough space, you can
297
- * specify an alternative location using the `tempdir` option.*
349
+ * specify an alternative location using the `tmpdir` option.
298
350
  *
299
- * See @ref working_with_memory for more details.
351
+ * - `use_zip64`: Make the zip library use ZIP64 extensions when writing very
352
+ * large xlsx files to allow the zip container, or individual XML files
353
+ * within it, to be greater than 4 GB. See [ZIP64 on Wikipedia][zip64_wiki]
354
+ * for more information. This option is off by default.
355
+ *
356
+ * [zip64_wiki]: https://en.wikipedia.org/wiki/Zip_(file_format)#ZIP64
357
+ *
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.
300
363
  *
301
364
  */
302
365
  lxw_workbook *workbook_new_opt(const char *filename,
@@ -317,7 +380,7 @@ lxw_workbook *new_workbook_opt(const char *filename,
317
380
  *
318
381
  * @return A lxw_worksheet object.
319
382
  *
320
- * The `%workbook_add_worksheet()` function adds a new worksheet to a workbook:
383
+ * The `%workbook_add_worksheet()` function adds a new worksheet to a workbook.
321
384
  *
322
385
  * At least one worksheet should be added to a new workbook: The @ref
323
386
  * worksheet.h "Worksheet" object is used to write data and configure a
@@ -336,18 +399,65 @@ lxw_workbook *new_workbook_opt(const char *filename,
336
399
  *
337
400
  * @image html workbook02.png
338
401
  *
339
- * The worksheet name must be a valid Excel worksheet name, i.e. it must be
340
- * less than 32 character and it cannot contain any of the characters:
402
+ * The worksheet name must be a valid Excel worksheet name, i.e:
341
403
  *
342
- * / \ [ ] : * ?
343
- *
344
- * In addition, you cannot use the same, case insensitive, `sheetname` for more
345
- * than one worksheet.
404
+ * - The name is less than or equal to 31 UTF-8 characters.
405
+ * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
406
+ * - The name doesn't start or end with an apostrophe.
407
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
408
+ * - The name isn't already in use. (Case insensitive).
346
409
  *
410
+ * If any of these errors are encountered the function will return NULL.
411
+ * You can check for valid name using the `workbook_validate_sheet_name()`
412
+ * function.
347
413
  */
348
414
  lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
349
415
  const char *sheetname);
350
416
 
417
+ /**
418
+ * @brief Add a new chartsheet to a workbook.
419
+ *
420
+ * @param workbook Pointer to a lxw_workbook instance.
421
+ * @param sheetname Optional chartsheet name, defaults to Chart1, etc.
422
+ *
423
+ * @return A lxw_chartsheet object.
424
+ *
425
+ * The `%workbook_add_chartsheet()` function adds a new chartsheet to a
426
+ * workbook. The @ref chartsheet.h "Chartsheet" object is like a worksheet
427
+ * except it displays a chart instead of cell data.
428
+ *
429
+ * @image html chartsheet.png
430
+ *
431
+ * The `sheetname` parameter is optional. If it is `NULL` the default
432
+ * Excel convention will be followed, i.e. Chart1, Chart2, etc.:
433
+ *
434
+ * @code
435
+ * chartsheet = workbook_add_chartsheet(workbook, NULL ); // Chart1
436
+ * chartsheet = workbook_add_chartsheet(workbook, "My Chart"); // My Chart
437
+ * chartsheet = workbook_add_chartsheet(workbook, NULL ); // Chart3
438
+ *
439
+ * @endcode
440
+ *
441
+ * The chartsheet name must be a valid Excel worksheet name, i.e.:
442
+ *
443
+ * - The name is less than or equal to 31 UTF-8 characters.
444
+ * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
445
+ * - The name doesn't start or end with an apostrophe.
446
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
447
+ * - The name isn't already in use. (Case insensitive).
448
+ *
449
+ * If any of these errors are encountered the function will return NULL.
450
+ * You can check for valid name using the `workbook_validate_sheet_name()`
451
+ * function.
452
+ *
453
+ * At least one worksheet should be added to a new workbook when creating a
454
+ * chartsheet in order to provide data for the chart. The @ref worksheet.h
455
+ * "Worksheet" object is used to write data and configure a worksheet in the
456
+ * workbook.
457
+ */
458
+ lxw_chartsheet *workbook_add_chartsheet(lxw_workbook *workbook,
459
+ const char *sheetname);
460
+
351
461
  /**
352
462
  * @brief Create a new @ref format.h "Format" object to formats cells in
353
463
  * worksheets.
@@ -677,8 +787,8 @@ lxw_error workbook_define_name(lxw_workbook *workbook, const char *name,
677
787
  /**
678
788
  * @brief Get a worksheet object from its name.
679
789
  *
680
- * @param workbook
681
- * @param name
790
+ * @param workbook Pointer to a lxw_workbook instance.
791
+ * @param name Worksheet name.
682
792
  *
683
793
  * @return A lxw_worksheet object.
684
794
  *
@@ -693,31 +803,98 @@ lxw_worksheet *workbook_get_worksheet_by_name(lxw_workbook *workbook,
693
803
  const char *name);
694
804
 
695
805
  /**
696
- * @brief Validate a worksheet name.
806
+ * @brief Get a chartsheet object from its name.
807
+ *
808
+ * @param workbook Pointer to a lxw_workbook instance.
809
+ * @param name chartsheet name.
810
+ *
811
+ * @return A lxw_chartsheet object.
812
+ *
813
+ * This function returns a lxw_chartsheet object reference based on its name:
814
+ *
815
+ * @code
816
+ * chartsheet = workbook_get_chartsheet_by_name(workbook, "Chart1");
817
+ * @endcode
818
+ *
819
+ */
820
+ lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
821
+ const char *name);
822
+
823
+ /**
824
+ * @brief Validate a worksheet or chartsheet name.
697
825
  *
698
826
  * @param workbook Pointer to a lxw_workbook instance.
699
- * @param sheetname Worksheet name to validate.
827
+ * @param sheetname Sheet name to validate.
700
828
  *
701
829
  * @return A #lxw_error.
702
830
  *
703
- * This function is used to validate a worksheet name according to the rules
704
- * used by Excel:
831
+ * This function is used to validate a worksheet or chartsheet name according
832
+ * to the rules used by Excel:
705
833
  *
706
834
  * - The name is less than or equal to 31 UTF-8 characters.
707
835
  * - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
708
- * - The name isn't already in use.
836
+ * - The name doesn't start or end with an apostrophe.
837
+ * - The name isn't "History", which is reserved by Excel. (Case insensitive).
838
+ * - The name isn't already in use. (Case insensitive, see the note below).
709
839
  *
710
840
  * @code
711
- * lxw_error err = workbook_validate_worksheet_name(workbook, "Foglio");
841
+ * lxw_error err = workbook_validate_sheet_name(workbook, "Foglio");
712
842
  * @endcode
713
843
  *
714
- * This function is called by `workbook_add_worksheet()` but it can be
715
- * explicitly called by the user beforehand to ensure that the worksheet
716
- * name is valid.
844
+ * This function is called by `workbook_add_worksheet()` and
845
+ * `workbook_add_chartsheet()` but it can be explicitly called by the user
846
+ * beforehand to ensure that the sheet name is valid.
847
+ *
848
+ * @note This function does an ASCII lowercase string comparison to determine
849
+ * if the sheet name is already in use. It doesn't take UTF-8 characters into
850
+ * account. Thus it would flag "Café" and "café" as a duplicate (just like
851
+ * Excel) but it wouldn't catch "CAFÉ". If you need a full UTF-8 case
852
+ * insensitive check you should use a third party library to implement it.
853
+ *
854
+ */
855
+ lxw_error workbook_validate_sheet_name(lxw_workbook *workbook,
856
+ const char *sheetname);
857
+
858
+ /**
859
+ * @brief Add a vbaProject binary to the Excel workbook.
860
+ *
861
+ * @param workbook Pointer to a lxw_workbook instance.
862
+ * @param filename The path/filename of the vbaProject.bin file.
717
863
  *
864
+ * The `%workbook_add_vba_project()` function can be used to add macros or
865
+ * functions to a workbook using a binary VBA project file that has been
866
+ * extracted from an existing Excel xlsm file:
867
+ *
868
+ * @code
869
+ * workbook_add_vba_project(workbook, "vbaProject.bin");
870
+ * @endcode
871
+ *
872
+ * Only one `vbaProject.bin file` can be added per workbook.
873
+ *
874
+ * @return A #lxw_error.
875
+ */
876
+ lxw_error workbook_add_vba_project(lxw_workbook *workbook,
877
+ const char *filename);
878
+
879
+ /**
880
+ * @brief Set the VBA name for the workbook.
881
+ *
882
+ * @param workbook Pointer to a lxw_workbook instance.
883
+ * @param name Name of the workbook used by VBA.
884
+ *
885
+ * The `workbook_set_vba_name()` function can be used to set the VBA name for
886
+ * the workbook. This is sometimes required when a vbaProject macro included
887
+ * via `workbook_add_vba_project()` refers to the workbook.
888
+ *
889
+ * @code
890
+ * workbook_set_vba_name(workbook, "MyWorkbook");
891
+ * @endcode
892
+ *
893
+ * The most common Excel VBA name for a workbook is `ThisWorkbook`.
894
+ *
895
+ * @return A #lxw_error.
718
896
  */
719
- lxw_error workbook_validate_worksheet_name(lxw_workbook *workbook,
720
- const char *sheetname);
897
+ lxw_error workbook_set_vba_name(lxw_workbook *workbook, const char *name);
721
898
 
722
899
  void lxw_workbook_free(lxw_workbook *workbook);
723
900
  void lxw_workbook_assemble_xml_file(lxw_workbook *workbook);
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libxlsxwriter
3
3
  *
4
- * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
4
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
5
  */
6
6
 
7
7
  /**
@@ -53,18 +53,19 @@
53
53
  #include "drawing.h"
54
54
  #include "common.h"
55
55
  #include "format.h"
56
+ #include "styles.h"
56
57
  #include "utility.h"
57
58
 
58
- #define LXW_ROW_MAX 1048576
59
- #define LXW_COL_MAX 16384
60
- #define LXW_COL_META_MAX 128
59
+ #define LXW_ROW_MAX 1048576
60
+ #define LXW_COL_MAX 16384
61
+ #define LXW_COL_META_MAX 128
61
62
  #define LXW_HEADER_FOOTER_MAX 255
62
- #define LXW_MAX_NUMBER_URLS 65530
63
- #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
63
+ #define LXW_MAX_NUMBER_URLS 65530
64
+ #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
64
65
 
65
66
  /* The Excel 2007 specification says that the maximum number of page
66
67
  * breaks is 1026. However, in practice it is actually 1023. */
67
- #define LXW_BREAKS_MAX 1023
68
+ #define LXW_BREAKS_MAX 1023
68
69
 
69
70
  /** Default column width in Excel */
70
71
  #define LXW_DEF_COL_WIDTH (double)8.43
@@ -76,18 +77,136 @@
76
77
  enum lxw_gridlines {
77
78
  /** Hide screen and print gridlines. */
78
79
  LXW_HIDE_ALL_GRIDLINES = 0,
80
+
79
81
  /** Show screen gridlines. */
80
82
  LXW_SHOW_SCREEN_GRIDLINES,
83
+
81
84
  /** Show print gridlines. */
82
85
  LXW_SHOW_PRINT_GRIDLINES,
86
+
83
87
  /** Show screen and print gridlines. */
84
88
  LXW_SHOW_ALL_GRIDLINES
85
89
  };
86
90
 
91
+ /** Data validation property values. */
92
+ enum lxw_validation_boolean {
93
+ LXW_VALIDATION_DEFAULT,
94
+
95
+ /** Turn a data validation property off. */
96
+ LXW_VALIDATION_OFF,
97
+
98
+ /** Turn a data validation property on. Data validation properties are
99
+ * generally on by default. */
100
+ LXW_VALIDATION_ON
101
+ };
102
+
103
+ /** Data validation types. */
104
+ enum lxw_validation_types {
105
+ LXW_VALIDATION_TYPE_NONE,
106
+
107
+ /** Restrict cell input to whole/integer numbers only. */
108
+ LXW_VALIDATION_TYPE_INTEGER,
109
+
110
+ /** Restrict cell input to whole/integer numbers only, using a cell
111
+ * reference. */
112
+ LXW_VALIDATION_TYPE_INTEGER_FORMULA,
113
+
114
+ /** Restrict cell input to decimal numbers only. */
115
+ LXW_VALIDATION_TYPE_DECIMAL,
116
+
117
+ /** Restrict cell input to decimal numbers only, using a cell
118
+ * reference. */
119
+ LXW_VALIDATION_TYPE_DECIMAL_FORMULA,
120
+
121
+ /** Restrict cell input to a list of strings in a dropdown. */
122
+ LXW_VALIDATION_TYPE_LIST,
123
+
124
+ /** Restrict cell input to a list of strings in a dropdown, using a
125
+ * cell range. */
126
+ LXW_VALIDATION_TYPE_LIST_FORMULA,
127
+
128
+ /** Restrict cell input to date values only, using a lxw_datetime type. */
129
+ LXW_VALIDATION_TYPE_DATE,
130
+
131
+ /** Restrict cell input to date values only, using a cell reference. */
132
+ LXW_VALIDATION_TYPE_DATE_FORMULA,
133
+
134
+ /* Restrict cell input to date values only, as a serial number.
135
+ * Undocumented. */
136
+ LXW_VALIDATION_TYPE_DATE_NUMBER,
137
+
138
+ /** Restrict cell input to time values only, using a lxw_datetime type. */
139
+ LXW_VALIDATION_TYPE_TIME,
140
+
141
+ /** Restrict cell input to time values only, using a cell reference. */
142
+ LXW_VALIDATION_TYPE_TIME_FORMULA,
143
+
144
+ /* Restrict cell input to time values only, as a serial number.
145
+ * Undocumented. */
146
+ LXW_VALIDATION_TYPE_TIME_NUMBER,
147
+
148
+ /** Restrict cell input to strings of defined length, using a cell
149
+ * reference. */
150
+ LXW_VALIDATION_TYPE_LENGTH,
151
+
152
+ /** Restrict cell input to strings of defined length, using a cell
153
+ * reference. */
154
+ LXW_VALIDATION_TYPE_LENGTH_FORMULA,
155
+
156
+ /** Restrict cell to input controlled by a custom formula that returns
157
+ * `TRUE/FALSE`. */
158
+ LXW_VALIDATION_TYPE_CUSTOM_FORMULA,
159
+
160
+ /** Allow any type of input. Mainly only useful for pop-up messages. */
161
+ LXW_VALIDATION_TYPE_ANY
162
+ };
163
+
164
+ /** Data validation criteria uses to control the selection of data. */
165
+ enum lxw_validation_criteria {
166
+ LXW_VALIDATION_CRITERIA_NONE,
167
+
168
+ /** Select data between two values. */
169
+ LXW_VALIDATION_CRITERIA_BETWEEN,
170
+
171
+ /** Select data that is not between two values. */
172
+ LXW_VALIDATION_CRITERIA_NOT_BETWEEN,
173
+
174
+ /** Select data equal to a value. */
175
+ LXW_VALIDATION_CRITERIA_EQUAL_TO,
176
+
177
+ /** Select data not equal to a value. */
178
+ LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO,
179
+
180
+ /** Select data greater than a value. */
181
+ LXW_VALIDATION_CRITERIA_GREATER_THAN,
182
+
183
+ /** Select data less than a value. */
184
+ LXW_VALIDATION_CRITERIA_LESS_THAN,
185
+
186
+ /** Select data greater than or equal to a value. */
187
+ LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
188
+
189
+ /** Select data less than or equal to a value. */
190
+ LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO
191
+ };
192
+
193
+ /** Data validation error types for pop-up messages. */
194
+ enum lxw_validation_error_types {
195
+ /** Show a "Stop" data validation pop-up message. This is the default. */
196
+ LXW_VALIDATION_ERROR_TYPE_STOP,
197
+
198
+ /** Show an "Error" data validation pop-up message. */
199
+ LXW_VALIDATION_ERROR_TYPE_WARNING,
200
+
201
+ /** Show an "Information" data validation pop-up message. */
202
+ LXW_VALIDATION_ERROR_TYPE_INFORMATION
203
+ };
204
+
87
205
  enum cell_types {
88
206
  NUMBER_CELL = 1,
89
207
  STRING_CELL,
90
208
  INLINE_STRING_CELL,
209
+ INLINE_RICH_STRING_CELL,
91
210
  FORMULA_CELL,
92
211
  ARRAY_FORMULA_CELL,
93
212
  BLANK_CELL,
@@ -140,6 +259,7 @@ struct lxw_table_rows {
140
259
 
141
260
  STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
142
261
  STAILQ_HEAD(lxw_selections, lxw_selection);
262
+ STAILQ_HEAD(lxw_data_validations, lxw_data_validation);
143
263
  STAILQ_HEAD(lxw_image_data, lxw_image_options);
144
264
  STAILQ_HEAD(lxw_chart_data, lxw_image_options);
145
265
 
@@ -149,12 +269,14 @@ STAILQ_HEAD(lxw_chart_data, lxw_image_options);
149
269
  * Options struct for the worksheet_set_column() and worksheet_set_row()
150
270
  * functions.
151
271
  *
152
- * It has the following members but currently only the `hidden` property is
153
- * supported:
272
+ * It has the following members:
154
273
  *
155
274
  * * `hidden`
156
275
  * * `level`
157
276
  * * `collapsed`
277
+ *
278
+ * The members of this struct are explained in @ref ww_outlines_grouping.
279
+ *
158
280
  */
159
281
  typedef struct lxw_row_col_options {
160
282
  /** Hide the row/column */
@@ -229,6 +351,180 @@ typedef struct lxw_selection {
229
351
 
230
352
  } lxw_selection;
231
353
 
354
+ /**
355
+ * @brief Worksheet data validation options.
356
+ */
357
+ typedef struct lxw_data_validation {
358
+
359
+ /**
360
+ * Set the validation type. Should be a #lxw_validation_types value.
361
+ */
362
+ uint8_t validate;
363
+
364
+ /**
365
+ * Set the validation criteria type to select the data. Should be a
366
+ * #lxw_validation_criteria value.
367
+ */
368
+ uint8_t criteria;
369
+
370
+ /** Controls whether a data validation is not applied to blank data in the
371
+ * cell. Should be a #lxw_validation_boolean value. It is on by
372
+ * default.
373
+ */
374
+ uint8_t ignore_blank;
375
+
376
+ /**
377
+ * This parameter is used to toggle on and off the 'Show input message
378
+ * when cell is selected' option in the Excel data validation dialog. When
379
+ * the option is off an input message is not displayed even if it has been
380
+ * set using input_message. Should be a #lxw_validation_boolean value. It
381
+ * is on by default.
382
+ */
383
+ uint8_t show_input;
384
+
385
+ /**
386
+ * This parameter is used to toggle on and off the 'Show error alert
387
+ * after invalid data is entered' option in the Excel data validation
388
+ * dialog. When the option is off an error message is not displayed even
389
+ * if it has been set using error_message. Should be a
390
+ * #lxw_validation_boolean value. It is on by default.
391
+ */
392
+ uint8_t show_error;
393
+
394
+ /**
395
+ * This parameter is used to specify the type of error dialog that is
396
+ * displayed. Should be a #lxw_validation_error_types value.
397
+ */
398
+ uint8_t error_type;
399
+
400
+ /**
401
+ * This parameter is used to toggle on and off the 'In-cell dropdown'
402
+ * option in the Excel data validation dialog. When the option is on a
403
+ * dropdown list will be shown for list validations. Should be a
404
+ * #lxw_validation_boolean value. It is on by default.
405
+ */
406
+ uint8_t dropdown;
407
+
408
+ uint8_t is_between;
409
+
410
+ /**
411
+ * This parameter is used to set the limiting value to which the criteria
412
+ * is applied using a whole or decimal number.
413
+ */
414
+ double value_number;
415
+
416
+ /**
417
+ * This parameter is used to set the limiting value to which the criteria
418
+ * is applied using a cell reference. It is valid for any of the
419
+ * `_FORMULA` validation types.
420
+ */
421
+ char *value_formula;
422
+
423
+ /**
424
+ * This parameter is used to set a list of strings for a drop down list.
425
+ * The list should be a `NULL` terminated array of char* strings:
426
+ *
427
+ * @code
428
+ * char *list[] = {"open", "high", "close", NULL};
429
+ *
430
+ * data_validation->validate = LXW_VALIDATION_TYPE_LIST;
431
+ * data_validation->value_list = list;
432
+ * @endcode
433
+ *
434
+ * The `value_formula` parameter can also be used to specify a list from
435
+ * an Excel cell range.
436
+ *
437
+ * Note, the string list is restricted by Excel to 255 characters,
438
+ * including comma separators.
439
+ */
440
+ char **value_list;
441
+
442
+ /**
443
+ * This parameter is used to set the limiting value to which the date or
444
+ * time criteria is applied using a #lxw_datetime struct.
445
+ */
446
+ lxw_datetime value_datetime;
447
+
448
+ /**
449
+ * This parameter is the same as `value_number` but for the minimum value
450
+ * when a `BETWEEN` criteria is used.
451
+ */
452
+ double minimum_number;
453
+
454
+ /**
455
+ * This parameter is the same as `value_formula` but for the minimum value
456
+ * when a `BETWEEN` criteria is used.
457
+ */
458
+ char *minimum_formula;
459
+
460
+ /**
461
+ * This parameter is the same as `value_datetime` but for the minimum value
462
+ * when a `BETWEEN` criteria is used.
463
+ */
464
+ lxw_datetime minimum_datetime;
465
+
466
+ /**
467
+ * This parameter is the same as `value_number` but for the maximum value
468
+ * when a `BETWEEN` criteria is used.
469
+ */
470
+ double maximum_number;
471
+
472
+ /**
473
+ * This parameter is the same as `value_formula` but for the maximum value
474
+ * when a `BETWEEN` criteria is used.
475
+ */
476
+ char *maximum_formula;
477
+
478
+ /**
479
+ * This parameter is the same as `value_datetime` but for the maximum value
480
+ * when a `BETWEEN` criteria is used.
481
+ */
482
+ lxw_datetime maximum_datetime;
483
+
484
+ /**
485
+ * The input_title parameter is used to set the title of the input message
486
+ * that is displayed when a cell is entered. It has no default value and
487
+ * is only displayed if the input message is displayed. See the
488
+ * `input_message` parameter below.
489
+ *
490
+ * The maximum title length is 32 characters.
491
+ */
492
+ char *input_title;
493
+
494
+ /**
495
+ * The input_message parameter is used to set the input message that is
496
+ * displayed when a cell is entered. It has no default value.
497
+ *
498
+ * The message can be split over several lines using newlines. The maximum
499
+ * message length is 255 characters.
500
+ */
501
+ char *input_message;
502
+
503
+ /**
504
+ * The error_title parameter is used to set the title of the error message
505
+ * that is displayed when the data validation criteria is not met. The
506
+ * default error title is 'Microsoft Excel'. The maximum title length is
507
+ * 32 characters.
508
+ */
509
+ char *error_title;
510
+
511
+ /**
512
+ * The error_message parameter is used to set the error message that is
513
+ * displayed when a cell is entered. The default error message is "The
514
+ * value you entered is not valid. A user has restricted values that can
515
+ * be entered into the cell".
516
+ *
517
+ * The message can be split over several lines using newlines. The maximum
518
+ * message length is 255 characters.
519
+ */
520
+ char *error_message;
521
+
522
+ char sqref[LXW_MAX_CELL_RANGE_LENGTH];
523
+
524
+ STAILQ_ENTRY (lxw_data_validation) list_pointers;
525
+
526
+ } lxw_data_validation;
527
+
232
528
  /**
233
529
  * @brief Options for inserted images
234
530
  *
@@ -252,6 +548,7 @@ typedef struct lxw_image_options {
252
548
  lxw_row_t row;
253
549
  lxw_col_t col;
254
550
  char *filename;
551
+ char *description;
255
552
  char *url;
256
553
  char *tip;
257
554
  uint8_t anchor;
@@ -259,9 +556,11 @@ typedef struct lxw_image_options {
259
556
  /* Internal metadata. */
260
557
  FILE *stream;
261
558
  uint8_t image_type;
559
+ uint8_t is_image_buffer;
560
+ unsigned char *image_buffer;
561
+ size_t image_buffer_size;
262
562
  double width;
263
563
  double height;
264
- char *short_name;
265
564
  char *extension;
266
565
  double x_dpi;
267
566
  double y_dpi;
@@ -329,15 +628,39 @@ typedef struct lxw_protection {
329
628
  /** Protect scenarios. */
330
629
  uint8_t scenarios;
331
630
 
332
- /** Protect drawing objects. */
631
+ /** Protect drawing objects. Worksheets only. */
333
632
  uint8_t objects;
334
633
 
634
+ /** Turn off chartsheet content protection. */
635
+ uint8_t no_content;
636
+
637
+ /** Turn off chartsheet objects. */
638
+ uint8_t no_objects;
639
+
335
640
  uint8_t no_sheet;
336
- uint8_t content;
337
641
  uint8_t is_configured;
338
642
  char hash[5];
339
643
  } lxw_protection;
340
644
 
645
+ /**
646
+ * @brief Struct to represent a rich string format/string pair.
647
+ *
648
+ * Arrays of this struct are used to define "rich" multi-format strings that
649
+ * are passed to `worksheet_write_rich_string()`. Each struct represents a
650
+ * fragment of the rich multi-format string with a lxw_format to define the
651
+ * format for the string part. If the string fragment is unformatted then
652
+ * `NULL` can be used for the format.
653
+ */
654
+ typedef struct lxw_rich_string_tuple {
655
+
656
+ /** The format for a string fragment in a rich string. NULL if the string
657
+ * isn't formatted. */
658
+ lxw_format *format;
659
+
660
+ /** The string fragment. */
661
+ char *string;
662
+ } lxw_rich_string_tuple;
663
+
341
664
  /**
342
665
  * @brief Struct to represent an Excel worksheet.
343
666
  *
@@ -354,6 +677,7 @@ typedef struct lxw_worksheet {
354
677
  struct lxw_cell **array;
355
678
  struct lxw_merged_ranges *merged_ranges;
356
679
  struct lxw_selections *selections;
680
+ struct lxw_data_validations *data_validations;
357
681
  struct lxw_image_data *image_data;
358
682
  struct lxw_chart_data *chart_data;
359
683
 
@@ -373,6 +697,7 @@ typedef struct lxw_worksheet {
373
697
  uint8_t hidden;
374
698
  uint16_t *active_sheet;
375
699
  uint16_t *first_sheet;
700
+ uint8_t is_chartsheet;
376
701
 
377
702
  lxw_col_options **col_options;
378
703
  uint16_t col_options_max;
@@ -403,6 +728,9 @@ typedef struct lxw_worksheet {
403
728
  uint8_t orientation;
404
729
  uint8_t outline_changed;
405
730
  uint8_t outline_on;
731
+ uint8_t outline_style;
732
+ uint8_t outline_below;
733
+ uint8_t outline_right;
406
734
  uint8_t page_order;
407
735
  uint8_t page_setup_changed;
408
736
  uint8_t page_view;
@@ -413,9 +741,10 @@ typedef struct lxw_worksheet {
413
741
  uint8_t right_to_left;
414
742
  uint8_t screen_gridlines;
415
743
  uint8_t show_zeros;
416
- uint8_t vba_codename;
417
744
  uint8_t vcenter;
418
745
  uint8_t zoom_scale_normal;
746
+ uint8_t num_validations;
747
+ char *vba_codename;
419
748
 
420
749
  lxw_color_t tab_color;
421
750
 
@@ -431,6 +760,8 @@ typedef struct lxw_worksheet {
431
760
  uint32_t default_col_pixels;
432
761
  uint8_t default_row_zeroed;
433
762
  uint8_t default_row_set;
763
+ uint8_t outline_row_level;
764
+ uint8_t outline_col_level;
434
765
 
435
766
  uint8_t header_footer_changed;
436
767
  char header[LXW_HEADER_FOOTER_MAX];
@@ -561,6 +892,10 @@ extern "C" {
561
892
  *
562
893
  * @image html write_number02.png
563
894
  *
895
+ * @note Excel doesn't support `NaN`, `Inf` or `-Inf` as a number value. If
896
+ * you are writing data that contains these values then your application
897
+ * should convert them to a string or handle them in some other way.
898
+ *
564
899
  */
565
900
  lxw_error worksheet_write_number(lxw_worksheet *worksheet,
566
901
  lxw_row_t row,
@@ -661,6 +996,7 @@ lxw_error worksheet_write_string(lxw_worksheet *worksheet,
661
996
  * worksheet_write_formula(worksheet, 1, 0, "=SUM(1; 2; 3)", NULL);
662
997
  * @endcode
663
998
  *
999
+ * See also @ref working_with_formulas.
664
1000
  */
665
1001
  lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
666
1002
  lxw_row_t row,
@@ -669,7 +1005,7 @@ lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
669
1005
  /**
670
1006
  * @brief Write an array formula to a worksheet cell.
671
1007
  *
672
- * @param worksheet
1008
+ * @param worksheet pointer to a lxw_worksheet instance to be updated.
673
1009
  * @param first_row The first row of the range. (All zero indexed.)
674
1010
  * @param first_col The first column of the range.
675
1011
  * @param last_row The last row of the range.
@@ -874,7 +1210,7 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
874
1210
  * @endcode
875
1211
  *
876
1212
  *
877
- * Alternatively, you can use Windows style forward slashes. These are
1213
+ * Alternatively, you can use Unix style forward slashes. These are
878
1214
  * translated internally to backslashes:
879
1215
  *
880
1216
  * @code
@@ -991,6 +1327,7 @@ lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
991
1327
  * worksheet_write_formula() function is the recommended way of writing
992
1328
  * formulas.
993
1329
  *
1330
+ * See also @ref working_with_formulas.
994
1331
  */
995
1332
  lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
996
1333
  lxw_row_t row,
@@ -998,6 +1335,81 @@ lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
998
1335
  const char *formula,
999
1336
  lxw_format *format, double result);
1000
1337
 
1338
+ /**
1339
+ * @brief Write a "Rich" multi-format string to a worksheet cell.
1340
+ *
1341
+ * @param worksheet pointer to a lxw_worksheet instance to be updated.
1342
+ * @param row The zero indexed row number.
1343
+ * @param col The zero indexed column number.
1344
+ * @param rich_string An array of format/string lxw_rich_string_tuple fragments.
1345
+ * @param format A pointer to a Format instance or NULL.
1346
+ *
1347
+ * @return A #lxw_error code.
1348
+ *
1349
+ * The `%worksheet_write_rich_string()` function is used to write strings with
1350
+ * multiple formats. For example to write the string 'This is **bold**
1351
+ * and this is *italic*' you would use the following:
1352
+ *
1353
+ * @code
1354
+ * lxw_format *bold = workbook_add_format(workbook);
1355
+ * format_set_bold(bold);
1356
+ *
1357
+ * lxw_format *italic = workbook_add_format(workbook);
1358
+ * format_set_italic(italic);
1359
+ *
1360
+ * lxw_rich_string_tuple fragment11 = {.format = NULL, .string = "This is " };
1361
+ * lxw_rich_string_tuple fragment12 = {.format = bold, .string = "bold" };
1362
+ * lxw_rich_string_tuple fragment13 = {.format = NULL, .string = " and this is "};
1363
+ * lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic" };
1364
+ *
1365
+ * lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
1366
+ * &fragment13, &fragment14, NULL};
1367
+ *
1368
+ * worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
1369
+ *
1370
+ * @endcode
1371
+ *
1372
+ * @image html rich_strings_small.png
1373
+ *
1374
+ * The basic rule is to break the string into fragments and put a lxw_format
1375
+ * object before the fragment that you want to format. So if we look at the
1376
+ * above example again:
1377
+ *
1378
+ * This is **bold** and this is *italic*
1379
+ *
1380
+ * The would be broken down into 4 fragments:
1381
+ *
1382
+ * default: |This is |
1383
+ * bold: |bold|
1384
+ * default: | and this is |
1385
+ * italic: |italic|
1386
+ *
1387
+ * This in then converted to the lxw_rich_string_tuple fragments shown in the
1388
+ * example above. For the default format we use `NULL`.
1389
+ *
1390
+ * The fragments are passed to `%worksheet_write_rich_string()` as a `NULL`
1391
+ * terminated array:
1392
+ *
1393
+ * @code
1394
+ * lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
1395
+ * &fragment13, &fragment14, NULL};
1396
+ *
1397
+ * worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
1398
+ *
1399
+ * @endcode
1400
+ *
1401
+ * **Note**:
1402
+ * Excel doesn't allow the use of two consecutive formats in a rich string or
1403
+ * an empty string fragment. For either of these conditions a warning is
1404
+ * raised and the input to `%worksheet_write_rich_string()` is ignored.
1405
+ *
1406
+ */
1407
+ lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
1408
+ lxw_row_t row,
1409
+ lxw_col_t col,
1410
+ lxw_rich_string_tuple *rich_string[],
1411
+ lxw_format *format);
1412
+
1001
1413
  /**
1002
1414
  * @brief Set the properties for a row of cells.
1003
1415
  *
@@ -1066,7 +1478,7 @@ lxw_error worksheet_set_row(lxw_worksheet *worksheet,
1066
1478
  * `worksheet_set_row()` with an additional `options` parameter.
1067
1479
  *
1068
1480
  * The `options` parameter is a #lxw_row_col_options struct. It has the
1069
- * following members but currently only the `hidden` property is supported:
1481
+ * following members:
1070
1482
  *
1071
1483
  * - `hidden`
1072
1484
  * - `level`
@@ -1076,12 +1488,41 @@ lxw_error worksheet_set_row(lxw_worksheet *worksheet,
1076
1488
  * example, to hide intermediary steps in a complicated calculation:
1077
1489
  *
1078
1490
  * @code
1079
- * lxw_row_col_options options = {.hidden = 1, .level = 0, .collapsed = 0};
1491
+ * lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
1492
+ *
1493
+ * // Hide the fourth and fifth (zero indexed) rows.
1494
+ * worksheet_set_row_opt(worksheet, 3, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1495
+ * worksheet_set_row_opt(worksheet, 4, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1080
1496
  *
1081
- * // Hide the fourth row.
1082
- * worksheet_set_row(worksheet, 3, 20, NULL, &options);
1083
1497
  * @endcode
1084
1498
  *
1499
+ * @image html hide_row_col2.png
1500
+ *
1501
+ * The `"hidden"`, `"level"`, and `"collapsed"`, options can also be used to
1502
+ * create Outlines and Grouping. See @ref working_with_outlines.
1503
+ *
1504
+ * @code
1505
+ * // The option structs with the outline level set.
1506
+ * lxw_row_col_options options1 = {.hidden = 0, .level = 2, .collapsed = 0};
1507
+ * lxw_row_col_options options2 = {.hidden = 0, .level = 1, .collapsed = 0};
1508
+ *
1509
+ *
1510
+ * // Set the row options with the outline level.
1511
+ * worksheet_set_row_opt(worksheet, 1, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1512
+ * worksheet_set_row_opt(worksheet, 2, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1513
+ * worksheet_set_row_opt(worksheet, 3, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1514
+ * worksheet_set_row_opt(worksheet, 4, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1515
+ * worksheet_set_row_opt(worksheet, 5, LXW_DEF_ROW_HEIGHT, NULL, &options2);
1516
+ *
1517
+ * worksheet_set_row_opt(worksheet, 6, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1518
+ * worksheet_set_row_opt(worksheet, 7, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1519
+ * worksheet_set_row_opt(worksheet, 8, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1520
+ * worksheet_set_row_opt(worksheet, 9, LXW_DEF_ROW_HEIGHT, NULL, &options1);
1521
+ * worksheet_set_row_opt(worksheet, 10, LXW_DEF_ROW_HEIGHT, NULL, &options2);
1522
+ * @endcode
1523
+ *
1524
+ * @image html outline1.png
1525
+ *
1085
1526
  */
1086
1527
  lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
1087
1528
  lxw_row_t row,
@@ -1151,7 +1592,7 @@ lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
1151
1592
  * format_set_bold(bold);
1152
1593
  *
1153
1594
  * // Set the first column to bold.
1154
- * worksheet_set_column(worksheet, 0, 0, LXW_DEF_COL_HEIGHT, bold);
1595
+ * worksheet_set_column(worksheet, 0, 0, LXW_DEF_COL_WIDTH, bold);
1155
1596
  * @endcode
1156
1597
  *
1157
1598
  * The `format` parameter will be applied to any cells in the column that
@@ -1189,36 +1630,48 @@ lxw_error worksheet_set_column(lxw_worksheet *worksheet,
1189
1630
  lxw_col_t last_col,
1190
1631
  double width, lxw_format *format);
1191
1632
 
1192
- /**
1193
- * @brief Set the properties for one or more columns of cells with options.
1194
- *
1195
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1196
- * @param first_col The zero indexed first column.
1197
- * @param last_col The zero indexed last column.
1198
- * @param width The width of the column(s).
1199
- * @param format A pointer to a Format instance or NULL.
1200
- * @param options Optional row parameters: hidden, level, collapsed.
1201
- *
1202
- * The `%worksheet_set_column_opt()` function is the same as
1203
- * `worksheet_set_column()` with an additional `options` parameter.
1204
- *
1205
- * The `options` parameter is a #lxw_row_col_options struct. It has the
1206
- * following members but currently only the `hidden` property is supported:
1207
- *
1208
- * - `hidden`
1209
- * - `level`
1210
- * - `collapsed`
1211
- *
1212
- * The `"hidden"` option is used to hide a column. This can be used, for
1213
- * example, to hide intermediary steps in a complicated calculation:
1214
- *
1215
- * @code
1216
- * lxw_row_col_options options = {.hidden = 1, .level = 0, .collapsed = 0};
1217
- *
1218
- * worksheet_set_column_opt(worksheet, COLS("A:A"), 8.43, NULL, &options);
1219
- * @endcode
1220
- *
1221
- */
1633
+ /**
1634
+ * @brief Set the properties for one or more columns of cells with options.
1635
+ *
1636
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1637
+ * @param first_col The zero indexed first column.
1638
+ * @param last_col The zero indexed last column.
1639
+ * @param width The width of the column(s).
1640
+ * @param format A pointer to a Format instance or NULL.
1641
+ * @param options Optional row parameters: hidden, level, collapsed.
1642
+ *
1643
+ * The `%worksheet_set_column_opt()` function is the same as
1644
+ * `worksheet_set_column()` with an additional `options` parameter.
1645
+ *
1646
+ * The `options` parameter is a #lxw_row_col_options struct. It has the
1647
+ * following members:
1648
+ *
1649
+ * - `hidden`
1650
+ * - `level`
1651
+ * - `collapsed`
1652
+ *
1653
+ * The `"hidden"` option is used to hide a column. This can be used, for
1654
+ * example, to hide intermediary steps in a complicated calculation:
1655
+ *
1656
+ * @code
1657
+ * lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
1658
+ *
1659
+ * worksheet_set_column_opt(worksheet, COLS("D:E"), LXW_DEF_COL_WIDTH, NULL, &options1);
1660
+ * @endcode
1661
+ *
1662
+ * @image html hide_row_col3.png
1663
+ *
1664
+ * The `"hidden"`, `"level"`, and `"collapsed"`, options can also be used to
1665
+ * create Outlines and Grouping. See @ref working_with_outlines.
1666
+ *
1667
+ * @code
1668
+ * lxw_row_col_options options1 = {.hidden = 0, .level = 1, .collapsed = 0};
1669
+ *
1670
+ * worksheet_set_column_opt(worksheet, COLS("B:G"), 5, NULL, &options1);
1671
+ * @endcode
1672
+ *
1673
+ * @image html outline8.png
1674
+ */
1222
1675
  lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
1223
1676
  lxw_col_t first_col,
1224
1677
  lxw_col_t last_col,
@@ -1295,6 +1748,77 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
1295
1748
  lxw_row_t row, lxw_col_t col,
1296
1749
  const char *filename,
1297
1750
  lxw_image_options *options);
1751
+
1752
+ /**
1753
+ * @brief Insert an image in a worksheet cell, from a memory buffer.
1754
+ *
1755
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1756
+ * @param row The zero indexed row number.
1757
+ * @param col The zero indexed column number.
1758
+ * @param image_buffer Pointer to an array of bytes that holds the image data.
1759
+ * @param image_size The size of the array of bytes.
1760
+ *
1761
+ * @return A #lxw_error code.
1762
+ *
1763
+ * This function can be used to insert a image into a worksheet from a memory
1764
+ * buffer:
1765
+ *
1766
+ * @code
1767
+ * worksheet_insert_image_buffer(worksheet, CELL("B3"), image_buffer, image_size);
1768
+ * @endcode
1769
+ *
1770
+ * @image html image_buffer.png
1771
+ *
1772
+ * The buffer should be a pointer to an array of unsigned char data with a
1773
+ * specified size.
1774
+ *
1775
+ * See `worksheet_insert_image()` for details about the supported image
1776
+ * formats, and other image features.
1777
+ */
1778
+ lxw_error worksheet_insert_image_buffer(lxw_worksheet *worksheet,
1779
+ lxw_row_t row,
1780
+ lxw_col_t col,
1781
+ const unsigned char *image_buffer,
1782
+ size_t image_size);
1783
+
1784
+ /**
1785
+ * @brief Insert an image in a worksheet cell, from a memory buffer.
1786
+ *
1787
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1788
+ * @param row The zero indexed row number.
1789
+ * @param col The zero indexed column number.
1790
+ * @param image_buffer Pointer to an array of bytes that holds the image data.
1791
+ * @param image_size The size of the array of bytes.
1792
+ * @param options Optional image parameters.
1793
+ *
1794
+ * @return A #lxw_error code.
1795
+ *
1796
+ * The `%worksheet_insert_image_buffer_opt()` function is like
1797
+ * `worksheet_insert_image_buffer()` function except that it takes an optional
1798
+ * #lxw_image_options struct to scale and position the image:
1799
+ *
1800
+ * @code
1801
+ * lxw_image_options options = {.x_offset = 32, .y_offset = 4,
1802
+ * .x_scale = 2, .y_scale = 1};
1803
+ *
1804
+ * worksheet_insert_image_buffer_opt(worksheet, CELL("B3"), image_buffer, image_size, &options);
1805
+ * @endcode
1806
+ *
1807
+ * @image html image_buffer_opt.png
1808
+ *
1809
+ * The buffer should be a pointer to an array of unsigned char data with a
1810
+ * specified size.
1811
+ *
1812
+ * See `worksheet_insert_image_buffer_opt()` for details about the supported
1813
+ * image formats, and other image options.
1814
+ */
1815
+ lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
1816
+ lxw_row_t row,
1817
+ lxw_col_t col,
1818
+ const unsigned char *image_buffer,
1819
+ size_t image_size,
1820
+ lxw_image_options *options);
1821
+
1298
1822
  /**
1299
1823
  * @brief Insert a chart object into a worksheet.
1300
1824
  *
@@ -1305,8 +1829,8 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
1305
1829
  *
1306
1830
  * @return A #lxw_error code.
1307
1831
  *
1308
- * The `%worksheet_insert_chart()` can be used to insert a chart into a
1309
- * worksheet. The chart object must be created first using the
1832
+ * The `%worksheet_insert_chart()` function can be used to insert a chart into
1833
+ * a worksheet. The chart object must be created first using the
1310
1834
  * `workbook_add_chart()` function and configured using the @ref chart.h
1311
1835
  * functions.
1312
1836
  *
@@ -1317,13 +1841,12 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
1317
1841
  * // Add a data series to the chart.
1318
1842
  * chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$6");
1319
1843
  *
1320
- * // Insert the chart into the worksheet
1844
+ * // Insert the chart into the worksheet.
1321
1845
  * worksheet_insert_chart(worksheet, 0, 2, chart);
1322
1846
  * @endcode
1323
1847
  *
1324
1848
  * @image html chart_working.png
1325
1849
  *
1326
- *
1327
1850
  * **Note:**
1328
1851
  *
1329
1852
  * A chart may only be inserted into a worksheet once. If several similar
@@ -1470,6 +1993,87 @@ lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
1470
1993
  lxw_col_t first_col, lxw_row_t last_row,
1471
1994
  lxw_col_t last_col);
1472
1995
 
1996
+ /**
1997
+ * @brief Add a data validation to a cell.
1998
+ *
1999
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2000
+ * @param row The zero indexed row number.
2001
+ * @param col The zero indexed column number.
2002
+ * @param validation A #lxw_data_validation object to control the validation.
2003
+ *
2004
+ * @return A #lxw_error code.
2005
+ *
2006
+ * The `%worksheet_data_validation_cell()` function is used to construct an
2007
+ * Excel data validation or to limit the user input to a dropdown list of
2008
+ * values:
2009
+ *
2010
+ * @code
2011
+ *
2012
+ * lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
2013
+ *
2014
+ * data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
2015
+ * data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
2016
+ * data_validation->minimum_number = 1;
2017
+ * data_validation->maximum_number = 10;
2018
+ *
2019
+ * worksheet_data_validation_cell(worksheet, 2, 1, data_validation);
2020
+ *
2021
+ * // Same as above with the CELL() macro.
2022
+ * worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);
2023
+ *
2024
+ * @endcode
2025
+ *
2026
+ * @image html data_validate4.png
2027
+ *
2028
+ * Data validation and the various options of #lxw_data_validation are
2029
+ * described in more detail in @ref working_with_data_validation.
2030
+ */
2031
+ lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
2032
+ lxw_row_t row, lxw_col_t col,
2033
+ lxw_data_validation *validation);
2034
+
2035
+ /**
2036
+ * @brief Add a data validation to a range cell.
2037
+ *
2038
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2039
+ * @param first_row The first row of the range. (All zero indexed.)
2040
+ * @param first_col The first column of the range.
2041
+ * @param last_row The last row of the range.
2042
+ * @param last_col The last col of the range.
2043
+ * @param validation A #lxw_data_validation object to control the validation.
2044
+ *
2045
+ * @return A #lxw_error code.
2046
+ *
2047
+ * The `%worksheet_data_validation_range()` function is the same as the
2048
+ * `%worksheet_data_validation_cell()`, see above, except the data validation
2049
+ * is applied to a range of cells:
2050
+ *
2051
+ * @code
2052
+ *
2053
+ * lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
2054
+ *
2055
+ * data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
2056
+ * data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
2057
+ * data_validation->minimum_number = 1;
2058
+ * data_validation->maximum_number = 10;
2059
+ *
2060
+ * worksheet_data_validation_range(worksheet, 2, 1, 4, 1, data_validation);
2061
+ *
2062
+ * // Same as above with the RANGE() macro.
2063
+ * worksheet_data_validation_range(worksheet, RANGE("B3:B5"), data_validation);
2064
+ *
2065
+ * @endcode
2066
+ *
2067
+ * Data validation and the various options of #lxw_data_validation are
2068
+ * described in more detail in @ref working_with_data_validation.
2069
+ */
2070
+ lxw_error worksheet_data_validation_range(lxw_worksheet *worksheet,
2071
+ lxw_row_t first_row,
2072
+ lxw_col_t first_col,
2073
+ lxw_row_t last_row,
2074
+ lxw_col_t last_col,
2075
+ lxw_data_validation *validation);
2076
+
1473
2077
  /**
1474
2078
  * @brief Make a worksheet the active, i.e., visible worksheet.
1475
2079
  *
@@ -1853,26 +2457,26 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
1853
2457
  * @code
1854
2458
  * worksheet_set_header(worksheet, "&LHello");
1855
2459
  *
1856
- * ---------------------------------------------------------------
1857
- * | |
1858
- * | Hello |
1859
- * | |
2460
+ * // ---------------------------------------------------------------
2461
+ * // | |
2462
+ * // | Hello |
2463
+ * // | |
1860
2464
  *
1861
2465
  *
1862
2466
  * worksheet_set_header(worksheet, "&CHello");
1863
2467
  *
1864
- * ---------------------------------------------------------------
1865
- * | |
1866
- * | Hello |
1867
- * | |
2468
+ * // ---------------------------------------------------------------
2469
+ * // | |
2470
+ * // | Hello |
2471
+ * // | |
1868
2472
  *
1869
2473
  *
1870
2474
  * worksheet_set_header(worksheet, "&RHello");
1871
2475
  *
1872
- * ---------------------------------------------------------------
1873
- * | |
1874
- * | Hello |
1875
- * | |
2476
+ * // ---------------------------------------------------------------
2477
+ * // | |
2478
+ * // | Hello |
2479
+ * // | |
1876
2480
  *
1877
2481
  *
1878
2482
  * @endcode
@@ -1884,10 +2488,10 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
1884
2488
  * @code
1885
2489
  * worksheet_set_header(worksheet, "Hello");
1886
2490
  *
1887
- * ---------------------------------------------------------------
1888
- * | |
1889
- * | Hello |
1890
- * | |
2491
+ * // ---------------------------------------------------------------
2492
+ * // | |
2493
+ * // | Hello |
2494
+ * // | |
1891
2495
  *
1892
2496
  * @endcode
1893
2497
  *
@@ -1896,10 +2500,10 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
1896
2500
  * @code
1897
2501
  * worksheet_set_header(worksheet, "&LCiao&CBello&RCielo");
1898
2502
  *
1899
- * ---------------------------------------------------------------
1900
- * | |
1901
- * | Ciao Bello Cielo |
1902
- * | |
2503
+ * // ---------------------------------------------------------------
2504
+ * // | |
2505
+ * // | Ciao Bello Cielo |
2506
+ * // | |
1903
2507
  *
1904
2508
  * @endcode
1905
2509
  *
@@ -1910,17 +2514,17 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
1910
2514
  * @code
1911
2515
  * worksheet_set_header(worksheet, "&CPage &P of &N");
1912
2516
  *
1913
- * ---------------------------------------------------------------
1914
- * | |
1915
- * | Page 1 of 6 |
1916
- * | |
2517
+ * // ---------------------------------------------------------------
2518
+ * // | |
2519
+ * // | Page 1 of 6 |
2520
+ * // | |
1917
2521
  *
1918
2522
  * worksheet_set_header(worksheet, "&CUpdated at &T");
1919
2523
  *
1920
- * ---------------------------------------------------------------
1921
- * | |
1922
- * | Updated at 12:30 PM |
1923
- * | |
2524
+ * // ---------------------------------------------------------------
2525
+ * // | |
2526
+ * // | Updated at 12:30 PM |
2527
+ * // | |
1924
2528
  *
1925
2529
  * @endcode
1926
2530
  *
@@ -2460,8 +3064,8 @@ void worksheet_hide_zero(lxw_worksheet *worksheet);
2460
3064
  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2461
3065
  * @param color The tab color.
2462
3066
  *
2463
- * The `%worksheet_set_tab_color()` function is used to change the color of the worksheet
2464
- * tab:
3067
+ * The `%worksheet_set_tab_color()` function is used to change the color of
3068
+ * the worksheet tab:
2465
3069
  *
2466
3070
  * @code
2467
3071
  * worksheet_set_tab_color(worksheet1, LXW_COLOR_RED);
@@ -2544,15 +3148,62 @@ void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
2544
3148
  *
2545
3149
  * See also the format_set_unlocked() and format_set_hidden() format functions.
2546
3150
  *
2547
- * **Note:** Worksheet level passwords in Excel offer **very** weak
3151
+ * **Note:** Sheet level passwords in Excel offer **very** weak
2548
3152
  * protection. They don't encrypt your data and are very easy to
2549
3153
  * deactivate. Full workbook encryption is not supported by `libxlsxwriter`
2550
- * since it requires a completely different file format and would take several
2551
- * man months to implement.
3154
+ * since it requires a completely different file format.
2552
3155
  */
2553
3156
  void worksheet_protect(lxw_worksheet *worksheet, const char *password,
2554
3157
  lxw_protection *options);
2555
3158
 
3159
+ /**
3160
+ * @brief Set the Outline and Grouping display properties.
3161
+ *
3162
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3163
+ * @param visible Outlines are visible. Optional, defaults to True.
3164
+ * @param symbols_below Show row outline symbols below the outline bar.
3165
+ * @param symbols_right Show column outline symbols to the right of outline.
3166
+ * @param auto_style Use Automatic outline style.
3167
+ *
3168
+ * The `%worksheet_outline_settings()` method is used to control the
3169
+ * appearance of outlines in Excel. Outlines are described the section on
3170
+ * @ref working_with_outlines.
3171
+ *
3172
+ * The `visible` parameter is used to control whether or not outlines are
3173
+ * visible. Setting this parameter to False will cause all outlines on the
3174
+ * worksheet to be hidden. They can be un-hidden in Excel by means of the
3175
+ * "Show Outline Symbols" command button. The default Excel setting is True
3176
+ * for visible outlines.
3177
+ *
3178
+ * The `symbols_below` parameter is used to control whether the row outline
3179
+ * symbol will appear above or below the outline level bar. The default Excel
3180
+ * setting is True for symbols to appear below the outline level bar.
3181
+ *
3182
+ * The `symbols_right` parameter is used to control whether the column outline
3183
+ * symbol will appear to the left or the right of the outline level bar. The
3184
+ * default Excel setting is True for symbols to appear to the right of the
3185
+ * outline level bar.
3186
+ *
3187
+ * The `auto_style` parameter is used to control whether the automatic outline
3188
+ * generator in Excel uses automatic styles when creating an outline. This has
3189
+ * no effect on a file generated by XlsxWriter but it does have an effect on
3190
+ * how the worksheet behaves after it is created. The default Excel setting is
3191
+ * False for "Automatic Styles" to be turned off.
3192
+ *
3193
+ * The default settings for all of these parameters in libxlsxwriter
3194
+ * correspond to Excel's default parameters and are shown below:
3195
+ *
3196
+ * @code
3197
+ * worksheet_outline_settings(worksheet1, LXW_TRUE, LXW_TRUE, LXW_TRUE, LXW_FALSE);
3198
+ * @endcode
3199
+ *
3200
+ * The worksheet parameters controlled by `worksheet_outline_settings()` are
3201
+ * rarely used.
3202
+ */
3203
+ void worksheet_outline_settings(lxw_worksheet *worksheet, uint8_t visible,
3204
+ uint8_t symbols_below, uint8_t symbols_right,
3205
+ uint8_t auto_style);
3206
+
2556
3207
  /**
2557
3208
  * @brief Set the default row properties.
2558
3209
  *
@@ -2584,22 +3235,58 @@ void worksheet_protect(lxw_worksheet *worksheet, const char *password,
2584
3235
  void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
2585
3236
  uint8_t hide_unused_rows);
2586
3237
 
3238
+ /**
3239
+ * @brief Set the VBA name for the worksheet.
3240
+ *
3241
+ * @param worksheet Pointer to a lxw_worksheet instance.
3242
+ * @param name Name of the worksheet used by VBA.
3243
+ *
3244
+ * The `worksheet_set_vba_name()` function can be used to set the VBA name for
3245
+ * the worksheet. This is sometimes required when a vbaProject macro included
3246
+ * via `workbook_add_vba_project()` refers to the worksheet.
3247
+ *
3248
+ * @code
3249
+ * workbook_set_vba_name (workbook, "MyWorkbook");
3250
+ * worksheet_set_vba_name(worksheet, "MySheet1");
3251
+ * @endcode
3252
+ *
3253
+ * In general Excel uses the worksheet name such as "Sheet1" as the VBA name.
3254
+ * However, this can be changed in the VBA environment or if the the macro was
3255
+ * extracted from a foreign language version of Excel.
3256
+ *
3257
+ * @return A #lxw_error.
3258
+ */
3259
+ lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
3260
+
2587
3261
  lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
2588
3262
  void lxw_worksheet_free(lxw_worksheet *worksheet);
2589
3263
  void lxw_worksheet_assemble_xml_file(lxw_worksheet *worksheet);
2590
3264
  void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
2591
3265
 
2592
3266
  void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
2593
- uint16_t image_ref_id, uint16_t drawing_id,
3267
+ uint32_t image_ref_id, uint32_t drawing_id,
2594
3268
  lxw_image_options *image_data);
2595
3269
 
2596
3270
  void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
2597
- uint16_t chart_ref_id, uint16_t drawing_id,
2598
- lxw_image_options *image_data);
3271
+ uint32_t chart_ref_id, uint32_t drawing_id,
3272
+ lxw_image_options *image_data,
3273
+ uint8_t is_chartsheet);
2599
3274
 
2600
3275
  lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
2601
3276
  lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
2602
3277
 
3278
+ /*
3279
+ * External functions to call intern XML methods shared with chartsheet.
3280
+ */
3281
+ void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
3282
+ void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
3283
+ void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
3284
+ void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3285
+ lxw_protection *protect);
3286
+ void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
3287
+ void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
3288
+ void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
3289
+
2603
3290
  /* Declarations required for unit testing. */
2604
3291
  #ifdef TESTING
2605
3292
 
@@ -2629,7 +3316,9 @@ STATIC void _worksheet_write_header_footer(lxw_worksheet *worksheet);
2629
3316
  STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
2630
3317
  STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
2631
3318
  STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
2632
- STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet);
3319
+ STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3320
+ lxw_protection *protect);
3321
+ STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
2633
3322
  #endif /* TESTING */
2634
3323
 
2635
3324
  /* *INDENT-OFF* */