1 /*
2  * libxlsxwriter
3  *
4  * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5  */
6 
7 /**
8  * @page worksheet_page The Worksheet object
9  *
10  * The Worksheet object represents an Excel worksheet. It handles
11  * operations such as writing data to cells or formatting worksheet
12  * layout.
13  *
14  * See @ref worksheet.h for full details of the functionality.
15  *
16  * @file worksheet.h
17  *
18  * @brief Functions related to adding data and formatting to a worksheet.
19  *
20  * The Worksheet object represents an Excel worksheet. It handles
21  * operations such as writing data to cells or formatting worksheet
22  * layout.
23  *
24  * A Worksheet object isn't created directly. Instead a worksheet is
25  * created by calling the workbook_add_worksheet() function from a
26  * Workbook object:
27  *
28  * @code
29  *     #include "xlsxwriter.h"
30  *
31  *     int main() {
32  *
33  *         lxw_workbook  *workbook  = workbook_new("filename.xlsx");
34  *         lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
35  *
36  *         worksheet_write_string(worksheet, 0, 0, "Hello Excel", NULL);
37  *
38  *         return workbook_close(workbook);
39  *     }
40  * @endcode
41  *
42  */
43 #ifndef __LXW_WORKSHEET_H__
44 #define __LXW_WORKSHEET_H__
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <stdint.h>
49 
50 #include "shared_strings.h"
51 #include "chart.h"
52 #include "drawing.h"
53 #include "common.h"
54 #include "format.h"
55 #include "styles.h"
56 #include "utility.h"
57 #include "relationships.h"
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 */
65 #define LXW_IMAGE_BUFFER_SIZE       1024
66 #define LXW_HEADER_FOOTER_OBJS_MAX  6   /* Header/footer image objs. */
67 
68 /* The Excel 2007 specification says that the maximum number of page
69  * breaks is 1026. However, in practice it is actually 1023. */
70 #define LXW_BREAKS_MAX        1023
71 
72 /** Default Excel column width in character units. */
73 #define LXW_DEF_COL_WIDTH (double)8.43
74 
75 /** Default Excel column height in character units. */
76 #define LXW_DEF_ROW_HEIGHT (double)15.0
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 
84 /** Gridline options using in `worksheet_gridlines()`. */
85 enum lxw_gridlines {
86     /** Hide screen and print gridlines. */
87     LXW_HIDE_ALL_GRIDLINES = 0,
88 
89     /** Show screen gridlines. */
90     LXW_SHOW_SCREEN_GRIDLINES,
91 
92     /** Show print gridlines. */
93     LXW_SHOW_PRINT_GRIDLINES,
94 
95     /** Show screen and print gridlines. */
96     LXW_SHOW_ALL_GRIDLINES
97 };
98 
99 /** Data validation property values. */
100 enum lxw_validation_boolean {
101     LXW_VALIDATION_DEFAULT,
102 
103     /** Turn a data validation property off. */
104     LXW_VALIDATION_OFF,
105 
106     /** Turn a data validation property on. Data validation properties are
107      * generally on by default. */
108     LXW_VALIDATION_ON
109 };
110 
111 /** Data validation types. */
112 enum lxw_validation_types {
113     LXW_VALIDATION_TYPE_NONE,
114 
115     /** Restrict cell input to whole/integer numbers only. */
116     LXW_VALIDATION_TYPE_INTEGER,
117 
118     /** Restrict cell input to whole/integer numbers only, using a cell
119      *  reference. */
120     LXW_VALIDATION_TYPE_INTEGER_FORMULA,
121 
122     /** Restrict cell input to decimal numbers only. */
123     LXW_VALIDATION_TYPE_DECIMAL,
124 
125     /** Restrict cell input to decimal numbers only, using a cell
126      * reference. */
127     LXW_VALIDATION_TYPE_DECIMAL_FORMULA,
128 
129     /** Restrict cell input to a list of strings in a dropdown. */
130     LXW_VALIDATION_TYPE_LIST,
131 
132     /** Restrict cell input to a list of strings in a dropdown, using a
133      * cell range. */
134     LXW_VALIDATION_TYPE_LIST_FORMULA,
135 
136     /** Restrict cell input to date values only, using a lxw_datetime type. */
137     LXW_VALIDATION_TYPE_DATE,
138 
139     /** Restrict cell input to date values only, using a cell reference. */
140     LXW_VALIDATION_TYPE_DATE_FORMULA,
141 
142     /* Restrict cell input to date values only, as a serial number.
143      * Undocumented. */
144     LXW_VALIDATION_TYPE_DATE_NUMBER,
145 
146     /** Restrict cell input to time values only, using a lxw_datetime type. */
147     LXW_VALIDATION_TYPE_TIME,
148 
149     /** Restrict cell input to time values only, using a cell reference. */
150     LXW_VALIDATION_TYPE_TIME_FORMULA,
151 
152     /* Restrict cell input to time values only, as a serial number.
153      * Undocumented. */
154     LXW_VALIDATION_TYPE_TIME_NUMBER,
155 
156     /** Restrict cell input to strings of defined length, using a cell
157      * reference. */
158     LXW_VALIDATION_TYPE_LENGTH,
159 
160     /** Restrict cell input to strings of defined length, using a cell
161      * reference. */
162     LXW_VALIDATION_TYPE_LENGTH_FORMULA,
163 
164     /** Restrict cell to input controlled by a custom formula that returns
165      * `TRUE/FALSE`. */
166     LXW_VALIDATION_TYPE_CUSTOM_FORMULA,
167 
168     /** Allow any type of input. Mainly only useful for pop-up messages. */
169     LXW_VALIDATION_TYPE_ANY
170 };
171 
172 /** Data validation criteria uses to control the selection of data. */
173 enum lxw_validation_criteria {
174     LXW_VALIDATION_CRITERIA_NONE,
175 
176     /** Select data between two values. */
177     LXW_VALIDATION_CRITERIA_BETWEEN,
178 
179     /** Select data that is not between two values. */
180     LXW_VALIDATION_CRITERIA_NOT_BETWEEN,
181 
182     /** Select data equal to a value. */
183     LXW_VALIDATION_CRITERIA_EQUAL_TO,
184 
185     /** Select data not equal to a value. */
186     LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO,
187 
188     /** Select data greater than a value. */
189     LXW_VALIDATION_CRITERIA_GREATER_THAN,
190 
191     /** Select data less than a value. */
192     LXW_VALIDATION_CRITERIA_LESS_THAN,
193 
194     /** Select data greater than or equal to a value. */
195     LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
196 
197     /** Select data less than or equal to a value. */
198     LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO
199 };
200 
201 /** Data validation error types for pop-up messages. */
202 enum lxw_validation_error_types {
203     /** Show a "Stop" data validation pop-up message. This is the default. */
204     LXW_VALIDATION_ERROR_TYPE_STOP,
205 
206     /** Show an "Error" data validation pop-up message. */
207     LXW_VALIDATION_ERROR_TYPE_WARNING,
208 
209     /** Show an "Information" data validation pop-up message. */
210     LXW_VALIDATION_ERROR_TYPE_INFORMATION
211 };
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: 3 colored arrows showing up, diagonal up, diagonal down
508      *  and down. */
509     LXW_CONDITIONAL_ICONS_4_ARROWS_COLORED,
510 
511     /** Icon style: 3 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 with the worksheet object with the cells. */
662     LXW_OBJECT_MOVE_AND_SIZE,
663 
664     /** Move but don't size with 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 
713 enum cell_types {
714     NUMBER_CELL = 1,
715     STRING_CELL,
716     INLINE_STRING_CELL,
717     INLINE_RICH_STRING_CELL,
718     FORMULA_CELL,
719     ARRAY_FORMULA_CELL,
720     DYNAMIC_ARRAY_FORMULA_CELL,
721     BLANK_CELL,
722     BOOLEAN_CELL,
723     COMMENT,
724     HYPERLINK_URL,
725     HYPERLINK_INTERNAL,
726     HYPERLINK_EXTERNAL
727 };
728 
729 enum pane_types {
730     NO_PANES = 0,
731     FREEZE_PANES,
732     SPLIT_PANES,
733     FREEZE_SPLIT_PANES
734 };
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 
745 /* Define the tree.h RB structs for the red-black head types. */
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);
750 
751 /* Define a RB_TREE struct manually to add extra members. */
752 struct lxw_table_rows {
753     struct lxw_row *rbh_root;
754     struct lxw_row *cached_row;
755     lxw_row_t cached_row_num;
756 };
757 
758 /* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
759  * warnings and to avoid portability issues with the _unused attribute. */
760 #define LXW_RB_GENERATE_ROW(name, type, field, cmp)       \
761     RB_GENERATE_INSERT_COLOR(name, type, field, static)   \
762     RB_GENERATE_REMOVE_COLOR(name, type, field, static)   \
763     RB_GENERATE_INSERT(name, type, field, cmp, static)    \
764     RB_GENERATE_REMOVE(name, type, field, static)         \
765     RB_GENERATE_FIND(name, type, field, cmp, static)      \
766     RB_GENERATE_NEXT(name, type, field, static)           \
767     RB_GENERATE_MINMAX(name, type, field, static)         \
768     /* Add unused struct to allow adding a semicolon */   \
769     struct lxw_rb_generate_row{int unused;}
770 
771 #define LXW_RB_GENERATE_CELL(name, type, field, cmp)      \
772     RB_GENERATE_INSERT_COLOR(name, type, field, static)   \
773     RB_GENERATE_REMOVE_COLOR(name, type, field, static)   \
774     RB_GENERATE_INSERT(name, type, field, cmp, static)    \
775     RB_GENERATE_REMOVE(name, type, field, static)         \
776     RB_GENERATE_FIND(name, type, field, cmp, static)      \
777     RB_GENERATE_NEXT(name, type, field, static)           \
778     RB_GENERATE_MINMAX(name, type, field, static)         \
779     /* Add unused struct to allow adding a semicolon */   \
780     struct lxw_rb_generate_cell{int unused;}
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 
815 STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
816 STAILQ_HEAD(lxw_selections, lxw_selection);
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);
823 
824 /**
825  * @brief Options for rows and columns.
826  *
827  * Options struct for the worksheet_set_column() and worksheet_set_row()
828  * functions.
829  *
830  * It has the following members:
831  *
832  * * `hidden`
833  * * `level`
834  * * `collapsed`
835  *
836  * The members of this struct are explained in @ref ww_outlines_grouping.
837  *
838  */
839 typedef struct lxw_row_col_options {
840     /** Hide the row/column. @ref ww_outlines_grouping.*/
841     uint8_t hidden;
842 
843     /** Outline level. See @ref ww_outlines_grouping.*/
844     uint8_t level;
845 
846     /** Set the outline row as collapsed. See @ref ww_outlines_grouping.*/
847     uint8_t collapsed;
848 } lxw_row_col_options;
849 
850 typedef struct lxw_col_options {
851     lxw_col_t firstcol;
852     lxw_col_t lastcol;
853     double width;
854     lxw_format *format;
855     uint8_t hidden;
856     uint8_t level;
857     uint8_t collapsed;
858 } lxw_col_options;
859 
860 typedef struct lxw_merged_range {
861     lxw_row_t first_row;
862     lxw_row_t last_row;
863     lxw_col_t first_col;
864     lxw_col_t last_col;
865 
866     STAILQ_ENTRY (lxw_merged_range) list_pointers;
867 } lxw_merged_range;
868 
869 typedef struct lxw_repeat_rows {
870     uint8_t in_use;
871     lxw_row_t first_row;
872     lxw_row_t last_row;
873 } lxw_repeat_rows;
874 
875 typedef struct lxw_repeat_cols {
876     uint8_t in_use;
877     lxw_col_t first_col;
878     lxw_col_t last_col;
879 } lxw_repeat_cols;
880 
881 typedef struct lxw_print_area {
882     uint8_t in_use;
883     lxw_row_t first_row;
884     lxw_row_t last_row;
885     lxw_col_t first_col;
886     lxw_col_t last_col;
887 } lxw_print_area;
888 
889 typedef struct lxw_autofilter {
890     uint8_t in_use;
891     uint8_t has_rules;
892     lxw_row_t first_row;
893     lxw_row_t last_row;
894     lxw_col_t first_col;
895     lxw_col_t last_col;
896 } lxw_autofilter;
897 
898 typedef struct lxw_panes {
899     uint8_t type;
900     lxw_row_t first_row;
901     lxw_col_t first_col;
902     lxw_row_t top_row;
903     lxw_col_t left_col;
904     double x_split;
905     double y_split;
906 } lxw_panes;
907 
908 typedef struct lxw_selection {
909     char pane[LXW_PANE_NAME_LENGTH];
910     char active_cell[LXW_MAX_CELL_RANGE_LENGTH];
911     char sqref[LXW_MAX_CELL_RANGE_LENGTH];
912 
913     STAILQ_ENTRY (lxw_selection) list_pointers;
914 
915 } lxw_selection;
916 
917 /**
918  * @brief Worksheet data validation options.
919  */
920 typedef struct lxw_data_validation {
921 
922     /**
923      * Set the validation type. Should be a #lxw_validation_types value.
924      */
925     uint8_t validate;
926 
927     /**
928      * Set the validation criteria type to select the data. Should be a
929      * #lxw_validation_criteria value.
930      */
931     uint8_t criteria;
932 
933     /** Controls whether a data validation is not applied to blank data in the
934      * cell. Should be a #lxw_validation_boolean value. It is on by
935      * default.
936      */
937     uint8_t ignore_blank;
938 
939     /**
940      * This parameter is used to toggle on and off the 'Show input message
941      * when cell is selected' option in the Excel data validation dialog. When
942      * the option is off an input message is not displayed even if it has been
943      * set using input_message. Should be a #lxw_validation_boolean value. It
944      * is on by default.
945      */
946     uint8_t show_input;
947 
948     /**
949      * This parameter is used to toggle on and off the 'Show error alert
950      * after invalid data is entered' option in the Excel data validation
951      * dialog. When the option is off an error message is not displayed even
952      * if it has been set using error_message. Should be a
953      * #lxw_validation_boolean value. It is on by default.
954      */
955     uint8_t show_error;
956 
957     /**
958      * This parameter is used to specify the type of error dialog that is
959      * displayed. Should be a #lxw_validation_error_types value.
960      */
961     uint8_t error_type;
962 
963     /**
964      * This parameter is used to toggle on and off the 'In-cell dropdown'
965      * option in the Excel data validation dialog. When the option is on a
966      * dropdown list will be shown for list validations. Should be a
967      * #lxw_validation_boolean value. It is on by default.
968      */
969     uint8_t dropdown;
970 
971     /**
972      * This parameter is used to set the limiting value to which the criteria
973      * is applied using a whole or decimal number.
974      */
975     double value_number;
976 
977     /**
978      * This parameter is used to set the limiting value to which the criteria
979      * is applied using a cell reference. It is valid for any of the
980      * `_FORMULA` validation types.
981      */
982     char *value_formula;
983 
984     /**
985      * This parameter is used to set a list of strings for a drop down list.
986      * The list should be a `NULL` terminated array of char* strings:
987      *
988      * @code
989      *    char *list[] = {"open", "high", "close", NULL};
990      *
991      *    data_validation->validate   = LXW_VALIDATION_TYPE_LIST;
992      *    data_validation->value_list = list;
993      * @endcode
994      *
995      * The `value_formula` parameter can also be used to specify a list from
996      * an Excel cell range.
997      *
998      * Note, the string list is restricted by Excel to 255 characters,
999      * including comma separators.
1000      */
1001     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     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     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     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     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     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     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     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     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     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     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     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     char *header;
1393 
1394     /** Set the formula for the column. */
1395     char *formula;
1396 
1397     /** Set the string description for the column total.  */
1398     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     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;
1597 
1598     /**
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;
1602 
1603     /**
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.
1618      */
1619     uint8_t total_row;
1620 
1621     /**
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.
1625      */
1626     lxw_table_column **columns;
1627 
1628 } lxw_table_options;
1629 
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;
1643 
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;
1650 
1651     char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1652     char filter_sqref[LXW_MAX_ATTRIBUTE_LENGTH];
1653     STAILQ_ENTRY (lxw_table_obj) list_pointers;
1654 
1655 } lxw_table_obj;
1656 
1657 /**
1658  * @brief Options for autofilter rules.
1659  *
1660  * Options to define an autofilter rule.
1661  *
1662  */
1663 typedef struct lxw_filter_rule {
1664 
1665     /** The #lxw_filter_criteria to define the rule. */
1666     uint8_t criteria;
1667 
1668     /** String value to which the criteria applies. */
1669     char *value_string;
1670 
1671     /** Numeric value to which the criteria applies (if value_string isn't used). */
1672     double value;
1673 
1674 } lxw_filter_rule;
1675 
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;
1694 
1695 /**
1696  * @brief Options for inserted images.
1697  *
1698  * Options for modifying images inserted via `worksheet_insert_image_opt()`.
1699  *
1700  */
1701 typedef struct lxw_image_options {
1702 
1703     /** Offset from the left of the cell in pixels. */
1704     int32_t x_offset;
1705 
1706     /** Offset from the top of the cell in pixels. */
1707     int32_t y_offset;
1708 
1709     /** X scale of the image as a decimal. */
1710     double x_scale;
1711 
1712     /** Y scale of the image as a decimal. */
1713     double y_scale;
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     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     char *url;
1734 
1735     /** Add an optional mouseover tip for a hyperlink to the image. */
1736     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     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;
1786     lxw_row_t row;
1787     lxw_col_t col;
1788     char *filename;
1789     char *description;
1790     char *url;
1791     char *tip;
1792     uint8_t object_position;
1793     FILE *stream;
1794     uint8_t image_type;
1795     uint8_t is_image_buffer;
1796     unsigned char *image_buffer;
1797     size_t image_buffer_size;
1798     double width;
1799     double height;
1800     char *extension;
1801     double x_dpi;
1802     double y_dpi;
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;
1809 
1810     STAILQ_ENTRY (lxw_object_properties) list_pointers;
1811 } lxw_object_properties;
1812 
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     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     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     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     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     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     uint32_t col_absolute;
1948     uint32_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;
1970 
1971 /**
1972  * @brief Header and footer options.
1973  *
1974  * Optional parameters used in the `worksheet_set_header_opt()` and
1975  * worksheet_set_footer_opt() functions.
1976  *
1977  */
1978 typedef struct lxw_header_footer_options {
1979     /** Header or footer margin in inches. Excel default is 0.3. Must by
1980      *  larger than 0.0.  See `worksheet_set_header_opt()`. */
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     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     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     char *image_right;
1997 
1998 } lxw_header_footer_options;
1999 
2000 /**
2001  * @brief Worksheet protection options.
2002  */
2003 typedef struct lxw_protection {
2004     /** Turn off selection of locked cells. This in on in Excel by default.*/
2005     uint8_t no_select_locked_cells;
2006 
2007     /** Turn off selection of unlocked cells. This in on in Excel by default.*/
2008     uint8_t no_select_unlocked_cells;
2009 
2010     /** Prevent formatting of cells. */
2011     uint8_t format_cells;
2012 
2013     /** Prevent formatting of columns. */
2014     uint8_t format_columns;
2015 
2016     /** Prevent formatting of rows. */
2017     uint8_t format_rows;
2018 
2019     /** Prevent insertion of columns. */
2020     uint8_t insert_columns;
2021 
2022     /** Prevent insertion of rows. */
2023     uint8_t insert_rows;
2024 
2025     /** Prevent insertion of hyperlinks. */
2026     uint8_t insert_hyperlinks;
2027 
2028     /** Prevent deletion of columns. */
2029     uint8_t delete_columns;
2030 
2031     /** Prevent deletion of rows. */
2032     uint8_t delete_rows;
2033 
2034     /** Prevent sorting data. */
2035     uint8_t sort;
2036 
2037     /** Prevent filtering data. */
2038     uint8_t autofilter;
2039 
2040     /** Prevent insertion of pivot tables. */
2041     uint8_t pivot_tables;
2042 
2043     /** Protect scenarios. */
2044     uint8_t scenarios;
2045 
2046     /** Protect drawing objects. Worksheets only. */
2047     uint8_t objects;
2048 
2049     /** Turn off chartsheet content protection. */
2050     uint8_t no_content;
2051 
2052     /** Turn off chartsheet objects. */
2053     uint8_t no_objects;
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;
2076     uint8_t no_sheet;
2077     uint8_t is_configured;
2078     char hash[5];
2079 } lxw_protection_obj;
2080 
2081 /**
2082  * @brief Struct to represent a rich string format/string pair.
2083  *
2084  * Arrays of this struct are used to define "rich" multi-format strings that
2085  * are passed to `worksheet_write_rich_string()`. Each struct represents a
2086  * fragment of the rich multi-format string with a lxw_format to define the
2087  * format for the string part. If the string fragment is unformatted then
2088  * `NULL` can be used for the format.
2089  */
2090 typedef struct lxw_rich_string_tuple {
2091 
2092     /** The format for a string fragment in a rich string. NULL if the string
2093      *  isn't formatted. */
2094     lxw_format *format;
2095 
2096     /** The string fragment. */
2097     char *string;
2098 } lxw_rich_string_tuple;
2099 
2100 /**
2101  * @brief Struct to represent an Excel worksheet.
2102  *
2103  * The members of the lxw_worksheet struct aren't modified directly. Instead
2104  * the worksheet properties are set by calling the functions shown in
2105  * worksheet.h.
2106  */
2107 typedef struct lxw_worksheet {
2108 
2109     FILE *file;
2110     FILE *optimize_tmpfile;
2111     struct lxw_table_rows *table;
2112     struct lxw_table_rows *hyperlinks;
2113     struct lxw_table_rows *comments;
2114     struct lxw_cell **array;
2115     struct lxw_merged_ranges *merged_ranges;
2116     struct lxw_selections *selections;
2117     struct lxw_data_validations *data_validations;
2118     struct lxw_cond_format_hash *conditional_formats;
2119     struct lxw_image_props *image_props;
2120     struct lxw_chart_props *chart_data;
2121     struct lxw_drawing_rel_ids *drawing_rel_ids;
2122     struct lxw_vml_drawing_rel_ids *vml_drawing_rel_ids;
2123     struct lxw_comment_objs *comment_objs;
2124     struct lxw_comment_objs *header_image_objs;
2125     struct lxw_comment_objs *button_objs;
2126     struct lxw_table_objs *table_objs;
2127     uint16_t table_count;
2128 
2129     lxw_row_t dim_rowmin;
2130     lxw_row_t dim_rowmax;
2131     lxw_col_t dim_colmin;
2132     lxw_col_t dim_colmax;
2133 
2134     lxw_sst *sst;
2135     char *name;
2136     char *quoted_name;
2137     char *tmpdir;
2138 
2139     uint16_t index;
2140     uint8_t active;
2141     uint8_t selected;
2142     uint8_t hidden;
2143     uint16_t *active_sheet;
2144     uint16_t *first_sheet;
2145     uint8_t is_chartsheet;
2146 
2147     lxw_col_options **col_options;
2148     uint16_t col_options_max;
2149 
2150     double *col_sizes;
2151     uint16_t col_sizes_max;
2152 
2153     lxw_format **col_formats;
2154     uint16_t col_formats_max;
2155 
2156     uint8_t col_size_changed;
2157     uint8_t row_size_changed;
2158     uint8_t optimize;
2159     struct lxw_row *optimize_row;
2160 
2161     uint16_t fit_height;
2162     uint16_t fit_width;
2163     uint16_t horizontal_dpi;
2164     uint16_t hlink_count;
2165     uint16_t page_start;
2166     uint16_t print_scale;
2167     uint16_t rel_count;
2168     uint16_t vertical_dpi;
2169     uint16_t zoom;
2170     uint8_t filter_on;
2171     uint8_t fit_page;
2172     uint8_t hcenter;
2173     uint8_t orientation;
2174     uint8_t outline_changed;
2175     uint8_t outline_on;
2176     uint8_t outline_style;
2177     uint8_t outline_below;
2178     uint8_t outline_right;
2179     uint8_t page_order;
2180     uint8_t page_setup_changed;
2181     uint8_t page_view;
2182     uint8_t paper_size;
2183     uint8_t print_gridlines;
2184     uint8_t print_headers;
2185     uint8_t print_options_changed;
2186     uint8_t right_to_left;
2187     uint8_t screen_gridlines;
2188     uint8_t show_zeros;
2189     uint8_t vcenter;
2190     uint8_t zoom_scale_normal;
2191     uint8_t num_validations;
2192     uint8_t has_dynamic_arrays;
2193     char *vba_codename;
2194     uint16_t num_buttons;
2195 
2196     lxw_color_t tab_color;
2197 
2198     double margin_left;
2199     double margin_right;
2200     double margin_top;
2201     double margin_bottom;
2202     double margin_header;
2203     double margin_footer;
2204 
2205     double default_row_height;
2206     uint32_t default_row_pixels;
2207     uint32_t default_col_pixels;
2208     uint8_t default_row_zeroed;
2209     uint8_t default_row_set;
2210     uint8_t outline_row_level;
2211     uint8_t outline_col_level;
2212 
2213     uint8_t header_footer_changed;
2214     char *header;
2215     char *footer;
2216 
2217     struct lxw_repeat_rows repeat_rows;
2218     struct lxw_repeat_cols repeat_cols;
2219     struct lxw_print_area print_area;
2220     struct lxw_autofilter autofilter;
2221 
2222     uint16_t merged_range_count;
2223     uint16_t max_url_length;
2224 
2225     lxw_row_t *hbreaks;
2226     lxw_col_t *vbreaks;
2227     uint16_t hbreaks_count;
2228     uint16_t vbreaks_count;
2229 
2230     uint32_t drawing_rel_id;
2231     uint32_t vml_drawing_rel_id;
2232     struct lxw_rel_tuples *external_hyperlinks;
2233     struct lxw_rel_tuples *external_drawing_links;
2234     struct lxw_rel_tuples *drawing_links;
2235     struct lxw_rel_tuples *vml_drawing_links;
2236     struct lxw_rel_tuples *external_table_links;
2237 
2238     struct lxw_panes panes;
2239 
2240     struct lxw_protection_obj protection;
2241 
2242     lxw_drawing *drawing;
2243     lxw_format *default_url_format;
2244 
2245     uint8_t has_vml;
2246     uint8_t has_comments;
2247     uint8_t has_header_vml;
2248     uint8_t has_background_image;
2249     uint8_t has_buttons;
2250     lxw_rel_tuple *external_vml_comment_link;
2251     lxw_rel_tuple *external_comment_link;
2252     lxw_rel_tuple *external_vml_header_link;
2253     lxw_rel_tuple *external_background_link;
2254     char *comment_author;
2255     char *vml_data_id_str;
2256     char *vml_header_id_str;
2257     uint32_t vml_shape_id;
2258     uint32_t vml_header_id;
2259     uint32_t dxf_priority;
2260     uint8_t comment_display_default;
2261     uint32_t data_bar_2010_index;
2262 
2263     uint8_t has_ignore_errors;
2264     char *ignore_number_stored_as_text;
2265     char *ignore_eval_error;
2266     char *ignore_formula_differs;
2267     char *ignore_formula_range;
2268     char *ignore_formula_unlocked;
2269     char *ignore_empty_cell_reference;
2270     char *ignore_list_data_validation;
2271     char *ignore_calculated_column;
2272     char *ignore_two_digit_text_year;
2273 
2274     uint16_t excel_version;
2275 
2276     lxw_object_properties **header_footer_objs[LXW_HEADER_FOOTER_OBJS_MAX];
2277     lxw_object_properties *header_left_object_props;
2278     lxw_object_properties *header_center_object_props;
2279     lxw_object_properties *header_right_object_props;
2280     lxw_object_properties *footer_left_object_props;
2281     lxw_object_properties *footer_center_object_props;
2282     lxw_object_properties *footer_right_object_props;
2283     lxw_object_properties *background_image;
2284 
2285     lxw_filter_rule_obj **filter_rules;
2286     lxw_col_t num_filter_rules;
2287 
2288     STAILQ_ENTRY (lxw_worksheet) list_pointers;
2289 
2290 } lxw_worksheet;
2291 
2292 /*
2293  * Worksheet initialization data.
2294  */
2295 typedef struct lxw_worksheet_init_data {
2296     uint16_t index;
2297     uint8_t hidden;
2298     uint8_t optimize;
2299     uint16_t *active_sheet;
2300     uint16_t *first_sheet;
2301     lxw_sst *sst;
2302     char *name;
2303     char *quoted_name;
2304     char *tmpdir;
2305     lxw_format *default_url_format;
2306     uint16_t max_url_length;
2307 
2308 } lxw_worksheet_init_data;
2309 
2310 /* Struct to represent a worksheet row. */
2311 typedef struct lxw_row {
2312     lxw_row_t row_num;
2313     double height;
2314     lxw_format *format;
2315     uint8_t hidden;
2316     uint8_t level;
2317     uint8_t collapsed;
2318     uint8_t row_changed;
2319     uint8_t data_changed;
2320     uint8_t height_changed;
2321 
2322     struct lxw_table_cells *cells;
2323 
2324     /* tree management pointers for tree.h. */
2325     RB_ENTRY (lxw_row) tree_pointers;
2326 } lxw_row;
2327 
2328 /* Struct to represent a worksheet cell. */
2329 typedef struct lxw_cell {
2330     lxw_row_t row_num;
2331     lxw_col_t col_num;
2332     enum cell_types type;
2333     lxw_format *format;
2334     lxw_vml_obj *comment;
2335 
2336     union {
2337         double number;
2338         int32_t string_id;
2339         char *string;
2340     } u;
2341 
2342     double formula_result;
2343     char *user_data1;
2344     char *user_data2;
2345     char *sst_string;
2346 
2347     /* List pointers for tree.h. */
2348     RB_ENTRY (lxw_cell) tree_pointers;
2349 } lxw_cell;
2350 
2351 /* Struct to represent a drawing Target/ID pair. */
2352 typedef struct lxw_drawing_rel_id {
2353     uint32_t id;
2354     char *target;
2355 
2356     RB_ENTRY (lxw_drawing_rel_id) tree_pointers;
2357 } lxw_drawing_rel_id;
2358 
2359 
2360 
2361 /* *INDENT-OFF* */
2362 #ifdef __cplusplus
2363 extern "C" {
2364 #endif
2365 /* *INDENT-ON* */
2366 
2367 /**
2368  * @brief Write a number to a worksheet cell.
2369  *
2370  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2371  * @param row       The zero indexed row number.
2372  * @param col       The zero indexed column number.
2373  * @param number    The number to write to the cell.
2374  * @param format    A pointer to a Format instance or NULL.
2375  *
2376  * @return A #lxw_error code.
2377  *
2378  * The `worksheet_write_number()` function writes numeric types to the cell
2379  * specified by `row` and `column`:
2380  *
2381  * @code
2382  *     worksheet_write_number(worksheet, 0, 0, 123456, NULL);
2383  *     worksheet_write_number(worksheet, 1, 0, 2.3451, NULL);
2384  * @endcode
2385  *
2386  * @image html write_number01.png
2387  *
2388  * The native data type for all numbers in Excel is a IEEE-754 64-bit
2389  * double-precision floating point, which is also the default type used by
2390  * `%worksheet_write_number`.
2391  *
2392  * The `format` parameter is used to apply formatting to the cell. This
2393  * parameter can be `NULL` to indicate no formatting or it can be a
2394  * @ref format.h "Format" object.
2395  *
2396  * @code
2397  *     lxw_format *format = workbook_add_format(workbook);
2398  *     format_set_num_format(format, "$#,##0.00");
2399  *
2400  *     worksheet_write_number(worksheet, 0, 0, 1234.567, format);
2401  * @endcode
2402  *
2403  * @image html write_number02.png
2404  *
2405  * @note Excel doesn't support `NaN`, `Inf` or `-Inf` as a number value. If
2406  * you are writing data that contains these values then your application
2407  * should convert them to a string or handle them in some other way.
2408  *
2409  */
2410 lxw_error worksheet_write_number(lxw_worksheet *worksheet,
2411                                  lxw_row_t row,
2412                                  lxw_col_t col, double number,
2413                                  lxw_format *format);
2414 /**
2415  * @brief Write a string to a worksheet cell.
2416  *
2417  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2418  * @param row       The zero indexed row number.
2419  * @param col       The zero indexed column number.
2420  * @param string    String to write to cell.
2421  * @param format    A pointer to a Format instance or NULL.
2422  *
2423  * @return A #lxw_error code.
2424  *
2425  * The `%worksheet_write_string()` function writes a string to the cell
2426  * specified by `row` and `column`:
2427  *
2428  * @code
2429  *     worksheet_write_string(worksheet, 0, 0, "This phrase is English!", NULL);
2430  * @endcode
2431  *
2432  * @image html write_string01.png
2433  *
2434  * The `format` parameter is used to apply formatting to the cell. This
2435  * parameter can be `NULL` to indicate no formatting or it can be a
2436  * @ref format.h "Format" object:
2437  *
2438  * @code
2439  *     lxw_format *format = workbook_add_format(workbook);
2440  *     format_set_bold(format);
2441  *
2442  *     worksheet_write_string(worksheet, 0, 0, "This phrase is Bold!", format);
2443  * @endcode
2444  *
2445  * @image html write_string02.png
2446  *
2447  * Unicode strings are supported in UTF-8 encoding. This generally requires
2448  * that your source file is UTF-8 encoded or that the data has been read from
2449  * a UTF-8 source:
2450  *
2451  * @code
2452  *    worksheet_write_string(worksheet, 0, 0, "Это фраза на русском!", NULL);
2453  * @endcode
2454  *
2455  * @image html write_string03.png
2456  *
2457  */
2458 lxw_error worksheet_write_string(lxw_worksheet *worksheet,
2459                                  lxw_row_t row,
2460                                  lxw_col_t col, const char *string,
2461                                  lxw_format *format);
2462 /**
2463  * @brief Write a formula to a worksheet cell.
2464  *
2465  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2466  * @param row       The zero indexed row number.
2467  * @param col       The zero indexed column number.
2468  * @param formula   Formula string to write to cell.
2469  * @param format    A pointer to a Format instance or NULL.
2470  *
2471  * @return A #lxw_error code.
2472  *
2473  * The `%worksheet_write_formula()` function writes a formula or function to
2474  * the cell specified by `row` and `column`:
2475  *
2476  * @code
2477  *  worksheet_write_formula(worksheet, 0, 0, "=B3 + 6",                    NULL);
2478  *  worksheet_write_formula(worksheet, 1, 0, "=SIN(PI()/4)",               NULL);
2479  *  worksheet_write_formula(worksheet, 2, 0, "=SUM(A1:A2)",                NULL);
2480  *  worksheet_write_formula(worksheet, 3, 0, "=IF(A3>1,\"Yes\", \"No\")",  NULL);
2481  *  worksheet_write_formula(worksheet, 4, 0, "=AVERAGE(1, 2, 3, 4)",       NULL);
2482  *  worksheet_write_formula(worksheet, 5, 0, "=DATEVALUE(\"1-Jan-2013\")", NULL);
2483  * @endcode
2484  *
2485  * @image html write_formula01.png
2486  *
2487  * The `format` parameter is used to apply formatting to the cell. This
2488  * parameter can be `NULL` to indicate no formatting or it can be a
2489  * @ref format.h "Format" object.
2490  *
2491  * Libxlsxwriter doesn't calculate the value of a formula and instead stores a
2492  * default value of `0`. The correct formula result is displayed in Excel, as
2493  * shown in the example above, since it recalculates the formulas when it loads
2494  * the file. For cases where this is an issue see the
2495  * `worksheet_write_formula_num()` function and the discussion in that section.
2496  *
2497  * Formulas must be written with the US style separator/range operator which
2498  * is a comma (not semi-colon). Therefore a formula with multiple values
2499  * should be written as follows:
2500  *
2501  * @code
2502  *     // OK.
2503  *     worksheet_write_formula(worksheet, 0, 0, "=SUM(1, 2, 3)", NULL);
2504  *
2505  *     // NO. Error on load.
2506  *     worksheet_write_formula(worksheet, 1, 0, "=SUM(1; 2; 3)", NULL);
2507  * @endcode
2508  *
2509  * See also @ref working_with_formulas.
2510  */
2511 lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
2512                                   lxw_row_t row,
2513                                   lxw_col_t col, const char *formula,
2514                                   lxw_format *format);
2515 /**
2516  * @brief Write an array formula to a worksheet cell.
2517  *
2518  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2519  * @param first_row The first row of the range. (All zero indexed.)
2520  * @param first_col The first column of the range.
2521  * @param last_row  The last row of the range.
2522  * @param last_col  The last col of the range.
2523  * @param formula   Array formula to write to cell.
2524  * @param format    A pointer to a Format instance or NULL.
2525  *
2526  * @return A #lxw_error code.
2527  *
2528  * The `%worksheet_write_array_formula()` function writes an array formula to
2529  * a cell range. In Excel an array formula is a formula that performs a
2530  * calculation on a set of values.
2531  *
2532  * In Excel an array formula is indicated by a pair of braces around the
2533  * formula: `{=SUM(A1:B1*A2:B2)}`.
2534  *
2535  * Array formulas can return a single value or a range or values. For array
2536  * formulas that return a range of values you must specify the range that the
2537  * return values will be written to. This is why this function has `first_`
2538  * and `last_` row/column parameters. The RANGE() macro can also be used to
2539  * specify the range:
2540  *
2541  * @code
2542  *     worksheet_write_array_formula(worksheet, 4, 0, 6, 0,     "{=TREND(C5:C7,B5:B7)}", NULL);
2543  *
2544  *     // Same as above using the RANGE() macro.
2545  *     worksheet_write_array_formula(worksheet, RANGE("A5:A7"), "{=TREND(C5:C7,B5:B7)}", NULL);
2546  * @endcode
2547  *
2548  * If the array formula returns a single value then the `first_` and `last_`
2549  * parameters should be the same:
2550  *
2551  * @code
2552  *     worksheet_write_array_formula(worksheet, 1, 0, 1, 0,     "{=SUM(B1:C1*B2:C2)}", NULL);
2553  *     worksheet_write_array_formula(worksheet, RANGE("A2:A2"), "{=SUM(B1:C1*B2:C2)}", NULL);
2554  * @endcode
2555  *
2556  */
2557 lxw_error worksheet_write_array_formula(lxw_worksheet *worksheet,
2558                                         lxw_row_t first_row,
2559                                         lxw_col_t first_col,
2560                                         lxw_row_t last_row,
2561                                         lxw_col_t last_col,
2562                                         const char *formula,
2563                                         lxw_format *format);
2564 
2565 /**
2566  * @brief Write an Excel 365 dynamic array formula to a worksheet range.
2567  *
2568  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2569  * @param first_row The first row of the range. (All zero indexed.)
2570  * @param first_col The first column of the range.
2571  * @param last_row  The last row of the range.
2572  * @param last_col  The last col of the range.
2573  * @param formula   Dynamic Array formula to write to cell.
2574  * @param format    A pointer to a Format instance or NULL.
2575  *
2576  * @return A #lxw_error code.
2577  *
2578  *
2579  * The `%worksheet_write_dynamic_array_formula()` function writes an Excel 365
2580  * dynamic array formula to a cell range. Some examples of functions that
2581  * return dynamic arrays are:
2582  *
2583  * - `FILTER`
2584  * - `RANDARRAY`
2585  * - `SEQUENCE`
2586  * - `SORTBY`
2587  * - `SORT`
2588  * - `UNIQUE`
2589  * - `XLOOKUP`
2590  * - `XMATCH`
2591  *
2592  * Dynamic array formulas and their usage in libxlsxwriter is explained in
2593  * detail @ref ww_formulas_dynamic_arrays. The following is a example usage:
2594  *
2595  * @code
2596  *     worksheet_write_dynamic_array_formula(worksheet, 1, 5, 1, 5,
2597  *                                           "=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
2598  *                                           NULL);
2599  * @endcode
2600  *
2601  * This formula gives the results shown in the image below.
2602  *
2603  * @image html dynamic_arrays02.png
2604  *
2605  * The need for the `_xlfn._xlws.` prefix in the formula is explained in @ref
2606  * ww_formulas_future.
2607  */
2608 lxw_error worksheet_write_dynamic_array_formula(lxw_worksheet *worksheet,
2609                                                 lxw_row_t first_row,
2610                                                 lxw_col_t first_col,
2611                                                 lxw_row_t last_row,
2612                                                 lxw_col_t last_col,
2613                                                 const char *formula,
2614                                                 lxw_format *format);
2615 
2616 /**
2617  * @brief Write an Excel 365 dynamic array formula to a worksheet cell.
2618  *
2619  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2620  * @param row       The zero indexed row number.
2621  * @param col       The zero indexed column number.
2622  * @param formula   Formula string to write to cell.
2623  * @param format    A pointer to a Format instance or NULL.
2624  *
2625  * @return A #lxw_error code.
2626  *
2627  * The `%worksheet_write_dynamic_formula()` function is similar to the
2628  * `worksheet_write_dynamic_array_formula()` function, shown above, except
2629  * that it writes a dynamic array formula to a single cell, rather than a
2630  * range. This is a syntactic shortcut since the array range isn't generally
2631  * known for a dynamic range and specifying the initial cell is sufficient for
2632  * Excel, as shown in the example below:
2633  *
2634  * @code
2635  *     worksheet_write_dynamic_formula(worksheet, 7, 1,
2636  *                                     "=_xlfn._xlws.SORT(_xlfn.UNIQUE(B2:B17))",
2637  *                                     NULL);
2638  * @endcode
2639  *
2640  * This formula gives the following result:
2641  *
2642  * @image html dynamic_arrays01.png
2643  *
2644  * The need for the `_xlfn.` and `_xlfn._xlws.` prefixes in the formula is
2645  * explained in @ref ww_formulas_future.
2646  */
2647 lxw_error worksheet_write_dynamic_formula(lxw_worksheet *worksheet,
2648                                           lxw_row_t row,
2649                                           lxw_col_t col,
2650                                           const char *formula,
2651                                           lxw_format *format);
2652 
2653 lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
2654                                             lxw_row_t first_row,
2655                                             lxw_col_t first_col,
2656                                             lxw_row_t last_row,
2657                                             lxw_col_t last_col,
2658                                             const char *formula,
2659                                             lxw_format *format,
2660                                             double result);
2661 
2662 lxw_error worksheet_write_dynamic_array_formula_num(lxw_worksheet *worksheet,
2663                                                     lxw_row_t first_row,
2664                                                     lxw_col_t first_col,
2665                                                     lxw_row_t last_row,
2666                                                     lxw_col_t last_col,
2667                                                     const char *formula,
2668                                                     lxw_format *format,
2669                                                     double result);
2670 
2671 lxw_error worksheet_write_dynamic_formula_num(lxw_worksheet *worksheet,
2672                                               lxw_row_t row,
2673                                               lxw_col_t col,
2674                                               const char *formula,
2675                                               lxw_format *format,
2676                                               double result);
2677 
2678 /**
2679  * @brief Write a date or time to a worksheet cell.
2680  *
2681  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2682  * @param row       The zero indexed row number.
2683  * @param col       The zero indexed column number.
2684  * @param datetime  The datetime to write to the cell.
2685  * @param format    A pointer to a Format instance or NULL.
2686  *
2687  * @return A #lxw_error code.
2688  *
2689  * The `%worksheet_write_datetime()` function can be used to write a date or
2690  * time to the cell specified by `row` and `column`:
2691  *
2692  * @dontinclude dates_and_times02.c
2693  * @skip include
2694  * @until num_format
2695  * @skip Feb
2696  * @until }
2697  *
2698  * The `format` parameter should be used to apply formatting to the cell using
2699  * a @ref format.h "Format" object as shown above. Without a date format the
2700  * datetime will appear as a number only.
2701  *
2702  * See @ref working_with_dates for more information about handling dates and
2703  * times in libxlsxwriter.
2704  */
2705 lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
2706                                    lxw_row_t row,
2707                                    lxw_col_t col, lxw_datetime *datetime,
2708                                    lxw_format *format);
2709 
2710 /**
2711  * @brief Write a Unix datetime to a worksheet cell.
2712  *
2713  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2714  * @param row       The zero indexed row number.
2715  * @param col       The zero indexed column number.
2716  * @param unixtime  The Unix datetime to write to the cell.
2717  * @param format    A pointer to a Format instance or NULL.
2718  *
2719  * @return A #lxw_error code.
2720  *
2721  * The `%worksheet_write_unixtime()` function can be used to write dates and
2722  * times in Unix date format to the cell specified by `row` and
2723  * `column`. [Unix Time](https://en.wikipedia.org/wiki/Unix_time) which is a
2724  * common integer time format. It is defined as the number of seconds since
2725  * the Unix epoch (1970-01-01 00:00 UTC). Negative values can also be used for
2726  * dates prior to 1970:
2727  *
2728  * @dontinclude dates_and_times03.c
2729  * @skip 1970
2730  * @until 2208988800
2731  *
2732  * The `format` parameter should be used to apply formatting to the cell using
2733  * a @ref format.h "Format" object as shown above. Without a date format the
2734  * datetime will appear as a number only.
2735  *
2736  * The output from this code sample is:
2737  *
2738  * @image html date_example03.png
2739  *
2740  * Unixtime is generally represented with a 32 bit `time_t` type which has a
2741  * range of approximately 1900-12-14 to 2038-01-19. To access the full Excel
2742  * date range of 1900-01-01 to 9999-12-31 this function uses a 64 bit
2743  * parameter.
2744  *
2745  * See @ref working_with_dates for more information about handling dates and
2746  * times in libxlsxwriter.
2747  */
2748 lxw_error worksheet_write_unixtime(lxw_worksheet *worksheet,
2749                                    lxw_row_t row,
2750                                    lxw_col_t col, int64_t unixtime,
2751                                    lxw_format *format);
2752 
2753 /**
2754  *
2755  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2756  * @param row       The zero indexed row number.
2757  * @param col       The zero indexed column number.
2758  * @param url       The url to write to the cell.
2759  * @param format    A pointer to a Format instance or NULL.
2760  *
2761  * @return A #lxw_error code.
2762  *
2763  *
2764  * The `%worksheet_write_url()` function is used to write a URL/hyperlink to a
2765  * worksheet cell specified by `row` and `column`.
2766  *
2767  * @code
2768  *     worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", NULL);
2769  * @endcode
2770  *
2771  * @image html hyperlinks_short.png
2772  *
2773  * The `format` parameter is used to apply formatting to the cell. This
2774  * parameter can be `NULL`, in which case the default Excel blue underlined
2775  * hyperlink style will be used. If required a user defined @ref format.h
2776  * "Format" object can be used:
2777  * underline:
2778  *
2779  * @code
2780  *    lxw_format *url_format   = workbook_add_format(workbook);
2781  *
2782  *    format_set_underline (url_format, LXW_UNDERLINE_SINGLE);
2783  *    format_set_font_color(url_format, LXW_COLOR_RED);
2784  *
2785  * @endcode
2786  *
2787  * The usual web style URI's are supported: `%http://`, `%https://`, `%ftp://`
2788  * and `mailto:` :
2789  *
2790  * @code
2791  *     worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/",     NULL);
2792  *     worksheet_write_url(worksheet, 1, 0, "http://www.python.org/",    NULL);
2793  *     worksheet_write_url(worksheet, 2, 0, "https://www.python.org/",   NULL);
2794  *     worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", NULL);
2795  *
2796  * @endcode
2797  *
2798  * An Excel hyperlink is comprised of two elements: the displayed string and
2799  * the non-displayed link. By default the displayed string is the same as the
2800  * link. However, it is possible to overwrite it with any other
2801  * `libxlsxwriter` type using the appropriate `worksheet_write_*()`
2802  * function. The most common case is to overwrite the displayed link text with
2803  * another string. To do this we must also match the default URL format using
2804  * `workbook_get_default_url_format()`:
2805  *
2806  * @code
2807  *     // Write a hyperlink with the default blue underline format.
2808  *     worksheet_write_url(worksheet, 2, 0, "http://libxlsxwriter.github.io", NULL);
2809  *
2810  *     // Get the default url format.
2811  *     lxw_format *url_format = workbook_get_default_url_format(workbook);
2812  *
2813  *     // Overwrite the hyperlink with a user defined string and default format.
2814  *     worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
2815  * @endcode
2816  *
2817  * @image html hyperlinks_short2.png
2818  *
2819  * Two local URIs are supported: `internal:` and `external:`. These are used
2820  * for hyperlinks to internal worksheet references or external workbook and
2821  * worksheet references:
2822  *
2823  * @code
2824  *     worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1",                NULL);
2825  *     worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2",                NULL);
2826  *     worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2",             NULL);
2827  *     worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1",          NULL);
2828  *     worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx",       NULL);
2829  *     worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1",   NULL);
2830  *     worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx",             NULL);
2831  *     worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1",   NULL);
2832  *     worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
2833  *
2834  * @endcode
2835  *
2836  * Worksheet references are typically of the form `Sheet1!A1`. You can also
2837  * link to a worksheet range using the standard Excel notation:
2838  * `Sheet1!A1:B2`.
2839  *
2840  * In external links the workbook and worksheet name must be separated by the
2841  * `#` character:
2842  *
2843  * @code
2844  *     worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1",   NULL);
2845  * @endcode
2846  *
2847  * You can also link to a named range in the target worksheet: For example say
2848  * you have a named range called `my_name` in the workbook `c:\temp\foo.xlsx`
2849  * you could link to it as follows:
2850  *
2851  * @code
2852  *     worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", NULL);
2853  *
2854  * @endcode
2855  *
2856  * Excel requires that worksheet names containing spaces or non alphanumeric
2857  * characters are single quoted as follows:
2858  *
2859  * @code
2860  *     worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", NULL);
2861  * @endcode
2862  *
2863  * Links to network files are also supported. Network files normally begin
2864  * with two back slashes as follows `\\NETWORK\etc`. In order to represent
2865  * this in a C string literal the backslashes should be escaped:
2866  * @code
2867  *     worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
2868  * @endcode
2869  *
2870  *
2871  * Alternatively, you can use Unix style forward slashes. These are
2872  * translated internally to backslashes:
2873  *
2874  * @code
2875  *     worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx",     NULL);
2876  *     worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", NULL);
2877  *
2878  * @endcode
2879  *
2880  *
2881  * **Note:**
2882  *
2883  *    libxlsxwriter will escape the following characters in URLs as required
2884  *    by Excel: `\s " < > \ [ ]  ^ { }`. Existing URL `%%xx` style escapes in
2885  *    the string are ignored to allow for user-escaped strings.
2886  *
2887  * **Note:**
2888  *
2889  *    The maximum allowable URL length in recent versions of Excel is 2079
2890  *    characters. In older versions of Excel (and libxlsxwriter <= 0.8.8) the
2891  *    limit was 255 characters.
2892  */
2893 lxw_error worksheet_write_url(lxw_worksheet *worksheet,
2894                               lxw_row_t row,
2895                               lxw_col_t col, const char *url,
2896                               lxw_format *format);
2897 
2898  /* Don't document for now since the string option can be achieved by a
2899   * subsequent cell worksheet_write() as shown in the docs, and the
2900   * tooltip option isn't very useful. */
2901 lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
2902                                   lxw_row_t row_num,
2903                                   lxw_col_t col_num, const char *url,
2904                                   lxw_format *format, const char *string,
2905                                   const char *tooltip);
2906 
2907 /**
2908  * @brief Write a formatted boolean worksheet cell.
2909  *
2910  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2911  * @param row       The zero indexed row number.
2912  * @param col       The zero indexed column number.
2913  * @param value     The boolean value to write to the cell.
2914  * @param format    A pointer to a Format instance or NULL.
2915  *
2916  * @return A #lxw_error code.
2917  *
2918  * Write an Excel boolean to the cell specified by `row` and `column`:
2919  *
2920  * @code
2921  *     worksheet_write_boolean(worksheet, 2, 2, 0, my_format);
2922  * @endcode
2923  *
2924  */
2925 lxw_error worksheet_write_boolean(lxw_worksheet *worksheet,
2926                                   lxw_row_t row, lxw_col_t col,
2927                                   int value, lxw_format *format);
2928 
2929 /**
2930  * @brief Write a formatted blank worksheet cell.
2931  *
2932  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2933  * @param row       The zero indexed row number.
2934  * @param col       The zero indexed column number.
2935  * @param format    A pointer to a Format instance or NULL.
2936  *
2937  * @return A #lxw_error code.
2938  *
2939  * Write a blank cell specified by `row` and `column`:
2940  *
2941  * @code
2942  *     worksheet_write_blank(worksheet, 1, 1, border_format);
2943  * @endcode
2944  *
2945  * This function is used to add formatting to a cell which doesn't contain a
2946  * string or number value.
2947  *
2948  * Excel differentiates between an "Empty" cell and a "Blank" cell. An Empty
2949  * cell is a cell which doesn't contain data or formatting whilst a Blank cell
2950  * doesn't contain data but does contain formatting. Excel stores Blank cells
2951  * but ignores Empty cells.
2952  *
2953  * As such, if you write an empty cell without formatting it is ignored.
2954  *
2955  */
2956 lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
2957                                 lxw_row_t row, lxw_col_t col,
2958                                 lxw_format *format);
2959 
2960 /**
2961  * @brief Write a formula to a worksheet cell with a user defined numeric
2962  *        result.
2963  *
2964  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
2965  * @param row       The zero indexed row number.
2966  * @param col       The zero indexed column number.
2967  * @param formula   Formula string to write to cell.
2968  * @param format    A pointer to a Format instance or NULL.
2969  * @param result    A user defined numeric result for the formula.
2970  *
2971  * @return A #lxw_error code.
2972  *
2973  * The `%worksheet_write_formula_num()` function writes a formula or Excel
2974  * function to the cell specified by `row` and `column` with a user defined
2975  * numeric result:
2976  *
2977  * @code
2978  *     // Required as a workaround only.
2979  *     worksheet_write_formula_num(worksheet, 0, 0, "=1 + 2", NULL, 3);
2980  * @endcode
2981  *
2982  * Libxlsxwriter doesn't calculate the value of a formula and instead stores
2983  * the value `0` as the formula result. It then sets a global flag in the XLSX
2984  * file to say that all formulas and functions should be recalculated when the
2985  * file is opened.
2986  *
2987  * This is the method recommended in the Excel documentation and in general it
2988  * works fine with spreadsheet applications.
2989  *
2990  * However, applications that don't have a facility to calculate formulas,
2991  * such as Excel Viewer, or some mobile applications will only display the `0`
2992  * results.
2993  *
2994  * If required, the `%worksheet_write_formula_num()` function can be used to
2995  * specify a formula and its result.
2996  *
2997  * This function is rarely required and is only provided for compatibility
2998  * with some third party applications. For most applications the
2999  * worksheet_write_formula() function is the recommended way of writing
3000  * formulas.
3001  *
3002  * See also @ref working_with_formulas.
3003  */
3004 lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
3005                                       lxw_row_t row,
3006                                       lxw_col_t col,
3007                                       const char *formula,
3008                                       lxw_format *format, double result);
3009 
3010 /**
3011  * @brief Write a formula to a worksheet cell with a user defined string
3012  *        result.
3013  *
3014  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3015  * @param row       The zero indexed row number.
3016  * @param col       The zero indexed column number.
3017  * @param formula   Formula string to write to cell.
3018  * @param format    A pointer to a Format instance or NULL.
3019  * @param result    A user defined string result for the formula.
3020  *
3021  * @return A #lxw_error code.
3022  *
3023  * The `%worksheet_write_formula_str()` function writes a formula or Excel
3024  * function to the cell specified by `row` and `column` with a user defined
3025  * string result:
3026  *
3027  * @code
3028  *     // The example formula is A & B -> AB.
3029  *     worksheet_write_formula_str(worksheet, 0, 0, "=\"A\" & \"B\"", NULL, "AB");
3030  * @endcode
3031  *
3032  * The `%worksheet_write_formula_str()` function is similar to the
3033  * `%worksheet_write_formula_num()` function except it writes a string result
3034  * instead or a numeric result. See `worksheet_write_formula_num()`  for more
3035  * details on why/when these functions are required.
3036  *
3037  * One place where the `%worksheet_write_formula_str()` function may be required
3038  * is to specify an empty result which will force a recalculation of the formula
3039  * when loaded in LibreOffice.
3040  *
3041  * @code
3042  *     worksheet_write_formula_str(worksheet, 0, 0, "=Sheet1!$A$1", NULL, "");
3043  * @endcode
3044  *
3045  * See the FAQ @ref faq_formula_zero.
3046  *
3047  * See also @ref working_with_formulas.
3048  */
3049 lxw_error worksheet_write_formula_str(lxw_worksheet *worksheet,
3050                                       lxw_row_t row,
3051                                       lxw_col_t col,
3052                                       const char *formula,
3053                                       lxw_format *format, const char *result);
3054 
3055 /**
3056  * @brief Write a "Rich" multi-format string to a worksheet cell.
3057  *
3058  * @param worksheet   Pointer to a lxw_worksheet instance to be updated.
3059  * @param row         The zero indexed row number.
3060  * @param col         The zero indexed column number.
3061  * @param rich_string An array of format/string lxw_rich_string_tuple fragments.
3062  * @param format      A pointer to a Format instance or NULL.
3063  *
3064  * @return A #lxw_error code.
3065  *
3066  * The `%worksheet_write_rich_string()` function is used to write strings with
3067  * multiple formats. For example to write the string 'This is **bold**
3068  * and this is *italic*' you would use the following:
3069  *
3070  * @code
3071  *     lxw_format *bold = workbook_add_format(workbook);
3072  *     format_set_bold(bold);
3073  *
3074  *     lxw_format *italic = workbook_add_format(workbook);
3075  *     format_set_italic(italic);
3076  *
3077  *     lxw_rich_string_tuple fragment11 = {.format = NULL,   .string = "This is "     };
3078  *     lxw_rich_string_tuple fragment12 = {.format = bold,   .string = "bold"         };
3079  *     lxw_rich_string_tuple fragment13 = {.format = NULL,   .string = " and this is "};
3080  *     lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic"       };
3081  *
3082  *     lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
3083  *                                              &fragment13, &fragment14, NULL};
3084  *
3085  *     worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
3086  *
3087  * @endcode
3088  *
3089  * @image html rich_strings_small.png
3090  *
3091  * The basic rule is to break the string into fragments and put a lxw_format
3092  * object before the fragment that you want to format. So if we look at the
3093  * above example again:
3094  *
3095  * This is **bold** and this is *italic*
3096  *
3097  * The would be broken down into 4 fragments:
3098  *
3099  *      default: |This is |
3100  *      bold:    |bold|
3101  *      default: | and this is |
3102  *      italic:  |italic|
3103  *
3104  * This in then converted to the lxw_rich_string_tuple fragments shown in the
3105  * example above. For the default format we use `NULL`.
3106  *
3107  * The fragments are passed to `%worksheet_write_rich_string()` as a `NULL`
3108  * terminated array:
3109  *
3110  * @code
3111  *     lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
3112  *                                              &fragment13, &fragment14, NULL};
3113  *
3114  *     worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
3115  *
3116  * @endcode
3117  *
3118  * **Note**:
3119  * Excel doesn't allow the use of two consecutive formats in a rich string or
3120  * an empty string fragment. For either of these conditions a warning is
3121  * raised and the input to `%worksheet_write_rich_string()` is ignored.
3122  *
3123  */
3124 lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
3125                                       lxw_row_t row,
3126                                       lxw_col_t col,
3127                                       lxw_rich_string_tuple *rich_string[],
3128                                       lxw_format *format);
3129 
3130 /**
3131  * @brief Write a comment to a worksheet cell.
3132  *
3133  * @param worksheet   Pointer to a lxw_worksheet instance to be updated.
3134  * @param row         The zero indexed row number.
3135  * @param col         The zero indexed column number.
3136  * @param string      The comment string to be written.
3137  *
3138  * @return A #lxw_error code.
3139  *
3140  * The `%worksheet_write_comment()` function is used to add a comment to a
3141  * cell. A comment is indicated in Excel by a small red triangle in the upper
3142  * right-hand corner of the cell. Moving the cursor over the red triangle will
3143  * reveal the comment.
3144  *
3145  * The following example shows how to add a comment to a cell:
3146  *
3147  * @code
3148  *     worksheet_write_comment(worksheet, 0, 0, "This is a comment");
3149  * @endcode
3150  *
3151  * @image html comments1.png
3152  *
3153  * See also @ref working_with_comments
3154  *
3155  */
3156 lxw_error worksheet_write_comment(lxw_worksheet *worksheet,
3157                                   lxw_row_t row, lxw_col_t col,
3158                                   const char *string);
3159 
3160 /**
3161  * @brief Write a comment to a worksheet cell with options.
3162  *
3163  * @param worksheet   Pointer to a lxw_worksheet instance to be updated.
3164  * @param row         The zero indexed row number.
3165  * @param col         The zero indexed column number.
3166  * @param string      The comment string to be written.
3167  * @param options     #lxw_comment_options to control position and format
3168  *                    of the comment.
3169  *
3170  * @return A #lxw_error code.
3171  *
3172  * The `%worksheet_write_comment_opt()` function is used to add a comment to a
3173  * cell with option that control the position, format and metadata of the
3174  * comment. A comment is indicated in Excel by a small red triangle in the
3175  * upper right-hand corner of the cell. Moving the cursor over the red
3176  * triangle will reveal the comment.
3177  *
3178  * The following example shows how to add a comment to a cell with options:
3179  *
3180  * @code
3181  *     lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_VISIBLE};
3182  *
3183  *     worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello.", &options);
3184  * @endcode
3185  *
3186  * The following options are available in #lxw_comment_options:
3187  *
3188  * - `author`
3189  * - `visible`
3190  * - `width`
3191  * - `height`
3192  * - `x_scale`
3193  * - `y_scale`
3194  * - `color`
3195  * - `font_name`
3196  * - `font_size`
3197  * - `start_row`
3198  * - `start_col`
3199  * - `x_offset`
3200  * - `y_offset`
3201  *
3202  * @image html comments2.png
3203  *
3204  * Comment options are explained in detail in the @ref ww_comments_properties
3205  * section of the docs.
3206  */
3207 lxw_error worksheet_write_comment_opt(lxw_worksheet *worksheet,
3208                                       lxw_row_t row, lxw_col_t col,
3209                                       const char *string,
3210                                       lxw_comment_options *options);
3211 
3212 /**
3213  * @brief Set the properties for a row of cells.
3214  *
3215  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3216  * @param row       The zero indexed row number.
3217  * @param height    The row height, in character units.
3218  * @param format    A pointer to a Format instance or NULL.
3219  *
3220  * @return A #lxw_error code.
3221  *
3222  * The `%worksheet_set_row()` function is used to change the default
3223  * properties of a row. The most common use for this function is to change the
3224  * height of a row:
3225  *
3226  * @code
3227  *     // Set the height of Row 1 to 20.
3228  *     worksheet_set_row(worksheet, 0, 20, NULL);
3229  * @endcode
3230  *
3231  * The height is specified in character units. To specify the height in pixels
3232  * use the `worksheet_set_row_pixels()` function.
3233  *
3234  * The other common use for `%worksheet_set_row()` is to set the a @ref
3235  * format.h "Format" for all cells in the row:
3236  *
3237  * @code
3238  *     lxw_format *bold = workbook_add_format(workbook);
3239  *     format_set_bold(bold);
3240  *
3241  *     // Set the header row to bold.
3242  *     worksheet_set_row(worksheet, 0, 15, bold);
3243  * @endcode
3244  *
3245  * If you wish to set the format of a row without changing the height you can
3246  * pass the default row height of #LXW_DEF_ROW_HEIGHT = 15:
3247  *
3248  * @code
3249  *     worksheet_set_row(worksheet, 0, LXW_DEF_ROW_HEIGHT, format);
3250  *     worksheet_set_row(worksheet, 0, 15, format); // Same as above.
3251  * @endcode
3252  *
3253  * The `format` parameter will be applied to any cells in the row that don't
3254  * have a format. As with Excel the row format is overridden by an explicit
3255  * cell format. For example:
3256  *
3257  * @code
3258  *     // Row 1 has format1.
3259  *     worksheet_set_row(worksheet, 0, 15, format1);
3260  *
3261  *     // Cell A1 in Row 1 defaults to format1.
3262  *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
3263  *
3264  *     // Cell B1 in Row 1 keeps format2.
3265  *     worksheet_write_string(worksheet, 0, 1, "Hello", format2);
3266  * @endcode
3267  *
3268  */
3269 lxw_error worksheet_set_row(lxw_worksheet *worksheet,
3270                             lxw_row_t row, double height, lxw_format *format);
3271 
3272 /**
3273  * @brief Set the properties for a row of cells.
3274  *
3275  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3276  * @param row       The zero indexed row number.
3277  * @param height    The row height.
3278  * @param format    A pointer to a Format instance or NULL.
3279  * @param options   Optional row parameters: hidden, level, collapsed.
3280  *
3281  * @return A #lxw_error code.
3282  *
3283  * The `%worksheet_set_row_opt()` function  is the same as
3284  *  `worksheet_set_row()` with an additional `options` parameter.
3285  *
3286  * The `options` parameter is a #lxw_row_col_options struct. It has the
3287  * following members:
3288  *
3289  * - `hidden`
3290  * - `level`
3291  * - `collapsed`
3292  *
3293  * The `"hidden"` option is used to hide a row. This can be used, for
3294  * example, to hide intermediary steps in a complicated calculation:
3295  *
3296  * @code
3297  *     lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
3298  *
3299  *     // Hide the fourth and fifth (zero indexed) rows.
3300  *     worksheet_set_row_opt(worksheet, 3,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3301  *     worksheet_set_row_opt(worksheet, 4,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3302  *
3303  * @endcode
3304  *
3305  * @image html hide_row_col2.png
3306  *
3307  * The `"hidden"`, `"level"`,  and `"collapsed"`, options can also be used to
3308  * create Outlines and Grouping. See @ref working_with_outlines.
3309  *
3310  * @code
3311  *     // The option structs with the outline level set.
3312  *     lxw_row_col_options options1 = {.hidden = 0, .level = 2, .collapsed = 0};
3313  *     lxw_row_col_options options2 = {.hidden = 0, .level = 1, .collapsed = 0};
3314  *
3315  *
3316  *     // Set the row options with the outline level.
3317  *     worksheet_set_row_opt(worksheet, 1,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3318  *     worksheet_set_row_opt(worksheet, 2,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3319  *     worksheet_set_row_opt(worksheet, 3,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3320  *     worksheet_set_row_opt(worksheet, 4,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3321  *     worksheet_set_row_opt(worksheet, 5,  LXW_DEF_ROW_HEIGHT, NULL, &options2);
3322  *
3323  *     worksheet_set_row_opt(worksheet, 6,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3324  *     worksheet_set_row_opt(worksheet, 7,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3325  *     worksheet_set_row_opt(worksheet, 8,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3326  *     worksheet_set_row_opt(worksheet, 9,  LXW_DEF_ROW_HEIGHT, NULL, &options1);
3327  *     worksheet_set_row_opt(worksheet, 10, LXW_DEF_ROW_HEIGHT, NULL, &options2);
3328  * @endcode
3329  *
3330  * @image html outline1.png
3331  *
3332  */
3333 lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
3334                                 lxw_row_t row,
3335                                 double height,
3336                                 lxw_format *format,
3337                                 lxw_row_col_options *options);
3338 
3339 /**
3340  * @brief Set the properties for a row of cells, with the height in pixels.
3341  *
3342  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3343  * @param row       The zero indexed row number.
3344  * @param pixels    The row height in pixels.
3345  * @param format    A pointer to a Format instance or NULL.
3346  *
3347  * @return A #lxw_error code.
3348  *
3349  * The `%worksheet_set_row_pixels()` function is the same as the
3350  * `worksheet_set_row()` function except that the height can be set in pixels
3351  *
3352  * @code
3353  *     // Set the height of Row 1 to 20 pixels.
3354  *     worksheet_set_row_pixels(worksheet, 0, 20, NULL);
3355  * @endcode
3356  *
3357  * If you wish to set the format of a row without changing the height you can
3358  * pass the default row height in pixels: #LXW_DEF_ROW_HEIGHT_PIXELS.
3359  */
3360 lxw_error worksheet_set_row_pixels(lxw_worksheet *worksheet,
3361                                    lxw_row_t row, uint32_t pixels,
3362                                    lxw_format *format);
3363 /**
3364  * @brief Set the properties for a row of cells, with the height in pixels.
3365  *
3366  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3367  * @param row       The zero indexed row number.
3368  * @param pixels    The row height in pixels.
3369  * @param format    A pointer to a Format instance or NULL.
3370  * @param options   Optional row parameters: hidden, level, collapsed.
3371  *
3372  * @return A #lxw_error code.
3373  *
3374  * The `%worksheet_set_row_pixels_opt()` function is the same as the
3375  * `worksheet_set_row_opt()` function except that the height can be set in
3376  * pixels.
3377  *
3378  */
3379 lxw_error worksheet_set_row_pixels_opt(lxw_worksheet *worksheet,
3380                                        lxw_row_t row,
3381                                        uint32_t pixels,
3382                                        lxw_format *format,
3383                                        lxw_row_col_options *options);
3384 
3385 /**
3386  * @brief Set the properties for one or more columns of cells.
3387  *
3388  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3389  * @param first_col The zero indexed first column.
3390  * @param last_col  The zero indexed last column.
3391  * @param width     The width of the column(s).
3392  * @param format    A pointer to a Format instance or NULL.
3393  *
3394  * @return A #lxw_error code.
3395  *
3396  * The `%worksheet_set_column()` function can be used to change the default
3397  * properties of a single column or a range of columns:
3398  *
3399  * @code
3400  *     // Width of columns B:D set to 30.
3401  *     worksheet_set_column(worksheet, 1, 3, 30, NULL);
3402  *
3403  * @endcode
3404  *
3405  * If `%worksheet_set_column()` is applied to a single column the value of
3406  * `first_col` and `last_col` should be the same:
3407  *
3408  * @code
3409  *     // Width of column B set to 30.
3410  *     worksheet_set_column(worksheet, 1, 1, 30, NULL);
3411  *
3412  * @endcode
3413  *
3414  * It is also possible, and generally clearer, to specify a column range using
3415  * the form of `COLS()` macro:
3416  *
3417  * @code
3418  *     worksheet_set_column(worksheet, 4, 4, 20, NULL);
3419  *     worksheet_set_column(worksheet, 5, 8, 30, NULL);
3420  *
3421  *     // Same as the examples above but clearer.
3422  *     worksheet_set_column(worksheet, COLS("E:E"), 20, NULL);
3423  *     worksheet_set_column(worksheet, COLS("F:H"), 30, NULL);
3424  *
3425  * @endcode
3426  *
3427  * The `width` parameter sets the column width in the same units used by Excel
3428  * which is: the number of characters in the default font. The default width
3429  * is 8.43 in the default font of Calibri 11. The actual relationship between
3430  * a string width and a column width in Excel is complex. See the
3431  * [following explanation of column widths](https://support.microsoft.com/en-us/kb/214123)
3432  * from the Microsoft support documentation for more details. To set the width
3433  * in pixels use the `worksheet_set_column_pixels()` function.
3434  *
3435  * There is no way to specify "AutoFit" for a column in the Excel file
3436  * format. This feature is only available at runtime from within Excel. It is
3437  * possible to simulate "AutoFit" in your application by tracking the maximum
3438  * width of the data in the column as your write it and then adjusting the
3439  * column width at the end.
3440  *
3441  * As usual the @ref format.h `format` parameter is optional. If you wish to
3442  * set the format without changing the width you can pass a default column
3443  * width of #LXW_DEF_COL_WIDTH = 8.43:
3444  *
3445  * @code
3446  *     lxw_format *bold = workbook_add_format(workbook);
3447  *     format_set_bold(bold);
3448  *
3449  *     // Set the first column to bold.
3450  *     worksheet_set_column(worksheet, 0, 0, LXW_DEF_COL_WIDTH, bold);
3451  * @endcode
3452  *
3453  * The `format` parameter will be applied to any cells in the column that
3454  * don't have a format. For example:
3455  *
3456  * @code
3457  *     // Column 1 has format1.
3458  *     worksheet_set_column(worksheet, COLS("A:A"), 8.43, format1);
3459  *
3460  *     // Cell A1 in column 1 defaults to format1.
3461  *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
3462  *
3463  *     // Cell A2 in column 1 keeps format2.
3464  *     worksheet_write_string(worksheet, 1, 0, "Hello", format2);
3465  * @endcode
3466  *
3467  * As in Excel a row format takes precedence over a default column format:
3468  *
3469  * @code
3470  *     // Row 1 has format1.
3471  *     worksheet_set_row(worksheet, 0, 15, format1);
3472  *
3473  *     // Col 1 has format2.
3474  *     worksheet_set_column(worksheet, COLS("A:A"), 8.43, format2);
3475  *
3476  *     // Cell A1 defaults to format1, the row format.
3477  *     worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
3478  *
3479  *    // Cell A2 keeps format2, the column format.
3480  *     worksheet_write_string(worksheet, 1, 0, "Hello", NULL);
3481  * @endcode
3482  */
3483 lxw_error worksheet_set_column(lxw_worksheet *worksheet,
3484                                lxw_col_t first_col,
3485                                lxw_col_t last_col,
3486                                double width, lxw_format *format);
3487 
3488 /**
3489  * @brief Set the properties for one or more columns of cells with options.
3490  *
3491  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3492  * @param first_col The zero indexed first column.
3493  * @param last_col  The zero indexed last column.
3494  * @param width     The width of the column(s).
3495  * @param format    A pointer to a Format instance or NULL.
3496  * @param options   Optional row parameters: hidden, level, collapsed.
3497  *
3498  * @return A #lxw_error code.
3499  *
3500  * The `%worksheet_set_column_opt()` function  is the same as
3501  * `worksheet_set_column()` with an additional `options` parameter.
3502  *
3503  * The `options` parameter is a #lxw_row_col_options struct. It has the
3504  * following members:
3505  *
3506  * - `hidden`
3507  * - `level`
3508  * - `collapsed`
3509  *
3510  * The `"hidden"` option is used to hide a column. This can be used, for
3511  * example, to hide intermediary steps in a complicated calculation:
3512  *
3513  * @code
3514  *     lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
3515  *
3516  *     worksheet_set_column_opt(worksheet, COLS("D:E"),  LXW_DEF_COL_WIDTH, NULL, &options1);
3517  * @endcode
3518  *
3519  * @image html hide_row_col3.png
3520  *
3521  * The `"hidden"`, `"level"`,  and `"collapsed"`, options can also be used to
3522  * create Outlines and Grouping. See @ref working_with_outlines.
3523  *
3524  * @code
3525  *     lxw_row_col_options options1 = {.hidden = 0, .level = 1, .collapsed = 0};
3526  *
3527  *     worksheet_set_column_opt(worksheet, COLS("B:G"),  5, NULL, &options1);
3528  * @endcode
3529  *
3530  * @image html outline8.png
3531  */
3532 lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
3533                                    lxw_col_t first_col,
3534                                    lxw_col_t last_col,
3535                                    double width,
3536                                    lxw_format *format,
3537                                    lxw_row_col_options *options);
3538 
3539 /**
3540  * @brief Set the properties for one or more columns of cells, with the width
3541  *        in pixels.
3542  *
3543  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3544  * @param first_col The zero indexed first column.
3545  * @param last_col  The zero indexed last column.
3546  * @param pixels    The width of the column(s) in pixels.
3547  * @param format    A pointer to a Format instance or NULL.
3548  *
3549  * @return A #lxw_error code.
3550  *
3551  * The `%worksheet_set_column_pixels()` function is the same as
3552  * `worksheet_set_column()` function except that the width can be set in
3553  * pixels:
3554  *
3555  * @code
3556  *     // Column width set to 75 pixels, the same as 10 character units.
3557  *     worksheet_set_column(worksheet, 5, 5, 75, NULL);
3558  * @endcode
3559  *
3560  * @image html set_column_pixels.png
3561  *
3562  * If you wish to set the format of a column without changing the width you can
3563  * pass the default column width in pixels: #LXW_DEF_COL_WIDTH_PIXELS.
3564  */
3565 lxw_error worksheet_set_column_pixels(lxw_worksheet *worksheet,
3566                                       lxw_col_t first_col,
3567                                       lxw_col_t last_col,
3568                                       uint32_t pixels, lxw_format *format);
3569 
3570 /**
3571  * @brief Set the properties for one or more columns of cells with options,
3572  *        with the width in pixels.
3573  *
3574  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3575  * @param first_col The zero indexed first column.
3576  * @param last_col  The zero indexed last column.
3577  * @param pixels    The width of the column(s) in pixels.
3578  * @param format    A pointer to a Format instance or NULL.
3579  * @param options   Optional row parameters: hidden, level, collapsed.
3580  *
3581  * @return A #lxw_error code.
3582  *
3583  * The `%worksheet_set_column_pixels_opt()` function is the same as the
3584  * `worksheet_set_column_opt()` function except that the width can be set in
3585  * pixels.
3586  *
3587  */
3588 lxw_error worksheet_set_column_pixels_opt(lxw_worksheet *worksheet,
3589                                           lxw_col_t first_col,
3590                                           lxw_col_t last_col,
3591                                           uint32_t pixels,
3592                                           lxw_format *format,
3593                                           lxw_row_col_options *options);
3594 
3595 /**
3596  * @brief Insert an image in a worksheet cell.
3597  *
3598  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3599  * @param row       The zero indexed row number.
3600  * @param col       The zero indexed column number.
3601  * @param filename  The image filename, with path if required.
3602  *
3603  * @return A #lxw_error code.
3604  *
3605  * This function can be used to insert a image into a worksheet. The image can
3606  * be in PNG, JPEG, GIF or BMP format:
3607  *
3608  * @code
3609  *     worksheet_insert_image(worksheet, 2, 1, "logo.png");
3610  * @endcode
3611  *
3612  * @image html insert_image.png
3613  *
3614  * The `worksheet_insert_image_opt()` function takes additional optional
3615  * parameters to position and scale the image, see below.
3616  *
3617  * **Note**:
3618  * The scaling of a image may be affected if is crosses a row that has its
3619  * default height changed due to a font that is larger than the default font
3620  * size or that has text wrapping turned on. To avoid this you should
3621  * explicitly set the height of the row using `worksheet_set_row()` if it
3622  * crosses an inserted image. See @ref working_with_object_positioning.
3623  *
3624  * BMP images are only supported for backward compatibility. In general it is
3625  * best to avoid BMP images since they aren't compressed. If used, BMP images
3626  * must be 24 bit, true color, bitmaps.
3627  */
3628 lxw_error worksheet_insert_image(lxw_worksheet *worksheet,
3629                                  lxw_row_t row, lxw_col_t col,
3630                                  const char *filename);
3631 
3632 /**
3633  * @brief Insert an image in a worksheet cell, with options.
3634  *
3635  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3636  * @param row       The zero indexed row number.
3637  * @param col       The zero indexed column number.
3638  * @param filename  The image filename, with path if required.
3639  * @param options   Optional image parameters.
3640  *
3641  * @return A #lxw_error code.
3642  *
3643  * The `%worksheet_insert_image_opt()` function is like
3644  * `worksheet_insert_image()` function except that it takes an optional
3645  * #lxw_image_options struct with the following members/options:
3646  *
3647  * - `x_offset`: Offset from the left of the cell in pixels.
3648  * - `y_offset`: Offset from the top of the cell in pixels.
3649  * - `x_scale`: X scale of the image as a decimal.
3650  * - `y_scale`: Y scale of the image as a decimal.
3651  * - `object_position`: See @ref working_with_object_positioning.
3652  * - `description`: Optional description or "Alt text" for the image.
3653  * - `decorative`: Optional parameter to mark image as decorative.
3654  * - `url`: Add an optional hyperlink to the image.
3655  * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
3656  *
3657  * For example, to scale and position the image:
3658  *
3659  * @code
3660  *     lxw_image_options options = {.x_offset = 30,  .y_offset = 10,
3661  *                                 .x_scale  = 0.5, .y_scale  = 0.5};
3662  *
3663  *     worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
3664  *
3665  * @endcode
3666  *
3667  * @image html insert_image_opt.png
3668  *
3669  * The `url` field of lxw_image_options can be use to used to add a hyperlink
3670  * to an image:
3671  *
3672  * @code
3673  *     lxw_image_options options = {.url = "https://github.com/jmcnamara"};
3674  *
3675  *     worksheet_insert_image_opt(worksheet, 3, 1, "logo.png", &options);
3676  * @endcode
3677  *
3678  * The supported URL formats are the same as those supported by the
3679  * `worksheet_write_url()` method and the same rules/limits apply.
3680  *
3681  * The `tip` field of lxw_image_options can be use to used to add a mouseover
3682  * tip to the hyperlink:
3683  *
3684  * @code
3685  *      lxw_image_options options = {.url = "https://github.com/jmcnamara",
3686                                      .tip = "GitHub"};
3687  *
3688  *     worksheet_insert_image_opt(worksheet, 4, 1, "logo.png", &options);
3689  * @endcode
3690  *
3691  * @note See the notes about row scaling and BMP images in
3692  * `worksheet_insert_image()` above.
3693  */
3694 lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
3695                                      lxw_row_t row, lxw_col_t col,
3696                                      const char *filename,
3697                                      lxw_image_options *options);
3698 
3699 /**
3700  * @brief Insert an image in a worksheet cell, from a memory buffer.
3701  *
3702  * @param worksheet    Pointer to a lxw_worksheet instance to be updated.
3703  * @param row          The zero indexed row number.
3704  * @param col          The zero indexed column number.
3705  * @param image_buffer Pointer to an array of bytes that holds the image data.
3706  * @param image_size   The size of the array of bytes.
3707  *
3708  * @return A #lxw_error code.
3709  *
3710  * This function can be used to insert a image into a worksheet from a memory
3711  * buffer:
3712  *
3713  * @code
3714  *     worksheet_insert_image_buffer(worksheet, CELL("B3"), image_buffer, image_size);
3715  * @endcode
3716  *
3717  * @image html image_buffer.png
3718  *
3719  * The buffer should be a pointer to an array of unsigned char data with a
3720  * specified size.
3721  *
3722  * See `worksheet_insert_image()` for details about the supported image
3723  * formats, and other image features.
3724  */
3725 lxw_error worksheet_insert_image_buffer(lxw_worksheet *worksheet,
3726                                         lxw_row_t row,
3727                                         lxw_col_t col,
3728                                         const unsigned char *image_buffer,
3729                                         size_t image_size);
3730 
3731 /**
3732  * @brief Insert an image in a worksheet cell, from a memory buffer.
3733  *
3734  * @param worksheet    Pointer to a lxw_worksheet instance to be updated.
3735  * @param row          The zero indexed row number.
3736  * @param col          The zero indexed column number.
3737  * @param image_buffer Pointer to an array of bytes that holds the image data.
3738  * @param image_size   The size of the array of bytes.
3739  * @param options      Optional image parameters.
3740  *
3741  * @return A #lxw_error code.
3742  *
3743  * The `%worksheet_insert_image_buffer_opt()` function is like
3744  * `worksheet_insert_image_buffer()` function except that it takes an optional
3745  * #lxw_image_options struct  * #lxw_image_options struct with the following members/options:
3746  *
3747  * - `x_offset`: Offset from the left of the cell in pixels.
3748  * - `y_offset`: Offset from the top of the cell in pixels.
3749  * - `x_scale`: X scale of the image as a decimal.
3750  * - `y_scale`: Y scale of the image as a decimal.
3751  * - `object_position`: See @ref working_with_object_positioning.
3752  * - `description`: Optional description or "Alt text" for the image.
3753  * - `decorative`: Optional parameter to mark image as decorative.
3754  * - `url`: Add an optional hyperlink to the image.
3755  * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
3756  *
3757  * For example, to scale and position the image:
3758  *
3759  * @code
3760  *     lxw_image_options options = {.x_offset = 32, .y_offset = 4,
3761  *                                  .x_scale  = 2,  .y_scale  = 1};
3762  *
3763  *     worksheet_insert_image_buffer_opt(worksheet, CELL("B3"), image_buffer, image_size, &options);
3764  * @endcode
3765  *
3766  * @image html image_buffer_opt.png
3767  *
3768  * The buffer should be a pointer to an array of unsigned char data with a
3769  * specified size.
3770  *
3771  * See `worksheet_insert_image_buffer_opt()` for details about the supported
3772  * image formats, and other image options.
3773  */
3774 lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
3775                                             lxw_row_t row,
3776                                             lxw_col_t col,
3777                                             const unsigned char *image_buffer,
3778                                             size_t image_size,
3779                                             lxw_image_options *options);
3780 
3781 /**
3782  * @brief Set the background image for a worksheet.
3783  *
3784  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3785  * @param filename  The image filename, with path if required.
3786  *
3787  * @return A #lxw_error code.
3788  *
3789  * The `%worksheet_set_background()` function can be used to set the
3790  * background image for a worksheet:
3791  *
3792  * @code
3793  *      worksheet_set_background(worksheet, "logo.png");
3794  * @endcode
3795  *
3796  * @image html background.png
3797  *
3798  * The ``set_background()`` method supports all the image formats supported by
3799  * `worksheet_insert_image()`.
3800  *
3801  * Some people use this method to add a watermark background to their
3802  * document. However, Microsoft recommends using a header image [to set a
3803  * watermark][watermark]. The choice of method depends on whether you want the
3804  * watermark to be visible in normal viewing mode or just when the file is
3805  * printed. In libxlsxwriter you can get the header watermark effect using
3806  * `worksheet_set_header()`:
3807  *
3808  * @code
3809  *     lxw_header_footer_options header_options = {.image_center = "watermark.png"};
3810  *     worksheet_set_header_opt(worksheet, "&C&G", &header_options);
3811  * @endcode
3812  *
3813  * [watermark]:https://support.microsoft.com/en-us/office/add-a-watermark-in-excel-a372182a-d733-484e-825c-18ddf3edf009
3814  *
3815  */
3816 lxw_error worksheet_set_background(lxw_worksheet *worksheet,
3817                                    const char *filename);
3818 
3819 /**
3820  * @brief Set the background image for a worksheet, from a buffer.
3821  *
3822  * @param worksheet    Pointer to a lxw_worksheet instance to be updated.
3823  * @param image_buffer Pointer to an array of bytes that holds the image data.
3824  * @param image_size   The size of the array of bytes.
3825  *
3826  * @return A #lxw_error code.
3827  *
3828  * This function can be used to insert a background image into a worksheet
3829  * from a memory buffer:
3830  *
3831  * @code
3832  *     worksheet_set_background_buffer(worksheet, image_buffer, image_size);
3833  * @endcode
3834  *
3835  * The buffer should be a pointer to an array of unsigned char data with a
3836  * specified size.
3837  *
3838  * See `worksheet_set_background()` for more details.
3839  *
3840  */
3841 lxw_error worksheet_set_background_buffer(lxw_worksheet *worksheet,
3842                                           const unsigned char *image_buffer,
3843                                           size_t image_size);
3844 
3845 /**
3846  * @brief Insert a chart object into a worksheet.
3847  *
3848  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3849  * @param row       The zero indexed row number.
3850  * @param col       The zero indexed column number.
3851  * @param chart     A #lxw_chart object created via workbook_add_chart().
3852  *
3853  * @return A #lxw_error code.
3854  *
3855  * The `%worksheet_insert_chart()` function can be used to insert a chart into
3856  * a worksheet. The chart object must be created first using the
3857  * `workbook_add_chart()` function and configured using the @ref chart.h
3858  * functions.
3859  *
3860  * @code
3861  *     // Create a chart object.
3862  *     lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
3863  *
3864  *     // Add a data series to the chart.
3865  *     chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$6");
3866  *
3867  *     // Insert the chart into the worksheet.
3868  *     worksheet_insert_chart(worksheet, 0, 2, chart);
3869  * @endcode
3870  *
3871  * @image html chart_working.png
3872  *
3873  * **Note:**
3874  *
3875  * A chart may only be inserted into a worksheet once. If several similar
3876  * charts are required then each one must be created separately with
3877  * `%worksheet_insert_chart()`.
3878  *
3879  */
3880 lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
3881                                  lxw_row_t row, lxw_col_t col,
3882                                  lxw_chart *chart);
3883 
3884 /**
3885  * @brief Insert a chart object into a worksheet, with options.
3886  *
3887  * @param worksheet    Pointer to a lxw_worksheet instance to be updated.
3888  * @param row          The zero indexed row number.
3889  * @param col          The zero indexed column number.
3890  * @param chart        A #lxw_chart object created via workbook_add_chart().
3891  * @param user_options Optional chart parameters.
3892  *
3893  * @return A #lxw_error code.
3894  *
3895  * The `%worksheet_insert_chart_opt()` function is like
3896  * `worksheet_insert_chart()` function except that it takes an optional
3897  * #lxw_chart_options struct to scale and position the chart:
3898  *
3899  * @code
3900  *    lxw_chart_options options = {.x_offset = 30,  .y_offset = 10,
3901  *                                 .x_scale  = 0.5, .y_scale  = 0.75};
3902  *
3903  *    worksheet_insert_chart_opt(worksheet, 0, 2, chart, &options);
3904  *
3905  * @endcode
3906  *
3907  * @image html chart_line_opt.png
3908  *
3909  */
3910 lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
3911                                      lxw_row_t row, lxw_col_t col,
3912                                      lxw_chart *chart,
3913                                      lxw_chart_options *user_options);
3914 
3915 /**
3916  * @brief Merge a range of cells.
3917  *
3918  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3919  * @param first_row The first row of the range. (All zero indexed.)
3920  * @param first_col The first column of the range.
3921  * @param last_row  The last row of the range.
3922  * @param last_col  The last col of the range.
3923  * @param string    String to write to the merged range.
3924  * @param format    A pointer to a Format instance or NULL.
3925  *
3926  * @return A #lxw_error code.
3927  *
3928  * The `%worksheet_merge_range()` function allows cells to be merged together
3929  * so that they act as a single area.
3930  *
3931  * Excel generally merges and centers cells at same time. To get similar
3932  * behavior with libxlsxwriter you need to apply a @ref format.h "Format"
3933  * object with the appropriate alignment:
3934  *
3935  * @code
3936  *     lxw_format *merge_format = workbook_add_format(workbook);
3937  *     format_set_align(merge_format, LXW_ALIGN_CENTER);
3938  *
3939  *     worksheet_merge_range(worksheet, 1, 1, 1, 3, "Merged Range", merge_format);
3940  *
3941  * @endcode
3942  *
3943  * It is possible to apply other formatting to the merged cells as well:
3944  *
3945  * @code
3946  *    format_set_align   (merge_format, LXW_ALIGN_CENTER);
3947  *    format_set_align   (merge_format, LXW_ALIGN_VERTICAL_CENTER);
3948  *    format_set_border  (merge_format, LXW_BORDER_DOUBLE);
3949  *    format_set_bold    (merge_format);
3950  *    format_set_bg_color(merge_format, 0xD7E4BC);
3951  *
3952  *    worksheet_merge_range(worksheet, 2, 1, 3, 3, "Merged Range", merge_format);
3953  *
3954  * @endcode
3955  *
3956  * @image html merge.png
3957  *
3958  * The `%worksheet_merge_range()` function writes a `char*` string using
3959  * `worksheet_write_string()`. In order to write other data types, such as a
3960  * number or a formula, you can overwrite the first cell with a call to one of
3961  * the other write functions. The same Format should be used as was used in
3962  * the merged range.
3963  *
3964  * @code
3965  *    // First write a range with a blank string.
3966  *    worksheet_merge_range (worksheet, 1, 1, 1, 3, "", format);
3967  *
3968  *    // Then overwrite the first cell with a number.
3969  *    worksheet_write_number(worksheet, 1, 1, 123, format);
3970  * @endcode
3971  *
3972  * @note Merged ranges generally don't work in libxlsxwriter when the Workbook
3973  * #lxw_workbook_options `constant_memory` mode is enabled.
3974  */
3975 lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
3976                                 lxw_col_t first_col, lxw_row_t last_row,
3977                                 lxw_col_t last_col, const char *string,
3978                                 lxw_format *format);
3979 
3980 /**
3981  * @brief Set the autofilter area in the worksheet.
3982  *
3983  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
3984  * @param first_row The first row of the range. (All zero indexed.)
3985  * @param first_col The first column of the range.
3986  * @param last_row  The last row of the range.
3987  * @param last_col  The last col of the range.
3988  *
3989  * @return A #lxw_error code.
3990  *
3991  * The `%worksheet_autofilter()` function allows an autofilter to be added to
3992  * a worksheet.
3993  *
3994  * An autofilter is a way of adding drop down lists to the headers of a 2D
3995  * range of worksheet data. This allows users to filter the data based on
3996  * simple criteria so that some data is shown and some is hidden.
3997  *
3998  * @image html autofilter3.png
3999  *
4000  * To add an autofilter to a worksheet:
4001  *
4002  * @code
4003  *     worksheet_autofilter(worksheet, 0, 0, 50, 3);
4004  *
4005  *     // Same as above using the RANGE() macro.
4006  *     worksheet_autofilter(worksheet, RANGE("A1:D51"));
4007  * @endcode
4008  *
4009  * In order to apply a filter condition it is necessary to add filter rules to
4010  * the columns using either the `%worksheet_filter_column()`,
4011  * `%worksheet_filter_column2()` or `%worksheet_filter_list()` functions:
4012  *
4013  * - `worksheet_filter_column()`: filter on a single criterion such as "Column ==
4014  *   East". More complex conditions such as "<=" or ">=" can also be use.
4015  *
4016  * - `worksheet_filter_column2()`: filter on two criteria such as "Column == East
4017  *   or Column == West". Complex conditions can also be used.
4018  *
4019  * - `worksheet_filter_list()`: filter on a list of values such as "Column in (East, West,
4020  *   North)".
4021  *
4022  * These functions are explained below. It isn't sufficient to just specify
4023  * the filter condition. You must also hide any rows that don't match the
4024  * filter condition. See @ref ww_autofilters_data for more details.
4025  *
4026  */
4027 lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
4028                                lxw_col_t first_col, lxw_row_t last_row,
4029                                lxw_col_t last_col);
4030 
4031 /**
4032  * @brief Write a filter rule to an autofilter column.
4033  *
4034  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4035  * @param col       The column in the autofilter that the rule applies to.
4036  * @param rule      The lxw_filter_rule autofilter rule.
4037  *
4038  * @return A #lxw_error code.
4039  *
4040  * The `worksheet_filter_column` function can be used to filter columns in a
4041  * autofilter range based on single rule conditions:
4042  *
4043  * @code
4044  *     lxw_filter_rule filter_rule = {.criteria     = LXW_FILTER_CRITERIA_EQUAL_TO,
4045  *                                    .value_string = "East"};
4046  *
4047  *    worksheet_filter_column(worksheet, 0, &filter_rule);
4048  *@endcode
4049  *
4050  * @image html autofilter4.png
4051  *
4052  * The rules and criteria are explained in more detail in @ref
4053  * ww_autofilters_criteria in @ref working_with_autofilters.
4054  *
4055  * The `col` parameter is a zero indexed column number and must refer to a
4056  * column in an existing autofilter created with `worksheet_autofilter()`.
4057  *
4058  * It isn't sufficient to just specify the filter condition. You must also
4059  * hide any rows that don't match the filter condition. See @ref
4060  * ww_autofilters_data for more details.
4061  */
4062 lxw_error worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col,
4063                                   lxw_filter_rule *rule);
4064 
4065 /**
4066  * @brief Write two filter rules to an autofilter column.
4067  *
4068  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4069  * @param col       The column in the autofilter that the rules applies to.
4070  * @param rule1     First lxw_filter_rule autofilter rule.
4071  * @param rule2     Second lxw_filter_rule autofilter rule.
4072  * @param and_or    A #lxw_filter_operator and/or operator.
4073  *
4074  * @return A #lxw_error code.
4075  *
4076  * The `worksheet_filter_column2` function can be used to filter columns in a autofilter
4077  * range based on two rule conditions:
4078  *
4079  * @code
4080  *     lxw_filter_rule filter_rule1 = {.criteria     = LXW_FILTER_CRITERIA_EQUAL_TO,
4081  *                                     .value_string = "East"};
4082  *
4083  *     lxw_filter_rule filter_rule2 = {.criteria     = LXW_FILTER_CRITERIA_EQUAL_TO,
4084  *                                     .value_string = "South"};
4085  *
4086  *     worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR);
4087  * @endcode
4088  *
4089  * @image html autofilter5.png
4090  *
4091  * The rules and criteria are explained in more detail in @ref
4092  * ww_autofilters_criteria in @ref working_with_autofilters.
4093  *
4094  * The `col` parameter is a zero indexed column number and must refer to a
4095  * column in an existing autofilter created with `worksheet_autofilter()`.
4096  *
4097  * The `and_or` parameter is either "and (LXW_FILTER_AND)" or "or  (LXW_FILTER_OR)".
4098  *
4099  * It isn't sufficient to just specify the filter condition. You must also
4100  * hide any rows that don't match the filter condition. See @ref
4101  * ww_autofilters_data for more details.
4102  */
4103 lxw_error worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col,
4104                                    lxw_filter_rule *rule1,
4105                                    lxw_filter_rule *rule2, uint8_t and_or);
4106 /**
4107  * @brief Write multiple string filters to an autofilter column.
4108  *
4109  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4110  * @param col       The column in the autofilter that the rules applies to.
4111  * @param list      A NULL terminated array of strings to filter on.
4112  *
4113  * @return A #lxw_error code.
4114  *
4115  * The `worksheet_filter_column_list()` function can be used specify multiple
4116  * string matching criteria. This is a newer type of filter introduced in
4117  * Excel 2007. Prior to that it was only possible to have either 1 or 2 filter
4118  * conditions, such as the ones used by `worksheet_filter_column()` and
4119  * `worksheet_filter_column2()`.
4120  *
4121  * As an example, consider a column that contains data for the months of the
4122  * year. The `%worksheet_filter_list()` function can be used to filter out
4123  * data rows for different months:
4124  *
4125  * @code
4126  *     char* list[] = {"March", "April", "May", NULL};
4127  *
4128  *     worksheet_filter_list(worksheet, 0, list);
4129  * @endcode
4130  *
4131  * @image html autofilter2.png
4132  *
4133  *
4134  * Note, the array must be NULL terminated to indicate the end of the array of
4135  * strings. To filter blanks as part of the list use `Blanks` as a list item:
4136  *
4137  * @code
4138  *     char* list[] = {"March", "April", "May", "Blanks", NULL};
4139  *
4140  *     worksheet_filter_list(worksheet, 0, list);
4141  * @endcode
4142  *
4143  * It isn't sufficient to just specify the filter condition. You must also
4144  * hide any rows that don't match the filter condition. See @ref
4145  * ww_autofilters_data for more details.
4146  */
4147 lxw_error worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col,
4148                                 char **list);
4149 
4150 /**
4151  * @brief Add a data validation to a cell.
4152  *
4153  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4154  * @param row        The zero indexed row number.
4155  * @param col        The zero indexed column number.
4156  * @param validation A #lxw_data_validation object to control the validation.
4157  *
4158  * @return A #lxw_error code.
4159  *
4160  * The `%worksheet_data_validation_cell()` function is used to construct an
4161  * Excel data validation or to limit the user input to a dropdown list of
4162  * values:
4163  *
4164  * @code
4165  *
4166  *    lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
4167  *
4168  *    data_validation->validate       = LXW_VALIDATION_TYPE_INTEGER;
4169  *    data_validation->criteria       = LXW_VALIDATION_CRITERIA_BETWEEN;
4170  *    data_validation->minimum_number = 1;
4171  *    data_validation->maximum_number = 10;
4172  *
4173  *    worksheet_data_validation_cell(worksheet, 2, 1, data_validation);
4174  *
4175  *    // Same as above with the CELL() macro.
4176  *    worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);
4177  *
4178  * @endcode
4179  *
4180  * @image html data_validate4.png
4181  *
4182  * Data validation and the various options of #lxw_data_validation are
4183  * described in more detail in @ref working_with_data_validation.
4184  */
4185 lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
4186                                          lxw_row_t row, lxw_col_t col,
4187                                          lxw_data_validation *validation);
4188 
4189 /**
4190  * @brief Add a data validation to a range.
4191  *
4192  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4193  * @param first_row  The first row of the range. (All zero indexed.)
4194  * @param first_col  The first column of the range.
4195  * @param last_row   The last row of the range.
4196  * @param last_col   The last col of the range.
4197  * @param validation A #lxw_data_validation object to control the validation.
4198  *
4199  * @return A #lxw_error code.
4200  *
4201  * The `%worksheet_data_validation_range()` function is the same as the
4202  * `%worksheet_data_validation_cell()`, see above,  except the data validation
4203  * is applied to a range of cells:
4204  *
4205  * @code
4206  *
4207  *    lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
4208  *
4209  *    data_validation->validate       = LXW_VALIDATION_TYPE_INTEGER;
4210  *    data_validation->criteria       = LXW_VALIDATION_CRITERIA_BETWEEN;
4211  *    data_validation->minimum_number = 1;
4212  *    data_validation->maximum_number = 10;
4213  *
4214  *    worksheet_data_validation_range(worksheet, 2, 1, 4, 1, data_validation);
4215  *
4216  *    // Same as above with the RANGE() macro.
4217  *    worksheet_data_validation_range(worksheet, RANGE("B3:B5"), data_validation);
4218  *
4219  * @endcode
4220  *
4221  * Data validation and the various options of #lxw_data_validation are
4222  * described in more detail in @ref working_with_data_validation.
4223  */
4224 lxw_error worksheet_data_validation_range(lxw_worksheet *worksheet,
4225                                           lxw_row_t first_row,
4226                                           lxw_col_t first_col,
4227                                           lxw_row_t last_row,
4228                                           lxw_col_t last_col,
4229                                           lxw_data_validation *validation);
4230 
4231 /**
4232  * @brief Add a conditional format to a worksheet cell.
4233  *
4234  * @param worksheet           Pointer to a lxw_worksheet instance to be updated.
4235  * @param row                 The zero indexed row number.
4236  * @param col                 The zero indexed column number.
4237  * @param conditional_format  A #lxw_conditional_format object to control the
4238  *                            conditional format.
4239  *
4240  * @return A #lxw_error code.
4241  *
4242  * The `%worksheet_conditional_format_cell()` function is used to set a
4243  * conditional format for a cell in a worksheet:
4244  *
4245  * @code
4246  *     conditional_format->type     = LXW_CONDITIONAL_TYPE_CELL;
4247  *     conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
4248  *     conditional_format->value    = 50;
4249  *     conditional_format->format   = format1;
4250  *     worksheet_conditional_format_cell(worksheet, CELL("A1"), conditional_format);
4251  * @endcode
4252  *
4253  * The conditional format parameters is specified in #lxw_conditional_format.
4254  *
4255  * See @ref working_with_conditional_formatting for full details.
4256  */
4257 lxw_error worksheet_conditional_format_cell(lxw_worksheet *worksheet,
4258                                             lxw_row_t row,
4259                                             lxw_col_t col,
4260                                             lxw_conditional_format
4261                                             *conditional_format);
4262 
4263 /**
4264  * @brief Add a conditional format to a worksheet range.
4265  *
4266  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4267  * @param first_row  The first row of the range. (All zero indexed.)
4268  * @param first_col  The first column of the range.
4269  * @param last_row   The last row of the range.
4270  * @param last_col   The last col of the range.
4271  * @param conditional_format  A #lxw_conditional_format object to control the
4272  *                            conditional format.
4273  *
4274  * @return A #lxw_error code.
4275  *
4276  * The `%worksheet_conditional_format_cell()` function is used to set a
4277  * conditional format for a range of cells in a worksheet:
4278  *
4279  * @code
4280  *     conditional_format->type     = LXW_CONDITIONAL_TYPE_CELL;
4281  *     conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
4282  *     conditional_format->value    = 50;
4283  *     conditional_format->format   = format1;
4284  *     worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
4285  *
4286  *     conditional_format->type     = LXW_CONDITIONAL_TYPE_CELL;
4287  *     conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_LESS_THAN;
4288  *     conditional_format->value    = 50;
4289  *     conditional_format->format   = format2;
4290  *     worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
4291  * @endcode
4292  *
4293  * Output:
4294  *
4295  * @image html conditional_format1.png
4296  *
4297  *
4298  * The conditional format parameters is specified in #lxw_conditional_format.
4299  *
4300  * See @ref working_with_conditional_formatting for full details.
4301  */
4302 lxw_error worksheet_conditional_format_range(lxw_worksheet *worksheet,
4303                                              lxw_row_t first_row,
4304                                              lxw_col_t first_col,
4305                                              lxw_row_t last_row,
4306                                              lxw_col_t last_col,
4307                                              lxw_conditional_format
4308                                              *conditional_format);
4309 /**
4310  * @brief Insert a button object into a worksheet.
4311  *
4312  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4313  * @param row        The zero indexed row number.
4314  * @param col        The zero indexed column number.
4315  * @param options    A #lxw_button_options object to set the button properties.
4316  *
4317  * @return A #lxw_error code.
4318  *
4319  * The `%worksheet_insert_button()` function can be used to insert an Excel
4320  * form button into a worksheet. This function is generally only useful when
4321  * used in conjunction with the `workbook_add_vba_project()` function to tie
4322  * the button to a macro from an embedded VBA project:
4323  *
4324  * @code
4325  *     lxw_button_options options = {.caption = "Press Me",
4326  *                                   .macro   = "say_hello"};
4327  *
4328  *     worksheet_insert_button(worksheet, 2, 1, &options);
4329  * @endcode
4330  *
4331  * @image html macros.png
4332  *
4333  * The button properties are set using the lxw_button_options struct.
4334  *
4335  * See also @ref working_with_macros
4336  */
4337 lxw_error worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row,
4338                                   lxw_col_t col, lxw_button_options *options);
4339 
4340 /**
4341  * @brief Add an Excel table to a worksheet.
4342  *
4343  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4344  * @param first_row  The first row of the range. (All zero indexed.)
4345  * @param first_col  The first column of the range.
4346  * @param last_row   The last row of the range.
4347  * @param last_col   The last col of the range.
4348  * @param options    A #lxw_table_options struct to define the table options.
4349  *
4350  * @return A #lxw_error code.
4351  *
4352  * The `%worksheet_add_table()` function is used to add a table to a
4353  * worksheet. Tables in Excel are a way of grouping a range of cells into a
4354  * single entity that has common formatting or that can be referenced from
4355  * formulas. Tables can have column headers, autofilters, total rows, column
4356  * formulas and default formatting.
4357  *
4358  * @code
4359  *     worksheet_add_table(worksheet, 2, 1, 6, 5, NULL);
4360  * @endcode
4361  *
4362  * Output:
4363  *
4364  * @image html tables1.png
4365  *
4366  * See @ref working_with_tables for more detailed usage information and also
4367  * @ref tables.c.
4368  *
4369  */
4370 lxw_error worksheet_add_table(lxw_worksheet *worksheet, lxw_row_t first_row,
4371                               lxw_col_t first_col, lxw_row_t last_row,
4372                               lxw_col_t last_col, lxw_table_options *options);
4373 
4374  /**
4375   * @brief Make a worksheet the active, i.e., visible worksheet.
4376   *
4377   * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4378   *
4379   * The `%worksheet_activate()` function is used to specify which worksheet is
4380   * initially visible in a multi-sheet workbook:
4381   *
4382   * @code
4383   *     lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
4384   *     lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
4385   *     lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL);
4386   *
4387   *     worksheet_activate(worksheet3);
4388   * @endcode
4389   *
4390   * @image html worksheet_activate.png
4391   *
4392   * More than one worksheet can be selected via the `worksheet_select()`
4393   * function, see below, however only one worksheet can be active.
4394   *
4395   * The default active worksheet is the first worksheet.
4396   *
4397   */
4398 void worksheet_activate(lxw_worksheet *worksheet);
4399 
4400  /**
4401   * @brief Set a worksheet tab as selected.
4402   *
4403   * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4404   *
4405   * The `%worksheet_select()` function is used to indicate that a worksheet is
4406   * selected in a multi-sheet workbook:
4407   *
4408   * @code
4409   *     worksheet_activate(worksheet1);
4410   *     worksheet_select(worksheet2);
4411   *     worksheet_select(worksheet3);
4412   *
4413   * @endcode
4414   *
4415   * A selected worksheet has its tab highlighted. Selecting worksheets is a
4416   * way of grouping them together so that, for example, several worksheets
4417   * could be printed in one go. A worksheet that has been activated via the
4418   * `worksheet_activate()` function will also appear as selected.
4419   *
4420   */
4421 void worksheet_select(lxw_worksheet *worksheet);
4422 
4423 /**
4424  * @brief Hide the current worksheet.
4425  *
4426  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4427  *
4428  * The `%worksheet_hide()` function is used to hide a worksheet:
4429  *
4430  * @code
4431  *     worksheet_hide(worksheet2);
4432  * @endcode
4433  *
4434  * You may wish to hide a worksheet in order to avoid confusing a user with
4435  * intermediate data or calculations.
4436  *
4437  * @image html hide_sheet.png
4438  *
4439  * A hidden worksheet can not be activated or selected so this function is
4440  * mutually exclusive with the `worksheet_activate()` and `worksheet_select()`
4441  * functions. In addition, since the first worksheet will default to being the
4442  * active worksheet, you cannot hide the first worksheet without activating
4443  * another sheet:
4444  *
4445  * @code
4446  *     worksheet_activate(worksheet2);
4447  *     worksheet_hide(worksheet1);
4448  * @endcode
4449  */
4450 void worksheet_hide(lxw_worksheet *worksheet);
4451 
4452 /**
4453  * @brief Set current worksheet as the first visible sheet tab.
4454  *
4455  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4456  *
4457  * The `worksheet_activate()` function determines which worksheet is initially
4458  * selected.  However, if there are a large number of worksheets the selected
4459  * worksheet may not appear on the screen. To avoid this you can select the
4460  * leftmost visible worksheet tab using `%worksheet_set_first_sheet()`:
4461  *
4462  * @code
4463  *     worksheet_set_first_sheet(worksheet19); // First visible worksheet tab.
4464  *     worksheet_activate(worksheet20);        // First visible worksheet.
4465  * @endcode
4466  *
4467  * This function is not required very often. The default value is the first
4468  * worksheet.
4469  */
4470 void worksheet_set_first_sheet(lxw_worksheet *worksheet);
4471 
4472 /**
4473  * @brief Split and freeze a worksheet into panes.
4474  *
4475  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4476  * @param row       The cell row (zero indexed).
4477  * @param col       The cell column (zero indexed).
4478  *
4479  * The `%worksheet_freeze_panes()` function can be used to divide a worksheet
4480  * into horizontal or vertical regions known as panes and to "freeze" these
4481  * panes so that the splitter bars are not visible.
4482  *
4483  * The parameters `row` and `col` are used to specify the location of the
4484  * split. It should be noted that the split is specified at the top or left of
4485  * a cell and that the function uses zero based indexing. Therefore to freeze
4486  * the first row of a worksheet it is necessary to specify the split at row 2
4487  * (which is 1 as the zero-based index).
4488  *
4489  * You can set one of the `row` and `col` parameters as zero if you do not
4490  * want either a vertical or horizontal split.
4491  *
4492  * Examples:
4493  *
4494  * @code
4495  *     worksheet_freeze_panes(worksheet1, 1, 0); // Freeze the first row.
4496  *     worksheet_freeze_panes(worksheet2, 0, 1); // Freeze the first column.
4497  *     worksheet_freeze_panes(worksheet3, 1, 1); // Freeze first row/column.
4498  *
4499  * @endcode
4500  *
4501  */
4502 void worksheet_freeze_panes(lxw_worksheet *worksheet,
4503                             lxw_row_t row, lxw_col_t col);
4504 /**
4505  * @brief Split a worksheet into panes.
4506  *
4507  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
4508  * @param vertical   The position for the vertical split.
4509  * @param horizontal The position for the horizontal split.
4510  *
4511  * The `%worksheet_split_panes()` function can be used to divide a worksheet
4512  * into horizontal or vertical regions known as panes. This function is
4513  * different from the `worksheet_freeze_panes()` function in that the splits
4514  * between the panes will be visible to the user and each pane will have its
4515  * own scroll bars.
4516  *
4517  * The parameters `vertical` and `horizontal` are used to specify the vertical
4518  * and horizontal position of the split. The units for `vertical` and
4519  * `horizontal` are the same as those used by Excel to specify row height and
4520  * column width. However, the vertical and horizontal units are different from
4521  * each other. Therefore you must specify the `vertical` and `horizontal`
4522  * parameters in terms of the row heights and column widths that you have set
4523  * or the default values which are 15 for a row and 8.43 for a column.
4524  *
4525  * Examples:
4526  *
4527  * @code
4528  *     worksheet_split_panes(worksheet1, 15, 0);    // First row.
4529  *     worksheet_split_panes(worksheet2, 0,  8.43); // First column.
4530  *     worksheet_split_panes(worksheet3, 15, 8.43); // First row and column.
4531  *
4532  * @endcode
4533  *
4534  */
4535 void worksheet_split_panes(lxw_worksheet *worksheet,
4536                            double vertical, double horizontal);
4537 
4538 /* worksheet_freeze_panes() with infrequent options. Undocumented for now. */
4539 void worksheet_freeze_panes_opt(lxw_worksheet *worksheet,
4540                                 lxw_row_t first_row, lxw_col_t first_col,
4541                                 lxw_row_t top_row, lxw_col_t left_col,
4542                                 uint8_t type);
4543 
4544 /* worksheet_split_panes() with infrequent options. Undocumented for now. */
4545 void worksheet_split_panes_opt(lxw_worksheet *worksheet,
4546                                double vertical, double horizontal,
4547                                lxw_row_t top_row, lxw_col_t left_col);
4548 /**
4549  * @brief Set the selected cell or cells in a worksheet:
4550  *
4551  * @param worksheet   A pointer to a lxw_worksheet instance to be updated.
4552  * @param first_row   The first row of the range. (All zero indexed.)
4553  * @param first_col   The first column of the range.
4554  * @param last_row    The last row of the range.
4555  * @param last_col    The last col of the range.
4556  *
4557  *
4558  * The `%worksheet_set_selection()` function can be used to specify which cell
4559  * or range of cells is selected in a worksheet: The most common requirement
4560  * is to select a single cell, in which case the `first_` and `last_`
4561  * parameters should be the same.
4562  *
4563  * The active cell within a selected range is determined by the order in which
4564  * `first_` and `last_` are specified.
4565  *
4566  * Examples:
4567  *
4568  * @code
4569  *     worksheet_set_selection(worksheet1, 3, 3, 3, 3);     // Cell D4.
4570  *     worksheet_set_selection(worksheet2, 3, 3, 6, 6);     // Cells D4 to G7.
4571  *     worksheet_set_selection(worksheet3, 6, 6, 3, 3);     // Cells G7 to D4.
4572  *     worksheet_set_selection(worksheet5, RANGE("D4:G7")); // Using the RANGE macro.
4573  *
4574  * @endcode
4575  *
4576  */
4577 void worksheet_set_selection(lxw_worksheet *worksheet,
4578                              lxw_row_t first_row, lxw_col_t first_col,
4579                              lxw_row_t last_row, lxw_col_t last_col);
4580 
4581 /**
4582  * @brief Set the page orientation as landscape.
4583  *
4584  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4585  *
4586  * This function is used to set the orientation of a worksheet's printed page
4587  * to landscape:
4588  *
4589  * @code
4590  *     worksheet_set_landscape(worksheet);
4591  * @endcode
4592  */
4593 void worksheet_set_landscape(lxw_worksheet *worksheet);
4594 
4595 /**
4596  * @brief Set the page orientation as portrait.
4597  *
4598  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4599  *
4600  * This function is used to set the orientation of a worksheet's printed page
4601  * to portrait. The default worksheet orientation is portrait, so this
4602  * function isn't generally required:
4603  *
4604  * @code
4605  *     worksheet_set_portrait(worksheet);
4606  * @endcode
4607  */
4608 void worksheet_set_portrait(lxw_worksheet *worksheet);
4609 
4610 /**
4611  * @brief Set the page layout to page view mode.
4612  *
4613  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4614  *
4615  * This function is used to display the worksheet in "Page View/Layout" mode:
4616  *
4617  * @code
4618  *     worksheet_set_page_view(worksheet);
4619  * @endcode
4620  */
4621 void worksheet_set_page_view(lxw_worksheet *worksheet);
4622 
4623 /**
4624  * @brief Set the paper type for printing.
4625  *
4626  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4627  * @param paper_type The Excel paper format type.
4628  *
4629  * This function is used to set the paper format for the printed output of a
4630  * worksheet. The following paper styles are available:
4631  *
4632  *
4633  *   Index    | Paper format            | Paper size
4634  *   :------- | :---------------------- | :-------------------
4635  *   0        | Printer default         | Printer default
4636  *   1        | Letter                  | 8 1/2 x 11 in
4637  *   2        | Letter Small            | 8 1/2 x 11 in
4638  *   3        | Tabloid                 | 11 x 17 in
4639  *   4        | Ledger                  | 17 x 11 in
4640  *   5        | Legal                   | 8 1/2 x 14 in
4641  *   6        | Statement               | 5 1/2 x 8 1/2 in
4642  *   7        | Executive               | 7 1/4 x 10 1/2 in
4643  *   8        | A3                      | 297 x 420 mm
4644  *   9        | A4                      | 210 x 297 mm
4645  *   10       | A4 Small                | 210 x 297 mm
4646  *   11       | A5                      | 148 x 210 mm
4647  *   12       | B4                      | 250 x 354 mm
4648  *   13       | B5                      | 182 x 257 mm
4649  *   14       | Folio                   | 8 1/2 x 13 in
4650  *   15       | Quarto                  | 215 x 275 mm
4651  *   16       | ---                     | 10x14 in
4652  *   17       | ---                     | 11x17 in
4653  *   18       | Note                    | 8 1/2 x 11 in
4654  *   19       | Envelope 9              | 3 7/8 x 8 7/8
4655  *   20       | Envelope 10             | 4 1/8 x 9 1/2
4656  *   21       | Envelope 11             | 4 1/2 x 10 3/8
4657  *   22       | Envelope 12             | 4 3/4 x 11
4658  *   23       | Envelope 14             | 5 x 11 1/2
4659  *   24       | C size sheet            | ---
4660  *   25       | D size sheet            | ---
4661  *   26       | E size sheet            | ---
4662  *   27       | Envelope DL             | 110 x 220 mm
4663  *   28       | Envelope C3             | 324 x 458 mm
4664  *   29       | Envelope C4             | 229 x 324 mm
4665  *   30       | Envelope C5             | 162 x 229 mm
4666  *   31       | Envelope C6             | 114 x 162 mm
4667  *   32       | Envelope C65            | 114 x 229 mm
4668  *   33       | Envelope B4             | 250 x 353 mm
4669  *   34       | Envelope B5             | 176 x 250 mm
4670  *   35       | Envelope B6             | 176 x 125 mm
4671  *   36       | Envelope                | 110 x 230 mm
4672  *   37       | Monarch                 | 3.875 x 7.5 in
4673  *   38       | Envelope                | 3 5/8 x 6 1/2 in
4674  *   39       | Fanfold                 | 14 7/8 x 11 in
4675  *   40       | German Std Fanfold      | 8 1/2 x 12 in
4676  *   41       | German Legal Fanfold    | 8 1/2 x 13 in
4677  *
4678  * Note, it is likely that not all of these paper types will be available to
4679  * the end user since it will depend on the paper formats that the user's
4680  * printer supports. Therefore, it is best to stick to standard paper types:
4681  *
4682  * @code
4683  *     worksheet_set_paper(worksheet1, 1);  // US Letter
4684  *     worksheet_set_paper(worksheet2, 9);  // A4
4685  * @endcode
4686  *
4687  * If you do not specify a paper type the worksheet will print using the
4688  * printer's default paper style.
4689  */
4690 void worksheet_set_paper(lxw_worksheet *worksheet, uint8_t paper_type);
4691 
4692 /**
4693  * @brief Set the worksheet margins for the printed page.
4694  *
4695  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4696  * @param left    Left margin in inches.   Excel default is 0.7.
4697  * @param right   Right margin in inches.  Excel default is 0.7.
4698  * @param top     Top margin in inches.    Excel default is 0.75.
4699  * @param bottom  Bottom margin in inches. Excel default is 0.75.
4700  *
4701  * The `%worksheet_set_margins()` function is used to set the margins of the
4702  * worksheet when it is printed. The units are in inches. Specifying `-1` for
4703  * any parameter will give the default Excel value as shown above.
4704  *
4705  * @code
4706  *    worksheet_set_margins(worksheet, 1.3, 1.2, -1, -1);
4707  * @endcode
4708  *
4709  */
4710 void worksheet_set_margins(lxw_worksheet *worksheet, double left,
4711                            double right, double top, double bottom);
4712 
4713 /**
4714  * @brief Set the printed page header caption.
4715  *
4716  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4717  * @param string    The header string.
4718  *
4719  * @return A #lxw_error code.
4720  *
4721  * Headers and footers are generated using a string which is a combination of
4722  * plain text and control characters.
4723  *
4724  * The available control character are:
4725  *
4726  *
4727  *   | Control         | Category      | Description           |
4728  *   | --------------- | ------------- | --------------------- |
4729  *   | `&L`            | Justification | Left                  |
4730  *   | `&C`            |               | Center                |
4731  *   | `&R`            |               | Right                 |
4732  *   | `&P`            | Information   | Page number           |
4733  *   | `&N`            |               | Total number of pages |
4734  *   | `&D`            |               | Date                  |
4735  *   | `&T`            |               | Time                  |
4736  *   | `&F`            |               | File name             |
4737  *   | `&A`            |               | Worksheet name        |
4738  *   | `&Z`            |               | Workbook path         |
4739  *   | `&fontsize`     | Font          | Font size             |
4740  *   | `&"font,style"` |               | Font name and style   |
4741  *   | `&U`            |               | Single underline      |
4742  *   | `&E`            |               | Double underline      |
4743  *   | `&S`            |               | Strikethrough         |
4744  *   | `&X`            |               | Superscript           |
4745  *   | `&Y`            |               | Subscript             |
4746  *   | `&[Picture]`    | Images        | Image placeholder     |
4747  *   | `&G`            |               | Same as `&[Picture]`  |
4748  *   | `&&`            | Miscellaneous | Literal ampersand &   |
4749  *
4750  * Note: inserting images requires the `worksheet_set_header_opt()` function.
4751  *
4752  * Text in headers and footers can be justified (aligned) to the left, center
4753  * and right by prefixing the text with the control characters `&L`, `&C` and
4754  * `&R`.
4755  *
4756  * For example (with ASCII art representation of the results):
4757  *
4758  * @code
4759  *     worksheet_set_header(worksheet, "&LHello");
4760  *
4761  *     //     ---------------------------------------------------------------
4762  *     //    |                                                               |
4763  *     //    | Hello                                                         |
4764  *     //    |                                                               |
4765  *
4766  *
4767  *     worksheet_set_header(worksheet, "&CHello");
4768  *
4769  *     //     ---------------------------------------------------------------
4770  *     //    |                                                               |
4771  *     //    |                          Hello                                |
4772  *     //    |                                                               |
4773  *
4774  *
4775  *     worksheet_set_header(worksheet, "&RHello");
4776  *
4777  *     //     ---------------------------------------------------------------
4778  *     //    |                                                               |
4779  *     //    |                                                         Hello |
4780  *     //    |                                                               |
4781  *
4782  *
4783  * @endcode
4784  *
4785  * For simple text, if you do not specify any justification the text will be
4786  * centered. However, you must prefix the text with `&C` if you specify a font
4787  * name or any other formatting:
4788  *
4789  * @code
4790  *     worksheet_set_header(worksheet, "Hello");
4791  *
4792  *     //     ---------------------------------------------------------------
4793  *     //    |                                                               |
4794  *     //    |                          Hello                                |
4795  *     //    |                                                               |
4796  *
4797  * @endcode
4798  *
4799  * You can have text in each of the justification regions:
4800  *
4801  * @code
4802  *     worksheet_set_header(worksheet, "&LCiao&CBello&RCielo");
4803  *
4804  *     //     ---------------------------------------------------------------
4805  *     //    |                                                               |
4806  *     //    | Ciao                     Bello                          Cielo |
4807  *     //    |                                                               |
4808  *
4809  * @endcode
4810  *
4811  * The information control characters act as variables that Excel will update
4812  * as the workbook or worksheet changes. Times and dates are in the users
4813  * default format:
4814  *
4815  * @code
4816  *     worksheet_set_header(worksheet, "&CPage &P of &N");
4817  *
4818  *     //     ---------------------------------------------------------------
4819  *     //    |                                                               |
4820  *     //    |                        Page 1 of 6                            |
4821  *     //    |                                                               |
4822  *
4823  *     worksheet_set_header(worksheet, "&CUpdated at &T");
4824  *
4825  *     //     ---------------------------------------------------------------
4826  *     //    |                                                               |
4827  *     //    |                    Updated at 12:30 PM                        |
4828  *     //    |                                                               |
4829  *
4830  * @endcode
4831  *
4832  * You can specify the font size of a section of the text by prefixing it with
4833  * the control character `&n` where `n` is the font size:
4834  *
4835  * @code
4836  *     worksheet_set_header(worksheet1, "&C&30Hello Big");
4837  *     worksheet_set_header(worksheet2, "&C&10Hello Small");
4838  *
4839  * @endcode
4840  *
4841  * You can specify the font of a section of the text by prefixing it with the
4842  * control sequence `&"font,style"` where `fontname` is a font name such as
4843  * Windows font descriptions: "Regular", "Italic", "Bold" or "Bold Italic":
4844  * "Courier New" or "Times New Roman" and `style` is one of the standard
4845  *
4846  * @code
4847  *     worksheet_set_header(worksheet1, "&C&\"Courier New,Italic\"Hello");
4848  *     worksheet_set_header(worksheet2, "&C&\"Courier New,Bold Italic\"Hello");
4849  *     worksheet_set_header(worksheet3, "&C&\"Times New Roman,Regular\"Hello");
4850  *
4851  * @endcode
4852  *
4853  * It is possible to combine all of these features together to create
4854  * sophisticated headers and footers. As an aid to setting up complicated
4855  * headers and footers you can record a page set-up as a macro in Excel and
4856  * look at the format strings that VBA produces. Remember however that VBA
4857  * uses two double quotes `""` to indicate a single double quote. For the last
4858  * example above the equivalent VBA code looks like this:
4859  *
4860  * @code
4861  *     .LeftHeader = ""
4862  *     .CenterHeader = "&""Times New Roman,Regular""Hello"
4863  *     .RightHeader = ""
4864  *
4865  * @endcode
4866  *
4867  * Alternatively you can inspect the header and footer strings in an Excel
4868  * file by unzipping it and grepping the XML sub-files. The following shows
4869  * how to do that using libxml's xmllint to format the XML for clarity:
4870  *
4871  * @code
4872  *
4873  *    $ unzip myfile.xlsm -d myfile
4874  *    $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer" | sed 's/&amp;/\&/g'
4875  *
4876  *      <headerFooter scaleWithDoc="0">
4877  *        <oddHeader>&L&P</oddHeader>
4878  *      </headerFooter>
4879  *
4880  * @endcode
4881  *
4882  * To include a single literal ampersand `&` in a header or footer you should
4883  * use a double ampersand `&&`:
4884  *
4885  * @code
4886  *     worksheet_set_header(worksheet, "&CCuriouser && Curiouser - Attorneys at Law");
4887  * @endcode
4888  *
4889  * @note
4890  * Excel requires that the header or footer string cannot be longer than 255
4891  * characters, including the control characters. Strings longer than this will
4892  * not be written.
4893  *
4894  */
4895 lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
4896 
4897 /**
4898  * @brief Set the printed page footer caption.
4899  *
4900  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4901  * @param string    The footer string.
4902  *
4903  * @return A #lxw_error code.
4904  *
4905  * The syntax of this function is the same as worksheet_set_header().
4906  *
4907  */
4908 lxw_error worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
4909 
4910 /**
4911  * @brief Set the printed page header caption with additional options.
4912  *
4913  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4914  * @param string    The header string.
4915  * @param options   Header options.
4916  *
4917  * @return A #lxw_error code.
4918  *
4919  * The syntax of this function is the same as `worksheet_set_header()` with an
4920  * additional parameter to specify options for the header.
4921  *
4922  * The #lxw_header_footer_options options are:
4923  *
4924  * - `margin`: Header or footer margin in inches. The value must by larger
4925  *   than 0.0. The Excel default is 0.3.
4926  *
4927  * - `image_left`: The left header image filename, with path if required. This
4928  *   should have a corresponding `&G/&[Picture]` placeholder in the `&L`
4929  *   section of the header/footer string.
4930  *
4931  * - `image_center`: The center header image filename, with path if
4932  *   required. This should have a corresponding `&G/&[Picture]` placeholder in
4933  *   the `&C` section of the header/footer string.
4934  *
4935  * - `image_right`: The right header image filename, with path if
4936  *   required. This should have a corresponding `&G/&[Picture]` placeholder in
4937  *   the `&R` section of the header/footer string.
4938  *
4939  * @code
4940  *     lxw_header_footer_options header_options = { .margin = 0.2 };
4941  *
4942  *     worksheet_set_header_opt(worksheet, "Some text", &header_options);
4943  * @endcode
4944  *
4945  * Images can be inserted in the header by specifying the `&[Picture]`
4946  * placeholder and a filename/path to the image:
4947  *
4948  * @code
4949  *     lxw_header_footer_options header_options = {.image_left = "logo.png"};
4950  *
4951  *    worksheet_set_header_opt(worksheet, "&L&[Picture]", &header_options);
4952  * @endcode
4953  *
4954  * @image html headers_footers.png
4955  *
4956  */
4957 lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
4958                                    const char *string,
4959                                    lxw_header_footer_options *options);
4960 
4961 /**
4962  * @brief Set the printed page footer caption with additional options.
4963  *
4964  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4965  * @param string    The footer string.
4966  * @param options   Footer options.
4967  *
4968  * @return A #lxw_error code.
4969  *
4970  * The syntax of this function is the same as `worksheet_set_header_opt()`.
4971  *
4972  */
4973 lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
4974                                    const char *string,
4975                                    lxw_header_footer_options *options);
4976 
4977 /**
4978  * @brief Set the horizontal page breaks on a worksheet.
4979  *
4980  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
4981  * @param breaks    Array of page breaks.
4982  *
4983  * @return A #lxw_error code.
4984  *
4985  * The `%worksheet_set_h_pagebreaks()` function adds horizontal page breaks to
4986  * a worksheet. A page break causes all the data that follows it to be printed
4987  * on the next page. Horizontal page breaks act between rows.
4988  *
4989  * The function takes an array of one or more page breaks. The type of the
4990  * array data is @ref lxw_row_t and the last element of the array must be 0:
4991  *
4992  * @code
4993  *    lxw_row_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
4994  *    lxw_row_t breaks2[] = {20, 40, 60, 80, 0};
4995  *
4996  *    worksheet_set_h_pagebreaks(worksheet1, breaks1);
4997  *    worksheet_set_h_pagebreaks(worksheet2, breaks2);
4998  * @endcode
4999  *
5000  * To create a page break between rows 20 and 21 you must specify the break at
5001  * row 21. However in zero index notation this is actually row 20:
5002  *
5003  * @code
5004  *    // Break between row 20 and 21.
5005  *    lxw_row_t breaks[] = {20, 0};
5006  *
5007  *    worksheet_set_h_pagebreaks(worksheet, breaks);
5008  * @endcode
5009  *
5010  * There is an Excel limitation of 1023 horizontal page breaks per worksheet.
5011  *
5012  * Note: If you specify the "fit to page" option via the
5013  * `worksheet_fit_to_pages()` function it will override all manual page
5014  * breaks.
5015  *
5016  */
5017 lxw_error worksheet_set_h_pagebreaks(lxw_worksheet *worksheet,
5018                                      lxw_row_t breaks[]);
5019 
5020 /**
5021  * @brief Set the vertical page breaks on a worksheet.
5022  *
5023  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5024  * @param breaks    Array of page breaks.
5025  *
5026  * @return A #lxw_error code.
5027  *
5028  * The `%worksheet_set_v_pagebreaks()` function adds vertical page breaks to a
5029  * worksheet. A page break causes all the data that follows it to be printed
5030  * on the next page. Vertical page breaks act between columns.
5031  *
5032  * The function takes an array of one or more page breaks. The type of the
5033  * array data is @ref lxw_col_t and the last element of the array must be 0:
5034  *
5035  * @code
5036  *    lxw_col_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
5037  *    lxw_col_t breaks2[] = {20, 40, 60, 80, 0};
5038  *
5039  *    worksheet_set_v_pagebreaks(worksheet1, breaks1);
5040  *    worksheet_set_v_pagebreaks(worksheet2, breaks2);
5041  * @endcode
5042  *
5043  * To create a page break between columns 20 and 21 you must specify the break
5044  * at column 21. However in zero index notation this is actually column 20:
5045  *
5046  * @code
5047  *    // Break between column 20 and 21.
5048  *    lxw_col_t breaks[] = {20, 0};
5049  *
5050  *    worksheet_set_v_pagebreaks(worksheet, breaks);
5051  * @endcode
5052  *
5053  * There is an Excel limitation of 1023 vertical page breaks per worksheet.
5054  *
5055  * Note: If you specify the "fit to page" option via the
5056  * `worksheet_fit_to_pages()` function it will override all manual page
5057  * breaks.
5058  *
5059  */
5060 lxw_error worksheet_set_v_pagebreaks(lxw_worksheet *worksheet,
5061                                      lxw_col_t breaks[]);
5062 
5063 /**
5064  * @brief Set the order in which pages are printed.
5065  *
5066  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5067  *
5068  * The `%worksheet_print_across()` function is used to change the default
5069  * print direction. This is referred to by Excel as the sheet "page order":
5070  *
5071  * @code
5072  *     worksheet_print_across(worksheet);
5073  * @endcode
5074  *
5075  * The default page order is shown below for a worksheet that extends over 4
5076  * pages. The order is called "down then across":
5077  *
5078  *     [1] [3]
5079  *     [2] [4]
5080  *
5081  * However, by using the `print_across` function the print order will be
5082  * changed to "across then down":
5083  *
5084  *     [1] [2]
5085  *     [3] [4]
5086  *
5087  */
5088 void worksheet_print_across(lxw_worksheet *worksheet);
5089 
5090 /**
5091  * @brief Set the worksheet zoom factor.
5092  *
5093  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5094  * @param scale     Worksheet zoom factor.
5095  *
5096  * Set the worksheet zoom factor in the range `10 <= zoom <= 400`:
5097  *
5098  * @code
5099  *     worksheet_set_zoom(worksheet1, 50);
5100  *     worksheet_set_zoom(worksheet2, 75);
5101  *     worksheet_set_zoom(worksheet3, 300);
5102  *     worksheet_set_zoom(worksheet4, 400);
5103  * @endcode
5104  *
5105  * The default zoom factor is 100. It isn't possible to set the zoom to
5106  * "Selection" because it is calculated by Excel at run-time.
5107  *
5108  * Note, `%worksheet_zoom()` does not affect the scale of the printed
5109  * page. For that you should use `worksheet_set_print_scale()`.
5110  */
5111 void worksheet_set_zoom(lxw_worksheet *worksheet, uint16_t scale);
5112 
5113 /**
5114  * @brief Set the option to display or hide gridlines on the screen and
5115  *        the printed page.
5116  *
5117  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5118  * @param option    Gridline option.
5119  *
5120  * Display or hide screen and print gridlines using one of the values of
5121  * @ref lxw_gridlines.
5122  *
5123  * @code
5124  *    worksheet_gridlines(worksheet1, LXW_HIDE_ALL_GRIDLINES);
5125  *
5126  *    worksheet_gridlines(worksheet2, LXW_SHOW_PRINT_GRIDLINES);
5127  * @endcode
5128  *
5129  * The Excel default is that the screen gridlines are on  and the printed
5130  * worksheet is off.
5131  *
5132  */
5133 void worksheet_gridlines(lxw_worksheet *worksheet, uint8_t option);
5134 
5135 /**
5136  * @brief Center the printed page horizontally.
5137  *
5138  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5139  *
5140  * Center the worksheet data horizontally between the margins on the printed
5141  * page:
5142  *
5143  * @code
5144  *     worksheet_center_horizontally(worksheet);
5145  * @endcode
5146  *
5147  */
5148 void worksheet_center_horizontally(lxw_worksheet *worksheet);
5149 
5150 /**
5151  * @brief Center the printed page vertically.
5152  *
5153  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5154  *
5155  * Center the worksheet data vertically between the margins on the printed
5156  * page:
5157  *
5158  * @code
5159  *     worksheet_center_vertically(worksheet);
5160  * @endcode
5161  *
5162  */
5163 void worksheet_center_vertically(lxw_worksheet *worksheet);
5164 
5165 /**
5166  * @brief Set the option to print the row and column headers on the printed
5167  *        page.
5168  *
5169  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5170  *
5171  * When printing a worksheet from Excel the row and column headers (the row
5172  * numbers on the left and the column letters at the top) aren't printed by
5173  * default.
5174  *
5175  * This function sets the printer option to print these headers:
5176  *
5177  * @code
5178  *    worksheet_print_row_col_headers(worksheet);
5179  * @endcode
5180  *
5181  */
5182 void worksheet_print_row_col_headers(lxw_worksheet *worksheet);
5183 
5184 /**
5185  * @brief Set the number of rows to repeat at the top of each printed page.
5186  *
5187  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5188  * @param first_row First row of repeat range.
5189  * @param last_row  Last row of repeat range.
5190  *
5191  * @return A #lxw_error code.
5192  *
5193  * For large Excel documents it is often desirable to have the first row or
5194  * rows of the worksheet print out at the top of each page.
5195  *
5196  * This can be achieved by using this function. The parameters `first_row`
5197  * and `last_row` are zero based:
5198  *
5199  * @code
5200  *     worksheet_repeat_rows(worksheet, 0, 0); // Repeat the first row.
5201  *     worksheet_repeat_rows(worksheet, 0, 1); // Repeat the first two rows.
5202  * @endcode
5203  */
5204 lxw_error worksheet_repeat_rows(lxw_worksheet *worksheet, lxw_row_t first_row,
5205                                 lxw_row_t last_row);
5206 
5207 /**
5208  * @brief Set the number of columns to repeat at the top of each printed page.
5209  *
5210  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5211  * @param first_col First column of repeat range.
5212  * @param last_col  Last column of repeat range.
5213  *
5214  * @return A #lxw_error code.
5215  *
5216  * For large Excel documents it is often desirable to have the first column or
5217  * columns of the worksheet print out at the left of each page.
5218  *
5219  * This can be achieved by using this function. The parameters `first_col`
5220  * and `last_col` are zero based:
5221  *
5222  * @code
5223  *     worksheet_repeat_columns(worksheet, 0, 0); // Repeat the first col.
5224  *     worksheet_repeat_columns(worksheet, 0, 1); // Repeat the first two cols.
5225  * @endcode
5226  */
5227 lxw_error worksheet_repeat_columns(lxw_worksheet *worksheet,
5228                                    lxw_col_t first_col, lxw_col_t last_col);
5229 
5230 /**
5231  * @brief Set the print area for a worksheet.
5232  *
5233  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5234  * @param first_row The first row of the range. (All zero indexed.)
5235  * @param first_col The first column of the range.
5236  * @param last_row  The last row of the range.
5237  * @param last_col  The last col of the range.
5238  *
5239  * @return A #lxw_error code.
5240  *
5241  * This function is used to specify the area of the worksheet that will be
5242  * printed. The RANGE() macro is often convenient for this.
5243  *
5244  * @code
5245  *     worksheet_print_area(worksheet, 0, 0, 41, 10); // A1:K42.
5246  *
5247  *     // Same as:
5248  *     worksheet_print_area(worksheet, RANGE("A1:K42"));
5249  * @endcode
5250  *
5251  * In order to set a row or column range you must specify the entire range:
5252  *
5253  * @code
5254  *     worksheet_print_area(worksheet, RANGE("A1:H1048576")); // Same as A:H.
5255  * @endcode
5256  */
5257 lxw_error worksheet_print_area(lxw_worksheet *worksheet, lxw_row_t first_row,
5258                                lxw_col_t first_col, lxw_row_t last_row,
5259                                lxw_col_t last_col);
5260 /**
5261  * @brief Fit the printed area to a specific number of pages both vertically
5262  *        and horizontally.
5263  *
5264  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5265  * @param width     Number of pages horizontally.
5266  * @param height    Number of pages vertically.
5267  *
5268  * The `%worksheet_fit_to_pages()` function is used to fit the printed area to
5269  * a specific number of pages both vertically and horizontally. If the printed
5270  * area exceeds the specified number of pages it will be scaled down to
5271  * fit. This ensures that the printed area will always appear on the specified
5272  * number of pages even if the page size or margins change:
5273  *
5274  * @code
5275  *     worksheet_fit_to_pages(worksheet1, 1, 1); // Fit to 1x1 pages.
5276  *     worksheet_fit_to_pages(worksheet2, 2, 1); // Fit to 2x1 pages.
5277  *     worksheet_fit_to_pages(worksheet3, 1, 2); // Fit to 1x2 pages.
5278  * @endcode
5279  *
5280  * The print area can be defined using the `worksheet_print_area()` function
5281  * as described above.
5282  *
5283  * A common requirement is to fit the printed output to `n` pages wide but
5284  * have the height be as long as necessary. To achieve this set the `height`
5285  * to zero:
5286  *
5287  * @code
5288  *     // 1 page wide and as long as necessary.
5289  *     worksheet_fit_to_pages(worksheet, 1, 0);
5290  * @endcode
5291  *
5292  * **Note**:
5293  *
5294  * - Although it is valid to use both `%worksheet_fit_to_pages()` and
5295  *   `worksheet_set_print_scale()` on the same worksheet Excel only allows one
5296  *   of these options to be active at a time. The last function call made will
5297  *   set the active option.
5298  *
5299  * - The `%worksheet_fit_to_pages()` function will override any manual page
5300  *   breaks that are defined in the worksheet.
5301  *
5302  * - When using `%worksheet_fit_to_pages()` it may also be required to set the
5303  *   printer paper size using `worksheet_set_paper()` or else Excel will
5304  *   default to "US Letter".
5305  *
5306  */
5307 void worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width,
5308                             uint16_t height);
5309 
5310 /**
5311  * @brief Set the start/first page number when printing.
5312  *
5313  * @param worksheet  Pointer to a lxw_worksheet instance to be updated.
5314  * @param start_page Page number of the starting page when printing.
5315  *
5316  * The `%worksheet_set_start_page()` function is used to set the number number
5317  * of the first page when the worksheet is printed out. It is the same as the
5318  * "First Page Number" option in Excel:
5319  *
5320  * @code
5321  *     // Start print from page 2.
5322  *     worksheet_set_start_page(worksheet, 2);
5323  * @endcode
5324  */
5325 void worksheet_set_start_page(lxw_worksheet *worksheet, uint16_t start_page);
5326 
5327 /**
5328  * @brief Set the scale factor for the printed page.
5329  *
5330  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5331  * @param scale     Print scale of worksheet to be printed.
5332  *
5333  * This function sets the scale factor of the printed page. The Scale factor
5334  * must be in the range `10 <= scale <= 400`:
5335  *
5336  * @code
5337  *     worksheet_set_print_scale(worksheet1, 75);
5338  *     worksheet_set_print_scale(worksheet2, 400);
5339  * @endcode
5340  *
5341  * The default scale factor is 100. Note, `%worksheet_set_print_scale()` does
5342  * not affect the scale of the visible page in Excel. For that you should use
5343  * `worksheet_set_zoom()`.
5344  *
5345  * Note that although it is valid to use both `worksheet_fit_to_pages()` and
5346  * `%worksheet_set_print_scale()` on the same worksheet Excel only allows one
5347  * of these options to be active at a time. The last function call made will
5348  * set the active option.
5349  *
5350  */
5351 void worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
5352 
5353 /**
5354  * @brief Display the worksheet cells from right to left for some versions of
5355  *        Excel.
5356  *
5357  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5358  *
5359   * The `%worksheet_right_to_left()` function is used to change the default
5360  * direction of the worksheet from left-to-right, with the `A1` cell in the
5361  * top left, to right-to-left, with the `A1` cell in the top right.
5362  *
5363  * @code
5364  *     worksheet_right_to_left(worksheet1);
5365  * @endcode
5366  *
5367  * This is useful when creating Arabic, Hebrew or other near or far eastern
5368  * worksheets that use right-to-left as the default direction.
5369  */
5370 void worksheet_right_to_left(lxw_worksheet *worksheet);
5371 
5372 /**
5373  * @brief Hide zero values in worksheet cells.
5374  *
5375  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5376  *
5377  * The `%worksheet_hide_zero()` function is used to hide any zero values that
5378  * appear in cells:
5379  *
5380  * @code
5381  *     worksheet_hide_zero(worksheet1);
5382  * @endcode
5383  */
5384 void worksheet_hide_zero(lxw_worksheet *worksheet);
5385 
5386 /**
5387  * @brief Set the color of the worksheet tab.
5388  *
5389  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5390  * @param color     The tab color.
5391  *
5392  * The `%worksheet_set_tab_color()` function is used to change the color of
5393  * the worksheet tab:
5394  *
5395  * @code
5396  *      worksheet_set_tab_color(worksheet1, LXW_COLOR_RED);
5397  *      worksheet_set_tab_color(worksheet2, LXW_COLOR_GREEN);
5398  *      worksheet_set_tab_color(worksheet3, 0xFF9900); // Orange.
5399  * @endcode
5400  *
5401  * The color should be an RGB integer value, see @ref working_with_colors.
5402  */
5403 void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
5404 
5405 /**
5406  * @brief Protect elements of a worksheet from modification.
5407  *
5408  * @param worksheet Pointer to a lxw_worksheet instance to be updated.
5409  * @param password  A worksheet password.
5410  * @param options   Worksheet elements to protect.
5411  *
5412  * The `%worksheet_protect()` function protects worksheet elements from modification:
5413  *
5414  * @code
5415  *     worksheet_protect(worksheet, "Some Password", options);
5416  * @endcode
5417  *
5418  * The `password` and lxw_protection pointer are both optional:
5419  *
5420  * @code
5421  *     worksheet_protect(worksheet1, NULL,       NULL);
5422  *     worksheet_protect(worksheet2, NULL,       my_options);
5423  *     worksheet_protect(worksheet3, "password", NULL);
5424  *     worksheet_protect(worksheet4, "password", my_options);
5425  * @endcode
5426  *
5427  * Passing a `NULL` password is the same as turning on protection without a
5428  * password. Passing a `NULL` password and `NULL` options, or any other
5429  * combination has the effect of enabling a cell's `locked` and `hidden`
5430  * properties if they have been set.
5431  *
5432  * A *locked* cell cannot be edited and this property is on by default for all
5433  * cells. A *hidden* cell will display the results of a formula but not the
5434  * formula itself. These properties can be set using the format_set_unlocked()
5435  * and format_set_hidden() format functions.
5436  *
5437  * You can specify which worksheet elements you wish to protect by passing a
5438  * lxw_protection pointer in the `options` argument with any or all of the
5439  * following members set:
5440  *
5441  *     no_select_locked_cells
5442  *     no_select_unlocked_cells
5443  *     format_cells
5444  *     format_columns
5445  *     format_rows
5446  *     insert_columns
5447  *     insert_rows
5448  *     insert_hyperlinks
5449  *     delete_columns
5450  *     delete_rows
5451  *     sort
5452  *     autofilter
5453  *     pivot_tables
5454  *     scenarios
5455  *     objects
5456  *
5457  * All parameters are off by default. Individual elements can be protected as
5458  * follows:
5459  *
5460  * @code
5461  *     lxw_protection options = {
5462  *         .format_cells             = 1,
5463  *         .insert_hyperlinks        = 1,
5464  *         .insert_rows              = 1,
5465  *         .delete_rows              = 1,
5466  *         .insert_columns           = 1,
5467  *         .delete_columns           = 1,
5468  *     };
5469  *
5470  *     worksheet_protect(worksheet, NULL, &options);
5471  *
5472  * @endcode
5473  *
5474  * See also the format_set_unlocked() and format_set_hidden() format functions.
5475  *
5476  * **Note:** Sheet level passwords in Excel offer **very** weak
5477  * protection. They don't encrypt your data and are very easy to
5478  * deactivate. Full workbook encryption is not supported by `libxlsxwriter`
5479  * since it requires a completely different file format.
5480  */
5481 void worksheet_protect(lxw_worksheet *worksheet, const char *password,
5482                        lxw_protection *options);
5483 
5484 /**
5485  * @brief Set the Outline and Grouping display properties.
5486  *
5487  * @param worksheet      Pointer to a lxw_worksheet instance to be updated.
5488  * @param visible        Outlines are visible. Optional, defaults to True.
5489  * @param symbols_below  Show row outline symbols below the outline bar.
5490  * @param symbols_right  Show column outline symbols to the right of outline.
5491  * @param auto_style     Use Automatic outline style.
5492  *
5493  * The `%worksheet_outline_settings()` method is used to control the
5494  * appearance of outlines in Excel. Outlines are described the section on
5495  * @ref working_with_outlines.
5496  *
5497  * The `visible` parameter is used to control whether or not outlines are
5498  * visible. Setting this parameter to False will cause all outlines on the
5499  * worksheet to be hidden. They can be un-hidden in Excel by means of the
5500  * "Show Outline Symbols" command button. The default Excel setting is True
5501  * for visible outlines.
5502  *
5503  * The `symbols_below` parameter is used to control whether the row outline
5504  * symbol will appear above or below the outline level bar. The default Excel
5505  * setting is True for symbols to appear below the outline level bar.
5506  *
5507  * The `symbols_right` parameter is used to control whether the column outline
5508  * symbol will appear to the left or the right of the outline level bar. The
5509  * default Excel setting is True for symbols to appear to the right of the
5510  * outline level bar.
5511  *
5512  * The `auto_style` parameter is used to control whether the automatic outline
5513  * generator in Excel uses automatic styles when creating an outline. This has
5514  * no effect on a file generated by XlsxWriter but it does have an effect on
5515  * how the worksheet behaves after it is created. The default Excel setting is
5516  * False for "Automatic Styles" to be turned off.
5517  *
5518  * The default settings for all of these parameters in libxlsxwriter
5519  * correspond to Excel's default parameters and are shown below:
5520  *
5521  * @code
5522  *     worksheet_outline_settings(worksheet1, LXW_TRUE, LXW_TRUE, LXW_TRUE, LXW_FALSE);
5523  * @endcode
5524  *
5525  * The worksheet parameters controlled by `worksheet_outline_settings()` are
5526  * rarely used.
5527  */
5528 void worksheet_outline_settings(lxw_worksheet *worksheet, uint8_t visible,
5529                                 uint8_t symbols_below, uint8_t symbols_right,
5530                                 uint8_t auto_style);
5531 
5532 /**
5533  * @brief Set the default row properties.
5534  *
5535  * @param worksheet        Pointer to a lxw_worksheet instance to be updated.
5536  * @param height           Default row height.
5537  * @param hide_unused_rows Hide unused cells.
5538  *
5539  * The `%worksheet_set_default_row()` function is used to set Excel default
5540  * row properties such as the default height and the option to hide unused
5541  * rows. These parameters are an optimization used by Excel to set row
5542  * properties without generating a very large file with an entry for each row.
5543  *
5544  * To set the default row height:
5545  *
5546  * @code
5547  *     worksheet_set_default_row(worksheet, 24, LXW_FALSE);
5548  *
5549  * @endcode
5550  *
5551  * To hide unused rows:
5552  *
5553  * @code
5554  *     worksheet_set_default_row(worksheet, 15, LXW_TRUE);
5555  * @endcode
5556  *
5557  * Note, in the previous case we use the default height #LXW_DEF_ROW_HEIGHT =
5558  * 15 so the the height remains unchanged.
5559  */
5560 void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
5561                                uint8_t hide_unused_rows);
5562 
5563 /**
5564  * @brief Set the VBA name for the worksheet.
5565  *
5566  * @param worksheet Pointer to a lxw_worksheet instance.
5567  * @param name      Name of the worksheet used by VBA.
5568  *
5569  * @return A #lxw_error.
5570  *
5571  * The `worksheet_set_vba_name()` function can be used to set the VBA name for
5572  * the worksheet. This is sometimes required when a vbaProject macro included
5573  * via `workbook_add_vba_project()` refers to the worksheet by a name other
5574  * than the worksheet name:
5575  *
5576  * @code
5577  *     workbook_set_vba_name (workbook,  "MyWorkbook");
5578  *     worksheet_set_vba_name(worksheet, "MySheet1");
5579  * @endcode
5580  *
5581  * In general Excel uses the worksheet name such as "Sheet1" as the VBA name.
5582  * However, this can be changed in the VBA environment or if the the macro was
5583  * extracted from a foreign language version of Excel.
5584  *
5585  * See also @ref working_with_macros
5586  */
5587 lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
5588 
5589 /**
5590  * @brief Make all comments in the worksheet visible.
5591  *
5592  * @param worksheet Pointer to a lxw_worksheet instance.
5593  *
5594  * This `%worksheet_show_comments()` function is used to make all cell
5595  * comments visible when a worksheet is opened:
5596  *
5597  * @code
5598  *     worksheet_show_comments(worksheet);
5599  * @endcode
5600  *
5601  * Individual comments can be made visible or hidden using the `visible`
5602  * option of the #lxw_comment_options struct and the `worksheet_write_comment_opt()`
5603  * function (see above and @ref ww_comments_visible).
5604  */
5605 void worksheet_show_comments(lxw_worksheet *worksheet);
5606 
5607 /**
5608  * @brief Set the default author of the cell comments.
5609  *
5610  * @param worksheet Pointer to a lxw_worksheet instance.
5611  * @param author    The name of the comment author.
5612  *
5613  * This `%worksheet_set_comments_author()` function is used to set the
5614  * default author of all cell comments:
5615  *
5616  * @code
5617  *     worksheet_set_comments_author(worksheet, "Jane Gloriana Villanueva")
5618  * @endcode
5619  *
5620  * Individual authors can be set using the `author` option of the
5621  * #lxw_comment_options struct and the `worksheet_write_comment_opt()`
5622  * function (see above and @ref ww_comments_author).
5623  */
5624 void worksheet_set_comments_author(lxw_worksheet *worksheet,
5625                                    const char *author);
5626 
5627 /**
5628  * @brief Ignore various Excel errors/warnings in a worksheet for user
5629  *        defined ranges.
5630  *
5631  * @param worksheet Pointer to a lxw_worksheet instance.
5632  * @param type      The type of error/warning to ignore. See #lxw_ignore_errors.
5633  * @param range     The range(s) for which the error/warning should be ignored.
5634  *
5635  * @return A #lxw_error.
5636  *
5637  *
5638  * The `%worksheet_ignore_errors()` function can be used to ignore various
5639  * worksheet cell errors/warnings. For example the following code writes a string
5640  * that looks like a number:
5641  *
5642  * @code
5643  *     worksheet_write_string(worksheet, CELL("D2"), "123", NULL);
5644  * @endcode
5645  *
5646  * This causes Excel to display a small green triangle in the top left hand
5647  * corner of the cell to indicate an error/warning:
5648  *
5649  * @image html ignore_errors1.png
5650  *
5651  * Sometimes these warnings are useful indicators that there is an issue in
5652  * the spreadsheet but sometimes it is preferable to turn them off. Warnings
5653  * can be turned off at the Excel level for all workbooks and worksheets by
5654  * using the using "Excel options -> Formulas -> Error checking
5655  * rules". Alternatively you can turn them off for individual cells in a
5656  * worksheet, or ranges of cells, using the `%worksheet_ignore_errors()`
5657  * function with different #lxw_ignore_errors options and ranges like this:
5658  *
5659  * @code
5660  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C3");
5661  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_EVAL_ERROR,            "C6");
5662  * @endcode
5663  *
5664  * The range can be a single cell, a range of cells, or multiple cells and ranges
5665  * separated by spaces:
5666  *
5667  * @code
5668  *     // Single cell.
5669  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6");
5670  *
5671  *     // Or a single range:
5672  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6:G8");
5673  *
5674  *     // Or multiple cells and ranges:
5675  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6 E6 G1:G20 J2:J6");
5676  * @endcode
5677  *
5678  * @note Calling `%worksheet_ignore_errors()` more than once for the same
5679  * #lxw_ignore_errors type will overwrite the previous range.
5680  *
5681  * You can turn off warnings for an entire column by specifying the range from
5682  * the first cell in the column to the last cell in the column:
5683  *
5684  * @code
5685  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:A1048576");
5686  * @endcode
5687  *
5688  * Or for the entire worksheet by specifying the range from the first cell in
5689  * the worksheet to the last cell in the worksheet:
5690  *
5691  * @code
5692  *     worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:XFD1048576");
5693  * @endcode
5694  *
5695  * The worksheet errors/warnings that can be ignored are:
5696  *
5697  * - #LXW_IGNORE_NUMBER_STORED_AS_TEXT: Turn off errors/warnings for numbers
5698  *    stores as text.
5699  *
5700  * - #LXW_IGNORE_EVAL_ERROR: Turn off errors/warnings for formula errors (such
5701  *    as divide by zero).
5702  *
5703  * - #LXW_IGNORE_FORMULA_DIFFERS: Turn off errors/warnings for formulas that
5704  *    differ from surrounding formulas.
5705  *
5706  * - #LXW_IGNORE_FORMULA_RANGE: Turn off errors/warnings for formulas that
5707  *    omit cells in a range.
5708  *
5709  * - #LXW_IGNORE_FORMULA_UNLOCKED: Turn off errors/warnings for unlocked cells
5710  *    that contain formulas.
5711  *
5712  * - #LXW_IGNORE_EMPTY_CELL_REFERENCE: Turn off errors/warnings for formulas
5713  *    that refer to empty cells.
5714  *
5715  * - #LXW_IGNORE_LIST_DATA_VALIDATION: Turn off errors/warnings for cells in a
5716  *    table that do not comply with applicable data validation rules.
5717  *
5718  * - #LXW_IGNORE_CALCULATED_COLUMN: Turn off errors/warnings for cell formulas
5719  *    that differ from the column formula.
5720  *
5721  * - #LXW_IGNORE_TWO_DIGIT_TEXT_YEAR: Turn off errors/warnings for formulas
5722  *    that contain a two digit text representation of a year.
5723  *
5724  */
5725 lxw_error worksheet_ignore_errors(lxw_worksheet *worksheet, uint8_t type,
5726                                   const char *range);
5727 
5728 lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
5729 void lxw_worksheet_free(lxw_worksheet *worksheet);
5730 void lxw_worksheet_assemble_xml_file(lxw_worksheet *worksheet);
5731 void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
5732 
5733 void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
5734                                  uint32_t image_ref_id, uint32_t drawing_id,
5735                                  lxw_object_properties *object_props);
5736 
5737 void lxw_worksheet_prepare_header_image(lxw_worksheet *worksheet,
5738                                         uint32_t image_ref_id,
5739                                         lxw_object_properties *object_props);
5740 
5741 void lxw_worksheet_prepare_background(lxw_worksheet *worksheet,
5742                                       uint32_t image_ref_id,
5743                                       lxw_object_properties *object_props);
5744 
5745 void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
5746                                  uint32_t chart_ref_id, uint32_t drawing_id,
5747                                  lxw_object_properties *object_props,
5748                                  uint8_t is_chartsheet);
5749 
5750 uint32_t lxw_worksheet_prepare_vml_objects(lxw_worksheet *worksheet,
5751                                            uint32_t vml_data_id,
5752                                            uint32_t vml_shape_id,
5753                                            uint32_t vml_drawing_id,
5754                                            uint32_t comment_id);
5755 
5756 void lxw_worksheet_prepare_header_vml_objects(lxw_worksheet *worksheet,
5757                                               uint32_t vml_header_id,
5758                                               uint32_t vml_drawing_id);
5759 
5760 void lxw_worksheet_prepare_tables(lxw_worksheet *worksheet,
5761                                   uint32_t table_id);
5762 
5763 lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
5764 lxw_cell *lxw_worksheet_find_cell_in_row(lxw_row *row, lxw_col_t col_num);
5765 /*
5766  * External functions to call intern XML functions shared with chartsheet.
5767  */
5768 void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
5769 void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
5770 void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
5771 void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
5772                                           lxw_protection_obj *protect);
5773 void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
5774 void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
5775 void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
5776 
5777 /* Declarations required for unit testing. */
5778 #ifdef TESTING
5779 
5780 STATIC void _worksheet_xml_declaration(lxw_worksheet *worksheet);
5781 STATIC void _worksheet_write_worksheet(lxw_worksheet *worksheet);
5782 STATIC void _worksheet_write_dimension(lxw_worksheet *worksheet);
5783 STATIC void _worksheet_write_sheet_view(lxw_worksheet *worksheet);
5784 STATIC void _worksheet_write_sheet_views(lxw_worksheet *worksheet);
5785 STATIC void _worksheet_write_sheet_format_pr(lxw_worksheet *worksheet);
5786 STATIC void _worksheet_write_sheet_data(lxw_worksheet *worksheet);
5787 STATIC void _worksheet_write_page_margins(lxw_worksheet *worksheet);
5788 STATIC void _worksheet_write_page_setup(lxw_worksheet *worksheet);
5789 STATIC void _worksheet_write_col_info(lxw_worksheet *worksheet,
5790                                       lxw_col_options *options);
5791 STATIC void _write_row(lxw_worksheet *worksheet, lxw_row *row, char *spans);
5792 STATIC lxw_row *_get_row_list(struct lxw_table_rows *table,
5793                               lxw_row_t row_num);
5794 
5795 STATIC void _worksheet_write_merge_cell(lxw_worksheet *worksheet,
5796                                         lxw_merged_range *merged_range);
5797 STATIC void _worksheet_write_merge_cells(lxw_worksheet *worksheet);
5798 
5799 STATIC void _worksheet_write_odd_header(lxw_worksheet *worksheet);
5800 STATIC void _worksheet_write_odd_footer(lxw_worksheet *worksheet);
5801 STATIC void _worksheet_write_header_footer(lxw_worksheet *worksheet);
5802 
5803 STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
5804 STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
5805 STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
5806 STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
5807                                               lxw_protection_obj *protect);
5808 STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
5809 
5810 STATIC double _pixels_to_height(double pixels);
5811 STATIC double _pixels_to_width(double pixels);
5812 
5813 STATIC void _worksheet_write_auto_filter(lxw_worksheet *worksheet);
5814 #endif /* TESTING */
5815 
5816 /* *INDENT-OFF* */
5817 #ifdef __cplusplus
5818 }
5819 #endif
5820 /* *INDENT-ON* */
5821 
5822 #endif /* __LXW_WORKSHEET_H__ */
5823