fast_excel 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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* */