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
  /**
@@ -46,7 +46,6 @@
46
46
  #include <stdio.h>
47
47
  #include <stdlib.h>
48
48
  #include <stdint.h>
49
- #include <string.h>
50
49
 
51
50
  #include "shared_strings.h"
52
51
  #include "chart.h"
@@ -55,24 +54,33 @@
55
54
  #include "format.h"
56
55
  #include "styles.h"
57
56
  #include "utility.h"
57
+ #include "relationships.h"
58
58
 
59
- #define LXW_ROW_MAX 1048576
60
- #define LXW_COL_MAX 16384
61
- #define LXW_COL_META_MAX 128
62
- #define LXW_HEADER_FOOTER_MAX 255
63
- #define LXW_MAX_NUMBER_URLS 65530
64
- #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
59
+ #define LXW_ROW_MAX 1048576
60
+ #define LXW_COL_MAX 16384
61
+ #define LXW_COL_META_MAX 128
62
+ #define LXW_HEADER_FOOTER_MAX 255
63
+ #define LXW_MAX_NUMBER_URLS 65530
64
+ #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
65
+ #define LXW_IMAGE_BUFFER_SIZE 1024
66
+ #define LXW_HEADER_FOOTER_OBJS_MAX 6 /* Header/footer image objs. */
65
67
 
66
68
  /* The Excel 2007 specification says that the maximum number of page
67
69
  * breaks is 1026. However, in practice it is actually 1023. */
68
70
  #define LXW_BREAKS_MAX 1023
69
71
 
70
- /** Default column width in Excel */
72
+ /** Default Excel column width in character units. */
71
73
  #define LXW_DEF_COL_WIDTH (double)8.43
72
74
 
73
- /** Default row height in Excel */
75
+ /** Default Excel column height in character units. */
74
76
  #define LXW_DEF_ROW_HEIGHT (double)15.0
75
77
 
78
+ /** Default Excel column width in pixels. */
79
+ #define LXW_DEF_COL_WIDTH_PIXELS 64
80
+
81
+ /** Default Excel column height in pixels. */
82
+ #define LXW_DEF_ROW_HEIGHT_PIXELS 20
83
+
76
84
  /** Gridline options using in `worksheet_gridlines()`. */
77
85
  enum lxw_gridlines {
78
86
  /** Hide screen and print gridlines. */
@@ -202,6 +210,506 @@ enum lxw_validation_error_types {
202
210
  LXW_VALIDATION_ERROR_TYPE_INFORMATION
203
211
  };
204
212
 
213
+ /** Set the display type for a cell comment. This is hidden by default but
214
+ * can be set to visible with the `worksheet_show_comments()` function. */
215
+ enum lxw_comment_display_types {
216
+ /** Default to the worksheet default which can be hidden or visible.*/
217
+ LXW_COMMENT_DISPLAY_DEFAULT,
218
+
219
+ /** Hide the cell comment. Usually the default. */
220
+ LXW_COMMENT_DISPLAY_HIDDEN,
221
+
222
+ /** Show the cell comment. Can also be set for the worksheet with the
223
+ * `worksheet_show_comments()` function.*/
224
+ LXW_COMMENT_DISPLAY_VISIBLE
225
+ };
226
+
227
+ /** @brief Type definitions for conditional formats.
228
+ *
229
+ * Values used to set the "type" field of conditional format.
230
+ */
231
+ enum lxw_conditional_format_types {
232
+ LXW_CONDITIONAL_TYPE_NONE,
233
+
234
+ /** The Cell type is the most common conditional formatting type. It is
235
+ * used when a format is applied to a cell based on a simple
236
+ * criterion. */
237
+ LXW_CONDITIONAL_TYPE_CELL,
238
+
239
+ /** The Text type is used to specify Excel's "Specific Text" style
240
+ * conditional format. */
241
+ LXW_CONDITIONAL_TYPE_TEXT,
242
+
243
+ /** The Time Period type is used to specify Excel's "Dates Occurring"
244
+ * style conditional format. */
245
+ LXW_CONDITIONAL_TYPE_TIME_PERIOD,
246
+
247
+ /** The Average type is used to specify Excel's "Average" style
248
+ * conditional format. */
249
+ LXW_CONDITIONAL_TYPE_AVERAGE,
250
+
251
+ /** The Duplicate type is used to highlight duplicate cells in a range. */
252
+ LXW_CONDITIONAL_TYPE_DUPLICATE,
253
+
254
+ /** The Unique type is used to highlight unique cells in a range. */
255
+ LXW_CONDITIONAL_TYPE_UNIQUE,
256
+
257
+ /** The Top type is used to specify the top n values by number or
258
+ * percentage in a range. */
259
+ LXW_CONDITIONAL_TYPE_TOP,
260
+
261
+ /** The Bottom type is used to specify the bottom n values by number or
262
+ * percentage in a range. */
263
+ LXW_CONDITIONAL_TYPE_BOTTOM,
264
+
265
+ /** The Blanks type is used to highlight blank cells in a range. */
266
+ LXW_CONDITIONAL_TYPE_BLANKS,
267
+
268
+ /** The No Blanks type is used to highlight non blank cells in a range. */
269
+ LXW_CONDITIONAL_TYPE_NO_BLANKS,
270
+
271
+ /** The Errors type is used to highlight error cells in a range. */
272
+ LXW_CONDITIONAL_TYPE_ERRORS,
273
+
274
+ /** The No Errors type is used to highlight non error cells in a range. */
275
+ LXW_CONDITIONAL_TYPE_NO_ERRORS,
276
+
277
+ /** The Formula type is used to specify a conditional format based on a
278
+ * user defined formula. */
279
+ LXW_CONDITIONAL_TYPE_FORMULA,
280
+
281
+ /** The 2 Color Scale type is used to specify Excel's "2 Color Scale"
282
+ * style conditional format. */
283
+ LXW_CONDITIONAL_2_COLOR_SCALE,
284
+
285
+ /** The 3 Color Scale type is used to specify Excel's "3 Color Scale"
286
+ * style conditional format. */
287
+ LXW_CONDITIONAL_3_COLOR_SCALE,
288
+
289
+ /** The Data Bar type is used to specify Excel's "Data Bar" style
290
+ * conditional format. */
291
+ LXW_CONDITIONAL_DATA_BAR,
292
+
293
+ /** The Icon Set type is used to specify a conditional format with a set
294
+ * of icons such as traffic lights or arrows. */
295
+ LXW_CONDITIONAL_TYPE_ICON_SETS,
296
+
297
+ LXW_CONDITIONAL_TYPE_LAST
298
+ };
299
+
300
+ /** @brief The criteria used in a conditional format.
301
+ *
302
+ * Criteria used to define how a conditional format works.
303
+ */
304
+ enum lxw_conditional_criteria {
305
+ LXW_CONDITIONAL_CRITERIA_NONE,
306
+
307
+ /** Format cells equal to a value. */
308
+ LXW_CONDITIONAL_CRITERIA_EQUAL_TO,
309
+
310
+ /** Format cells not equal to a value. */
311
+ LXW_CONDITIONAL_CRITERIA_NOT_EQUAL_TO,
312
+
313
+ /** Format cells greater than a value. */
314
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN,
315
+
316
+ /** Format cells less than a value. */
317
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN,
318
+
319
+ /** Format cells greater than or equal to a value. */
320
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
321
+
322
+ /** Format cells less than or equal to a value. */
323
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN_OR_EQUAL_TO,
324
+
325
+ /** Format cells between two values. */
326
+ LXW_CONDITIONAL_CRITERIA_BETWEEN,
327
+
328
+ /** Format cells that is not between two values. */
329
+ LXW_CONDITIONAL_CRITERIA_NOT_BETWEEN,
330
+
331
+ /** Format cells that contain the specified text. */
332
+ LXW_CONDITIONAL_CRITERIA_TEXT_CONTAINING,
333
+
334
+ /** Format cells that don't contain the specified text. */
335
+ LXW_CONDITIONAL_CRITERIA_TEXT_NOT_CONTAINING,
336
+
337
+ /** Format cells that begin with the specified text. */
338
+ LXW_CONDITIONAL_CRITERIA_TEXT_BEGINS_WITH,
339
+
340
+ /** Format cells that end with the specified text. */
341
+ LXW_CONDITIONAL_CRITERIA_TEXT_ENDS_WITH,
342
+
343
+ /** Format cells with a date of yesterday. */
344
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_YESTERDAY,
345
+
346
+ /** Format cells with a date of today. */
347
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TODAY,
348
+
349
+ /** Format cells with a date of tomorrow. */
350
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TOMORROW,
351
+
352
+ /** Format cells with a date in the last 7 days. */
353
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_7_DAYS,
354
+
355
+ /** Format cells with a date in the last week. */
356
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_WEEK,
357
+
358
+ /** Format cells with a date in the current week. */
359
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_WEEK,
360
+
361
+ /** Format cells with a date in the next week. */
362
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_WEEK,
363
+
364
+ /** Format cells with a date in the last month. */
365
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_MONTH,
366
+
367
+ /** Format cells with a date in the current month. */
368
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_MONTH,
369
+
370
+ /** Format cells with a date in the next month. */
371
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_MONTH,
372
+
373
+ /** Format cells above the average for the range. */
374
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE,
375
+
376
+ /** Format cells below the average for the range. */
377
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW,
378
+
379
+ /** Format cells above or equal to the average for the range. */
380
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE_OR_EQUAL,
381
+
382
+ /** Format cells below or equal to the average for the range. */
383
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW_OR_EQUAL,
384
+
385
+ /** Format cells 1 standard deviation above the average for the range. */
386
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_ABOVE,
387
+
388
+ /** Format cells 1 standard deviation below the average for the range. */
389
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_BELOW,
390
+
391
+ /** Format cells 2 standard deviation above the average for the range. */
392
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_ABOVE,
393
+
394
+ /** Format cells 2 standard deviation below the average for the range. */
395
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_BELOW,
396
+
397
+ /** Format cells 3 standard deviation above the average for the range. */
398
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_ABOVE,
399
+
400
+ /** Format cells 3 standard deviation below the average for the range. */
401
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_BELOW,
402
+
403
+ /** Format cells in the top of bottom percentage. */
404
+ LXW_CONDITIONAL_CRITERIA_TOP_OR_BOTTOM_PERCENT
405
+ };
406
+
407
+ /** @brief Conditional format rule types.
408
+ *
409
+ * Conditional format rule types that apply to Color Scale and Data Bars.
410
+ */
411
+ enum lxw_conditional_format_rule_types {
412
+ LXW_CONDITIONAL_RULE_TYPE_NONE,
413
+
414
+ /** Conditional format rule type: matches the minimum values in the
415
+ * range. Can only be applied to min_rule_type.*/
416
+ LXW_CONDITIONAL_RULE_TYPE_MINIMUM,
417
+
418
+ /** Conditional format rule type: use a number to set the bound.*/
419
+ LXW_CONDITIONAL_RULE_TYPE_NUMBER,
420
+
421
+ /** Conditional format rule type: use a percentage to set the bound.*/
422
+ LXW_CONDITIONAL_RULE_TYPE_PERCENT,
423
+
424
+ /** Conditional format rule type: use a percentile to set the bound.*/
425
+ LXW_CONDITIONAL_RULE_TYPE_PERCENTILE,
426
+
427
+ /** Conditional format rule type: use a formula to set the bound.*/
428
+ LXW_CONDITIONAL_RULE_TYPE_FORMULA,
429
+
430
+ /** Conditional format rule type: matches the maximum values in the
431
+ * range. Can only be applied to max_rule_type.*/
432
+ LXW_CONDITIONAL_RULE_TYPE_MAXIMUM,
433
+
434
+ /* Used internally for Excel2010 bars. Not documented. */
435
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MIN,
436
+
437
+ /* Used internally for Excel2010 bars. Not documented. */
438
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MAX
439
+ };
440
+
441
+ /** @brief Conditional format data bar directions.
442
+ *
443
+ * Values used to set the bar direction of a conditional format data bar.
444
+ */
445
+ enum lxw_conditional_format_bar_direction {
446
+
447
+ /** Data bar direction is set by Excel based on the context of the data
448
+ * displayed. */
449
+ LXW_CONDITIONAL_BAR_DIRECTION_CONTEXT,
450
+
451
+ /** Data bar direction is from right to left. */
452
+ LXW_CONDITIONAL_BAR_DIRECTION_RIGHT_TO_LEFT,
453
+
454
+ /** Data bar direction is from left to right. */
455
+ LXW_CONDITIONAL_BAR_DIRECTION_LEFT_TO_RIGHT
456
+ };
457
+
458
+ /** @brief Conditional format data bar axis options.
459
+ *
460
+ * Values used to set the position of the axis in a conditional format data
461
+ * bar.
462
+ */
463
+ enum lxw_conditional_bar_axis_position {
464
+
465
+ /** Data bar axis position is set by Excel based on the context of the
466
+ * data displayed. */
467
+ LXW_CONDITIONAL_BAR_AXIS_AUTOMATIC,
468
+
469
+ /** Data bar axis position is set at the midpoint. */
470
+ LXW_CONDITIONAL_BAR_AXIS_MIDPOINT,
471
+
472
+ /** Data bar axis is turned off. */
473
+ LXW_CONDITIONAL_BAR_AXIS_NONE
474
+ };
475
+
476
+ /** @brief Icon types used in the #lxw_conditional_format icon_style field.
477
+ *
478
+ * Definitions of icon styles used with Icon Set conditional formats.
479
+ */
480
+ enum lxw_conditional_icon_types {
481
+
482
+ /** Icon style: 3 colored arrows showing up, sideways and down. */
483
+ LXW_CONDITIONAL_ICONS_3_ARROWS_COLORED,
484
+
485
+ /** Icon style: 3 gray arrows showing up, sideways and down. */
486
+ LXW_CONDITIONAL_ICONS_3_ARROWS_GRAY,
487
+
488
+ /** Icon style: 3 colored flags in red, yellow and green. */
489
+ LXW_CONDITIONAL_ICONS_3_FLAGS,
490
+
491
+ /** Icon style: 3 traffic lights - rounded. */
492
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_UNRIMMED,
493
+
494
+ /** Icon style: 3 traffic lights with a rim - squarish. */
495
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_RIMMED,
496
+
497
+ /** Icon style: 3 colored shapes - a circle, triangle and diamond. */
498
+ LXW_CONDITIONAL_ICONS_3_SIGNS,
499
+
500
+ /** Icon style: 3 circled symbols with tick mark, exclamation and
501
+ * cross. */
502
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_CIRCLED,
503
+
504
+ /** Icon style: 3 symbols with tick mark, exclamation and cross. */
505
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_UNCIRCLED,
506
+
507
+ /** Icon style: 4 colored arrows showing up, diagonal up, diagonal down
508
+ * and down. */
509
+ LXW_CONDITIONAL_ICONS_4_ARROWS_COLORED,
510
+
511
+ /** Icon style: 4 gray arrows showing up, diagonal up, diagonal down and
512
+ * down. */
513
+ LXW_CONDITIONAL_ICONS_4_ARROWS_GRAY,
514
+
515
+ /** Icon style: 4 circles in 4 colors going from red to black. */
516
+ LXW_CONDITIONAL_ICONS_4_RED_TO_BLACK,
517
+
518
+ /** Icon style: 4 histogram ratings. */
519
+ LXW_CONDITIONAL_ICONS_4_RATINGS,
520
+
521
+ /** Icon style: 4 traffic lights. */
522
+ LXW_CONDITIONAL_ICONS_4_TRAFFIC_LIGHTS,
523
+
524
+ /** Icon style: 5 colored arrows showing up, diagonal up, sideways,
525
+ * diagonal down and down. */
526
+ LXW_CONDITIONAL_ICONS_5_ARROWS_COLORED,
527
+
528
+ /** Icon style: 5 gray arrows showing up, diagonal up, sideways, diagonal
529
+ * down and down. */
530
+ LXW_CONDITIONAL_ICONS_5_ARROWS_GRAY,
531
+
532
+ /** Icon style: 5 histogram ratings. */
533
+ LXW_CONDITIONAL_ICONS_5_RATINGS,
534
+
535
+ /** Icon style: 5 quarters, from 0 to 4 quadrants filled. */
536
+ LXW_CONDITIONAL_ICONS_5_QUARTERS
537
+ };
538
+
539
+ /** @brief The type of table style.
540
+ *
541
+ * The type of table style (Light, Medium or Dark).
542
+ */
543
+ enum lxw_table_style_type {
544
+
545
+ LXW_TABLE_STYLE_TYPE_DEFAULT,
546
+
547
+ /** Light table style. */
548
+ LXW_TABLE_STYLE_TYPE_LIGHT,
549
+
550
+ /** Light table style. */
551
+ LXW_TABLE_STYLE_TYPE_MEDIUM,
552
+
553
+ /** Light table style. */
554
+ LXW_TABLE_STYLE_TYPE_DARK
555
+ };
556
+
557
+ /**
558
+ * @brief Standard Excel functions for totals in tables.
559
+ *
560
+ * Definitions for the standard Excel functions that are available via the
561
+ * dropdown in the total row of an Excel table.
562
+ *
563
+ */
564
+ enum lxw_table_total_functions {
565
+
566
+ LXW_TABLE_FUNCTION_NONE = 0,
567
+
568
+ /** Use the average function as the table total. */
569
+ LXW_TABLE_FUNCTION_AVERAGE = 101,
570
+
571
+ /** Use the count numbers function as the table total. */
572
+ LXW_TABLE_FUNCTION_COUNT_NUMS = 102,
573
+
574
+ /** Use the count function as the table total. */
575
+ LXW_TABLE_FUNCTION_COUNT = 103,
576
+
577
+ /** Use the max function as the table total. */
578
+ LXW_TABLE_FUNCTION_MAX = 104,
579
+
580
+ /** Use the min function as the table total. */
581
+ LXW_TABLE_FUNCTION_MIN = 105,
582
+
583
+ /** Use the standard deviation function as the table total. */
584
+ LXW_TABLE_FUNCTION_STD_DEV = 107,
585
+
586
+ /** Use the sum function as the table total. */
587
+ LXW_TABLE_FUNCTION_SUM = 109,
588
+
589
+ /** Use the var function as the table total. */
590
+ LXW_TABLE_FUNCTION_VAR = 110
591
+ };
592
+
593
+ /** @brief The criteria used in autofilter rules.
594
+ *
595
+ * Criteria used to define an autofilter rule condition.
596
+ */
597
+ enum lxw_filter_criteria {
598
+ LXW_FILTER_CRITERIA_NONE,
599
+
600
+ /** Filter cells equal to a value. */
601
+ LXW_FILTER_CRITERIA_EQUAL_TO,
602
+
603
+ /** Filter cells not equal to a value. */
604
+ LXW_FILTER_CRITERIA_NOT_EQUAL_TO,
605
+
606
+ /** Filter cells greater than a value. */
607
+ LXW_FILTER_CRITERIA_GREATER_THAN,
608
+
609
+ /** Filter cells less than a value. */
610
+ LXW_FILTER_CRITERIA_LESS_THAN,
611
+
612
+ /** Filter cells greater than or equal to a value. */
613
+ LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
614
+
615
+ /** Filter cells less than or equal to a value. */
616
+ LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO,
617
+
618
+ /** Filter cells that are blank. */
619
+ LXW_FILTER_CRITERIA_BLANKS,
620
+
621
+ /** Filter cells that are not blank. */
622
+ LXW_FILTER_CRITERIA_NON_BLANKS
623
+ };
624
+
625
+ /**
626
+ * @brief And/or operator when using 2 filter rules.
627
+ *
628
+ * And/or operator conditions when using 2 filter rules with
629
+ * worksheet_filter_column2(). In general LXW_FILTER_OR is used with
630
+ * LXW_FILTER_CRITERIA_EQUAL_TO and LXW_FILTER_AND is used with the other
631
+ * filter criteria.
632
+ */
633
+ enum lxw_filter_operator {
634
+ /** Logical "and" of 2 filter rules. */
635
+ LXW_FILTER_AND,
636
+
637
+ /** Logical "or" of 2 filter rules. */
638
+ LXW_FILTER_OR
639
+ };
640
+
641
+ /* Internal filter types. */
642
+ enum lxw_filter_type {
643
+ LXW_FILTER_TYPE_NONE,
644
+
645
+ LXW_FILTER_TYPE_SINGLE,
646
+
647
+ LXW_FILTER_TYPE_AND,
648
+
649
+ LXW_FILTER_TYPE_OR,
650
+
651
+ LXW_FILTER_TYPE_STRING_LIST
652
+ };
653
+
654
+ /** Options to control the positioning of worksheet objects such as images
655
+ * or charts. See @ref working_with_object_positioning. */
656
+ enum lxw_object_position {
657
+
658
+ /** Default positioning for the object. */
659
+ LXW_OBJECT_POSITION_DEFAULT,
660
+
661
+ /** Move and size the worksheet object with the cells. */
662
+ LXW_OBJECT_MOVE_AND_SIZE,
663
+
664
+ /** Move but don't size the worksheet object with the cells. */
665
+ LXW_OBJECT_MOVE_DONT_SIZE,
666
+
667
+ /** Don't move or size the worksheet object with the cells. */
668
+ LXW_OBJECT_DONT_MOVE_DONT_SIZE,
669
+
670
+ /** Same as #LXW_OBJECT_MOVE_AND_SIZE except libxlsxwriter applies hidden
671
+ * cells after the object is inserted. */
672
+ LXW_OBJECT_MOVE_AND_SIZE_AFTER
673
+ };
674
+
675
+ /** Options for ignoring worksheet errors/warnings. See worksheet_ignore_errors(). */
676
+ enum lxw_ignore_errors {
677
+
678
+ /** Turn off errors/warnings for numbers stores as text. */
679
+ LXW_IGNORE_NUMBER_STORED_AS_TEXT = 1,
680
+
681
+ /** Turn off errors/warnings for formula errors (such as divide by
682
+ * zero). */
683
+ LXW_IGNORE_EVAL_ERROR,
684
+
685
+ /** Turn off errors/warnings for formulas that differ from surrounding
686
+ * formulas. */
687
+ LXW_IGNORE_FORMULA_DIFFERS,
688
+
689
+ /** Turn off errors/warnings for formulas that omit cells in a range. */
690
+ LXW_IGNORE_FORMULA_RANGE,
691
+
692
+ /** Turn off errors/warnings for unlocked cells that contain formulas. */
693
+ LXW_IGNORE_FORMULA_UNLOCKED,
694
+
695
+ /** Turn off errors/warnings for formulas that refer to empty cells. */
696
+ LXW_IGNORE_EMPTY_CELL_REFERENCE,
697
+
698
+ /** Turn off errors/warnings for cells in a table that do not comply with
699
+ * applicable data validation rules. */
700
+ LXW_IGNORE_LIST_DATA_VALIDATION,
701
+
702
+ /** Turn off errors/warnings for cell formulas that differ from the column
703
+ * formula. */
704
+ LXW_IGNORE_CALCULATED_COLUMN,
705
+
706
+ /** Turn off errors/warnings for formulas that contain a two digit text
707
+ * representation of a year. */
708
+ LXW_IGNORE_TWO_DIGIT_TEXT_YEAR,
709
+
710
+ LXW_IGNORE_LAST_OPTION
711
+ };
712
+
205
713
  enum cell_types {
206
714
  NUMBER_CELL = 1,
207
715
  STRING_CELL,
@@ -209,8 +717,10 @@ enum cell_types {
209
717
  INLINE_RICH_STRING_CELL,
210
718
  FORMULA_CELL,
211
719
  ARRAY_FORMULA_CELL,
720
+ DYNAMIC_ARRAY_FORMULA_CELL,
212
721
  BLANK_CELL,
213
722
  BOOLEAN_CELL,
723
+ COMMENT,
214
724
  HYPERLINK_URL,
215
725
  HYPERLINK_INTERNAL,
216
726
  HYPERLINK_EXTERNAL
@@ -223,8 +733,20 @@ enum pane_types {
223
733
  FREEZE_SPLIT_PANES
224
734
  };
225
735
 
736
+ enum lxw_image_position {
737
+ HEADER_LEFT = 0,
738
+ HEADER_CENTER,
739
+ HEADER_RIGHT,
740
+ FOOTER_LEFT,
741
+ FOOTER_CENTER,
742
+ FOOTER_RIGHT
743
+ };
744
+
226
745
  /* Define the tree.h RB structs for the red-black head types. */
227
746
  RB_HEAD(lxw_table_cells, lxw_cell);
747
+ RB_HEAD(lxw_drawing_rel_ids, lxw_drawing_rel_id);
748
+ RB_HEAD(lxw_vml_drawing_rel_ids, lxw_drawing_rel_id);
749
+ RB_HEAD(lxw_cond_format_hash, lxw_cond_format_hash_element);
228
750
 
229
751
  /* Define a RB_TREE struct manually to add extra members. */
230
752
  struct lxw_table_rows {
@@ -257,11 +779,47 @@ struct lxw_table_rows {
257
779
  /* Add unused struct to allow adding a semicolon */ \
258
780
  struct lxw_rb_generate_cell{int unused;}
259
781
 
782
+ #define LXW_RB_GENERATE_DRAWING_REL_IDS(name, type, field, cmp) \
783
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
784
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
785
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
786
+ RB_GENERATE_REMOVE(name, type, field, static) \
787
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
788
+ RB_GENERATE_NEXT(name, type, field, static) \
789
+ RB_GENERATE_MINMAX(name, type, field, static) \
790
+ /* Add unused struct to allow adding a semicolon */ \
791
+ struct lxw_rb_generate_drawing_rel_ids{int unused;}
792
+
793
+ #define LXW_RB_GENERATE_VML_DRAWING_REL_IDS(name, type, field, cmp) \
794
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
795
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
796
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
797
+ RB_GENERATE_REMOVE(name, type, field, static) \
798
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
799
+ RB_GENERATE_NEXT(name, type, field, static) \
800
+ RB_GENERATE_MINMAX(name, type, field, static) \
801
+ /* Add unused struct to allow adding a semicolon */ \
802
+ struct lxw_rb_generate_vml_drawing_rel_ids{int unused;}
803
+
804
+ #define LXW_RB_GENERATE_COND_FORMAT_HASH(name, type, field, cmp) \
805
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
806
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
807
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
808
+ RB_GENERATE_REMOVE(name, type, field, static) \
809
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
810
+ RB_GENERATE_NEXT(name, type, field, static) \
811
+ RB_GENERATE_MINMAX(name, type, field, static) \
812
+ /* Add unused struct to allow adding a semicolon */ \
813
+ struct lxw_rb_generate_cond_format_hash{int unused;}
814
+
260
815
  STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
261
816
  STAILQ_HEAD(lxw_selections, lxw_selection);
262
- STAILQ_HEAD(lxw_data_validations, lxw_data_validation);
263
- STAILQ_HEAD(lxw_image_data, lxw_image_options);
264
- STAILQ_HEAD(lxw_chart_data, lxw_image_options);
817
+ STAILQ_HEAD(lxw_data_validations, lxw_data_val_obj);
818
+ STAILQ_HEAD(lxw_cond_format_list, lxw_cond_format_obj);
819
+ STAILQ_HEAD(lxw_image_props, lxw_object_properties);
820
+ STAILQ_HEAD(lxw_chart_props, lxw_object_properties);
821
+ STAILQ_HEAD(lxw_comment_objs, lxw_vml_obj);
822
+ STAILQ_HEAD(lxw_table_objs, lxw_table_obj);
265
823
 
266
824
  /**
267
825
  * @brief Options for rows and columns.
@@ -279,9 +837,13 @@ STAILQ_HEAD(lxw_chart_data, lxw_image_options);
279
837
  *
280
838
  */
281
839
  typedef struct lxw_row_col_options {
282
- /** Hide the row/column */
840
+ /** Hide the row/column. @ref ww_outlines_grouping.*/
283
841
  uint8_t hidden;
842
+
843
+ /** Outline level. See @ref ww_outlines_grouping.*/
284
844
  uint8_t level;
845
+
846
+ /** Set the outline row as collapsed. See @ref ww_outlines_grouping.*/
285
847
  uint8_t collapsed;
286
848
  } lxw_row_col_options;
287
849
 
@@ -326,6 +888,7 @@ typedef struct lxw_print_area {
326
888
 
327
889
  typedef struct lxw_autofilter {
328
890
  uint8_t in_use;
891
+ uint8_t has_rules;
329
892
  lxw_row_t first_row;
330
893
  lxw_row_t last_row;
331
894
  lxw_col_t first_col;
@@ -405,8 +968,6 @@ typedef struct lxw_data_validation {
405
968
  */
406
969
  uint8_t dropdown;
407
970
 
408
- uint8_t is_between;
409
-
410
971
  /**
411
972
  * This parameter is used to set the limiting value to which the criteria
412
973
  * is applied using a whole or decimal number.
@@ -418,7 +979,7 @@ typedef struct lxw_data_validation {
418
979
  * is applied using a cell reference. It is valid for any of the
419
980
  * `_FORMULA` validation types.
420
981
  */
421
- char *value_formula;
982
+ const char *value_formula;
422
983
 
423
984
  /**
424
985
  * This parameter is used to set a list of strings for a drop down list.
@@ -437,96 +998,702 @@ typedef struct lxw_data_validation {
437
998
  * Note, the string list is restricted by Excel to 255 characters,
438
999
  * including comma separators.
439
1000
  */
440
- char **value_list;
1001
+ const char **value_list;
1002
+
1003
+ /**
1004
+ * This parameter is used to set the limiting value to which the date or
1005
+ * time criteria is applied using a #lxw_datetime struct.
1006
+ */
1007
+ lxw_datetime value_datetime;
1008
+
1009
+ /**
1010
+ * This parameter is the same as `value_number` but for the minimum value
1011
+ * when a `BETWEEN` criteria is used.
1012
+ */
1013
+ double minimum_number;
1014
+
1015
+ /**
1016
+ * This parameter is the same as `value_formula` but for the minimum value
1017
+ * when a `BETWEEN` criteria is used.
1018
+ */
1019
+ const char *minimum_formula;
1020
+
1021
+ /**
1022
+ * This parameter is the same as `value_datetime` but for the minimum value
1023
+ * when a `BETWEEN` criteria is used.
1024
+ */
1025
+ lxw_datetime minimum_datetime;
1026
+
1027
+ /**
1028
+ * This parameter is the same as `value_number` but for the maximum value
1029
+ * when a `BETWEEN` criteria is used.
1030
+ */
1031
+ double maximum_number;
1032
+
1033
+ /**
1034
+ * This parameter is the same as `value_formula` but for the maximum value
1035
+ * when a `BETWEEN` criteria is used.
1036
+ */
1037
+ const char *maximum_formula;
1038
+
1039
+ /**
1040
+ * This parameter is the same as `value_datetime` but for the maximum value
1041
+ * when a `BETWEEN` criteria is used.
1042
+ */
1043
+ lxw_datetime maximum_datetime;
1044
+
1045
+ /**
1046
+ * The input_title parameter is used to set the title of the input message
1047
+ * that is displayed when a cell is entered. It has no default value and
1048
+ * is only displayed if the input message is displayed. See the
1049
+ * `input_message` parameter below.
1050
+ *
1051
+ * The maximum title length is 32 characters.
1052
+ */
1053
+ const char *input_title;
1054
+
1055
+ /**
1056
+ * The input_message parameter is used to set the input message that is
1057
+ * displayed when a cell is entered. It has no default value.
1058
+ *
1059
+ * The message can be split over several lines using newlines. The maximum
1060
+ * message length is 255 characters.
1061
+ */
1062
+ const char *input_message;
1063
+
1064
+ /**
1065
+ * The error_title parameter is used to set the title of the error message
1066
+ * that is displayed when the data validation criteria is not met. The
1067
+ * default error title is 'Microsoft Excel'. The maximum title length is
1068
+ * 32 characters.
1069
+ */
1070
+ const char *error_title;
1071
+
1072
+ /**
1073
+ * The error_message parameter is used to set the error message that is
1074
+ * displayed when a cell is entered. The default error message is "The
1075
+ * value you entered is not valid. A user has restricted values that can
1076
+ * be entered into the cell".
1077
+ *
1078
+ * The message can be split over several lines using newlines. The maximum
1079
+ * message length is 255 characters.
1080
+ */
1081
+ const char *error_message;
1082
+
1083
+ } lxw_data_validation;
1084
+
1085
+ /* A copy of lxw_data_validation which is used internally and which contains
1086
+ * some additional fields.
1087
+ */
1088
+ typedef struct lxw_data_val_obj {
1089
+ uint8_t validate;
1090
+ uint8_t criteria;
1091
+ uint8_t ignore_blank;
1092
+ uint8_t show_input;
1093
+ uint8_t show_error;
1094
+ uint8_t error_type;
1095
+ uint8_t dropdown;
1096
+ double value_number;
1097
+ char *value_formula;
1098
+ char **value_list;
1099
+ double minimum_number;
1100
+ char *minimum_formula;
1101
+ lxw_datetime minimum_datetime;
1102
+ double maximum_number;
1103
+ char *maximum_formula;
1104
+ lxw_datetime maximum_datetime;
1105
+ char *input_title;
1106
+ char *input_message;
1107
+ char *error_title;
1108
+ char *error_message;
1109
+ char sqref[LXW_MAX_CELL_RANGE_LENGTH];
1110
+
1111
+ STAILQ_ENTRY (lxw_data_val_obj) list_pointers;
1112
+ } lxw_data_val_obj;
1113
+
1114
+ /**
1115
+ * @brief Worksheet conditional formatting options.
1116
+ *
1117
+ * The fields/options in the the lxw_conditional_format are used to define a
1118
+ * worksheet conditional format. It is used in conjunction with
1119
+ * `worksheet_conditional_format()`.
1120
+ *
1121
+ */
1122
+ typedef struct lxw_conditional_format {
1123
+
1124
+ /** The type of conditional format such as #LXW_CONDITIONAL_TYPE_CELL or
1125
+ * #LXW_CONDITIONAL_DATA_BAR. Should be a #lxw_conditional_format_types
1126
+ * value.*/
1127
+ uint8_t type;
1128
+
1129
+ /** The criteria parameter is used to set the criteria by which the cell
1130
+ * data will be evaluated. For example in the expression `a > 5 the
1131
+ * criteria is `>` or, in libxlsxwriter terms,
1132
+ * #LXW_CONDITIONAL_CRITERIA_GREATER_THAN. The criteria that are
1133
+ * applicable depend on the conditional format type. The criteria
1134
+ * options are defined in #lxw_conditional_criteria. */
1135
+ uint8_t criteria;
1136
+
1137
+ /** The number value to which the condition refers. For example in the
1138
+ * expression `a > 5`, the value is 5.*/
1139
+ double value;
1140
+
1141
+ /** The string value to which the condition refers, such as `"=A1"`. If a
1142
+ * value_string exists in the struct then the number value is
1143
+ * ignored. Note, if the condition refers to a text string then it must
1144
+ * be double quoted like this `"foo"`. */
1145
+ const char *value_string;
1146
+
1147
+ /** The format field is used to specify the #lxw_format format that will
1148
+ * be applied to the cell when the conditional formatting criterion is
1149
+ * met. The #lxw_format is created using the `workbook_add_format()`
1150
+ * method in the same way as cell formats.
1151
+ *
1152
+ * @note In Excel, a conditional format is superimposed over the existing
1153
+ * cell format and not all cell format properties can be
1154
+ * modified. Properties that @b cannot be modified, in Excel, by a
1155
+ * conditional format are: font name, font size, superscript and
1156
+ * subscript, diagonal borders, all alignment properties and all
1157
+ * protection properties. */
1158
+ lxw_format *format;
1159
+
1160
+ /** The minimum value used for Cell, Color Scale and Data Bar conditional
1161
+ * formats. For Cell types this is usually used with a "Between" style criteria. */
1162
+ double min_value;
1163
+
1164
+ /** The minimum string value used for Cell, Color Scale and Data Bar conditional
1165
+ * formats. Usually used to set ranges like `=A1`. */
1166
+ const char *min_value_string;
1167
+
1168
+ /** The rule used for the minimum condition in Color Scale and Data Bar
1169
+ * conditional formats. The rule types are defined in
1170
+ * #lxw_conditional_format_rule_types. */
1171
+ uint8_t min_rule_type;
1172
+
1173
+ /** The color used for the minimum Color Scale conditional format.
1174
+ * See @ref working_with_colors. */
1175
+ lxw_color_t min_color;
1176
+
1177
+ /** The middle value used for Color Scale and Data Bar conditional
1178
+ * formats. */
1179
+ double mid_value;
1180
+
1181
+ /** The middle string value used for Color Scale and Data Bar conditional
1182
+ * formats. Usually used to set ranges like `=A1`. */
1183
+ const char *mid_value_string;
1184
+
1185
+ /** The rule used for the middle condition in Color Scale and Data Bar
1186
+ * conditional formats. The rule types are defined in
1187
+ * #lxw_conditional_format_rule_types. */
1188
+ uint8_t mid_rule_type;
1189
+
1190
+ /** The color used for the middle Color Scale conditional format.
1191
+ * See @ref working_with_colors. */
1192
+ lxw_color_t mid_color;
1193
+
1194
+ /** The maximum value used for Cell, Color Scale and Data Bar conditional
1195
+ * formats. For Cell types this is usually used with a "Between" style
1196
+ * criteria. */
1197
+ double max_value;
1198
+
1199
+ /** The maximum string value used for Cell, Color Scale and Data Bar conditional
1200
+ * formats. Usually used to set ranges like `=A1`. */
1201
+ const char *max_value_string;
1202
+
1203
+ /** The rule used for the maximum condition in Color Scale and Data Bar
1204
+ * conditional formats. The rule types are defined in
1205
+ * #lxw_conditional_format_rule_types. */
1206
+ uint8_t max_rule_type;
1207
+
1208
+ /** The color used for the maximum Color Scale conditional format.
1209
+ * See @ref working_with_colors. */
1210
+ lxw_color_t max_color;
1211
+
1212
+ /** The bar_color field sets the fill color for data bars. See @ref
1213
+ * working_with_colors. */
1214
+ lxw_color_t bar_color;
1215
+
1216
+ /** The bar_only field sets The bar_only field displays a bar data but
1217
+ * not the data in the cells. */
1218
+ uint8_t bar_only;
1219
+
1220
+ /** In Excel 2010 additional data bar properties were added such as solid
1221
+ * (non-gradient) bars and control over how negative values are
1222
+ * displayed. These properties can shown below.
1223
+ *
1224
+ * The data_bar_2010 field sets Excel 2010 style data bars even when
1225
+ * Excel 2010 specific properties aren't used. */
1226
+ uint8_t data_bar_2010;
1227
+
1228
+ /** The bar_solid field turns on a solid (non-gradient) fill for data
1229
+ * bars. Set to LXW_TRUE to turn on. Excel 2010 only. */
1230
+ uint8_t bar_solid;
1231
+
1232
+ /** The bar_negative_color field sets the color fill for the negative
1233
+ * portion of a data bar. See @ref working_with_colors. Excel 2010 only. */
1234
+ lxw_color_t bar_negative_color;
1235
+
1236
+ /** The bar_border_color field sets the color for the border line of a
1237
+ * data bar. See @ref working_with_colors. Excel 2010 only. */
1238
+ lxw_color_t bar_border_color;
1239
+
1240
+ /** The bar_negative_border_color field sets the color for the border of
1241
+ * the negative portion of a data bar. See @ref
1242
+ * working_with_colors. Excel 2010 only. */
1243
+ lxw_color_t bar_negative_border_color;
1244
+
1245
+ /** The bar_negative_color_same field sets the fill color for the negative
1246
+ * portion of a data bar to be the same as the fill color for the
1247
+ * positive portion of the data bar. Set to LXW_TRUE to turn on. Excel
1248
+ * 2010 only. */
1249
+ uint8_t bar_negative_color_same;
1250
+
1251
+ /** The bar_negative_border_color_same field sets the border color for the
1252
+ * negative portion of a data bar to be the same as the border color for
1253
+ * the positive portion of the data bar. Set to LXW_TRUE to turn
1254
+ * on. Excel 2010 only. */
1255
+ uint8_t bar_negative_border_color_same;
1256
+
1257
+ /** The bar_no_border field turns off the border for data bars. Set to
1258
+ * LXW_TRUE to enable. Excel 2010 only. */
1259
+ uint8_t bar_no_border;
1260
+
1261
+ /** The bar_direction field sets the direction for data bars. This
1262
+ * property can be either left for left-to-right or right for
1263
+ * right-to-left. If the property isn't set then Excel will adjust the
1264
+ * position automatically based on the context. Should be a
1265
+ * #lxw_conditional_format_bar_direction value. Excel 2010 only. */
1266
+ uint8_t bar_direction;
1267
+
1268
+ /** The bar_axis_position field sets the position within the cells for the
1269
+ * axis that is shown in data bars when there are negative values to
1270
+ * display. The property can be either middle or none. If the property
1271
+ * isn't set then Excel will position the axis based on the range of
1272
+ * positive and negative values. Should be a
1273
+ * lxw_conditional_bar_axis_position value. Excel 2010 only. */
1274
+ uint8_t bar_axis_position;
1275
+
1276
+ /** The bar_axis_color field sets the color for the axis that is shown
1277
+ * in data bars when there are negative values to display. See @ref
1278
+ * working_with_colors. Excel 2010 only. */
1279
+ lxw_color_t bar_axis_color;
1280
+
1281
+ /** The Icons Sets style is specified by the icon_style parameter. Should
1282
+ * be a #lxw_conditional_icon_types. */
1283
+ uint8_t icon_style;
1284
+
1285
+ /** The order of Icon Sets icons can be reversed by setting reverse_icons
1286
+ * to LXW_TRUE. */
1287
+ uint8_t reverse_icons;
1288
+
1289
+ /** The icons can be displayed without the cell value by settings the
1290
+ * icons_only parameter to LXW_TRUE. */
1291
+ uint8_t icons_only;
1292
+
1293
+ /** The multi_range field is used to extend a conditional format over
1294
+ * non-contiguous ranges.
1295
+ *
1296
+ * It is possible to apply the conditional format to different cell
1297
+ * ranges in a worksheet using multiple calls to
1298
+ * `worksheet_conditional_format()`. However, as a minor optimization it
1299
+ * is also possible in Excel to apply the same conditional format to
1300
+ * different non-contiguous cell ranges.
1301
+ *
1302
+ * This is replicated in `worksheet_conditional_format()` using the
1303
+ * multi_range option. The range must contain the primary range for the
1304
+ * conditional format and any others separated by spaces. For example
1305
+ * `"A1 C1:C5 E2 G1:G100"`.
1306
+ */
1307
+ const char *multi_range;
1308
+
1309
+ /** The stop_if_true parameter can be used to set the "stop if true"
1310
+ * feature of a conditional formatting rule when more than one rule is
1311
+ * applied to a cell or a range of cells. When this parameter is set then
1312
+ * subsequent rules are not evaluated if the current rule is true. Set to
1313
+ * LXW_TRUE to turn on. */
1314
+ uint8_t stop_if_true;
1315
+
1316
+ } lxw_conditional_format;
1317
+
1318
+ /* Internal */
1319
+ typedef struct lxw_cond_format_obj {
1320
+ uint8_t type;
1321
+ uint8_t criteria;
1322
+
1323
+ double min_value;
1324
+ char *min_value_string;
1325
+ uint8_t min_rule_type;
1326
+ lxw_color_t min_color;
1327
+
1328
+ double mid_value;
1329
+ char *mid_value_string;
1330
+ uint8_t mid_value_type;
1331
+ uint8_t mid_rule_type;
1332
+ lxw_color_t mid_color;
1333
+
1334
+ double max_value;
1335
+ char *max_value_string;
1336
+ uint8_t max_value_type;
1337
+ uint8_t max_rule_type;
1338
+ lxw_color_t max_color;
1339
+
1340
+ uint8_t data_bar_2010;
1341
+ uint8_t auto_min;
1342
+ uint8_t auto_max;
1343
+ uint8_t bar_only;
1344
+ uint8_t bar_solid;
1345
+ uint8_t bar_negative_color_same;
1346
+ uint8_t bar_negative_border_color_same;
1347
+ uint8_t bar_no_border;
1348
+ uint8_t bar_direction;
1349
+ uint8_t bar_axis_position;
1350
+ lxw_color_t bar_color;
1351
+ lxw_color_t bar_negative_color;
1352
+ lxw_color_t bar_border_color;
1353
+ lxw_color_t bar_negative_border_color;
1354
+ lxw_color_t bar_axis_color;
1355
+
1356
+ uint8_t icon_style;
1357
+ uint8_t reverse_icons;
1358
+ uint8_t icons_only;
1359
+
1360
+ uint8_t stop_if_true;
1361
+ uint8_t has_max;
1362
+ char *type_string;
1363
+ char *guid;
1364
+
1365
+ int32_t dxf_index;
1366
+ uint32_t dxf_priority;
1367
+
1368
+ char first_cell[LXW_MAX_CELL_NAME_LENGTH];
1369
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1370
+
1371
+ STAILQ_ENTRY (lxw_cond_format_obj) list_pointers;
1372
+ } lxw_cond_format_obj;
1373
+
1374
+ typedef struct lxw_cond_format_hash_element {
1375
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1376
+
1377
+ struct lxw_cond_format_list *cond_formats;
1378
+
1379
+ RB_ENTRY (lxw_cond_format_hash_element) tree_pointers;
1380
+ } lxw_cond_format_hash_element;
1381
+
1382
+ /**
1383
+ * @brief Table columns options.
1384
+ *
1385
+ * Structure to set the options of a table column added with
1386
+ * worksheet_add_table(). See @ref ww_tables_columns.
1387
+ */
1388
+ typedef struct lxw_table_column {
1389
+
1390
+ /** Set the header name/caption for the column. If NULL the header defaults
1391
+ * to Column 1, Column 2, etc. */
1392
+ const char *header;
1393
+
1394
+ /** Set the formula for the column. */
1395
+ const char *formula;
1396
+
1397
+ /** Set the string description for the column total. */
1398
+ const char *total_string;
1399
+
1400
+ /** Set the function for the column total. */
1401
+ uint8_t total_function;
1402
+
1403
+ /** Set the format for the column header. */
1404
+ lxw_format *header_format;
1405
+
1406
+ /** Set the format for the data rows in the column. */
1407
+ lxw_format *format;
1408
+
1409
+ /** Set the formula value for the column total (not generally required). */
1410
+ double total_value;
1411
+
1412
+ } lxw_table_column;
1413
+
1414
+ /**
1415
+ * @brief Worksheet table options.
1416
+ *
1417
+ * Options used to define worksheet tables. See @ref working_with_tables for
1418
+ * more information.
1419
+ *
1420
+ */
1421
+ typedef struct lxw_table_options {
1422
+
1423
+ /**
1424
+ * The `name` parameter is used to set the name of the table. This
1425
+ * parameter is optional and by default tables are named `Table1`,
1426
+ * `Table2`, etc. in the worksheet order that they are added.
1427
+ *
1428
+ * @code
1429
+ * lxw_table_options options = {.name = "Sales"};
1430
+ *
1431
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
1432
+ * @endcode
1433
+ *
1434
+ * If you override the table name you must ensure that it doesn't clash
1435
+ * with an existing table name and that it follows Excel's requirements
1436
+ * for table names, see the Microsoft Office documentation on
1437
+ * [Naming an Excel Table]
1438
+ * (https://support.microsoft.com/en-us/office/rename-an-excel-table-fbf49a4f-82a3-43eb-8ba2-44d21233b114).
1439
+ */
1440
+ const char *name;
1441
+
1442
+ /**
1443
+ * The `no_header_row` parameter can be used to turn off the header row in
1444
+ * the table. It is on by default:
1445
+ *
1446
+ * @code
1447
+ * lxw_table_options options = {.no_header_row = LXW_TRUE};
1448
+ *
1449
+ * worksheet_add_table(worksheet, RANGE("B4:F7"), &options);
1450
+ * @endcode
1451
+ *
1452
+ * @image html tables4.png
1453
+ *
1454
+ * Without this option the header row will contain default captions such
1455
+ * as `Column 1`, ``Column 2``, etc. These captions can be overridden
1456
+ * using the `columns` parameter shown below.
1457
+ *
1458
+ */
1459
+ uint8_t no_header_row;
1460
+
1461
+ /**
1462
+ * The `no_autofilter` parameter can be used to turn off the autofilter in
1463
+ * the header row. It is on by default:
1464
+ *
1465
+ * @code
1466
+ * lxw_table_options options = {.no_autofilter = LXW_TRUE};
1467
+ *
1468
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
1469
+ * @endcode
1470
+ *
1471
+ * @image html tables3.png
1472
+ *
1473
+ * The autofilter is only shown if the `no_header_row` parameter is off
1474
+ * (the default). Filter conditions within the table are not supported.
1475
+ *
1476
+ */
1477
+ uint8_t no_autofilter;
1478
+
1479
+ /**
1480
+ * The `no_banded_rows` parameter can be used to turn off the rows of alternating
1481
+ * color in the table. It is on by default:
1482
+ *
1483
+ * @code
1484
+ * lxw_table_options options = {.no_banded_rows = LXW_TRUE};
1485
+ *
1486
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
1487
+ * @endcode
1488
+ *
1489
+ * @image html tables6.png
1490
+ *
1491
+ */
1492
+ uint8_t no_banded_rows;
1493
+
1494
+ /**
1495
+ * The `banded_columns` parameter can be used to used to create columns of
1496
+ * alternating color in the table. It is off by default:
1497
+ *
1498
+ * @code
1499
+ * lxw_table_options options = {.banded_columns = LXW_TRUE};
1500
+ *
1501
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
1502
+ * @endcode
1503
+ *
1504
+ * The banded columns formatting is shown in the image in the previous
1505
+ * section above.
1506
+ */
1507
+ uint8_t banded_columns;
1508
+
1509
+ /**
1510
+ * The `first_column` parameter can be used to highlight the first column
1511
+ * of the table. The type of highlighting will depend on the `style_type`
1512
+ * of the table. It may be bold text or a different color. It is off by
1513
+ * default:
1514
+ *
1515
+ * @code
1516
+ * lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
1517
+ *
1518
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
1519
+ * @endcode
1520
+ *
1521
+ * @image html tables5.png
1522
+ */
1523
+ uint8_t first_column;
1524
+
1525
+ /**
1526
+ * The `last_column` parameter can be used to highlight the last column of
1527
+ * the table. The type of highlighting will depend on the `style` of the
1528
+ * table. It may be bold text or a different color. It is off by default:
1529
+ *
1530
+ * @code
1531
+ * lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
1532
+ *
1533
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
1534
+ * @endcode
1535
+ *
1536
+ * The `last_column` formatting is shown in the image in the previous
1537
+ * section above.
1538
+ */
1539
+ uint8_t last_column;
1540
+
1541
+ /**
1542
+ * The `style_type` parameter can be used to set the style of the table,
1543
+ * in conjunction with the `style_type_number` parameter:
1544
+ *
1545
+ * @code
1546
+ * lxw_table_options options = {
1547
+ * .style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
1548
+ * .style_type_number = 11,
1549
+ * };
1550
+ *
1551
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
1552
+ * @endcode
1553
+ *
1554
+ *
1555
+ * @image html tables11.png
1556
+ *
1557
+ * There are three types of table style in Excel: Light, Medium and Dark
1558
+ * which are represented using the #lxw_table_style_type enum values:
1559
+ *
1560
+ * - #LXW_TABLE_STYLE_TYPE_LIGHT
1561
+ *
1562
+ * - #LXW_TABLE_STYLE_TYPE_MEDIUM
1563
+ *
1564
+ * - #LXW_TABLE_STYLE_TYPE_DARK
1565
+ *
1566
+ * Within those ranges there are between 11 and 28 other style types which
1567
+ * can be set with `style_type_number` (depending on the style type).
1568
+ * Check Excel to find the style that you want. The dialog with the
1569
+ * options laid out in numeric order are shown below:
1570
+ *
1571
+ * @image html tables14.png
1572
+ *
1573
+ * The default table style in Excel is 'Table Style Medium 9' (highlighted
1574
+ * with a green border in the image above), which is set by default in
1575
+ * libxlsxwriter as:
1576
+ *
1577
+ * @code
1578
+ * lxw_table_options options = {
1579
+ * .style_type = LXW_TABLE_STYLE_TYPE_MEDIUM,
1580
+ * .style_type_number = 9,
1581
+ * };
1582
+ * @endcode
1583
+ *
1584
+ * You can also turn the table style off by setting it to Light 0:
1585
+ *
1586
+ * @code
1587
+ * lxw_table_options options = {
1588
+ * .style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
1589
+ * .style_type_number = 0,
1590
+ * };
1591
+ * @endcode
1592
+ *
1593
+ * @image html tables13.png
1594
+ *
1595
+ */
1596
+ uint8_t style_type;
441
1597
 
442
1598
  /**
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;
1599
+ * The `style_type_number` parameter is used with `style_type` to set the
1600
+ * style of a worksheet table. */
1601
+ uint8_t style_type_number;
447
1602
 
448
1603
  /**
449
- * This parameter is the same as `value_number` but for the minimum value
450
- * when a `BETWEEN` criteria is used.
1604
+ * The `total_row` parameter can be used to turn on the total row in the
1605
+ * last row of a table. It is distinguished from the other rows by a
1606
+ * different formatting and also with dropdown `SUBTOTAL` functions:
1607
+ *
1608
+ * @code
1609
+ * lxw_table_options options = {.total_row = LXW_TRUE};
1610
+ *
1611
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
1612
+ * @endcode
1613
+ *
1614
+ * @image html tables9.png
1615
+ *
1616
+ * The default total row doesn't have any captions or functions. These
1617
+ * must by specified via the `columns` parameter below.
451
1618
  */
452
- double minimum_number;
1619
+ uint8_t total_row;
453
1620
 
454
1621
  /**
455
- * This parameter is the same as `value_formula` but for the minimum value
456
- * when a `BETWEEN` criteria is used.
1622
+ * The `columns` parameter can be used to set properties for columns
1623
+ * within the table. See @ref ww_tables_columns for a detailed
1624
+ * explanation.
457
1625
  */
458
- char *minimum_formula;
1626
+ lxw_table_column **columns;
459
1627
 
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;
1628
+ } lxw_table_options;
465
1629
 
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;
1630
+ typedef struct lxw_table_obj {
1631
+ char *name;
1632
+ char *total_string;
1633
+ lxw_table_column **columns;
1634
+ uint8_t banded_columns;
1635
+ uint8_t first_column;
1636
+ uint8_t last_column;
1637
+ uint8_t no_autofilter;
1638
+ uint8_t no_banded_rows;
1639
+ uint8_t no_header_row;
1640
+ uint8_t style_type;
1641
+ uint8_t style_type_number;
1642
+ uint8_t total_row;
471
1643
 
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;
1644
+ lxw_row_t first_row;
1645
+ lxw_col_t first_col;
1646
+ lxw_row_t last_row;
1647
+ lxw_col_t last_col;
1648
+ lxw_col_t num_cols;
1649
+ uint32_t id;
477
1650
 
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;
1651
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1652
+ char filter_sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1653
+ STAILQ_ENTRY (lxw_table_obj) list_pointers;
483
1654
 
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;
1655
+ } lxw_table_obj;
493
1656
 
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;
1657
+ /**
1658
+ * @brief Options for autofilter rules.
1659
+ *
1660
+ * Options to define an autofilter rule.
1661
+ *
1662
+ */
1663
+ typedef struct lxw_filter_rule {
502
1664
 
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;
1665
+ /** The #lxw_filter_criteria to define the rule. */
1666
+ uint8_t criteria;
510
1667
 
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;
1668
+ /** String value to which the criteria applies. */
1669
+ const char *value_string;
521
1670
 
522
- char sqref[LXW_MAX_CELL_RANGE_LENGTH];
1671
+ /** Numeric value to which the criteria applies (if value_string isn't used). */
1672
+ double value;
523
1673
 
524
- STAILQ_ENTRY (lxw_data_validation) list_pointers;
1674
+ } lxw_filter_rule;
525
1675
 
526
- } lxw_data_validation;
1676
+ typedef struct lxw_filter_rule_obj {
1677
+
1678
+ uint8_t type;
1679
+ uint8_t is_custom;
1680
+ uint8_t has_blanks;
1681
+ lxw_col_t col_num;
1682
+
1683
+ uint8_t criteria1;
1684
+ uint8_t criteria2;
1685
+ double value1;
1686
+ double value2;
1687
+ char *value1_string;
1688
+ char *value2_string;
1689
+
1690
+ uint16_t num_list_filters;
1691
+ char **list;
1692
+
1693
+ } lxw_filter_rule_obj;
527
1694
 
528
1695
  /**
529
- * @brief Options for inserted images
1696
+ * @brief Options for inserted images.
530
1697
  *
531
1698
  * Options for modifying images inserted via `worksheet_insert_image_opt()`.
532
1699
  *
@@ -545,19 +1712,88 @@ typedef struct lxw_image_options {
545
1712
  /** Y scale of the image as a decimal. */
546
1713
  double y_scale;
547
1714
 
1715
+ /** Object position - use one of the values of #lxw_object_position.
1716
+ * See @ref working_with_object_positioning.*/
1717
+ uint8_t object_position;
1718
+
1719
+ /** Optional description or "Alt text" for the image. This field can be
1720
+ * used to provide a text description of the image to help
1721
+ * accessibility. Defaults to the image filename as in Excel. Set to ""
1722
+ * to ignore the description field. */
1723
+ const char *description;
1724
+
1725
+ /** Optional parameter to help accessibility. It is used to mark the image
1726
+ * as decorative, and thus uninformative, for automated screen
1727
+ * readers. As in Excel, if this parameter is in use the `description`
1728
+ * field isn't written. */
1729
+ uint8_t decorative;
1730
+
1731
+ /** Add an optional hyperlink to the image. Follows the same URL rules
1732
+ * and types as `worksheet_write_url()`. */
1733
+ const char *url;
1734
+
1735
+ /** Add an optional mouseover tip for a hyperlink to the image. */
1736
+ const char *tip;
1737
+
1738
+ } lxw_image_options;
1739
+
1740
+ /**
1741
+ * @brief Options for inserted charts.
1742
+ *
1743
+ * Options for modifying charts inserted via `worksheet_insert_chart_opt()`.
1744
+ *
1745
+ */
1746
+ typedef struct lxw_chart_options {
1747
+
1748
+ /** Offset from the left of the cell in pixels. */
1749
+ int32_t x_offset;
1750
+
1751
+ /** Offset from the top of the cell in pixels. */
1752
+ int32_t y_offset;
1753
+
1754
+ /** X scale of the chart as a decimal. */
1755
+ double x_scale;
1756
+
1757
+ /** Y scale of the chart as a decimal. */
1758
+ double y_scale;
1759
+
1760
+ /** Object position - use one of the values of #lxw_object_position.
1761
+ * See @ref working_with_object_positioning.*/
1762
+ uint8_t object_position;
1763
+
1764
+ /** Optional description or "Alt text" for the chart. This field can be
1765
+ * used to provide a text description of the chart to help
1766
+ * accessibility. Defaults to the image filename as in Excel. Set to NULL
1767
+ * to ignore the description field. */
1768
+ const char *description;
1769
+
1770
+ /** Optional parameter to help accessibility. It is used to mark the chart
1771
+ * as decorative, and thus uninformative, for automated screen
1772
+ * readers. As in Excel, if this parameter is in use the `description`
1773
+ * field isn't written. */
1774
+ uint8_t decorative;
1775
+
1776
+ } lxw_chart_options;
1777
+
1778
+ /* Internal struct to represent lxw_image_options and lxw_chart_options
1779
+ * values as well as internal metadata.
1780
+ */
1781
+ typedef struct lxw_object_properties {
1782
+ int32_t x_offset;
1783
+ int32_t y_offset;
1784
+ double x_scale;
1785
+ double y_scale;
548
1786
  lxw_row_t row;
549
1787
  lxw_col_t col;
550
1788
  char *filename;
551
1789
  char *description;
552
1790
  char *url;
553
1791
  char *tip;
554
- uint8_t anchor;
555
-
556
- /* Internal metadata. */
1792
+ uint8_t object_position;
557
1793
  FILE *stream;
558
1794
  uint8_t image_type;
559
1795
  uint8_t is_image_buffer;
560
- unsigned char *image_buffer;
1796
+ char *image_buffer;
561
1797
  size_t image_buffer_size;
562
1798
  double width;
563
1799
  double height;
@@ -565,21 +1801,200 @@ typedef struct lxw_image_options {
565
1801
  double x_dpi;
566
1802
  double y_dpi;
567
1803
  lxw_chart *chart;
1804
+ uint8_t is_duplicate;
1805
+ uint8_t is_background;
1806
+ char *md5;
1807
+ char *image_position;
1808
+ uint8_t decorative;
568
1809
 
569
- STAILQ_ENTRY (lxw_image_options) list_pointers;
1810
+ STAILQ_ENTRY (lxw_object_properties) list_pointers;
1811
+ } lxw_object_properties;
570
1812
 
571
- } lxw_image_options;
1813
+ /**
1814
+ * @brief Options for inserted comments.
1815
+ *
1816
+ * Options for modifying comments inserted via `worksheet_write_comment_opt()`.
1817
+ *
1818
+ */
1819
+ typedef struct lxw_comment_options {
1820
+
1821
+ /** This option is used to make a cell comment visible when the worksheet
1822
+ * is opened. The default behavior in Excel is that comments are
1823
+ * initially hidden. However, it is also possible in Excel to make
1824
+ * individual comments or all comments visible. You can make all
1825
+ * comments in the worksheet visible using the
1826
+ * `worksheet_show_comments()` function. Defaults to
1827
+ * LXW_COMMENT_DISPLAY_DEFAULT. See also @ref ww_comments_visible. */
1828
+ uint8_t visible;
1829
+
1830
+ /** This option is used to indicate the author of the cell comment. Excel
1831
+ * displays the author in the status bar at the bottom of the
1832
+ * worksheet. The default author for all cell comments in a worksheet can
1833
+ * be set using the `worksheet_set_comments_author()` function. Set to
1834
+ * NULL if not required. See also @ref ww_comments_author. */
1835
+ const char *author;
1836
+
1837
+ /** This option is used to set the width of the cell comment box
1838
+ * explicitly in pixels. The default width is 128 pixels. See also @ref
1839
+ * ww_comments_width. */
1840
+ uint16_t width;
1841
+
1842
+ /** This option is used to set the height of the cell comment box
1843
+ * explicitly in pixels. The default height is 74 pixels. See also @ref
1844
+ * ww_comments_height. */
1845
+ uint16_t height;
1846
+
1847
+ /** X scale of the comment as a decimal. See also
1848
+ * @ref ww_comments_x_scale. */
1849
+ double x_scale;
1850
+
1851
+ /** Y scale of the comment as a decimal. See also
1852
+ * @ref ww_comments_y_scale. */
1853
+ double y_scale;
1854
+
1855
+ /** This option is used to set the background color of cell comment
1856
+ * box. The color should be an RGB integer value, see @ref
1857
+ * working_with_colors. See also @ref ww_comments_color. */
1858
+ lxw_color_t color;
1859
+
1860
+ /** This option is used to set the font for the comment. The default font
1861
+ * is 'Tahoma'. See also @ref ww_comments_font_name. */
1862
+ const char *font_name;
1863
+
1864
+ /** This option is used to set the font size for the comment. The default
1865
+ * is 8. See also @ref ww_comments_font_size. */
1866
+ double font_size;
1867
+
1868
+ /** This option is used to set the font family number for the comment.
1869
+ * Not required very often. Set to 0. */
1870
+ uint8_t font_family;
1871
+
1872
+ /** This option is used to set the row in which the comment will
1873
+ * appear. By default Excel displays comments one cell to the right and
1874
+ * one cell above the cell to which the comment relates. The `start_row`
1875
+ * and `start_col` options should both be set to 0 if not used. See also
1876
+ * @ref ww_comments_start_row. */
1877
+ lxw_row_t start_row;
1878
+
1879
+ /** This option is used to set the column in which the comment will
1880
+ * appear. See the `start_row` option for more information and see also
1881
+ * @ref ww_comments_start_col. */
1882
+ lxw_col_t start_col;
1883
+
1884
+ /** Offset from the left of the cell in pixels. See also
1885
+ * @ref ww_comments_x_offset. */
1886
+ int32_t x_offset;
1887
+
1888
+ /** Offset from the top of the cell in pixels. See also
1889
+ * @ref ww_comments_y_offset. */
1890
+ int32_t y_offset;
1891
+
1892
+ } lxw_comment_options;
1893
+
1894
+ /**
1895
+ * @brief Options for inserted buttons.
1896
+ *
1897
+ * Options for modifying buttons inserted via `worksheet_insert_button()`.
1898
+ *
1899
+ */
1900
+ typedef struct lxw_button_options {
1901
+
1902
+ /** Sets the caption on the button. The default is "Button n" where n is
1903
+ * the current number of buttons in the worksheet, including this
1904
+ * button. */
1905
+ const char *caption;
1906
+
1907
+ /** Name of the macro to run when the button is pressed. The macro must be
1908
+ * included with workbook_add_vba_project(). */
1909
+ const char *macro;
1910
+
1911
+ /** Optional description or "Alt text" for the button. This field can be
1912
+ * used to provide a text description of the button to help
1913
+ * accessibility. Set to NULL to ignore the description field. */
1914
+ const char *description;
1915
+
1916
+ /** This option is used to set the width of the cell button box
1917
+ * explicitly in pixels. The default width is 64 pixels. */
1918
+ uint16_t width;
1919
+
1920
+ /** This option is used to set the height of the cell button box
1921
+ * explicitly in pixels. The default height is 20 pixels. */
1922
+ uint16_t height;
1923
+
1924
+ /** X scale of the button as a decimal. */
1925
+ double x_scale;
1926
+
1927
+ /** Y scale of the button as a decimal. */
1928
+ double y_scale;
1929
+
1930
+ /** Offset from the left of the cell in pixels. */
1931
+ int32_t x_offset;
1932
+
1933
+ /** Offset from the top of the cell in pixels. */
1934
+ int32_t y_offset;
1935
+
1936
+ } lxw_button_options;
1937
+
1938
+ /* Internal structure for VML object options. */
1939
+ typedef struct lxw_vml_obj {
1940
+
1941
+ lxw_row_t row;
1942
+ lxw_col_t col;
1943
+ lxw_row_t start_row;
1944
+ lxw_col_t start_col;
1945
+ int32_t x_offset;
1946
+ int32_t y_offset;
1947
+ uint64_t col_absolute;
1948
+ uint64_t row_absolute;
1949
+ uint32_t width;
1950
+ uint32_t height;
1951
+ double x_dpi;
1952
+ double y_dpi;
1953
+ lxw_color_t color;
1954
+ uint8_t font_family;
1955
+ uint8_t visible;
1956
+ uint32_t author_id;
1957
+ uint32_t rel_index;
1958
+ double font_size;
1959
+ struct lxw_drawing_coords from;
1960
+ struct lxw_drawing_coords to;
1961
+ char *author;
1962
+ char *font_name;
1963
+ char *text;
1964
+ char *image_position;
1965
+ char *name;
1966
+ char *macro;
1967
+ STAILQ_ENTRY (lxw_vml_obj) list_pointers;
1968
+
1969
+ } lxw_vml_obj;
572
1970
 
573
1971
  /**
574
1972
  * @brief Header and footer options.
575
1973
  *
576
- * Optional parameters used in the worksheet_set_header_opt() and
1974
+ * Optional parameters used in the `worksheet_set_header_opt()` and
577
1975
  * worksheet_set_footer_opt() functions.
578
1976
  *
579
1977
  */
580
1978
  typedef struct lxw_header_footer_options {
581
- /** Header or footer margin in inches. Excel default is 0.3. */
1979
+ /** Header or footer margin in inches. Excel default is 0.3. Must by
1980
+ * larger than 0.0. See `worksheet_set_header_opt()`. */
582
1981
  double margin;
1982
+
1983
+ /** The left header image filename, with path if required. This should
1984
+ * have a corresponding `&G/&[Picture]` placeholder in the `&L` section of
1985
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1986
+ const char *image_left;
1987
+
1988
+ /** The center header image filename, with path if required. This should
1989
+ * have a corresponding `&G/&[Picture]` placeholder in the `&C` section of
1990
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1991
+ const char *image_center;
1992
+
1993
+ /** The right header image filename, with path if required. This should
1994
+ * have a corresponding `&G/&[Picture]` placeholder in the `&R` section of
1995
+ * the header/footer string. See `worksheet_set_header_opt()`. */
1996
+ const char *image_right;
1997
+
583
1998
  } lxw_header_footer_options;
584
1999
 
585
2000
  /**
@@ -637,10 +2052,31 @@ typedef struct lxw_protection {
637
2052
  /** Turn off chartsheet objects. */
638
2053
  uint8_t no_objects;
639
2054
 
2055
+ } lxw_protection;
2056
+
2057
+ /* Internal struct to copy lxw_protection options and internal metadata. */
2058
+ typedef struct lxw_protection_obj {
2059
+ uint8_t no_select_locked_cells;
2060
+ uint8_t no_select_unlocked_cells;
2061
+ uint8_t format_cells;
2062
+ uint8_t format_columns;
2063
+ uint8_t format_rows;
2064
+ uint8_t insert_columns;
2065
+ uint8_t insert_rows;
2066
+ uint8_t insert_hyperlinks;
2067
+ uint8_t delete_columns;
2068
+ uint8_t delete_rows;
2069
+ uint8_t sort;
2070
+ uint8_t autofilter;
2071
+ uint8_t pivot_tables;
2072
+ uint8_t scenarios;
2073
+ uint8_t objects;
2074
+ uint8_t no_content;
2075
+ uint8_t no_objects;
640
2076
  uint8_t no_sheet;
641
2077
  uint8_t is_configured;
642
2078
  char hash[5];
643
- } lxw_protection;
2079
+ } lxw_protection_obj;
644
2080
 
645
2081
  /**
646
2082
  * @brief Struct to represent a rich string format/string pair.
@@ -658,7 +2094,7 @@ typedef struct lxw_rich_string_tuple {
658
2094
  lxw_format *format;
659
2095
 
660
2096
  /** The string fragment. */
661
- char *string;
2097
+ const char *string;
662
2098
  } lxw_rich_string_tuple;
663
2099
 
664
2100
  /**
@@ -672,14 +2108,25 @@ typedef struct lxw_worksheet {
672
2108
 
673
2109
  FILE *file;
674
2110
  FILE *optimize_tmpfile;
2111
+ char *optimize_buffer;
2112
+ size_t optimize_buffer_size;
675
2113
  struct lxw_table_rows *table;
676
2114
  struct lxw_table_rows *hyperlinks;
2115
+ struct lxw_table_rows *comments;
677
2116
  struct lxw_cell **array;
678
2117
  struct lxw_merged_ranges *merged_ranges;
679
2118
  struct lxw_selections *selections;
680
2119
  struct lxw_data_validations *data_validations;
681
- struct lxw_image_data *image_data;
682
- struct lxw_chart_data *chart_data;
2120
+ struct lxw_cond_format_hash *conditional_formats;
2121
+ struct lxw_image_props *image_props;
2122
+ struct lxw_chart_props *chart_data;
2123
+ struct lxw_drawing_rel_ids *drawing_rel_ids;
2124
+ struct lxw_vml_drawing_rel_ids *vml_drawing_rel_ids;
2125
+ struct lxw_comment_objs *comment_objs;
2126
+ struct lxw_comment_objs *header_image_objs;
2127
+ struct lxw_comment_objs *button_objs;
2128
+ struct lxw_table_objs *table_objs;
2129
+ uint16_t table_count;
683
2130
 
684
2131
  lxw_row_t dim_rowmin;
685
2132
  lxw_row_t dim_rowmax;
@@ -687,11 +2134,11 @@ typedef struct lxw_worksheet {
687
2134
  lxw_col_t dim_colmax;
688
2135
 
689
2136
  lxw_sst *sst;
690
- char *name;
691
- char *quoted_name;
692
- char *tmpdir;
2137
+ const char *name;
2138
+ const char *quoted_name;
2139
+ const char *tmpdir;
693
2140
 
694
- uint32_t index;
2141
+ uint16_t index;
695
2142
  uint8_t active;
696
2143
  uint8_t selected;
697
2144
  uint8_t hidden;
@@ -743,8 +2190,11 @@ typedef struct lxw_worksheet {
743
2190
  uint8_t show_zeros;
744
2191
  uint8_t vcenter;
745
2192
  uint8_t zoom_scale_normal;
2193
+ uint8_t black_white;
746
2194
  uint8_t num_validations;
2195
+ uint8_t has_dynamic_arrays;
747
2196
  char *vba_codename;
2197
+ uint16_t num_buttons;
748
2198
 
749
2199
  lxw_color_t tab_color;
750
2200
 
@@ -764,8 +2214,8 @@ typedef struct lxw_worksheet {
764
2214
  uint8_t outline_col_level;
765
2215
 
766
2216
  uint8_t header_footer_changed;
767
- char header[LXW_HEADER_FOOTER_MAX];
768
- char footer[LXW_HEADER_FOOTER_MAX];
2217
+ char *header;
2218
+ char *footer;
769
2219
 
770
2220
  struct lxw_repeat_rows repeat_rows;
771
2221
  struct lxw_repeat_cols repeat_cols;
@@ -773,21 +2223,71 @@ typedef struct lxw_worksheet {
773
2223
  struct lxw_autofilter autofilter;
774
2224
 
775
2225
  uint16_t merged_range_count;
2226
+ uint16_t max_url_length;
776
2227
 
777
2228
  lxw_row_t *hbreaks;
778
2229
  lxw_col_t *vbreaks;
779
2230
  uint16_t hbreaks_count;
780
2231
  uint16_t vbreaks_count;
781
2232
 
2233
+ uint32_t drawing_rel_id;
2234
+ uint32_t vml_drawing_rel_id;
782
2235
  struct lxw_rel_tuples *external_hyperlinks;
783
2236
  struct lxw_rel_tuples *external_drawing_links;
784
2237
  struct lxw_rel_tuples *drawing_links;
2238
+ struct lxw_rel_tuples *vml_drawing_links;
2239
+ struct lxw_rel_tuples *external_table_links;
785
2240
 
786
2241
  struct lxw_panes panes;
2242
+ char top_left_cell[LXW_MAX_CELL_NAME_LENGTH];
787
2243
 
788
- struct lxw_protection protection;
2244
+ struct lxw_protection_obj protection;
789
2245
 
790
2246
  lxw_drawing *drawing;
2247
+ lxw_format *default_url_format;
2248
+
2249
+ uint8_t has_vml;
2250
+ uint8_t has_comments;
2251
+ uint8_t has_header_vml;
2252
+ uint8_t has_background_image;
2253
+ uint8_t has_buttons;
2254
+ lxw_rel_tuple *external_vml_comment_link;
2255
+ lxw_rel_tuple *external_comment_link;
2256
+ lxw_rel_tuple *external_vml_header_link;
2257
+ lxw_rel_tuple *external_background_link;
2258
+ char *comment_author;
2259
+ char *vml_data_id_str;
2260
+ char *vml_header_id_str;
2261
+ uint32_t vml_shape_id;
2262
+ uint32_t vml_header_id;
2263
+ uint32_t dxf_priority;
2264
+ uint8_t comment_display_default;
2265
+ uint32_t data_bar_2010_index;
2266
+
2267
+ uint8_t has_ignore_errors;
2268
+ char *ignore_number_stored_as_text;
2269
+ char *ignore_eval_error;
2270
+ char *ignore_formula_differs;
2271
+ char *ignore_formula_range;
2272
+ char *ignore_formula_unlocked;
2273
+ char *ignore_empty_cell_reference;
2274
+ char *ignore_list_data_validation;
2275
+ char *ignore_calculated_column;
2276
+ char *ignore_two_digit_text_year;
2277
+
2278
+ uint16_t excel_version;
2279
+
2280
+ lxw_object_properties **header_footer_objs[LXW_HEADER_FOOTER_OBJS_MAX];
2281
+ lxw_object_properties *header_left_object_props;
2282
+ lxw_object_properties *header_center_object_props;
2283
+ lxw_object_properties *header_right_object_props;
2284
+ lxw_object_properties *footer_left_object_props;
2285
+ lxw_object_properties *footer_center_object_props;
2286
+ lxw_object_properties *footer_right_object_props;
2287
+ lxw_object_properties *background_image;
2288
+
2289
+ lxw_filter_rule_obj **filter_rules;
2290
+ lxw_col_t num_filter_rules;
791
2291
 
792
2292
  STAILQ_ENTRY (lxw_worksheet) list_pointers;
793
2293
 
@@ -797,15 +2297,17 @@ typedef struct lxw_worksheet {
797
2297
  * Worksheet initialization data.
798
2298
  */
799
2299
  typedef struct lxw_worksheet_init_data {
800
- uint32_t index;
2300
+ uint16_t index;
801
2301
  uint8_t hidden;
802
2302
  uint8_t optimize;
803
2303
  uint16_t *active_sheet;
804
2304
  uint16_t *first_sheet;
805
2305
  lxw_sst *sst;
806
- char *name;
807
- char *quoted_name;
808
- char *tmpdir;
2306
+ const char *name;
2307
+ const char *quoted_name;
2308
+ const char *tmpdir;
2309
+ lxw_format *default_url_format;
2310
+ uint16_t max_url_length;
809
2311
 
810
2312
  } lxw_worksheet_init_data;
811
2313
 
@@ -820,6 +2322,7 @@ typedef struct lxw_row {
820
2322
  uint8_t row_changed;
821
2323
  uint8_t data_changed;
822
2324
  uint8_t height_changed;
2325
+
823
2326
  struct lxw_table_cells *cells;
824
2327
 
825
2328
  /* tree management pointers for tree.h. */
@@ -832,11 +2335,12 @@ typedef struct lxw_cell {
832
2335
  lxw_col_t col_num;
833
2336
  enum cell_types type;
834
2337
  lxw_format *format;
2338
+ lxw_vml_obj *comment;
835
2339
 
836
2340
  union {
837
2341
  double number;
838
2342
  int32_t string_id;
839
- char *string;
2343
+ const char *string;
840
2344
  } u;
841
2345
 
842
2346
  double formula_result;
@@ -848,6 +2352,16 @@ typedef struct lxw_cell {
848
2352
  RB_ENTRY (lxw_cell) tree_pointers;
849
2353
  } lxw_cell;
850
2354
 
2355
+ /* Struct to represent a drawing Target/ID pair. */
2356
+ typedef struct lxw_drawing_rel_id {
2357
+ uint32_t id;
2358
+ char *target;
2359
+
2360
+ RB_ENTRY (lxw_drawing_rel_id) tree_pointers;
2361
+ } lxw_drawing_rel_id;
2362
+
2363
+
2364
+
851
2365
  /* *INDENT-OFF* */
852
2366
  #ifdef __cplusplus
853
2367
  extern "C" {
@@ -857,7 +2371,7 @@ extern "C" {
857
2371
  /**
858
2372
  * @brief Write a number to a worksheet cell.
859
2373
  *
860
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2374
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
861
2375
  * @param row The zero indexed row number.
862
2376
  * @param col The zero indexed column number.
863
2377
  * @param number The number to write to the cell.
@@ -904,7 +2418,7 @@ lxw_error worksheet_write_number(lxw_worksheet *worksheet,
904
2418
  /**
905
2419
  * @brief Write a string to a worksheet cell.
906
2420
  *
907
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2421
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
908
2422
  * @param row The zero indexed row number.
909
2423
  * @param col The zero indexed column number.
910
2424
  * @param string String to write to cell.
@@ -952,7 +2466,7 @@ lxw_error worksheet_write_string(lxw_worksheet *worksheet,
952
2466
  /**
953
2467
  * @brief Write a formula to a worksheet cell.
954
2468
  *
955
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2469
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
956
2470
  * @param row The zero indexed row number.
957
2471
  * @param col The zero indexed column number.
958
2472
  * @param formula Formula string to write to cell.
@@ -1005,17 +2519,17 @@ lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
1005
2519
  /**
1006
2520
  * @brief Write an array formula to a worksheet cell.
1007
2521
  *
1008
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
1009
- * @param first_row The first row of the range. (All zero indexed.)
1010
- * @param first_col The first column of the range.
1011
- * @param last_row The last row of the range.
1012
- * @param last_col The last col of the range.
1013
- * @param formula Array formula to write to cell.
1014
- * @param format A pointer to a Format instance or NULL.
2522
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2523
+ * @param first_row The first row of the range. (All zero indexed.)
2524
+ * @param first_col The first column of the range.
2525
+ * @param last_row The last row of the range.
2526
+ * @param last_col The last col of the range.
2527
+ * @param formula Array formula to write to cell.
2528
+ * @param format A pointer to a Format instance or NULL.
1015
2529
  *
1016
2530
  * @return A #lxw_error code.
1017
2531
  *
1018
- * The `%worksheet_write_array_formula()` function writes an array formula to
2532
+ * The `%worksheet_write_array_formula()` function writes an array formula to
1019
2533
  * a cell range. In Excel an array formula is a formula that performs a
1020
2534
  * calculation on a set of values.
1021
2535
  *
@@ -1039,18 +2553,106 @@ lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
1039
2553
  * parameters should be the same:
1040
2554
  *
1041
2555
  * @code
1042
- * worksheet_write_array_formula(worksheet, 1, 0, 1, 0, "{=SUM(B1:C1*B2:C2)}", NULL);
1043
- * worksheet_write_array_formula(worksheet, RANGE("A2:A2"), "{=SUM(B1:C1*B2:C2)}", NULL);
2556
+ * worksheet_write_array_formula(worksheet, 1, 0, 1, 0, "{=SUM(B1:C1*B2:C2)}", NULL);
2557
+ * worksheet_write_array_formula(worksheet, RANGE("A2:A2"), "{=SUM(B1:C1*B2:C2)}", NULL);
2558
+ * @endcode
2559
+ *
2560
+ */
2561
+ lxw_error worksheet_write_array_formula(lxw_worksheet *worksheet,
2562
+ lxw_row_t first_row,
2563
+ lxw_col_t first_col,
2564
+ lxw_row_t last_row,
2565
+ lxw_col_t last_col,
2566
+ const char *formula,
2567
+ lxw_format *format);
2568
+
2569
+ /**
2570
+ * @brief Write an Excel 365 dynamic array formula to a worksheet range.
2571
+ *
2572
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2573
+ * @param first_row The first row of the range. (All zero indexed.)
2574
+ * @param first_col The first column of the range.
2575
+ * @param last_row The last row of the range.
2576
+ * @param last_col The last col of the range.
2577
+ * @param formula Dynamic Array formula to write to cell.
2578
+ * @param format A pointer to a Format instance or NULL.
2579
+ *
2580
+ * @return A #lxw_error code.
2581
+ *
2582
+ *
2583
+ * The `%worksheet_write_dynamic_array_formula()` function writes an Excel 365
2584
+ * dynamic array formula to a cell range. Some examples of functions that
2585
+ * return dynamic arrays are:
2586
+ *
2587
+ * - `FILTER`
2588
+ * - `RANDARRAY`
2589
+ * - `SEQUENCE`
2590
+ * - `SORTBY`
2591
+ * - `SORT`
2592
+ * - `UNIQUE`
2593
+ * - `XLOOKUP`
2594
+ * - `XMATCH`
2595
+ *
2596
+ * Dynamic array formulas and their usage in libxlsxwriter is explained in
2597
+ * detail @ref ww_formulas_dynamic_arrays. The following is a example usage:
2598
+ *
2599
+ * @code
2600
+ * worksheet_write_dynamic_array_formula(worksheet, 1, 5, 1, 5,
2601
+ * "=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
2602
+ * NULL);
2603
+ * @endcode
2604
+ *
2605
+ * This formula gives the results shown in the image below.
2606
+ *
2607
+ * @image html dynamic_arrays02.png
2608
+ *
2609
+ * The need for the `_xlfn._xlws.` prefix in the formula is explained in @ref
2610
+ * ww_formulas_future.
2611
+ */
2612
+ lxw_error worksheet_write_dynamic_array_formula(lxw_worksheet *worksheet,
2613
+ lxw_row_t first_row,
2614
+ lxw_col_t first_col,
2615
+ lxw_row_t last_row,
2616
+ lxw_col_t last_col,
2617
+ const char *formula,
2618
+ lxw_format *format);
2619
+
2620
+ /**
2621
+ * @brief Write an Excel 365 dynamic array formula to a worksheet cell.
2622
+ *
2623
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2624
+ * @param row The zero indexed row number.
2625
+ * @param col The zero indexed column number.
2626
+ * @param formula Formula string to write to cell.
2627
+ * @param format A pointer to a Format instance or NULL.
2628
+ *
2629
+ * @return A #lxw_error code.
2630
+ *
2631
+ * The `%worksheet_write_dynamic_formula()` function is similar to the
2632
+ * `worksheet_write_dynamic_array_formula()` function, shown above, except
2633
+ * that it writes a dynamic array formula to a single cell, rather than a
2634
+ * range. This is a syntactic shortcut since the array range isn't generally
2635
+ * known for a dynamic range and specifying the initial cell is sufficient for
2636
+ * Excel, as shown in the example below:
2637
+ *
2638
+ * @code
2639
+ * worksheet_write_dynamic_formula(worksheet, 7, 1,
2640
+ * "=_xlfn._xlws.SORT(_xlfn.UNIQUE(B2:B17))",
2641
+ * NULL);
1044
2642
  * @endcode
1045
2643
  *
2644
+ * This formula gives the following result:
2645
+ *
2646
+ * @image html dynamic_arrays01.png
2647
+ *
2648
+ * The need for the `_xlfn.` and `_xlfn._xlws.` prefixes in the formula is
2649
+ * explained in @ref ww_formulas_future.
1046
2650
  */
1047
- lxw_error worksheet_write_array_formula(lxw_worksheet *worksheet,
1048
- lxw_row_t first_row,
1049
- lxw_col_t first_col,
1050
- lxw_row_t last_row,
1051
- lxw_col_t last_col,
1052
- const char *formula,
1053
- lxw_format *format);
2651
+ lxw_error worksheet_write_dynamic_formula(lxw_worksheet *worksheet,
2652
+ lxw_row_t row,
2653
+ lxw_col_t col,
2654
+ const char *formula,
2655
+ lxw_format *format);
1054
2656
 
1055
2657
  lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
1056
2658
  lxw_row_t first_row,
@@ -1061,10 +2663,26 @@ lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
1061
2663
  lxw_format *format,
1062
2664
  double result);
1063
2665
 
2666
+ lxw_error worksheet_write_dynamic_array_formula_num(lxw_worksheet *worksheet,
2667
+ lxw_row_t first_row,
2668
+ lxw_col_t first_col,
2669
+ lxw_row_t last_row,
2670
+ lxw_col_t last_col,
2671
+ const char *formula,
2672
+ lxw_format *format,
2673
+ double result);
2674
+
2675
+ lxw_error worksheet_write_dynamic_formula_num(lxw_worksheet *worksheet,
2676
+ lxw_row_t row,
2677
+ lxw_col_t col,
2678
+ const char *formula,
2679
+ lxw_format *format,
2680
+ double result);
2681
+
1064
2682
  /**
1065
2683
  * @brief Write a date or time to a worksheet cell.
1066
2684
  *
1067
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2685
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1068
2686
  * @param row The zero indexed row number.
1069
2687
  * @param col The zero indexed column number.
1070
2688
  * @param datetime The datetime to write to the cell.
@@ -1072,7 +2690,7 @@ lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
1072
2690
  *
1073
2691
  * @return A #lxw_error code.
1074
2692
  *
1075
- * The `worksheet_write_datetime()` function can be used to write a date or
2693
+ * The `%worksheet_write_datetime()` function can be used to write a date or
1076
2694
  * time to the cell specified by `row` and `column`:
1077
2695
  *
1078
2696
  * @dontinclude dates_and_times02.c
@@ -1093,14 +2711,52 @@ lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
1093
2711
  lxw_col_t col, lxw_datetime *datetime,
1094
2712
  lxw_format *format);
1095
2713
 
1096
- lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1097
- lxw_row_t row_num,
1098
- lxw_col_t col_num, const char *url,
1099
- lxw_format *format, const char *string,
1100
- const char *tooltip);
2714
+ /**
2715
+ * @brief Write a Unix datetime to a worksheet cell.
2716
+ *
2717
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2718
+ * @param row The zero indexed row number.
2719
+ * @param col The zero indexed column number.
2720
+ * @param unixtime The Unix datetime to write to the cell.
2721
+ * @param format A pointer to a Format instance or NULL.
2722
+ *
2723
+ * @return A #lxw_error code.
2724
+ *
2725
+ * The `%worksheet_write_unixtime()` function can be used to write dates and
2726
+ * times in Unix date format to the cell specified by `row` and
2727
+ * `column`. [Unix Time](https://en.wikipedia.org/wiki/Unix_time) which is a
2728
+ * common integer time format. It is defined as the number of seconds since
2729
+ * the Unix epoch (1970-01-01 00:00 UTC). Negative values can also be used for
2730
+ * dates prior to 1970:
2731
+ *
2732
+ * @dontinclude dates_and_times03.c
2733
+ * @skip 1970
2734
+ * @until 2208988800
2735
+ *
2736
+ * The `format` parameter should be used to apply formatting to the cell using
2737
+ * a @ref format.h "Format" object as shown above. Without a date format the
2738
+ * datetime will appear as a number only.
2739
+ *
2740
+ * The output from this code sample is:
2741
+ *
2742
+ * @image html date_example03.png
2743
+ *
2744
+ * Unixtime is generally represented with a 32 bit `time_t` type which has a
2745
+ * range of approximately 1900-12-14 to 2038-01-19. To access the full Excel
2746
+ * date range of 1900-01-01 to 9999-12-31 this function uses a 64 bit
2747
+ * parameter.
2748
+ *
2749
+ * See @ref working_with_dates for more information about handling dates and
2750
+ * times in libxlsxwriter.
2751
+ */
2752
+ lxw_error worksheet_write_unixtime(lxw_worksheet *worksheet,
2753
+ lxw_row_t row,
2754
+ lxw_col_t col, int64_t unixtime,
2755
+ lxw_format *format);
2756
+
1101
2757
  /**
1102
2758
  *
1103
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2759
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1104
2760
  * @param row The zero indexed row number.
1105
2761
  * @param col The zero indexed column number.
1106
2762
  * @param url The url to write to the cell.
@@ -1113,21 +2769,22 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1113
2769
  * worksheet cell specified by `row` and `column`.
1114
2770
  *
1115
2771
  * @code
1116
- * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", url_format);
2772
+ * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", NULL);
1117
2773
  * @endcode
1118
2774
  *
1119
2775
  * @image html hyperlinks_short.png
1120
2776
  *
1121
2777
  * The `format` parameter is used to apply formatting to the cell. This
1122
- * parameter can be `NULL` to indicate no formatting or it can be a @ref
1123
- * format.h "Format" object. The typical worksheet format for a hyperlink is a
1124
- * blue underline:
2778
+ * parameter can be `NULL`, in which case the default Excel blue underlined
2779
+ * hyperlink style will be used. If required a user defined @ref format.h
2780
+ * "Format" object can be used:
2781
+ * underline:
1125
2782
  *
1126
2783
  * @code
1127
2784
  * lxw_format *url_format = workbook_add_format(workbook);
1128
2785
  *
1129
2786
  * format_set_underline (url_format, LXW_UNDERLINE_SINGLE);
1130
- * format_set_font_color(url_format, LXW_COLOR_BLUE);
2787
+ * format_set_font_color(url_format, LXW_COLOR_RED);
1131
2788
  *
1132
2789
  * @endcode
1133
2790
  *
@@ -1135,10 +2792,10 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1135
2792
  * and `mailto:` :
1136
2793
  *
1137
2794
  * @code
1138
- * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", url_format);
1139
- * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", url_format);
1140
- * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", url_format);
1141
- * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", url_format);
2795
+ * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", NULL);
2796
+ * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", NULL);
2797
+ * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", NULL);
2798
+ * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", NULL);
1142
2799
  *
1143
2800
  * @endcode
1144
2801
  *
@@ -1147,13 +2804,18 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1147
2804
  * link. However, it is possible to overwrite it with any other
1148
2805
  * `libxlsxwriter` type using the appropriate `worksheet_write_*()`
1149
2806
  * function. The most common case is to overwrite the displayed link text with
1150
- * another string:
2807
+ * another string. To do this we must also match the default URL format using
2808
+ * `workbook_get_default_url_format()`:
1151
2809
  *
1152
2810
  * @code
1153
- * // Write a hyperlink but overwrite the displayed string.
1154
- * worksheet_write_url (worksheet, 2, 0, "http://libxlsxwriter.github.io", url_format);
1155
- * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
2811
+ * // Write a hyperlink with the default blue underline format.
2812
+ * worksheet_write_url(worksheet, 2, 0, "http://libxlsxwriter.github.io", NULL);
2813
+ *
2814
+ * // Get the default url format.
2815
+ * lxw_format *url_format = workbook_get_default_url_format(workbook);
1156
2816
  *
2817
+ * // Overwrite the hyperlink with a user defined string and default format.
2818
+ * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
1157
2819
  * @endcode
1158
2820
  *
1159
2821
  * @image html hyperlinks_short2.png
@@ -1163,15 +2825,15 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1163
2825
  * worksheet references:
1164
2826
  *
1165
2827
  * @code
1166
- * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", url_format);
1167
- * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", url_format);
1168
- * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", url_format);
1169
- * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", url_format);
1170
- * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", url_format);
1171
- * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
1172
- * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", url_format);
1173
- * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", url_format);
1174
- * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
2828
+ * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", NULL);
2829
+ * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", NULL);
2830
+ * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", NULL);
2831
+ * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", NULL);
2832
+ * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", NULL);
2833
+ * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
2834
+ * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", NULL);
2835
+ * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", NULL);
2836
+ * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
1175
2837
  *
1176
2838
  * @endcode
1177
2839
  *
@@ -1183,7 +2845,7 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1183
2845
  * `#` character:
1184
2846
  *
1185
2847
  * @code
1186
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
2848
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
1187
2849
  * @endcode
1188
2850
  *
1189
2851
  * You can also link to a named range in the target worksheet: For example say
@@ -1191,7 +2853,7 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1191
2853
  * you could link to it as follows:
1192
2854
  *
1193
2855
  * @code
1194
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", url_format);
2856
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", NULL);
1195
2857
  *
1196
2858
  * @endcode
1197
2859
  *
@@ -1199,14 +2861,14 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1199
2861
  * characters are single quoted as follows:
1200
2862
  *
1201
2863
  * @code
1202
- * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", url_format);
2864
+ * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", NULL);
1203
2865
  * @endcode
1204
2866
  *
1205
2867
  * Links to network files are also supported. Network files normally begin
1206
2868
  * with two back slashes as follows `\\NETWORK\etc`. In order to represent
1207
2869
  * this in a C string literal the backslashes should be escaped:
1208
2870
  * @code
1209
- * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
2871
+ * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
1210
2872
  * @endcode
1211
2873
  *
1212
2874
  *
@@ -1214,8 +2876,8 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1214
2876
  * translated internally to backslashes:
1215
2877
  *
1216
2878
  * @code
1217
- * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", url_format);
1218
- * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", url_format);
2879
+ * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", NULL);
2880
+ * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", NULL);
1219
2881
  *
1220
2882
  * @endcode
1221
2883
  *
@@ -1223,20 +2885,33 @@ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
1223
2885
  * **Note:**
1224
2886
  *
1225
2887
  * libxlsxwriter will escape the following characters in URLs as required
1226
- * by Excel: `\s " < > \ [ ] ^ { }` unless the URL already contains `%%xx`
1227
- * style escapes. In which case it is assumed that the URL was escaped
1228
- * correctly by the user and will by passed directly to Excel.
2888
+ * by Excel: `\s " < > \ [ ] ^ { }`. Existing URL `%%xx` style escapes in
2889
+ * the string are ignored to allow for user-escaped strings.
1229
2890
  *
2891
+ * **Note:**
2892
+ *
2893
+ * The maximum allowable URL length in recent versions of Excel is 2079
2894
+ * characters. In older versions of Excel (and libxlsxwriter <= 0.8.8) the
2895
+ * limit was 255 characters.
1230
2896
  */
1231
2897
  lxw_error worksheet_write_url(lxw_worksheet *worksheet,
1232
2898
  lxw_row_t row,
1233
2899
  lxw_col_t col, const char *url,
1234
2900
  lxw_format *format);
1235
2901
 
2902
+ /* Don't document for now since the string option can be achieved by a
2903
+ * subsequent cell worksheet_write() as shown in the docs, and the
2904
+ * tooltip option isn't very useful. */
2905
+ lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
2906
+ lxw_row_t row_num,
2907
+ lxw_col_t col_num, const char *url,
2908
+ lxw_format *format, const char *string,
2909
+ const char *tooltip);
2910
+
1236
2911
  /**
1237
2912
  * @brief Write a formatted boolean worksheet cell.
1238
2913
  *
1239
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2914
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1240
2915
  * @param row The zero indexed row number.
1241
2916
  * @param col The zero indexed column number.
1242
2917
  * @param value The boolean value to write to the cell.
@@ -1258,7 +2933,7 @@ lxw_error worksheet_write_boolean(lxw_worksheet *worksheet,
1258
2933
  /**
1259
2934
  * @brief Write a formatted blank worksheet cell.
1260
2935
  *
1261
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2936
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1262
2937
  * @param row The zero indexed row number.
1263
2938
  * @param col The zero indexed column number.
1264
2939
  * @param format A pointer to a Format instance or NULL.
@@ -1287,20 +2962,21 @@ lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
1287
2962
  lxw_format *format);
1288
2963
 
1289
2964
  /**
1290
- * @brief Write a formula to a worksheet cell with a user defined result.
2965
+ * @brief Write a formula to a worksheet cell with a user defined numeric
2966
+ * result.
1291
2967
  *
1292
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
2968
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1293
2969
  * @param row The zero indexed row number.
1294
2970
  * @param col The zero indexed column number.
1295
2971
  * @param formula Formula string to write to cell.
1296
2972
  * @param format A pointer to a Format instance or NULL.
1297
- * @param result A user defined result for a formula.
2973
+ * @param result A user defined numeric result for the formula.
1298
2974
  *
1299
2975
  * @return A #lxw_error code.
1300
2976
  *
1301
2977
  * The `%worksheet_write_formula_num()` function writes a formula or Excel
1302
2978
  * function to the cell specified by `row` and `column` with a user defined
1303
- * result:
2979
+ * numeric result:
1304
2980
  *
1305
2981
  * @code
1306
2982
  * // Required as a workaround only.
@@ -1335,10 +3011,55 @@ lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
1335
3011
  const char *formula,
1336
3012
  lxw_format *format, double result);
1337
3013
 
3014
+ /**
3015
+ * @brief Write a formula to a worksheet cell with a user defined string
3016
+ * result.
3017
+ *
3018
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3019
+ * @param row The zero indexed row number.
3020
+ * @param col The zero indexed column number.
3021
+ * @param formula Formula string to write to cell.
3022
+ * @param format A pointer to a Format instance or NULL.
3023
+ * @param result A user defined string result for the formula.
3024
+ *
3025
+ * @return A #lxw_error code.
3026
+ *
3027
+ * The `%worksheet_write_formula_str()` function writes a formula or Excel
3028
+ * function to the cell specified by `row` and `column` with a user defined
3029
+ * string result:
3030
+ *
3031
+ * @code
3032
+ * // The example formula is A & B -> AB.
3033
+ * worksheet_write_formula_str(worksheet, 0, 0, "=\"A\" & \"B\"", NULL, "AB");
3034
+ * @endcode
3035
+ *
3036
+ * The `%worksheet_write_formula_str()` function is similar to the
3037
+ * `%worksheet_write_formula_num()` function except it writes a string result
3038
+ * instead or a numeric result. See `worksheet_write_formula_num()` for more
3039
+ * details on why/when these functions are required.
3040
+ *
3041
+ * One place where the `%worksheet_write_formula_str()` function may be required
3042
+ * is to specify an empty result which will force a recalculation of the formula
3043
+ * when loaded in LibreOffice.
3044
+ *
3045
+ * @code
3046
+ * worksheet_write_formula_str(worksheet, 0, 0, "=Sheet1!$A$1", NULL, "");
3047
+ * @endcode
3048
+ *
3049
+ * See the FAQ @ref faq_formula_zero.
3050
+ *
3051
+ * See also @ref working_with_formulas.
3052
+ */
3053
+ lxw_error worksheet_write_formula_str(lxw_worksheet *worksheet,
3054
+ lxw_row_t row,
3055
+ lxw_col_t col,
3056
+ const char *formula,
3057
+ lxw_format *format, const char *result);
3058
+
1338
3059
  /**
1339
3060
  * @brief Write a "Rich" multi-format string to a worksheet cell.
1340
3061
  *
1341
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
3062
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1342
3063
  * @param row The zero indexed row number.
1343
3064
  * @param col The zero indexed column number.
1344
3065
  * @param rich_string An array of format/string lxw_rich_string_tuple fragments.
@@ -1410,14 +3131,98 @@ lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
1410
3131
  lxw_rich_string_tuple *rich_string[],
1411
3132
  lxw_format *format);
1412
3133
 
3134
+ /**
3135
+ * @brief Write a comment to a worksheet cell.
3136
+ *
3137
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3138
+ * @param row The zero indexed row number.
3139
+ * @param col The zero indexed column number.
3140
+ * @param string The comment string to be written.
3141
+ *
3142
+ * @return A #lxw_error code.
3143
+ *
3144
+ * The `%worksheet_write_comment()` function is used to add a comment to a
3145
+ * cell. A comment is indicated in Excel by a small red triangle in the upper
3146
+ * right-hand corner of the cell. Moving the cursor over the red triangle will
3147
+ * reveal the comment.
3148
+ *
3149
+ * The following example shows how to add a comment to a cell:
3150
+ *
3151
+ * @code
3152
+ * worksheet_write_comment(worksheet, 0, 0, "This is a comment");
3153
+ * @endcode
3154
+ *
3155
+ * @image html comments1.png
3156
+ *
3157
+ * See also @ref working_with_comments
3158
+ *
3159
+ */
3160
+ lxw_error worksheet_write_comment(lxw_worksheet *worksheet,
3161
+ lxw_row_t row, lxw_col_t col,
3162
+ const char *string);
3163
+
3164
+ /**
3165
+ * @brief Write a comment to a worksheet cell with options.
3166
+ *
3167
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3168
+ * @param row The zero indexed row number.
3169
+ * @param col The zero indexed column number.
3170
+ * @param string The comment string to be written.
3171
+ * @param options #lxw_comment_options to control position and format
3172
+ * of the comment.
3173
+ *
3174
+ * @return A #lxw_error code.
3175
+ *
3176
+ * The `%worksheet_write_comment_opt()` function is used to add a comment to a
3177
+ * cell with option that control the position, format and metadata of the
3178
+ * comment. A comment is indicated in Excel by a small red triangle in the
3179
+ * upper right-hand corner of the cell. Moving the cursor over the red
3180
+ * triangle will reveal the comment.
3181
+ *
3182
+ * The following example shows how to add a comment to a cell with options:
3183
+ *
3184
+ * @code
3185
+ * lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_VISIBLE};
3186
+ *
3187
+ * worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello.", &options);
3188
+ * @endcode
3189
+ *
3190
+ * The following options are available in #lxw_comment_options:
3191
+ *
3192
+ * - `author`
3193
+ * - `visible`
3194
+ * - `width`
3195
+ * - `height`
3196
+ * - `x_scale`
3197
+ * - `y_scale`
3198
+ * - `color`
3199
+ * - `font_name`
3200
+ * - `font_size`
3201
+ * - `start_row`
3202
+ * - `start_col`
3203
+ * - `x_offset`
3204
+ * - `y_offset`
3205
+ *
3206
+ * @image html comments2.png
3207
+ *
3208
+ * Comment options are explained in detail in the @ref ww_comments_properties
3209
+ * section of the docs.
3210
+ */
3211
+ lxw_error worksheet_write_comment_opt(lxw_worksheet *worksheet,
3212
+ lxw_row_t row, lxw_col_t col,
3213
+ const char *string,
3214
+ lxw_comment_options *options);
3215
+
1413
3216
  /**
1414
3217
  * @brief Set the properties for a row of cells.
1415
3218
  *
1416
3219
  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
1417
3220
  * @param row The zero indexed row number.
1418
- * @param height The row height.
3221
+ * @param height The row height, in character units.
1419
3222
  * @param format A pointer to a Format instance or NULL.
1420
3223
  *
3224
+ * @return A #lxw_error code.
3225
+ *
1421
3226
  * The `%worksheet_set_row()` function is used to change the default
1422
3227
  * properties of a row. The most common use for this function is to change the
1423
3228
  * height of a row:
@@ -1427,6 +3232,9 @@ lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
1427
3232
  * worksheet_set_row(worksheet, 0, 20, NULL);
1428
3233
  * @endcode
1429
3234
  *
3235
+ * The height is specified in character units. To specify the height in pixels
3236
+ * use the `worksheet_set_row_pixels()` function.
3237
+ *
1430
3238
  * The other common use for `%worksheet_set_row()` is to set the a @ref
1431
3239
  * format.h "Format" for all cells in the row:
1432
3240
  *
@@ -1474,6 +3282,8 @@ lxw_error worksheet_set_row(lxw_worksheet *worksheet,
1474
3282
  * @param format A pointer to a Format instance or NULL.
1475
3283
  * @param options Optional row parameters: hidden, level, collapsed.
1476
3284
  *
3285
+ * @return A #lxw_error code.
3286
+ *
1477
3287
  * The `%worksheet_set_row_opt()` function is the same as
1478
3288
  * `worksheet_set_row()` with an additional `options` parameter.
1479
3289
  *
@@ -1530,6 +3340,52 @@ lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
1530
3340
  lxw_format *format,
1531
3341
  lxw_row_col_options *options);
1532
3342
 
3343
+ /**
3344
+ * @brief Set the properties for a row of cells, with the height in pixels.
3345
+ *
3346
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3347
+ * @param row The zero indexed row number.
3348
+ * @param pixels The row height in pixels.
3349
+ * @param format A pointer to a Format instance or NULL.
3350
+ *
3351
+ * @return A #lxw_error code.
3352
+ *
3353
+ * The `%worksheet_set_row_pixels()` function is the same as the
3354
+ * `worksheet_set_row()` function except that the height can be set in pixels
3355
+ *
3356
+ * @code
3357
+ * // Set the height of Row 1 to 20 pixels.
3358
+ * worksheet_set_row_pixels(worksheet, 0, 20, NULL);
3359
+ * @endcode
3360
+ *
3361
+ * If you wish to set the format of a row without changing the height you can
3362
+ * pass the default row height in pixels: #LXW_DEF_ROW_HEIGHT_PIXELS.
3363
+ */
3364
+ lxw_error worksheet_set_row_pixels(lxw_worksheet *worksheet,
3365
+ lxw_row_t row, uint32_t pixels,
3366
+ lxw_format *format);
3367
+ /**
3368
+ * @brief Set the properties for a row of cells, with the height in pixels.
3369
+ *
3370
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3371
+ * @param row The zero indexed row number.
3372
+ * @param pixels The row height in pixels.
3373
+ * @param format A pointer to a Format instance or NULL.
3374
+ * @param options Optional row parameters: hidden, level, collapsed.
3375
+ *
3376
+ * @return A #lxw_error code.
3377
+ *
3378
+ * The `%worksheet_set_row_pixels_opt()` function is the same as the
3379
+ * `worksheet_set_row_opt()` function except that the height can be set in
3380
+ * pixels.
3381
+ *
3382
+ */
3383
+ lxw_error worksheet_set_row_pixels_opt(lxw_worksheet *worksheet,
3384
+ lxw_row_t row,
3385
+ uint32_t pixels,
3386
+ lxw_format *format,
3387
+ lxw_row_col_options *options);
3388
+
1533
3389
  /**
1534
3390
  * @brief Set the properties for one or more columns of cells.
1535
3391
  *
@@ -1539,6 +3395,8 @@ lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
1539
3395
  * @param width The width of the column(s).
1540
3396
  * @param format A pointer to a Format instance or NULL.
1541
3397
  *
3398
+ * @return A #lxw_error code.
3399
+ *
1542
3400
  * The `%worksheet_set_column()` function can be used to change the default
1543
3401
  * properties of a single column or a range of columns:
1544
3402
  *
@@ -1575,7 +3433,8 @@ lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
1575
3433
  * is 8.43 in the default font of Calibri 11. The actual relationship between
1576
3434
  * a string width and a column width in Excel is complex. See the
1577
3435
  * [following explanation of column widths](https://support.microsoft.com/en-us/kb/214123)
1578
- * from the Microsoft support documentation for more details.
3436
+ * from the Microsoft support documentation for more details. To set the width
3437
+ * in pixels use the `worksheet_set_column_pixels()` function.
1579
3438
  *
1580
3439
  * There is no way to specify "AutoFit" for a column in the Excel file
1581
3440
  * format. This feature is only available at runtime from within Excel. It is
@@ -1640,6 +3499,8 @@ lxw_error worksheet_set_column(lxw_worksheet *worksheet,
1640
3499
  * @param format A pointer to a Format instance or NULL.
1641
3500
  * @param options Optional row parameters: hidden, level, collapsed.
1642
3501
  *
3502
+ * @return A #lxw_error code.
3503
+ *
1643
3504
  * The `%worksheet_set_column_opt()` function is the same as
1644
3505
  * `worksheet_set_column()` with an additional `options` parameter.
1645
3506
  *
@@ -1679,6 +3540,62 @@ lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
1679
3540
  lxw_format *format,
1680
3541
  lxw_row_col_options *options);
1681
3542
 
3543
+ /**
3544
+ * @brief Set the properties for one or more columns of cells, with the width
3545
+ * in pixels.
3546
+ *
3547
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3548
+ * @param first_col The zero indexed first column.
3549
+ * @param last_col The zero indexed last column.
3550
+ * @param pixels The width of the column(s) in pixels.
3551
+ * @param format A pointer to a Format instance or NULL.
3552
+ *
3553
+ * @return A #lxw_error code.
3554
+ *
3555
+ * The `%worksheet_set_column_pixels()` function is the same as
3556
+ * `worksheet_set_column()` function except that the width can be set in
3557
+ * pixels:
3558
+ *
3559
+ * @code
3560
+ * // Column width set to 75 pixels, the same as 10 character units.
3561
+ * worksheet_set_column(worksheet, 5, 5, 75, NULL);
3562
+ * @endcode
3563
+ *
3564
+ * @image html set_column_pixels.png
3565
+ *
3566
+ * If you wish to set the format of a column without changing the width you can
3567
+ * pass the default column width in pixels: #LXW_DEF_COL_WIDTH_PIXELS.
3568
+ */
3569
+ lxw_error worksheet_set_column_pixels(lxw_worksheet *worksheet,
3570
+ lxw_col_t first_col,
3571
+ lxw_col_t last_col,
3572
+ uint32_t pixels, lxw_format *format);
3573
+
3574
+ /**
3575
+ * @brief Set the properties for one or more columns of cells with options,
3576
+ * with the width in pixels.
3577
+ *
3578
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3579
+ * @param first_col The zero indexed first column.
3580
+ * @param last_col The zero indexed last column.
3581
+ * @param pixels The width of the column(s) in pixels.
3582
+ * @param format A pointer to a Format instance or NULL.
3583
+ * @param options Optional row parameters: hidden, level, collapsed.
3584
+ *
3585
+ * @return A #lxw_error code.
3586
+ *
3587
+ * The `%worksheet_set_column_pixels_opt()` function is the same as the
3588
+ * `worksheet_set_column_opt()` function except that the width can be set in
3589
+ * pixels.
3590
+ *
3591
+ */
3592
+ lxw_error worksheet_set_column_pixels_opt(lxw_worksheet *worksheet,
3593
+ lxw_col_t first_col,
3594
+ lxw_col_t last_col,
3595
+ uint32_t pixels,
3596
+ lxw_format *format,
3597
+ lxw_row_col_options *options);
3598
+
1682
3599
  /**
1683
3600
  * @brief Insert an image in a worksheet cell.
1684
3601
  *
@@ -1690,7 +3607,7 @@ lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
1690
3607
  * @return A #lxw_error code.
1691
3608
  *
1692
3609
  * This function can be used to insert a image into a worksheet. The image can
1693
- * be in PNG, JPEG or BMP format:
3610
+ * be in PNG, JPEG, GIF or BMP format:
1694
3611
  *
1695
3612
  * @code
1696
3613
  * worksheet_insert_image(worksheet, 2, 1, "logo.png");
@@ -1706,7 +3623,7 @@ lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
1706
3623
  * default height changed due to a font that is larger than the default font
1707
3624
  * size or that has text wrapping turned on. To avoid this you should
1708
3625
  * explicitly set the height of the row using `worksheet_set_row()` if it
1709
- * crosses an inserted image.
3626
+ * crosses an inserted image. See @ref working_with_object_positioning.
1710
3627
  *
1711
3628
  * BMP images are only supported for backward compatibility. In general it is
1712
3629
  * best to avoid BMP images since they aren't compressed. If used, BMP images
@@ -1729,18 +3646,52 @@ lxw_error worksheet_insert_image(lxw_worksheet *worksheet,
1729
3646
  *
1730
3647
  * The `%worksheet_insert_image_opt()` function is like
1731
3648
  * `worksheet_insert_image()` function except that it takes an optional
1732
- * #lxw_image_options struct to scale and position the image:
3649
+ * #lxw_image_options struct with the following members/options:
3650
+ *
3651
+ * - `x_offset`: Offset from the left of the cell in pixels.
3652
+ * - `y_offset`: Offset from the top of the cell in pixels.
3653
+ * - `x_scale`: X scale of the image as a decimal.
3654
+ * - `y_scale`: Y scale of the image as a decimal.
3655
+ * - `object_position`: See @ref working_with_object_positioning.
3656
+ * - `description`: Optional description or "Alt text" for the image.
3657
+ * - `decorative`: Optional parameter to mark image as decorative.
3658
+ * - `url`: Add an optional hyperlink to the image.
3659
+ * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
3660
+ *
3661
+ * For example, to scale and position the image:
1733
3662
  *
1734
3663
  * @code
1735
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
3664
+ * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
1736
3665
  * .x_scale = 0.5, .y_scale = 0.5};
1737
3666
  *
1738
- * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
3667
+ * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
1739
3668
  *
1740
3669
  * @endcode
1741
3670
  *
1742
3671
  * @image html insert_image_opt.png
1743
3672
  *
3673
+ * The `url` field of lxw_image_options can be use to used to add a hyperlink
3674
+ * to an image:
3675
+ *
3676
+ * @code
3677
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara"};
3678
+ *
3679
+ * worksheet_insert_image_opt(worksheet, 3, 1, "logo.png", &options);
3680
+ * @endcode
3681
+ *
3682
+ * The supported URL formats are the same as those supported by the
3683
+ * `worksheet_write_url()` method and the same rules/limits apply.
3684
+ *
3685
+ * The `tip` field of lxw_image_options can be use to used to add a mouseover
3686
+ * tip to the hyperlink:
3687
+ *
3688
+ * @code
3689
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara",
3690
+ .tip = "GitHub"};
3691
+ *
3692
+ * worksheet_insert_image_opt(worksheet, 4, 1, "logo.png", &options);
3693
+ * @endcode
3694
+ *
1744
3695
  * @note See the notes about row scaling and BMP images in
1745
3696
  * `worksheet_insert_image()` above.
1746
3697
  */
@@ -1782,42 +3733,118 @@ lxw_error worksheet_insert_image_buffer(lxw_worksheet *worksheet,
1782
3733
  size_t image_size);
1783
3734
 
1784
3735
  /**
1785
- * @brief Insert an image in a worksheet cell, from a memory buffer.
3736
+ * @brief Insert an image in a worksheet cell, from a memory buffer.
3737
+ *
3738
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3739
+ * @param row The zero indexed row number.
3740
+ * @param col The zero indexed column number.
3741
+ * @param image_buffer Pointer to an array of bytes that holds the image data.
3742
+ * @param image_size The size of the array of bytes.
3743
+ * @param options Optional image parameters.
3744
+ *
3745
+ * @return A #lxw_error code.
3746
+ *
3747
+ * The `%worksheet_insert_image_buffer_opt()` function is like
3748
+ * `worksheet_insert_image_buffer()` function except that it takes an optional
3749
+ * #lxw_image_options struct * #lxw_image_options struct with the following members/options:
3750
+ *
3751
+ * - `x_offset`: Offset from the left of the cell in pixels.
3752
+ * - `y_offset`: Offset from the top of the cell in pixels.
3753
+ * - `x_scale`: X scale of the image as a decimal.
3754
+ * - `y_scale`: Y scale of the image as a decimal.
3755
+ * - `object_position`: See @ref working_with_object_positioning.
3756
+ * - `description`: Optional description or "Alt text" for the image.
3757
+ * - `decorative`: Optional parameter to mark image as decorative.
3758
+ * - `url`: Add an optional hyperlink to the image.
3759
+ * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
3760
+ *
3761
+ * For example, to scale and position the image:
3762
+ *
3763
+ * @code
3764
+ * lxw_image_options options = {.x_offset = 32, .y_offset = 4,
3765
+ * .x_scale = 2, .y_scale = 1};
3766
+ *
3767
+ * worksheet_insert_image_buffer_opt(worksheet, CELL("B3"), image_buffer, image_size, &options);
3768
+ * @endcode
3769
+ *
3770
+ * @image html image_buffer_opt.png
3771
+ *
3772
+ * The buffer should be a pointer to an array of unsigned char data with a
3773
+ * specified size.
3774
+ *
3775
+ * See `worksheet_insert_image_buffer_opt()` for details about the supported
3776
+ * image formats, and other image options.
3777
+ */
3778
+ lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
3779
+ lxw_row_t row,
3780
+ lxw_col_t col,
3781
+ const unsigned char *image_buffer,
3782
+ size_t image_size,
3783
+ lxw_image_options *options);
3784
+
3785
+ /**
3786
+ * @brief Set the background image for a worksheet.
3787
+ *
3788
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3789
+ * @param filename The image filename, with path if required.
3790
+ *
3791
+ * @return A #lxw_error code.
3792
+ *
3793
+ * The `%worksheet_set_background()` function can be used to set the
3794
+ * background image for a worksheet:
3795
+ *
3796
+ * @code
3797
+ * worksheet_set_background(worksheet, "logo.png");
3798
+ * @endcode
3799
+ *
3800
+ * @image html background.png
3801
+ *
3802
+ * The ``set_background()`` method supports all the image formats supported by
3803
+ * `worksheet_insert_image()`.
3804
+ *
3805
+ * Some people use this method to add a watermark background to their
3806
+ * document. However, Microsoft recommends using a header image [to set a
3807
+ * watermark][watermark]. The choice of method depends on whether you want the
3808
+ * watermark to be visible in normal viewing mode or just when the file is
3809
+ * printed. In libxlsxwriter you can get the header watermark effect using
3810
+ * `worksheet_set_header()`:
3811
+ *
3812
+ * @code
3813
+ * lxw_header_footer_options header_options = {.image_center = "watermark.png"};
3814
+ * worksheet_set_header_opt(worksheet, "&C&G", &header_options);
3815
+ * @endcode
3816
+ *
3817
+ * [watermark]:https://support.microsoft.com/en-us/office/add-a-watermark-in-excel-a372182a-d733-484e-825c-18ddf3edf009
3818
+ *
3819
+ */
3820
+ lxw_error worksheet_set_background(lxw_worksheet *worksheet,
3821
+ const char *filename);
3822
+
3823
+ /**
3824
+ * @brief Set the background image for a worksheet, from a buffer.
1786
3825
  *
1787
3826
  * @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
3827
  * @param image_buffer Pointer to an array of bytes that holds the image data.
1791
3828
  * @param image_size The size of the array of bytes.
1792
- * @param options Optional image parameters.
1793
3829
  *
1794
3830
  * @return A #lxw_error code.
1795
3831
  *
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:
3832
+ * This function can be used to insert a background image into a worksheet
3833
+ * from a memory buffer:
1799
3834
  *
1800
3835
  * @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);
3836
+ * worksheet_set_background_buffer(worksheet, image_buffer, image_size);
1805
3837
  * @endcode
1806
3838
  *
1807
- * @image html image_buffer_opt.png
1808
- *
1809
3839
  * The buffer should be a pointer to an array of unsigned char data with a
1810
3840
  * specified size.
1811
3841
  *
1812
- * See `worksheet_insert_image_buffer_opt()` for details about the supported
1813
- * image formats, and other image options.
3842
+ * See `worksheet_set_background()` for more details.
3843
+ *
1814
3844
  */
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);
3845
+ lxw_error worksheet_set_background_buffer(lxw_worksheet *worksheet,
3846
+ const unsigned char *image_buffer,
3847
+ size_t image_size);
1821
3848
 
1822
3849
  /**
1823
3850
  * @brief Insert a chart object into a worksheet.
@@ -1871,10 +3898,10 @@ lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
1871
3898
  *
1872
3899
  * The `%worksheet_insert_chart_opt()` function is like
1873
3900
  * `worksheet_insert_chart()` function except that it takes an optional
1874
- * #lxw_image_options struct to scale and position the image of the chart:
3901
+ * #lxw_chart_options struct to scale and position the chart:
1875
3902
  *
1876
3903
  * @code
1877
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
3904
+ * lxw_chart_options options = {.x_offset = 30, .y_offset = 10,
1878
3905
  * .x_scale = 0.5, .y_scale = 0.75};
1879
3906
  *
1880
3907
  * worksheet_insert_chart_opt(worksheet, 0, 2, chart, &options);
@@ -1883,14 +3910,11 @@ lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
1883
3910
  *
1884
3911
  * @image html chart_line_opt.png
1885
3912
  *
1886
- * The #lxw_image_options struct is the same struct used in
1887
- * `worksheet_insert_image_opt()` to position and scale images.
1888
- *
1889
3913
  */
1890
3914
  lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
1891
3915
  lxw_row_t row, lxw_col_t col,
1892
3916
  lxw_chart *chart,
1893
- lxw_image_options *user_options);
3917
+ lxw_chart_options *user_options);
1894
3918
 
1895
3919
  /**
1896
3920
  * @brief Merge a range of cells.
@@ -1949,7 +3973,7 @@ lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
1949
3973
  * worksheet_write_number(worksheet, 1, 1, 123, format);
1950
3974
  * @endcode
1951
3975
  *
1952
- * @note Merged ranges generally dont work in libxlsxwriter when the Workbook
3976
+ * @note Merged ranges generally don't work in libxlsxwriter when the Workbook
1953
3977
  * #lxw_workbook_options `constant_memory` mode is enabled.
1954
3978
  */
1955
3979
  lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
@@ -1975,7 +3999,7 @@ lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
1975
3999
  * range of worksheet data. This allows users to filter the data based on
1976
4000
  * simple criteria so that some data is shown and some is hidden.
1977
4001
  *
1978
- * @image html autofilter.png
4002
+ * @image html autofilter3.png
1979
4003
  *
1980
4004
  * To add an autofilter to a worksheet:
1981
4005
  *
@@ -1986,13 +4010,147 @@ lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
1986
4010
  * worksheet_autofilter(worksheet, RANGE("A1:D51"));
1987
4011
  * @endcode
1988
4012
  *
1989
- * Note: it isn't currently possible to apply filter conditions to the
1990
- * autofilter.
4013
+ * In order to apply a filter condition it is necessary to add filter rules to
4014
+ * the columns using either the `%worksheet_filter_column()`,
4015
+ * `%worksheet_filter_column2()` or `%worksheet_filter_list()` functions:
4016
+ *
4017
+ * - `worksheet_filter_column()`: filter on a single criterion such as "Column ==
4018
+ * East". More complex conditions such as "<=" or ">=" can also be use.
4019
+ *
4020
+ * - `worksheet_filter_column2()`: filter on two criteria such as "Column == East
4021
+ * or Column == West". Complex conditions can also be used.
4022
+ *
4023
+ * - `worksheet_filter_list()`: filter on a list of values such as "Column in (East, West,
4024
+ * North)".
4025
+ *
4026
+ * These functions are explained below. It isn't sufficient to just specify
4027
+ * the filter condition. You must also hide any rows that don't match the
4028
+ * filter condition. See @ref ww_autofilters_data for more details.
4029
+ *
1991
4030
  */
1992
4031
  lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
1993
4032
  lxw_col_t first_col, lxw_row_t last_row,
1994
4033
  lxw_col_t last_col);
1995
4034
 
4035
+ /**
4036
+ * @brief Write a filter rule to an autofilter column.
4037
+ *
4038
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4039
+ * @param col The column in the autofilter that the rule applies to.
4040
+ * @param rule The lxw_filter_rule autofilter rule.
4041
+ *
4042
+ * @return A #lxw_error code.
4043
+ *
4044
+ * The `worksheet_filter_column` function can be used to filter columns in a
4045
+ * autofilter range based on single rule conditions:
4046
+ *
4047
+ * @code
4048
+ * lxw_filter_rule filter_rule = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
4049
+ * .value_string = "East"};
4050
+ *
4051
+ * worksheet_filter_column(worksheet, 0, &filter_rule);
4052
+ *@endcode
4053
+ *
4054
+ * @image html autofilter4.png
4055
+ *
4056
+ * The rules and criteria are explained in more detail in @ref
4057
+ * ww_autofilters_criteria in @ref working_with_autofilters.
4058
+ *
4059
+ * The `col` parameter is a zero indexed column number and must refer to a
4060
+ * column in an existing autofilter created with `worksheet_autofilter()`.
4061
+ *
4062
+ * It isn't sufficient to just specify the filter condition. You must also
4063
+ * hide any rows that don't match the filter condition. See @ref
4064
+ * ww_autofilters_data for more details.
4065
+ */
4066
+ lxw_error worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col,
4067
+ lxw_filter_rule *rule);
4068
+
4069
+ /**
4070
+ * @brief Write two filter rules to an autofilter column.
4071
+ *
4072
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4073
+ * @param col The column in the autofilter that the rules applies to.
4074
+ * @param rule1 First lxw_filter_rule autofilter rule.
4075
+ * @param rule2 Second lxw_filter_rule autofilter rule.
4076
+ * @param and_or A #lxw_filter_operator and/or operator.
4077
+ *
4078
+ * @return A #lxw_error code.
4079
+ *
4080
+ * The `worksheet_filter_column2` function can be used to filter columns in a autofilter
4081
+ * range based on two rule conditions:
4082
+ *
4083
+ * @code
4084
+ * lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
4085
+ * .value_string = "East"};
4086
+ *
4087
+ * lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
4088
+ * .value_string = "South"};
4089
+ *
4090
+ * worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR);
4091
+ * @endcode
4092
+ *
4093
+ * @image html autofilter5.png
4094
+ *
4095
+ * The rules and criteria are explained in more detail in @ref
4096
+ * ww_autofilters_criteria in @ref working_with_autofilters.
4097
+ *
4098
+ * The `col` parameter is a zero indexed column number and must refer to a
4099
+ * column in an existing autofilter created with `worksheet_autofilter()`.
4100
+ *
4101
+ * The `and_or` parameter is either "and (LXW_FILTER_AND)" or "or (LXW_FILTER_OR)".
4102
+ *
4103
+ * It isn't sufficient to just specify the filter condition. You must also
4104
+ * hide any rows that don't match the filter condition. See @ref
4105
+ * ww_autofilters_data for more details.
4106
+ */
4107
+ lxw_error worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col,
4108
+ lxw_filter_rule *rule1,
4109
+ lxw_filter_rule *rule2, uint8_t and_or);
4110
+ /**
4111
+ * @brief Write multiple string filters to an autofilter column.
4112
+ *
4113
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4114
+ * @param col The column in the autofilter that the rules applies to.
4115
+ * @param list A NULL terminated array of strings to filter on.
4116
+ *
4117
+ * @return A #lxw_error code.
4118
+ *
4119
+ * The `worksheet_filter_column_list()` function can be used specify multiple
4120
+ * string matching criteria. This is a newer type of filter introduced in
4121
+ * Excel 2007. Prior to that it was only possible to have either 1 or 2 filter
4122
+ * conditions, such as the ones used by `worksheet_filter_column()` and
4123
+ * `worksheet_filter_column2()`.
4124
+ *
4125
+ * As an example, consider a column that contains data for the months of the
4126
+ * year. The `%worksheet_filter_list()` function can be used to filter out
4127
+ * data rows for different months:
4128
+ *
4129
+ * @code
4130
+ * char* list[] = {"March", "April", "May", NULL};
4131
+ *
4132
+ * worksheet_filter_list(worksheet, 0, list);
4133
+ * @endcode
4134
+ *
4135
+ * @image html autofilter2.png
4136
+ *
4137
+ *
4138
+ * Note, the array must be NULL terminated to indicate the end of the array of
4139
+ * strings. To filter blanks as part of the list use `Blanks` as a list item:
4140
+ *
4141
+ * @code
4142
+ * char* list[] = {"March", "April", "May", "Blanks", NULL};
4143
+ *
4144
+ * worksheet_filter_list(worksheet, 0, list);
4145
+ * @endcode
4146
+ *
4147
+ * It isn't sufficient to just specify the filter condition. You must also
4148
+ * hide any rows that don't match the filter condition. See @ref
4149
+ * ww_autofilters_data for more details.
4150
+ */
4151
+ lxw_error worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col,
4152
+ const char **list);
4153
+
1996
4154
  /**
1997
4155
  * @brief Add a data validation to a cell.
1998
4156
  *
@@ -2033,7 +4191,7 @@ lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
2033
4191
  lxw_data_validation *validation);
2034
4192
 
2035
4193
  /**
2036
- * @brief Add a data validation to a range cell.
4194
+ * @brief Add a data validation to a range.
2037
4195
  *
2038
4196
  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2039
4197
  * @param first_row The first row of the range. (All zero indexed.)
@@ -2074,6 +4232,149 @@ lxw_error worksheet_data_validation_range(lxw_worksheet *worksheet,
2074
4232
  lxw_col_t last_col,
2075
4233
  lxw_data_validation *validation);
2076
4234
 
4235
+ /**
4236
+ * @brief Add a conditional format to a worksheet cell.
4237
+ *
4238
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4239
+ * @param row The zero indexed row number.
4240
+ * @param col The zero indexed column number.
4241
+ * @param conditional_format A #lxw_conditional_format object to control the
4242
+ * conditional format.
4243
+ *
4244
+ * @return A #lxw_error code.
4245
+ *
4246
+ * The `%worksheet_conditional_format_cell()` function is used to set a
4247
+ * conditional format for a cell in a worksheet:
4248
+ *
4249
+ * @code
4250
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
4251
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
4252
+ * conditional_format->value = 50;
4253
+ * conditional_format->format = format1;
4254
+ * worksheet_conditional_format_cell(worksheet, CELL("A1"), conditional_format);
4255
+ * @endcode
4256
+ *
4257
+ * The conditional format parameters is specified in #lxw_conditional_format.
4258
+ *
4259
+ * See @ref working_with_conditional_formatting for full details.
4260
+ */
4261
+ lxw_error worksheet_conditional_format_cell(lxw_worksheet *worksheet,
4262
+ lxw_row_t row,
4263
+ lxw_col_t col,
4264
+ lxw_conditional_format
4265
+ *conditional_format);
4266
+
4267
+ /**
4268
+ * @brief Add a conditional format to a worksheet range.
4269
+ *
4270
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4271
+ * @param first_row The first row of the range. (All zero indexed.)
4272
+ * @param first_col The first column of the range.
4273
+ * @param last_row The last row of the range.
4274
+ * @param last_col The last col of the range.
4275
+ * @param conditional_format A #lxw_conditional_format object to control the
4276
+ * conditional format.
4277
+ *
4278
+ * @return A #lxw_error code.
4279
+ *
4280
+ * The `%worksheet_conditional_format_cell()` function is used to set a
4281
+ * conditional format for a range of cells in a worksheet:
4282
+ *
4283
+ * @code
4284
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
4285
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
4286
+ * conditional_format->value = 50;
4287
+ * conditional_format->format = format1;
4288
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
4289
+ *
4290
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
4291
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_LESS_THAN;
4292
+ * conditional_format->value = 50;
4293
+ * conditional_format->format = format2;
4294
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
4295
+ * @endcode
4296
+ *
4297
+ * Output:
4298
+ *
4299
+ * @image html conditional_format1.png
4300
+ *
4301
+ *
4302
+ * The conditional format parameters is specified in #lxw_conditional_format.
4303
+ *
4304
+ * See @ref working_with_conditional_formatting for full details.
4305
+ */
4306
+ lxw_error worksheet_conditional_format_range(lxw_worksheet *worksheet,
4307
+ lxw_row_t first_row,
4308
+ lxw_col_t first_col,
4309
+ lxw_row_t last_row,
4310
+ lxw_col_t last_col,
4311
+ lxw_conditional_format
4312
+ *conditional_format);
4313
+ /**
4314
+ * @brief Insert a button object into a worksheet.
4315
+ *
4316
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4317
+ * @param row The zero indexed row number.
4318
+ * @param col The zero indexed column number.
4319
+ * @param options A #lxw_button_options object to set the button properties.
4320
+ *
4321
+ * @return A #lxw_error code.
4322
+ *
4323
+ * The `%worksheet_insert_button()` function can be used to insert an Excel
4324
+ * form button into a worksheet. This function is generally only useful when
4325
+ * used in conjunction with the `workbook_add_vba_project()` function to tie
4326
+ * the button to a macro from an embedded VBA project:
4327
+ *
4328
+ * @code
4329
+ * lxw_button_options options = {.caption = "Press Me",
4330
+ * .macro = "say_hello"};
4331
+ *
4332
+ * worksheet_insert_button(worksheet, 2, 1, &options);
4333
+ * @endcode
4334
+ *
4335
+ * @image html macros.png
4336
+ *
4337
+ * The button properties are set using the lxw_button_options struct.
4338
+ *
4339
+ * See also @ref working_with_macros
4340
+ */
4341
+ lxw_error worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row,
4342
+ lxw_col_t col, lxw_button_options *options);
4343
+
4344
+ /**
4345
+ * @brief Add an Excel table to a worksheet.
4346
+ *
4347
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4348
+ * @param first_row The first row of the range. (All zero indexed.)
4349
+ * @param first_col The first column of the range.
4350
+ * @param last_row The last row of the range.
4351
+ * @param last_col The last col of the range.
4352
+ * @param options A #lxw_table_options struct to define the table options.
4353
+ *
4354
+ * @return A #lxw_error code.
4355
+ *
4356
+ * The `%worksheet_add_table()` function is used to add a table to a
4357
+ * worksheet. Tables in Excel are a way of grouping a range of cells into a
4358
+ * single entity that has common formatting or that can be referenced from
4359
+ * formulas. Tables can have column headers, autofilters, total rows, column
4360
+ * formulas and default formatting.
4361
+ *
4362
+ * @code
4363
+ * worksheet_add_table(worksheet, 2, 1, 6, 5, NULL);
4364
+ * @endcode
4365
+ *
4366
+ * Output:
4367
+ *
4368
+ * @image html tables1.png
4369
+ *
4370
+ * See @ref working_with_tables for more detailed usage information and also
4371
+ * @ref tables.c.
4372
+ *
4373
+ */
4374
+ lxw_error worksheet_add_table(lxw_worksheet *worksheet, lxw_row_t first_row,
4375
+ lxw_col_t first_col, lxw_row_t last_row,
4376
+ lxw_col_t last_col, lxw_table_options *options);
4377
+
2077
4378
  /**
2078
4379
  * @brief Make a worksheet the active, i.e., visible worksheet.
2079
4380
  *
@@ -2251,7 +4552,7 @@ void worksheet_split_panes_opt(lxw_worksheet *worksheet,
2251
4552
  /**
2252
4553
  * @brief Set the selected cell or cells in a worksheet:
2253
4554
  *
2254
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4555
+ * @param worksheet A pointer to a lxw_worksheet instance to be updated.
2255
4556
  * @param first_row The first row of the range. (All zero indexed.)
2256
4557
  * @param first_col The first column of the range.
2257
4558
  * @param last_row The last row of the range.
@@ -2281,6 +4582,27 @@ void worksheet_set_selection(lxw_worksheet *worksheet,
2281
4582
  lxw_row_t first_row, lxw_col_t first_col,
2282
4583
  lxw_row_t last_row, lxw_col_t last_col);
2283
4584
 
4585
+ /**
4586
+ * @brief Set the first visible cell at the top left of a worksheet.
4587
+ *
4588
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4589
+ * @param row The cell row (zero indexed).
4590
+ * @param col The cell column (zero indexed).
4591
+ *
4592
+ * The `%worksheet_set_top_left_cell()` function can be used to set the
4593
+ * top leftmost visible cell in the worksheet:
4594
+ *
4595
+ * @code
4596
+ * worksheet_set_top_left_cell(worksheet, 31, 26);
4597
+ * worksheet_set_top_left_cell(worksheet, CELL("AA32")); // Same as above.
4598
+ * @endcode
4599
+ *
4600
+ * @image html top_left_cell.png
4601
+ *
4602
+ */
4603
+ void worksheet_set_top_left_cell(lxw_worksheet *worksheet, lxw_row_t row,
4604
+ lxw_col_t col);
4605
+
2284
4606
  /**
2285
4607
  * @brief Set the page orientation as landscape.
2286
4608
  *
@@ -2446,7 +4768,11 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2446
4768
  * | `&S` | | Strikethrough |
2447
4769
  * | `&X` | | Superscript |
2448
4770
  * | `&Y` | | Subscript |
4771
+ * | `&[Picture]` | Images | Image placeholder |
4772
+ * | `&G` | | Same as `&[Picture]` |
4773
+ * | `&&` | Miscellaneous | Literal ampersand & |
2449
4774
  *
4775
+ * Note: inserting images requires the `worksheet_set_header_opt()` function.
2450
4776
  *
2451
4777
  * Text in headers and footers can be justified (aligned) to the left, center
2452
4778
  * and right by prefixing the text with the control characters `&L`, `&C` and
@@ -2570,17 +4896,14 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2570
4896
  * @code
2571
4897
  *
2572
4898
  * $ unzip myfile.xlsm -d myfile
2573
- * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer"
4899
+ * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer" | sed 's/&amp;/\&/g'
2574
4900
  *
2575
4901
  * <headerFooter scaleWithDoc="0">
2576
- * <oddHeader>&amp;L&amp;P</oddHeader>
4902
+ * <oddHeader>&L&P</oddHeader>
2577
4903
  * </headerFooter>
2578
4904
  *
2579
4905
  * @endcode
2580
4906
  *
2581
- * Note that in this case you need to unescape the Html. In the above example
2582
- * the header string would be `&L&P`.
2583
- *
2584
4907
  * To include a single literal ampersand `&` in a header or footer you should
2585
4908
  * use a double ampersand `&&`:
2586
4909
  *
@@ -2588,8 +4911,10 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
2588
4911
  * worksheet_set_header(worksheet, "&CCuriouser && Curiouser - Attorneys at Law");
2589
4912
  * @endcode
2590
4913
  *
2591
- * Note, the header or footer string must be less than 255 characters. Strings
2592
- * longer than this will not be written.
4914
+ * @note
4915
+ * Excel requires that the header or footer string cannot be longer than 255
4916
+ * characters, including the control characters. Strings longer than this will
4917
+ * not be written.
2593
4918
  *
2594
4919
  */
2595
4920
  lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
@@ -2616,19 +4941,43 @@ lxw_error worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
2616
4941
  *
2617
4942
  * @return A #lxw_error code.
2618
4943
  *
2619
- * The syntax of this function is the same as worksheet_set_header() with an
4944
+ * The syntax of this function is the same as `worksheet_set_header()` with an
2620
4945
  * additional parameter to specify options for the header.
2621
4946
  *
2622
- * Currently, the only available option is the header margin:
4947
+ * The #lxw_header_footer_options options are:
4948
+ *
4949
+ * - `margin`: Header or footer margin in inches. The value must by larger
4950
+ * than 0.0. The Excel default is 0.3.
4951
+ *
4952
+ * - `image_left`: The left header image filename, with path if required. This
4953
+ * should have a corresponding `&G/&[Picture]` placeholder in the `&L`
4954
+ * section of the header/footer string.
4955
+ *
4956
+ * - `image_center`: The center header image filename, with path if
4957
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
4958
+ * the `&C` section of the header/footer string.
4959
+ *
4960
+ * - `image_right`: The right header image filename, with path if
4961
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
4962
+ * the `&R` section of the header/footer string.
2623
4963
  *
2624
4964
  * @code
4965
+ * lxw_header_footer_options header_options = { .margin = 0.2 };
4966
+ *
4967
+ * worksheet_set_header_opt(worksheet, "Some text", &header_options);
4968
+ * @endcode
2625
4969
  *
2626
- * lxw_header_footer_options header_options = { 0.2 };
4970
+ * Images can be inserted in the header by specifying the `&[Picture]`
4971
+ * placeholder and a filename/path to the image:
2627
4972
  *
2628
- * worksheet_set_header_opt(worksheet, "Some text", &header_options);
4973
+ * @code
4974
+ * lxw_header_footer_options header_options = {.image_left = "logo.png"};
2629
4975
  *
4976
+ * worksheet_set_header_opt(worksheet, "&L&[Picture]", &header_options);
2630
4977
  * @endcode
2631
4978
  *
4979
+ * @image html headers_footers.png
4980
+ *
2632
4981
  */
2633
4982
  lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
2634
4983
  const char *string,
@@ -2643,7 +4992,7 @@ lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
2643
4992
  *
2644
4993
  * @return A #lxw_error code.
2645
4994
  *
2646
- * The syntax of this function is the same as worksheet_set_header_opt().
4995
+ * The syntax of this function is the same as `worksheet_set_header_opt()`.
2647
4996
  *
2648
4997
  */
2649
4998
  lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
@@ -2984,13 +5333,14 @@ void worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width,
2984
5333
  uint16_t height);
2985
5334
 
2986
5335
  /**
2987
- * @brief Set the start page number when printing.
5336
+ * @brief Set the start/first page number when printing.
2988
5337
  *
2989
5338
  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2990
- * @param start_page Starting page number.
5339
+ * @param start_page Page number of the starting page when printing.
2991
5340
  *
2992
- * The `%worksheet_set_start_page()` function is used to set the number of
2993
- * the starting page when the worksheet is printed out:
5341
+ * The `%worksheet_set_start_page()` function is used to set the number number
5342
+ * of the first page when the worksheet is printed out. It is the same as the
5343
+ * "First Page Number" option in Excel:
2994
5344
  *
2995
5345
  * @code
2996
5346
  * // Start print from page 2.
@@ -3025,6 +5375,18 @@ void worksheet_set_start_page(lxw_worksheet *worksheet, uint16_t start_page);
3025
5375
  */
3026
5376
  void worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
3027
5377
 
5378
+ /**
5379
+ * @brief Set the worksheet to print in black and white
5380
+ *
5381
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5382
+ *
5383
+ * Set the option to print the worksheet in black and white:
5384
+ * @code
5385
+ * worksheet_print_black_and_white(worksheet);
5386
+ * @endcode
5387
+ */
5388
+ void worksheet_print_black_and_white(lxw_worksheet *worksheet);
5389
+
3028
5390
  /**
3029
5391
  * @brief Display the worksheet cells from right to left for some versions of
3030
5392
  * Excel.
@@ -3241,9 +5603,12 @@ void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
3241
5603
  * @param worksheet Pointer to a lxw_worksheet instance.
3242
5604
  * @param name Name of the worksheet used by VBA.
3243
5605
  *
5606
+ * @return A #lxw_error.
5607
+ *
3244
5608
  * The `worksheet_set_vba_name()` function can be used to set the VBA name for
3245
5609
  * the worksheet. This is sometimes required when a vbaProject macro included
3246
- * via `workbook_add_vba_project()` refers to the worksheet.
5610
+ * via `workbook_add_vba_project()` refers to the worksheet by a name other
5611
+ * than the worksheet name:
3247
5612
  *
3248
5613
  * @code
3249
5614
  * workbook_set_vba_name (workbook, "MyWorkbook");
@@ -3254,10 +5619,149 @@ void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
3254
5619
  * However, this can be changed in the VBA environment or if the the macro was
3255
5620
  * extracted from a foreign language version of Excel.
3256
5621
  *
3257
- * @return A #lxw_error.
5622
+ * See also @ref working_with_macros
3258
5623
  */
3259
5624
  lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
3260
5625
 
5626
+ /**
5627
+ * @brief Make all comments in the worksheet visible.
5628
+ *
5629
+ * @param worksheet Pointer to a lxw_worksheet instance.
5630
+ *
5631
+ * This `%worksheet_show_comments()` function is used to make all cell
5632
+ * comments visible when a worksheet is opened:
5633
+ *
5634
+ * @code
5635
+ * worksheet_show_comments(worksheet);
5636
+ * @endcode
5637
+ *
5638
+ * Individual comments can be made visible or hidden using the `visible`
5639
+ * option of the #lxw_comment_options struct and the `worksheet_write_comment_opt()`
5640
+ * function (see above and @ref ww_comments_visible).
5641
+ */
5642
+ void worksheet_show_comments(lxw_worksheet *worksheet);
5643
+
5644
+ /**
5645
+ * @brief Set the default author of the cell comments.
5646
+ *
5647
+ * @param worksheet Pointer to a lxw_worksheet instance.
5648
+ * @param author The name of the comment author.
5649
+ *
5650
+ * This `%worksheet_set_comments_author()` function is used to set the
5651
+ * default author of all cell comments:
5652
+ *
5653
+ * @code
5654
+ * worksheet_set_comments_author(worksheet, "Jane Gloriana Villanueva")
5655
+ * @endcode
5656
+ *
5657
+ * Individual authors can be set using the `author` option of the
5658
+ * #lxw_comment_options struct and the `worksheet_write_comment_opt()`
5659
+ * function (see above and @ref ww_comments_author).
5660
+ */
5661
+ void worksheet_set_comments_author(lxw_worksheet *worksheet,
5662
+ const char *author);
5663
+
5664
+ /**
5665
+ * @brief Ignore various Excel errors/warnings in a worksheet for user
5666
+ * defined ranges.
5667
+ *
5668
+ * @param worksheet Pointer to a lxw_worksheet instance.
5669
+ * @param type The type of error/warning to ignore. See #lxw_ignore_errors.
5670
+ * @param range The range(s) for which the error/warning should be ignored.
5671
+ *
5672
+ * @return A #lxw_error.
5673
+ *
5674
+ *
5675
+ * The `%worksheet_ignore_errors()` function can be used to ignore various
5676
+ * worksheet cell errors/warnings. For example the following code writes a string
5677
+ * that looks like a number:
5678
+ *
5679
+ * @code
5680
+ * worksheet_write_string(worksheet, CELL("D2"), "123", NULL);
5681
+ * @endcode
5682
+ *
5683
+ * This causes Excel to display a small green triangle in the top left hand
5684
+ * corner of the cell to indicate an error/warning:
5685
+ *
5686
+ * @image html ignore_errors1.png
5687
+ *
5688
+ * Sometimes these warnings are useful indicators that there is an issue in
5689
+ * the spreadsheet but sometimes it is preferable to turn them off. Warnings
5690
+ * can be turned off at the Excel level for all workbooks and worksheets by
5691
+ * using the using "Excel options -> Formulas -> Error checking
5692
+ * rules". Alternatively you can turn them off for individual cells in a
5693
+ * worksheet, or ranges of cells, using the `%worksheet_ignore_errors()`
5694
+ * function with different #lxw_ignore_errors options and ranges like this:
5695
+ *
5696
+ * @code
5697
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C3");
5698
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_EVAL_ERROR, "C6");
5699
+ * @endcode
5700
+ *
5701
+ * The range can be a single cell, a range of cells, or multiple cells and ranges
5702
+ * separated by spaces:
5703
+ *
5704
+ * @code
5705
+ * // Single cell.
5706
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6");
5707
+ *
5708
+ * // Or a single range:
5709
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6:G8");
5710
+ *
5711
+ * // Or multiple cells and ranges:
5712
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6 E6 G1:G20 J2:J6");
5713
+ * @endcode
5714
+ *
5715
+ * @note Calling `%worksheet_ignore_errors()` more than once for the same
5716
+ * #lxw_ignore_errors type will overwrite the previous range.
5717
+ *
5718
+ * You can turn off warnings for an entire column by specifying the range from
5719
+ * the first cell in the column to the last cell in the column:
5720
+ *
5721
+ * @code
5722
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:A1048576");
5723
+ * @endcode
5724
+ *
5725
+ * Or for the entire worksheet by specifying the range from the first cell in
5726
+ * the worksheet to the last cell in the worksheet:
5727
+ *
5728
+ * @code
5729
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:XFD1048576");
5730
+ * @endcode
5731
+ *
5732
+ * The worksheet errors/warnings that can be ignored are:
5733
+ *
5734
+ * - #LXW_IGNORE_NUMBER_STORED_AS_TEXT: Turn off errors/warnings for numbers
5735
+ * stores as text.
5736
+ *
5737
+ * - #LXW_IGNORE_EVAL_ERROR: Turn off errors/warnings for formula errors (such
5738
+ * as divide by zero).
5739
+ *
5740
+ * - #LXW_IGNORE_FORMULA_DIFFERS: Turn off errors/warnings for formulas that
5741
+ * differ from surrounding formulas.
5742
+ *
5743
+ * - #LXW_IGNORE_FORMULA_RANGE: Turn off errors/warnings for formulas that
5744
+ * omit cells in a range.
5745
+ *
5746
+ * - #LXW_IGNORE_FORMULA_UNLOCKED: Turn off errors/warnings for unlocked cells
5747
+ * that contain formulas.
5748
+ *
5749
+ * - #LXW_IGNORE_EMPTY_CELL_REFERENCE: Turn off errors/warnings for formulas
5750
+ * that refer to empty cells.
5751
+ *
5752
+ * - #LXW_IGNORE_LIST_DATA_VALIDATION: Turn off errors/warnings for cells in a
5753
+ * table that do not comply with applicable data validation rules.
5754
+ *
5755
+ * - #LXW_IGNORE_CALCULATED_COLUMN: Turn off errors/warnings for cell formulas
5756
+ * that differ from the column formula.
5757
+ *
5758
+ * - #LXW_IGNORE_TWO_DIGIT_TEXT_YEAR: Turn off errors/warnings for formulas
5759
+ * that contain a two digit text representation of a year.
5760
+ *
5761
+ */
5762
+ lxw_error worksheet_ignore_errors(lxw_worksheet *worksheet, uint8_t type,
5763
+ const char *range);
5764
+
3261
5765
  lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
3262
5766
  void lxw_worksheet_free(lxw_worksheet *worksheet);
3263
5767
  void lxw_worksheet_assemble_xml_file(lxw_worksheet *worksheet);
@@ -3265,24 +5769,44 @@ void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
3265
5769
 
3266
5770
  void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
3267
5771
  uint32_t image_ref_id, uint32_t drawing_id,
3268
- lxw_image_options *image_data);
5772
+ lxw_object_properties *object_props);
5773
+
5774
+ void lxw_worksheet_prepare_header_image(lxw_worksheet *worksheet,
5775
+ uint32_t image_ref_id,
5776
+ lxw_object_properties *object_props);
5777
+
5778
+ void lxw_worksheet_prepare_background(lxw_worksheet *worksheet,
5779
+ uint32_t image_ref_id,
5780
+ lxw_object_properties *object_props);
3269
5781
 
3270
5782
  void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
3271
5783
  uint32_t chart_ref_id, uint32_t drawing_id,
3272
- lxw_image_options *image_data,
5784
+ lxw_object_properties *object_props,
3273
5785
  uint8_t is_chartsheet);
3274
5786
 
3275
- lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
3276
- lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
5787
+ uint32_t lxw_worksheet_prepare_vml_objects(lxw_worksheet *worksheet,
5788
+ uint32_t vml_data_id,
5789
+ uint32_t vml_shape_id,
5790
+ uint32_t vml_drawing_id,
5791
+ uint32_t comment_id);
5792
+
5793
+ void lxw_worksheet_prepare_header_vml_objects(lxw_worksheet *worksheet,
5794
+ uint32_t vml_header_id,
5795
+ uint32_t vml_drawing_id);
3277
5796
 
5797
+ void lxw_worksheet_prepare_tables(lxw_worksheet *worksheet,
5798
+ uint32_t table_id);
5799
+
5800
+ lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
5801
+ lxw_cell *lxw_worksheet_find_cell_in_row(lxw_row *row, lxw_col_t col_num);
3278
5802
  /*
3279
- * External functions to call intern XML methods shared with chartsheet.
5803
+ * External functions to call intern XML functions shared with chartsheet.
3280
5804
  */
3281
5805
  void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
3282
5806
  void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
3283
5807
  void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
3284
5808
  void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3285
- lxw_protection *protect);
5809
+ lxw_protection_obj *protect);
3286
5810
  void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
3287
5811
  void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
3288
5812
  void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
@@ -3317,8 +5841,13 @@ STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
3317
5841
  STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
3318
5842
  STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
3319
5843
  STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
3320
- lxw_protection *protect);
5844
+ lxw_protection_obj *protect);
3321
5845
  STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
5846
+
5847
+ STATIC double _pixels_to_height(double pixels);
5848
+ STATIC double _pixels_to_width(double pixels);
5849
+
5850
+ STATIC void _worksheet_write_auto_filter(lxw_worksheet *worksheet);
3322
5851
  #endif /* TESTING */
3323
5852
 
3324
5853
  /* *INDENT-OFF* */