libxlsxwriter/include/xlsxwriter/worksheet.h in fast_excel-0.4.1 vs libxlsxwriter/include/xlsxwriter/worksheet.h in fast_excel-0.5.0
- old
+ new
@@ -1,9 +1,9 @@
/*
* libxlsxwriter
*
- * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
+ * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
*/
/**
* @page worksheet_page The Worksheet object
*
@@ -44,37 +44,45 @@
#define __LXW_WORKSHEET_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
-#include <string.h>
#include "shared_strings.h"
#include "chart.h"
#include "drawing.h"
#include "common.h"
#include "format.h"
#include "styles.h"
#include "utility.h"
+#include "relationships.h"
-#define LXW_ROW_MAX 1048576
-#define LXW_COL_MAX 16384
-#define LXW_COL_META_MAX 128
-#define LXW_HEADER_FOOTER_MAX 255
-#define LXW_MAX_NUMBER_URLS 65530
-#define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
+#define LXW_ROW_MAX 1048576
+#define LXW_COL_MAX 16384
+#define LXW_COL_META_MAX 128
+#define LXW_HEADER_FOOTER_MAX 255
+#define LXW_MAX_NUMBER_URLS 65530
+#define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
+#define LXW_IMAGE_BUFFER_SIZE 1024
+#define LXW_HEADER_FOOTER_OBJS_MAX 6 /* Header/footer image objs. */
/* The Excel 2007 specification says that the maximum number of page
* breaks is 1026. However, in practice it is actually 1023. */
#define LXW_BREAKS_MAX 1023
-/** Default column width in Excel */
+/** Default Excel column width in character units. */
#define LXW_DEF_COL_WIDTH (double)8.43
-/** Default row height in Excel */
+/** Default Excel column height in character units. */
#define LXW_DEF_ROW_HEIGHT (double)15.0
+/** Default Excel column width in pixels. */
+#define LXW_DEF_COL_WIDTH_PIXELS 64
+
+/** Default Excel column height in pixels. */
+#define LXW_DEF_ROW_HEIGHT_PIXELS 20
+
/** Gridline options using in `worksheet_gridlines()`. */
enum lxw_gridlines {
/** Hide screen and print gridlines. */
LXW_HIDE_ALL_GRIDLINES = 0,
@@ -200,19 +208,521 @@
/** Show an "Information" data validation pop-up message. */
LXW_VALIDATION_ERROR_TYPE_INFORMATION
};
+/** Set the display type for a cell comment. This is hidden by default but
+ * can be set to visible with the `worksheet_show_comments()` function. */
+enum lxw_comment_display_types {
+ /** Default to the worksheet default which can be hidden or visible.*/
+ LXW_COMMENT_DISPLAY_DEFAULT,
+
+ /** Hide the cell comment. Usually the default. */
+ LXW_COMMENT_DISPLAY_HIDDEN,
+
+ /** Show the cell comment. Can also be set for the worksheet with the
+ * `worksheet_show_comments()` function.*/
+ LXW_COMMENT_DISPLAY_VISIBLE
+};
+
+/** @brief Type definitions for conditional formats.
+ *
+ * Values used to set the "type" field of conditional format.
+ */
+enum lxw_conditional_format_types {
+ LXW_CONDITIONAL_TYPE_NONE,
+
+ /** The Cell type is the most common conditional formatting type. It is
+ * used when a format is applied to a cell based on a simple
+ * criterion. */
+ LXW_CONDITIONAL_TYPE_CELL,
+
+ /** The Text type is used to specify Excel's "Specific Text" style
+ * conditional format. */
+ LXW_CONDITIONAL_TYPE_TEXT,
+
+ /** The Time Period type is used to specify Excel's "Dates Occurring"
+ * style conditional format. */
+ LXW_CONDITIONAL_TYPE_TIME_PERIOD,
+
+ /** The Average type is used to specify Excel's "Average" style
+ * conditional format. */
+ LXW_CONDITIONAL_TYPE_AVERAGE,
+
+ /** The Duplicate type is used to highlight duplicate cells in a range. */
+ LXW_CONDITIONAL_TYPE_DUPLICATE,
+
+ /** The Unique type is used to highlight unique cells in a range. */
+ LXW_CONDITIONAL_TYPE_UNIQUE,
+
+ /** The Top type is used to specify the top n values by number or
+ * percentage in a range. */
+ LXW_CONDITIONAL_TYPE_TOP,
+
+ /** The Bottom type is used to specify the bottom n values by number or
+ * percentage in a range. */
+ LXW_CONDITIONAL_TYPE_BOTTOM,
+
+ /** The Blanks type is used to highlight blank cells in a range. */
+ LXW_CONDITIONAL_TYPE_BLANKS,
+
+ /** The No Blanks type is used to highlight non blank cells in a range. */
+ LXW_CONDITIONAL_TYPE_NO_BLANKS,
+
+ /** The Errors type is used to highlight error cells in a range. */
+ LXW_CONDITIONAL_TYPE_ERRORS,
+
+ /** The No Errors type is used to highlight non error cells in a range. */
+ LXW_CONDITIONAL_TYPE_NO_ERRORS,
+
+ /** The Formula type is used to specify a conditional format based on a
+ * user defined formula. */
+ LXW_CONDITIONAL_TYPE_FORMULA,
+
+ /** The 2 Color Scale type is used to specify Excel's "2 Color Scale"
+ * style conditional format. */
+ LXW_CONDITIONAL_2_COLOR_SCALE,
+
+ /** The 3 Color Scale type is used to specify Excel's "3 Color Scale"
+ * style conditional format. */
+ LXW_CONDITIONAL_3_COLOR_SCALE,
+
+ /** The Data Bar type is used to specify Excel's "Data Bar" style
+ * conditional format. */
+ LXW_CONDITIONAL_DATA_BAR,
+
+ /** The Icon Set type is used to specify a conditional format with a set
+ * of icons such as traffic lights or arrows. */
+ LXW_CONDITIONAL_TYPE_ICON_SETS,
+
+ LXW_CONDITIONAL_TYPE_LAST
+};
+
+/** @brief The criteria used in a conditional format.
+ *
+ * Criteria used to define how a conditional format works.
+ */
+enum lxw_conditional_criteria {
+ LXW_CONDITIONAL_CRITERIA_NONE,
+
+ /** Format cells equal to a value. */
+ LXW_CONDITIONAL_CRITERIA_EQUAL_TO,
+
+ /** Format cells not equal to a value. */
+ LXW_CONDITIONAL_CRITERIA_NOT_EQUAL_TO,
+
+ /** Format cells greater than a value. */
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN,
+
+ /** Format cells less than a value. */
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN,
+
+ /** Format cells greater than or equal to a value. */
+ LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
+
+ /** Format cells less than or equal to a value. */
+ LXW_CONDITIONAL_CRITERIA_LESS_THAN_OR_EQUAL_TO,
+
+ /** Format cells between two values. */
+ LXW_CONDITIONAL_CRITERIA_BETWEEN,
+
+ /** Format cells that is not between two values. */
+ LXW_CONDITIONAL_CRITERIA_NOT_BETWEEN,
+
+ /** Format cells that contain the specified text. */
+ LXW_CONDITIONAL_CRITERIA_TEXT_CONTAINING,
+
+ /** Format cells that don't contain the specified text. */
+ LXW_CONDITIONAL_CRITERIA_TEXT_NOT_CONTAINING,
+
+ /** Format cells that begin with the specified text. */
+ LXW_CONDITIONAL_CRITERIA_TEXT_BEGINS_WITH,
+
+ /** Format cells that end with the specified text. */
+ LXW_CONDITIONAL_CRITERIA_TEXT_ENDS_WITH,
+
+ /** Format cells with a date of yesterday. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_YESTERDAY,
+
+ /** Format cells with a date of today. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TODAY,
+
+ /** Format cells with a date of tomorrow. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_TOMORROW,
+
+ /** Format cells with a date in the last 7 days. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_7_DAYS,
+
+ /** Format cells with a date in the last week. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_WEEK,
+
+ /** Format cells with a date in the current week. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_WEEK,
+
+ /** Format cells with a date in the next week. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_WEEK,
+
+ /** Format cells with a date in the last month. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_LAST_MONTH,
+
+ /** Format cells with a date in the current month. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_THIS_MONTH,
+
+ /** Format cells with a date in the next month. */
+ LXW_CONDITIONAL_CRITERIA_TIME_PERIOD_NEXT_MONTH,
+
+ /** Format cells above the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE,
+
+ /** Format cells below the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW,
+
+ /** Format cells above or equal to the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_ABOVE_OR_EQUAL,
+
+ /** Format cells below or equal to the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_BELOW_OR_EQUAL,
+
+ /** Format cells 1 standard deviation above the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_ABOVE,
+
+ /** Format cells 1 standard deviation below the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_1_STD_DEV_BELOW,
+
+ /** Format cells 2 standard deviation above the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_ABOVE,
+
+ /** Format cells 2 standard deviation below the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_2_STD_DEV_BELOW,
+
+ /** Format cells 3 standard deviation above the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_ABOVE,
+
+ /** Format cells 3 standard deviation below the average for the range. */
+ LXW_CONDITIONAL_CRITERIA_AVERAGE_3_STD_DEV_BELOW,
+
+ /** Format cells in the top of bottom percentage. */
+ LXW_CONDITIONAL_CRITERIA_TOP_OR_BOTTOM_PERCENT
+};
+
+/** @brief Conditional format rule types.
+ *
+ * Conditional format rule types that apply to Color Scale and Data Bars.
+ */
+enum lxw_conditional_format_rule_types {
+ LXW_CONDITIONAL_RULE_TYPE_NONE,
+
+ /** Conditional format rule type: matches the minimum values in the
+ * range. Can only be applied to min_rule_type.*/
+ LXW_CONDITIONAL_RULE_TYPE_MINIMUM,
+
+ /** Conditional format rule type: use a number to set the bound.*/
+ LXW_CONDITIONAL_RULE_TYPE_NUMBER,
+
+ /** Conditional format rule type: use a percentage to set the bound.*/
+ LXW_CONDITIONAL_RULE_TYPE_PERCENT,
+
+ /** Conditional format rule type: use a percentile to set the bound.*/
+ LXW_CONDITIONAL_RULE_TYPE_PERCENTILE,
+
+ /** Conditional format rule type: use a formula to set the bound.*/
+ LXW_CONDITIONAL_RULE_TYPE_FORMULA,
+
+ /** Conditional format rule type: matches the maximum values in the
+ * range. Can only be applied to max_rule_type.*/
+ LXW_CONDITIONAL_RULE_TYPE_MAXIMUM,
+
+ /* Used internally for Excel2010 bars. Not documented. */
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MIN,
+
+ /* Used internally for Excel2010 bars. Not documented. */
+ LXW_CONDITIONAL_RULE_TYPE_AUTO_MAX
+};
+
+/** @brief Conditional format data bar directions.
+ *
+ * Values used to set the bar direction of a conditional format data bar.
+ */
+enum lxw_conditional_format_bar_direction {
+
+ /** Data bar direction is set by Excel based on the context of the data
+ * displayed. */
+ LXW_CONDITIONAL_BAR_DIRECTION_CONTEXT,
+
+ /** Data bar direction is from right to left. */
+ LXW_CONDITIONAL_BAR_DIRECTION_RIGHT_TO_LEFT,
+
+ /** Data bar direction is from left to right. */
+ LXW_CONDITIONAL_BAR_DIRECTION_LEFT_TO_RIGHT
+};
+
+/** @brief Conditional format data bar axis options.
+ *
+ * Values used to set the position of the axis in a conditional format data
+ * bar.
+ */
+enum lxw_conditional_bar_axis_position {
+
+ /** Data bar axis position is set by Excel based on the context of the
+ * data displayed. */
+ LXW_CONDITIONAL_BAR_AXIS_AUTOMATIC,
+
+ /** Data bar axis position is set at the midpoint. */
+ LXW_CONDITIONAL_BAR_AXIS_MIDPOINT,
+
+ /** Data bar axis is turned off. */
+ LXW_CONDITIONAL_BAR_AXIS_NONE
+};
+
+/** @brief Icon types used in the #lxw_conditional_format icon_style field.
+ *
+ * Definitions of icon styles used with Icon Set conditional formats.
+ */
+enum lxw_conditional_icon_types {
+
+ /** Icon style: 3 colored arrows showing up, sideways and down. */
+ LXW_CONDITIONAL_ICONS_3_ARROWS_COLORED,
+
+ /** Icon style: 3 gray arrows showing up, sideways and down. */
+ LXW_CONDITIONAL_ICONS_3_ARROWS_GRAY,
+
+ /** Icon style: 3 colored flags in red, yellow and green. */
+ LXW_CONDITIONAL_ICONS_3_FLAGS,
+
+ /** Icon style: 3 traffic lights - rounded. */
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_UNRIMMED,
+
+ /** Icon style: 3 traffic lights with a rim - squarish. */
+ LXW_CONDITIONAL_ICONS_3_TRAFFIC_LIGHTS_RIMMED,
+
+ /** Icon style: 3 colored shapes - a circle, triangle and diamond. */
+ LXW_CONDITIONAL_ICONS_3_SIGNS,
+
+ /** Icon style: 3 circled symbols with tick mark, exclamation and
+ * cross. */
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_CIRCLED,
+
+ /** Icon style: 3 symbols with tick mark, exclamation and cross. */
+ LXW_CONDITIONAL_ICONS_3_SYMBOLS_UNCIRCLED,
+
+ /** Icon style: 4 colored arrows showing up, diagonal up, diagonal down
+ * and down. */
+ LXW_CONDITIONAL_ICONS_4_ARROWS_COLORED,
+
+ /** Icon style: 4 gray arrows showing up, diagonal up, diagonal down and
+ * down. */
+ LXW_CONDITIONAL_ICONS_4_ARROWS_GRAY,
+
+ /** Icon style: 4 circles in 4 colors going from red to black. */
+ LXW_CONDITIONAL_ICONS_4_RED_TO_BLACK,
+
+ /** Icon style: 4 histogram ratings. */
+ LXW_CONDITIONAL_ICONS_4_RATINGS,
+
+ /** Icon style: 4 traffic lights. */
+ LXW_CONDITIONAL_ICONS_4_TRAFFIC_LIGHTS,
+
+ /** Icon style: 5 colored arrows showing up, diagonal up, sideways,
+ * diagonal down and down. */
+ LXW_CONDITIONAL_ICONS_5_ARROWS_COLORED,
+
+ /** Icon style: 5 gray arrows showing up, diagonal up, sideways, diagonal
+ * down and down. */
+ LXW_CONDITIONAL_ICONS_5_ARROWS_GRAY,
+
+ /** Icon style: 5 histogram ratings. */
+ LXW_CONDITIONAL_ICONS_5_RATINGS,
+
+ /** Icon style: 5 quarters, from 0 to 4 quadrants filled. */
+ LXW_CONDITIONAL_ICONS_5_QUARTERS
+};
+
+/** @brief The type of table style.
+ *
+ * The type of table style (Light, Medium or Dark).
+ */
+enum lxw_table_style_type {
+
+ LXW_TABLE_STYLE_TYPE_DEFAULT,
+
+ /** Light table style. */
+ LXW_TABLE_STYLE_TYPE_LIGHT,
+
+ /** Light table style. */
+ LXW_TABLE_STYLE_TYPE_MEDIUM,
+
+ /** Light table style. */
+ LXW_TABLE_STYLE_TYPE_DARK
+};
+
+/**
+ * @brief Standard Excel functions for totals in tables.
+ *
+ * Definitions for the standard Excel functions that are available via the
+ * dropdown in the total row of an Excel table.
+ *
+ */
+enum lxw_table_total_functions {
+
+ LXW_TABLE_FUNCTION_NONE = 0,
+
+ /** Use the average function as the table total. */
+ LXW_TABLE_FUNCTION_AVERAGE = 101,
+
+ /** Use the count numbers function as the table total. */
+ LXW_TABLE_FUNCTION_COUNT_NUMS = 102,
+
+ /** Use the count function as the table total. */
+ LXW_TABLE_FUNCTION_COUNT = 103,
+
+ /** Use the max function as the table total. */
+ LXW_TABLE_FUNCTION_MAX = 104,
+
+ /** Use the min function as the table total. */
+ LXW_TABLE_FUNCTION_MIN = 105,
+
+ /** Use the standard deviation function as the table total. */
+ LXW_TABLE_FUNCTION_STD_DEV = 107,
+
+ /** Use the sum function as the table total. */
+ LXW_TABLE_FUNCTION_SUM = 109,
+
+ /** Use the var function as the table total. */
+ LXW_TABLE_FUNCTION_VAR = 110
+};
+
+/** @brief The criteria used in autofilter rules.
+ *
+ * Criteria used to define an autofilter rule condition.
+ */
+enum lxw_filter_criteria {
+ LXW_FILTER_CRITERIA_NONE,
+
+ /** Filter cells equal to a value. */
+ LXW_FILTER_CRITERIA_EQUAL_TO,
+
+ /** Filter cells not equal to a value. */
+ LXW_FILTER_CRITERIA_NOT_EQUAL_TO,
+
+ /** Filter cells greater than a value. */
+ LXW_FILTER_CRITERIA_GREATER_THAN,
+
+ /** Filter cells less than a value. */
+ LXW_FILTER_CRITERIA_LESS_THAN,
+
+ /** Filter cells greater than or equal to a value. */
+ LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
+
+ /** Filter cells less than or equal to a value. */
+ LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO,
+
+ /** Filter cells that are blank. */
+ LXW_FILTER_CRITERIA_BLANKS,
+
+ /** Filter cells that are not blank. */
+ LXW_FILTER_CRITERIA_NON_BLANKS
+};
+
+/**
+ * @brief And/or operator when using 2 filter rules.
+ *
+ * And/or operator conditions when using 2 filter rules with
+ * worksheet_filter_column2(). In general LXW_FILTER_OR is used with
+ * LXW_FILTER_CRITERIA_EQUAL_TO and LXW_FILTER_AND is used with the other
+ * filter criteria.
+ */
+enum lxw_filter_operator {
+ /** Logical "and" of 2 filter rules. */
+ LXW_FILTER_AND,
+
+ /** Logical "or" of 2 filter rules. */
+ LXW_FILTER_OR
+};
+
+/* Internal filter types. */
+enum lxw_filter_type {
+ LXW_FILTER_TYPE_NONE,
+
+ LXW_FILTER_TYPE_SINGLE,
+
+ LXW_FILTER_TYPE_AND,
+
+ LXW_FILTER_TYPE_OR,
+
+ LXW_FILTER_TYPE_STRING_LIST
+};
+
+/** Options to control the positioning of worksheet objects such as images
+ * or charts. See @ref working_with_object_positioning. */
+enum lxw_object_position {
+
+ /** Default positioning for the object. */
+ LXW_OBJECT_POSITION_DEFAULT,
+
+ /** Move and size the worksheet object with the cells. */
+ LXW_OBJECT_MOVE_AND_SIZE,
+
+ /** Move but don't size the worksheet object with the cells. */
+ LXW_OBJECT_MOVE_DONT_SIZE,
+
+ /** Don't move or size the worksheet object with the cells. */
+ LXW_OBJECT_DONT_MOVE_DONT_SIZE,
+
+ /** Same as #LXW_OBJECT_MOVE_AND_SIZE except libxlsxwriter applies hidden
+ * cells after the object is inserted. */
+ LXW_OBJECT_MOVE_AND_SIZE_AFTER
+};
+
+/** Options for ignoring worksheet errors/warnings. See worksheet_ignore_errors(). */
+enum lxw_ignore_errors {
+
+ /** Turn off errors/warnings for numbers stores as text. */
+ LXW_IGNORE_NUMBER_STORED_AS_TEXT = 1,
+
+ /** Turn off errors/warnings for formula errors (such as divide by
+ * zero). */
+ LXW_IGNORE_EVAL_ERROR,
+
+ /** Turn off errors/warnings for formulas that differ from surrounding
+ * formulas. */
+ LXW_IGNORE_FORMULA_DIFFERS,
+
+ /** Turn off errors/warnings for formulas that omit cells in a range. */
+ LXW_IGNORE_FORMULA_RANGE,
+
+ /** Turn off errors/warnings for unlocked cells that contain formulas. */
+ LXW_IGNORE_FORMULA_UNLOCKED,
+
+ /** Turn off errors/warnings for formulas that refer to empty cells. */
+ LXW_IGNORE_EMPTY_CELL_REFERENCE,
+
+ /** Turn off errors/warnings for cells in a table that do not comply with
+ * applicable data validation rules. */
+ LXW_IGNORE_LIST_DATA_VALIDATION,
+
+ /** Turn off errors/warnings for cell formulas that differ from the column
+ * formula. */
+ LXW_IGNORE_CALCULATED_COLUMN,
+
+ /** Turn off errors/warnings for formulas that contain a two digit text
+ * representation of a year. */
+ LXW_IGNORE_TWO_DIGIT_TEXT_YEAR,
+
+ LXW_IGNORE_LAST_OPTION
+};
+
enum cell_types {
NUMBER_CELL = 1,
STRING_CELL,
INLINE_STRING_CELL,
INLINE_RICH_STRING_CELL,
FORMULA_CELL,
ARRAY_FORMULA_CELL,
+ DYNAMIC_ARRAY_FORMULA_CELL,
BLANK_CELL,
BOOLEAN_CELL,
+ COMMENT,
HYPERLINK_URL,
HYPERLINK_INTERNAL,
HYPERLINK_EXTERNAL
};
@@ -221,12 +731,24 @@
FREEZE_PANES,
SPLIT_PANES,
FREEZE_SPLIT_PANES
};
+enum lxw_image_position {
+ HEADER_LEFT = 0,
+ HEADER_CENTER,
+ HEADER_RIGHT,
+ FOOTER_LEFT,
+ FOOTER_CENTER,
+ FOOTER_RIGHT
+};
+
/* Define the tree.h RB structs for the red-black head types. */
RB_HEAD(lxw_table_cells, lxw_cell);
+RB_HEAD(lxw_drawing_rel_ids, lxw_drawing_rel_id);
+RB_HEAD(lxw_vml_drawing_rel_ids, lxw_drawing_rel_id);
+RB_HEAD(lxw_cond_format_hash, lxw_cond_format_hash_element);
/* Define a RB_TREE struct manually to add extra members. */
struct lxw_table_rows {
struct lxw_row *rbh_root;
struct lxw_row *cached_row;
@@ -255,15 +777,51 @@
RB_GENERATE_NEXT(name, type, field, static) \
RB_GENERATE_MINMAX(name, type, field, static) \
/* Add unused struct to allow adding a semicolon */ \
struct lxw_rb_generate_cell{int unused;}
+#define LXW_RB_GENERATE_DRAWING_REL_IDS(name, type, field, cmp) \
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
+ RB_GENERATE_REMOVE(name, type, field, static) \
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
+ RB_GENERATE_NEXT(name, type, field, static) \
+ RB_GENERATE_MINMAX(name, type, field, static) \
+ /* Add unused struct to allow adding a semicolon */ \
+ struct lxw_rb_generate_drawing_rel_ids{int unused;}
+
+#define LXW_RB_GENERATE_VML_DRAWING_REL_IDS(name, type, field, cmp) \
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
+ RB_GENERATE_REMOVE(name, type, field, static) \
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
+ RB_GENERATE_NEXT(name, type, field, static) \
+ RB_GENERATE_MINMAX(name, type, field, static) \
+ /* Add unused struct to allow adding a semicolon */ \
+ struct lxw_rb_generate_vml_drawing_rel_ids{int unused;}
+
+#define LXW_RB_GENERATE_COND_FORMAT_HASH(name, type, field, cmp) \
+ RB_GENERATE_INSERT_COLOR(name, type, field, static) \
+ RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
+ RB_GENERATE_INSERT(name, type, field, cmp, static) \
+ RB_GENERATE_REMOVE(name, type, field, static) \
+ RB_GENERATE_FIND(name, type, field, cmp, static) \
+ RB_GENERATE_NEXT(name, type, field, static) \
+ RB_GENERATE_MINMAX(name, type, field, static) \
+ /* Add unused struct to allow adding a semicolon */ \
+ struct lxw_rb_generate_cond_format_hash{int unused;}
+
STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
STAILQ_HEAD(lxw_selections, lxw_selection);
-STAILQ_HEAD(lxw_data_validations, lxw_data_validation);
-STAILQ_HEAD(lxw_image_data, lxw_image_options);
-STAILQ_HEAD(lxw_chart_data, lxw_image_options);
+STAILQ_HEAD(lxw_data_validations, lxw_data_val_obj);
+STAILQ_HEAD(lxw_cond_format_list, lxw_cond_format_obj);
+STAILQ_HEAD(lxw_image_props, lxw_object_properties);
+STAILQ_HEAD(lxw_chart_props, lxw_object_properties);
+STAILQ_HEAD(lxw_comment_objs, lxw_vml_obj);
+STAILQ_HEAD(lxw_table_objs, lxw_table_obj);
/**
* @brief Options for rows and columns.
*
* Options struct for the worksheet_set_column() and worksheet_set_row()
@@ -277,13 +835,17 @@
*
* The members of this struct are explained in @ref ww_outlines_grouping.
*
*/
typedef struct lxw_row_col_options {
- /** Hide the row/column */
+ /** Hide the row/column. @ref ww_outlines_grouping.*/
uint8_t hidden;
+
+ /** Outline level. See @ref ww_outlines_grouping.*/
uint8_t level;
+
+ /** Set the outline row as collapsed. See @ref ww_outlines_grouping.*/
uint8_t collapsed;
} lxw_row_col_options;
typedef struct lxw_col_options {
lxw_col_t firstcol;
@@ -324,10 +886,11 @@
lxw_col_t last_col;
} lxw_print_area;
typedef struct lxw_autofilter {
uint8_t in_use;
+ uint8_t has_rules;
lxw_row_t first_row;
lxw_row_t last_row;
lxw_col_t first_col;
lxw_col_t last_col;
} lxw_autofilter;
@@ -403,12 +966,10 @@
* dropdown list will be shown for list validations. Should be a
* #lxw_validation_boolean value. It is on by default.
*/
uint8_t dropdown;
- uint8_t is_between;
-
/**
* This parameter is used to set the limiting value to which the criteria
* is applied using a whole or decimal number.
*/
double value_number;
@@ -416,11 +977,11 @@
/**
* This parameter is used to set the limiting value to which the criteria
* is applied using a cell reference. It is valid for any of the
* `_FORMULA` validation types.
*/
- char *value_formula;
+ const char *value_formula;
/**
* This parameter is used to set a list of strings for a drop down list.
* The list should be a `NULL` terminated array of char* strings:
*
@@ -435,11 +996,11 @@
* an Excel cell range.
*
* Note, the string list is restricted by Excel to 255 characters,
* including comma separators.
*/
- char **value_list;
+ const char **value_list;
/**
* This parameter is used to set the limiting value to which the date or
* time criteria is applied using a #lxw_datetime struct.
*/
@@ -453,11 +1014,11 @@
/**
* This parameter is the same as `value_formula` but for the minimum value
* when a `BETWEEN` criteria is used.
*/
- char *minimum_formula;
+ const char *minimum_formula;
/**
* This parameter is the same as `value_datetime` but for the minimum value
* when a `BETWEEN` criteria is used.
*/
@@ -471,11 +1032,11 @@
/**
* This parameter is the same as `value_formula` but for the maximum value
* when a `BETWEEN` criteria is used.
*/
- char *maximum_formula;
+ const char *maximum_formula;
/**
* This parameter is the same as `value_datetime` but for the maximum value
* when a `BETWEEN` criteria is used.
*/
@@ -487,49 +1048,655 @@
* is only displayed if the input message is displayed. See the
* `input_message` parameter below.
*
* The maximum title length is 32 characters.
*/
- char *input_title;
+ const char *input_title;
/**
* The input_message parameter is used to set the input message that is
* displayed when a cell is entered. It has no default value.
*
* The message can be split over several lines using newlines. The maximum
* message length is 255 characters.
*/
- char *input_message;
+ const char *input_message;
/**
* The error_title parameter is used to set the title of the error message
* that is displayed when the data validation criteria is not met. The
* default error title is 'Microsoft Excel'. The maximum title length is
* 32 characters.
*/
- char *error_title;
+ const char *error_title;
/**
* The error_message parameter is used to set the error message that is
* displayed when a cell is entered. The default error message is "The
* value you entered is not valid. A user has restricted values that can
* be entered into the cell".
*
* The message can be split over several lines using newlines. The maximum
* message length is 255 characters.
*/
- char *error_message;
+ const char *error_message;
+} lxw_data_validation;
+
+/* A copy of lxw_data_validation which is used internally and which contains
+ * some additional fields.
+ */
+typedef struct lxw_data_val_obj {
+ uint8_t validate;
+ uint8_t criteria;
+ uint8_t ignore_blank;
+ uint8_t show_input;
+ uint8_t show_error;
+ uint8_t error_type;
+ uint8_t dropdown;
+ double value_number;
+ char *value_formula;
+ char **value_list;
+ double minimum_number;
+ char *minimum_formula;
+ lxw_datetime minimum_datetime;
+ double maximum_number;
+ char *maximum_formula;
+ lxw_datetime maximum_datetime;
+ char *input_title;
+ char *input_message;
+ char *error_title;
+ char *error_message;
char sqref[LXW_MAX_CELL_RANGE_LENGTH];
- STAILQ_ENTRY (lxw_data_validation) list_pointers;
+ STAILQ_ENTRY (lxw_data_val_obj) list_pointers;
+} lxw_data_val_obj;
-} lxw_data_validation;
+/**
+ * @brief Worksheet conditional formatting options.
+ *
+ * The fields/options in the the lxw_conditional_format are used to define a
+ * worksheet conditional format. It is used in conjunction with
+ * `worksheet_conditional_format()`.
+ *
+ */
+typedef struct lxw_conditional_format {
+ /** The type of conditional format such as #LXW_CONDITIONAL_TYPE_CELL or
+ * #LXW_CONDITIONAL_DATA_BAR. Should be a #lxw_conditional_format_types
+ * value.*/
+ uint8_t type;
+
+ /** The criteria parameter is used to set the criteria by which the cell
+ * data will be evaluated. For example in the expression `a > 5 the
+ * criteria is `>` or, in libxlsxwriter terms,
+ * #LXW_CONDITIONAL_CRITERIA_GREATER_THAN. The criteria that are
+ * applicable depend on the conditional format type. The criteria
+ * options are defined in #lxw_conditional_criteria. */
+ uint8_t criteria;
+
+ /** The number value to which the condition refers. For example in the
+ * expression `a > 5`, the value is 5.*/
+ double value;
+
+ /** The string value to which the condition refers, such as `"=A1"`. If a
+ * value_string exists in the struct then the number value is
+ * ignored. Note, if the condition refers to a text string then it must
+ * be double quoted like this `"foo"`. */
+ const char *value_string;
+
+ /** The format field is used to specify the #lxw_format format that will
+ * be applied to the cell when the conditional formatting criterion is
+ * met. The #lxw_format is created using the `workbook_add_format()`
+ * method in the same way as cell formats.
+ *
+ * @note In Excel, a conditional format is superimposed over the existing
+ * cell format and not all cell format properties can be
+ * modified. Properties that @b cannot be modified, in Excel, by a
+ * conditional format are: font name, font size, superscript and
+ * subscript, diagonal borders, all alignment properties and all
+ * protection properties. */
+ lxw_format *format;
+
+ /** The minimum value used for Cell, Color Scale and Data Bar conditional
+ * formats. For Cell types this is usually used with a "Between" style criteria. */
+ double min_value;
+
+ /** The minimum string value used for Cell, Color Scale and Data Bar conditional
+ * formats. Usually used to set ranges like `=A1`. */
+ const char *min_value_string;
+
+ /** The rule used for the minimum condition in Color Scale and Data Bar
+ * conditional formats. The rule types are defined in
+ * #lxw_conditional_format_rule_types. */
+ uint8_t min_rule_type;
+
+ /** The color used for the minimum Color Scale conditional format.
+ * See @ref working_with_colors. */
+ lxw_color_t min_color;
+
+ /** The middle value used for Color Scale and Data Bar conditional
+ * formats. */
+ double mid_value;
+
+ /** The middle string value used for Color Scale and Data Bar conditional
+ * formats. Usually used to set ranges like `=A1`. */
+ const char *mid_value_string;
+
+ /** The rule used for the middle condition in Color Scale and Data Bar
+ * conditional formats. The rule types are defined in
+ * #lxw_conditional_format_rule_types. */
+ uint8_t mid_rule_type;
+
+ /** The color used for the middle Color Scale conditional format.
+ * See @ref working_with_colors. */
+ lxw_color_t mid_color;
+
+ /** The maximum value used for Cell, Color Scale and Data Bar conditional
+ * formats. For Cell types this is usually used with a "Between" style
+ * criteria. */
+ double max_value;
+
+ /** The maximum string value used for Cell, Color Scale and Data Bar conditional
+ * formats. Usually used to set ranges like `=A1`. */
+ const char *max_value_string;
+
+ /** The rule used for the maximum condition in Color Scale and Data Bar
+ * conditional formats. The rule types are defined in
+ * #lxw_conditional_format_rule_types. */
+ uint8_t max_rule_type;
+
+ /** The color used for the maximum Color Scale conditional format.
+ * See @ref working_with_colors. */
+ lxw_color_t max_color;
+
+ /** The bar_color field sets the fill color for data bars. See @ref
+ * working_with_colors. */
+ lxw_color_t bar_color;
+
+ /** The bar_only field sets The bar_only field displays a bar data but
+ * not the data in the cells. */
+ uint8_t bar_only;
+
+ /** In Excel 2010 additional data bar properties were added such as solid
+ * (non-gradient) bars and control over how negative values are
+ * displayed. These properties can shown below.
+ *
+ * The data_bar_2010 field sets Excel 2010 style data bars even when
+ * Excel 2010 specific properties aren't used. */
+ uint8_t data_bar_2010;
+
+ /** The bar_solid field turns on a solid (non-gradient) fill for data
+ * bars. Set to LXW_TRUE to turn on. Excel 2010 only. */
+ uint8_t bar_solid;
+
+ /** The bar_negative_color field sets the color fill for the negative
+ * portion of a data bar. See @ref working_with_colors. Excel 2010 only. */
+ lxw_color_t bar_negative_color;
+
+ /** The bar_border_color field sets the color for the border line of a
+ * data bar. See @ref working_with_colors. Excel 2010 only. */
+ lxw_color_t bar_border_color;
+
+ /** The bar_negative_border_color field sets the color for the border of
+ * the negative portion of a data bar. See @ref
+ * working_with_colors. Excel 2010 only. */
+ lxw_color_t bar_negative_border_color;
+
+ /** The bar_negative_color_same field sets the fill color for the negative
+ * portion of a data bar to be the same as the fill color for the
+ * positive portion of the data bar. Set to LXW_TRUE to turn on. Excel
+ * 2010 only. */
+ uint8_t bar_negative_color_same;
+
+ /** The bar_negative_border_color_same field sets the border color for the
+ * negative portion of a data bar to be the same as the border color for
+ * the positive portion of the data bar. Set to LXW_TRUE to turn
+ * on. Excel 2010 only. */
+ uint8_t bar_negative_border_color_same;
+
+ /** The bar_no_border field turns off the border for data bars. Set to
+ * LXW_TRUE to enable. Excel 2010 only. */
+ uint8_t bar_no_border;
+
+ /** The bar_direction field sets the direction for data bars. This
+ * property can be either left for left-to-right or right for
+ * right-to-left. If the property isn't set then Excel will adjust the
+ * position automatically based on the context. Should be a
+ * #lxw_conditional_format_bar_direction value. Excel 2010 only. */
+ uint8_t bar_direction;
+
+ /** The bar_axis_position field sets the position within the cells for the
+ * axis that is shown in data bars when there are negative values to
+ * display. The property can be either middle or none. If the property
+ * isn't set then Excel will position the axis based on the range of
+ * positive and negative values. Should be a
+ * lxw_conditional_bar_axis_position value. Excel 2010 only. */
+ uint8_t bar_axis_position;
+
+ /** The bar_axis_color field sets the color for the axis that is shown
+ * in data bars when there are negative values to display. See @ref
+ * working_with_colors. Excel 2010 only. */
+ lxw_color_t bar_axis_color;
+
+ /** The Icons Sets style is specified by the icon_style parameter. Should
+ * be a #lxw_conditional_icon_types. */
+ uint8_t icon_style;
+
+ /** The order of Icon Sets icons can be reversed by setting reverse_icons
+ * to LXW_TRUE. */
+ uint8_t reverse_icons;
+
+ /** The icons can be displayed without the cell value by settings the
+ * icons_only parameter to LXW_TRUE. */
+ uint8_t icons_only;
+
+ /** The multi_range field is used to extend a conditional format over
+ * non-contiguous ranges.
+ *
+ * It is possible to apply the conditional format to different cell
+ * ranges in a worksheet using multiple calls to
+ * `worksheet_conditional_format()`. However, as a minor optimization it
+ * is also possible in Excel to apply the same conditional format to
+ * different non-contiguous cell ranges.
+ *
+ * This is replicated in `worksheet_conditional_format()` using the
+ * multi_range option. The range must contain the primary range for the
+ * conditional format and any others separated by spaces. For example
+ * `"A1 C1:C5 E2 G1:G100"`.
+ */
+ const char *multi_range;
+
+ /** The stop_if_true parameter can be used to set the "stop if true"
+ * feature of a conditional formatting rule when more than one rule is
+ * applied to a cell or a range of cells. When this parameter is set then
+ * subsequent rules are not evaluated if the current rule is true. Set to
+ * LXW_TRUE to turn on. */
+ uint8_t stop_if_true;
+
+} lxw_conditional_format;
+
+/* Internal */
+typedef struct lxw_cond_format_obj {
+ uint8_t type;
+ uint8_t criteria;
+
+ double min_value;
+ char *min_value_string;
+ uint8_t min_rule_type;
+ lxw_color_t min_color;
+
+ double mid_value;
+ char *mid_value_string;
+ uint8_t mid_value_type;
+ uint8_t mid_rule_type;
+ lxw_color_t mid_color;
+
+ double max_value;
+ char *max_value_string;
+ uint8_t max_value_type;
+ uint8_t max_rule_type;
+ lxw_color_t max_color;
+
+ uint8_t data_bar_2010;
+ uint8_t auto_min;
+ uint8_t auto_max;
+ uint8_t bar_only;
+ uint8_t bar_solid;
+ uint8_t bar_negative_color_same;
+ uint8_t bar_negative_border_color_same;
+ uint8_t bar_no_border;
+ uint8_t bar_direction;
+ uint8_t bar_axis_position;
+ lxw_color_t bar_color;
+ lxw_color_t bar_negative_color;
+ lxw_color_t bar_border_color;
+ lxw_color_t bar_negative_border_color;
+ lxw_color_t bar_axis_color;
+
+ uint8_t icon_style;
+ uint8_t reverse_icons;
+ uint8_t icons_only;
+
+ uint8_t stop_if_true;
+ uint8_t has_max;
+ char *type_string;
+ char *guid;
+
+ int32_t dxf_index;
+ uint32_t dxf_priority;
+
+ char first_cell[LXW_MAX_CELL_NAME_LENGTH];
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
+
+ STAILQ_ENTRY (lxw_cond_format_obj) list_pointers;
+} lxw_cond_format_obj;
+
+typedef struct lxw_cond_format_hash_element {
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
+
+ struct lxw_cond_format_list *cond_formats;
+
+ RB_ENTRY (lxw_cond_format_hash_element) tree_pointers;
+} lxw_cond_format_hash_element;
+
/**
- * @brief Options for inserted images
+ * @brief Table columns options.
*
+ * Structure to set the options of a table column added with
+ * worksheet_add_table(). See @ref ww_tables_columns.
+ */
+typedef struct lxw_table_column {
+
+ /** Set the header name/caption for the column. If NULL the header defaults
+ * to Column 1, Column 2, etc. */
+ const char *header;
+
+ /** Set the formula for the column. */
+ const char *formula;
+
+ /** Set the string description for the column total. */
+ const char *total_string;
+
+ /** Set the function for the column total. */
+ uint8_t total_function;
+
+ /** Set the format for the column header. */
+ lxw_format *header_format;
+
+ /** Set the format for the data rows in the column. */
+ lxw_format *format;
+
+ /** Set the formula value for the column total (not generally required). */
+ double total_value;
+
+} lxw_table_column;
+
+/**
+ * @brief Worksheet table options.
+ *
+ * Options used to define worksheet tables. See @ref working_with_tables for
+ * more information.
+ *
+ */
+typedef struct lxw_table_options {
+
+ /**
+ * The `name` parameter is used to set the name of the table. This
+ * parameter is optional and by default tables are named `Table1`,
+ * `Table2`, etc. in the worksheet order that they are added.
+ *
+ * @code
+ * lxw_table_options options = {.name = "Sales"};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
+ * @endcode
+ *
+ * If you override the table name you must ensure that it doesn't clash
+ * with an existing table name and that it follows Excel's requirements
+ * for table names, see the Microsoft Office documentation on
+ * [Naming an Excel Table]
+ * (https://support.microsoft.com/en-us/office/rename-an-excel-table-fbf49a4f-82a3-43eb-8ba2-44d21233b114).
+ */
+ const char *name;
+
+ /**
+ * The `no_header_row` parameter can be used to turn off the header row in
+ * the table. It is on by default:
+ *
+ * @code
+ * lxw_table_options options = {.no_header_row = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B4:F7"), &options);
+ * @endcode
+ *
+ * @image html tables4.png
+ *
+ * Without this option the header row will contain default captions such
+ * as `Column 1`, ``Column 2``, etc. These captions can be overridden
+ * using the `columns` parameter shown below.
+ *
+ */
+ uint8_t no_header_row;
+
+ /**
+ * The `no_autofilter` parameter can be used to turn off the autofilter in
+ * the header row. It is on by default:
+ *
+ * @code
+ * lxw_table_options options = {.no_autofilter = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
+ * @endcode
+ *
+ * @image html tables3.png
+ *
+ * The autofilter is only shown if the `no_header_row` parameter is off
+ * (the default). Filter conditions within the table are not supported.
+ *
+ */
+ uint8_t no_autofilter;
+
+ /**
+ * The `no_banded_rows` parameter can be used to turn off the rows of alternating
+ * color in the table. It is on by default:
+ *
+ * @code
+ * lxw_table_options options = {.no_banded_rows = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
+ * @endcode
+ *
+ * @image html tables6.png
+ *
+ */
+ uint8_t no_banded_rows;
+
+ /**
+ * The `banded_columns` parameter can be used to used to create columns of
+ * alternating color in the table. It is off by default:
+ *
+ * @code
+ * lxw_table_options options = {.banded_columns = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
+ * @endcode
+ *
+ * The banded columns formatting is shown in the image in the previous
+ * section above.
+ */
+ uint8_t banded_columns;
+
+ /**
+ * The `first_column` parameter can be used to highlight the first column
+ * of the table. The type of highlighting will depend on the `style_type`
+ * of the table. It may be bold text or a different color. It is off by
+ * default:
+ *
+ * @code
+ * lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
+ * @endcode
+ *
+ * @image html tables5.png
+ */
+ uint8_t first_column;
+
+ /**
+ * The `last_column` parameter can be used to highlight the last column of
+ * the table. The type of highlighting will depend on the `style` of the
+ * table. It may be bold text or a different color. It is off by default:
+ *
+ * @code
+ * lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
+ * @endcode
+ *
+ * The `last_column` formatting is shown in the image in the previous
+ * section above.
+ */
+ uint8_t last_column;
+
+ /**
+ * The `style_type` parameter can be used to set the style of the table,
+ * in conjunction with the `style_type_number` parameter:
+ *
+ * @code
+ * lxw_table_options options = {
+ * .style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
+ * .style_type_number = 11,
+ * };
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
+ * @endcode
+ *
+ *
+ * @image html tables11.png
+ *
+ * There are three types of table style in Excel: Light, Medium and Dark
+ * which are represented using the #lxw_table_style_type enum values:
+ *
+ * - #LXW_TABLE_STYLE_TYPE_LIGHT
+ *
+ * - #LXW_TABLE_STYLE_TYPE_MEDIUM
+ *
+ * - #LXW_TABLE_STYLE_TYPE_DARK
+ *
+ * Within those ranges there are between 11 and 28 other style types which
+ * can be set with `style_type_number` (depending on the style type).
+ * Check Excel to find the style that you want. The dialog with the
+ * options laid out in numeric order are shown below:
+ *
+ * @image html tables14.png
+ *
+ * The default table style in Excel is 'Table Style Medium 9' (highlighted
+ * with a green border in the image above), which is set by default in
+ * libxlsxwriter as:
+ *
+ * @code
+ * lxw_table_options options = {
+ * .style_type = LXW_TABLE_STYLE_TYPE_MEDIUM,
+ * .style_type_number = 9,
+ * };
+ * @endcode
+ *
+ * You can also turn the table style off by setting it to Light 0:
+ *
+ * @code
+ * lxw_table_options options = {
+ * .style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
+ * .style_type_number = 0,
+ * };
+ * @endcode
+ *
+ * @image html tables13.png
+ *
+ */
+ uint8_t style_type;
+
+ /**
+ * The `style_type_number` parameter is used with `style_type` to set the
+ * style of a worksheet table. */
+ uint8_t style_type_number;
+
+ /**
+ * The `total_row` parameter can be used to turn on the total row in the
+ * last row of a table. It is distinguished from the other rows by a
+ * different formatting and also with dropdown `SUBTOTAL` functions:
+ *
+ * @code
+ * lxw_table_options options = {.total_row = LXW_TRUE};
+ *
+ * worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
+ * @endcode
+ *
+ * @image html tables9.png
+ *
+ * The default total row doesn't have any captions or functions. These
+ * must by specified via the `columns` parameter below.
+ */
+ uint8_t total_row;
+
+ /**
+ * The `columns` parameter can be used to set properties for columns
+ * within the table. See @ref ww_tables_columns for a detailed
+ * explanation.
+ */
+ lxw_table_column **columns;
+
+} lxw_table_options;
+
+typedef struct lxw_table_obj {
+ char *name;
+ char *total_string;
+ lxw_table_column **columns;
+ uint8_t banded_columns;
+ uint8_t first_column;
+ uint8_t last_column;
+ uint8_t no_autofilter;
+ uint8_t no_banded_rows;
+ uint8_t no_header_row;
+ uint8_t style_type;
+ uint8_t style_type_number;
+ uint8_t total_row;
+
+ lxw_row_t first_row;
+ lxw_col_t first_col;
+ lxw_row_t last_row;
+ lxw_col_t last_col;
+ lxw_col_t num_cols;
+ uint32_t id;
+
+ char sqref[LXW_MAX_ATTRIBUTE_LENGTH];
+ char filter_sqref[LXW_MAX_ATTRIBUTE_LENGTH];
+ STAILQ_ENTRY (lxw_table_obj) list_pointers;
+
+} lxw_table_obj;
+
+/**
+ * @brief Options for autofilter rules.
+ *
+ * Options to define an autofilter rule.
+ *
+ */
+typedef struct lxw_filter_rule {
+
+ /** The #lxw_filter_criteria to define the rule. */
+ uint8_t criteria;
+
+ /** String value to which the criteria applies. */
+ const char *value_string;
+
+ /** Numeric value to which the criteria applies (if value_string isn't used). */
+ double value;
+
+} lxw_filter_rule;
+
+typedef struct lxw_filter_rule_obj {
+
+ uint8_t type;
+ uint8_t is_custom;
+ uint8_t has_blanks;
+ lxw_col_t col_num;
+
+ uint8_t criteria1;
+ uint8_t criteria2;
+ double value1;
+ double value2;
+ char *value1_string;
+ char *value2_string;
+
+ uint16_t num_list_filters;
+ char **list;
+
+} lxw_filter_rule_obj;
+
+/**
+ * @brief Options for inserted images.
+ *
* Options for modifying images inserted via `worksheet_insert_image_opt()`.
*
*/
typedef struct lxw_image_options {
@@ -543,45 +1710,293 @@
double x_scale;
/** Y scale of the image as a decimal. */
double y_scale;
+ /** Object position - use one of the values of #lxw_object_position.
+ * See @ref working_with_object_positioning.*/
+ uint8_t object_position;
+
+ /** Optional description or "Alt text" for the image. This field can be
+ * used to provide a text description of the image to help
+ * accessibility. Defaults to the image filename as in Excel. Set to ""
+ * to ignore the description field. */
+ const char *description;
+
+ /** Optional parameter to help accessibility. It is used to mark the image
+ * as decorative, and thus uninformative, for automated screen
+ * readers. As in Excel, if this parameter is in use the `description`
+ * field isn't written. */
+ uint8_t decorative;
+
+ /** Add an optional hyperlink to the image. Follows the same URL rules
+ * and types as `worksheet_write_url()`. */
+ const char *url;
+
+ /** Add an optional mouseover tip for a hyperlink to the image. */
+ const char *tip;
+
+} lxw_image_options;
+
+/**
+ * @brief Options for inserted charts.
+ *
+ * Options for modifying charts inserted via `worksheet_insert_chart_opt()`.
+ *
+ */
+typedef struct lxw_chart_options {
+
+ /** Offset from the left of the cell in pixels. */
+ int32_t x_offset;
+
+ /** Offset from the top of the cell in pixels. */
+ int32_t y_offset;
+
+ /** X scale of the chart as a decimal. */
+ double x_scale;
+
+ /** Y scale of the chart as a decimal. */
+ double y_scale;
+
+ /** Object position - use one of the values of #lxw_object_position.
+ * See @ref working_with_object_positioning.*/
+ uint8_t object_position;
+
+ /** Optional description or "Alt text" for the chart. This field can be
+ * used to provide a text description of the chart to help
+ * accessibility. Defaults to the image filename as in Excel. Set to NULL
+ * to ignore the description field. */
+ const char *description;
+
+ /** Optional parameter to help accessibility. It is used to mark the chart
+ * as decorative, and thus uninformative, for automated screen
+ * readers. As in Excel, if this parameter is in use the `description`
+ * field isn't written. */
+ uint8_t decorative;
+
+} lxw_chart_options;
+
+/* Internal struct to represent lxw_image_options and lxw_chart_options
+ * values as well as internal metadata.
+ */
+typedef struct lxw_object_properties {
+ int32_t x_offset;
+ int32_t y_offset;
+ double x_scale;
+ double y_scale;
lxw_row_t row;
lxw_col_t col;
char *filename;
char *description;
char *url;
char *tip;
- uint8_t anchor;
-
- /* Internal metadata. */
+ uint8_t object_position;
FILE *stream;
uint8_t image_type;
uint8_t is_image_buffer;
- unsigned char *image_buffer;
+ char *image_buffer;
size_t image_buffer_size;
double width;
double height;
char *extension;
double x_dpi;
double y_dpi;
lxw_chart *chart;
+ uint8_t is_duplicate;
+ uint8_t is_background;
+ char *md5;
+ char *image_position;
+ uint8_t decorative;
- STAILQ_ENTRY (lxw_image_options) list_pointers;
+ STAILQ_ENTRY (lxw_object_properties) list_pointers;
+} lxw_object_properties;
-} lxw_image_options;
+/**
+ * @brief Options for inserted comments.
+ *
+ * Options for modifying comments inserted via `worksheet_write_comment_opt()`.
+ *
+ */
+typedef struct lxw_comment_options {
+ /** This option is used to make a cell comment visible when the worksheet
+ * is opened. The default behavior in Excel is that comments are
+ * initially hidden. However, it is also possible in Excel to make
+ * individual comments or all comments visible. You can make all
+ * comments in the worksheet visible using the
+ * `worksheet_show_comments()` function. Defaults to
+ * LXW_COMMENT_DISPLAY_DEFAULT. See also @ref ww_comments_visible. */
+ uint8_t visible;
+
+ /** This option is used to indicate the author of the cell comment. Excel
+ * displays the author in the status bar at the bottom of the
+ * worksheet. The default author for all cell comments in a worksheet can
+ * be set using the `worksheet_set_comments_author()` function. Set to
+ * NULL if not required. See also @ref ww_comments_author. */
+ const char *author;
+
+ /** This option is used to set the width of the cell comment box
+ * explicitly in pixels. The default width is 128 pixels. See also @ref
+ * ww_comments_width. */
+ uint16_t width;
+
+ /** This option is used to set the height of the cell comment box
+ * explicitly in pixels. The default height is 74 pixels. See also @ref
+ * ww_comments_height. */
+ uint16_t height;
+
+ /** X scale of the comment as a decimal. See also
+ * @ref ww_comments_x_scale. */
+ double x_scale;
+
+ /** Y scale of the comment as a decimal. See also
+ * @ref ww_comments_y_scale. */
+ double y_scale;
+
+ /** This option is used to set the background color of cell comment
+ * box. The color should be an RGB integer value, see @ref
+ * working_with_colors. See also @ref ww_comments_color. */
+ lxw_color_t color;
+
+ /** This option is used to set the font for the comment. The default font
+ * is 'Tahoma'. See also @ref ww_comments_font_name. */
+ const char *font_name;
+
+ /** This option is used to set the font size for the comment. The default
+ * is 8. See also @ref ww_comments_font_size. */
+ double font_size;
+
+ /** This option is used to set the font family number for the comment.
+ * Not required very often. Set to 0. */
+ uint8_t font_family;
+
+ /** This option is used to set the row in which the comment will
+ * appear. By default Excel displays comments one cell to the right and
+ * one cell above the cell to which the comment relates. The `start_row`
+ * and `start_col` options should both be set to 0 if not used. See also
+ * @ref ww_comments_start_row. */
+ lxw_row_t start_row;
+
+ /** This option is used to set the column in which the comment will
+ * appear. See the `start_row` option for more information and see also
+ * @ref ww_comments_start_col. */
+ lxw_col_t start_col;
+
+ /** Offset from the left of the cell in pixels. See also
+ * @ref ww_comments_x_offset. */
+ int32_t x_offset;
+
+ /** Offset from the top of the cell in pixels. See also
+ * @ref ww_comments_y_offset. */
+ int32_t y_offset;
+
+} lxw_comment_options;
+
/**
+ * @brief Options for inserted buttons.
+ *
+ * Options for modifying buttons inserted via `worksheet_insert_button()`.
+ *
+ */
+typedef struct lxw_button_options {
+
+ /** Sets the caption on the button. The default is "Button n" where n is
+ * the current number of buttons in the worksheet, including this
+ * button. */
+ const char *caption;
+
+ /** Name of the macro to run when the button is pressed. The macro must be
+ * included with workbook_add_vba_project(). */
+ const char *macro;
+
+ /** Optional description or "Alt text" for the button. This field can be
+ * used to provide a text description of the button to help
+ * accessibility. Set to NULL to ignore the description field. */
+ const char *description;
+
+ /** This option is used to set the width of the cell button box
+ * explicitly in pixels. The default width is 64 pixels. */
+ uint16_t width;
+
+ /** This option is used to set the height of the cell button box
+ * explicitly in pixels. The default height is 20 pixels. */
+ uint16_t height;
+
+ /** X scale of the button as a decimal. */
+ double x_scale;
+
+ /** Y scale of the button as a decimal. */
+ double y_scale;
+
+ /** Offset from the left of the cell in pixels. */
+ int32_t x_offset;
+
+ /** Offset from the top of the cell in pixels. */
+ int32_t y_offset;
+
+} lxw_button_options;
+
+/* Internal structure for VML object options. */
+typedef struct lxw_vml_obj {
+
+ lxw_row_t row;
+ lxw_col_t col;
+ lxw_row_t start_row;
+ lxw_col_t start_col;
+ int32_t x_offset;
+ int32_t y_offset;
+ uint64_t col_absolute;
+ uint64_t row_absolute;
+ uint32_t width;
+ uint32_t height;
+ double x_dpi;
+ double y_dpi;
+ lxw_color_t color;
+ uint8_t font_family;
+ uint8_t visible;
+ uint32_t author_id;
+ uint32_t rel_index;
+ double font_size;
+ struct lxw_drawing_coords from;
+ struct lxw_drawing_coords to;
+ char *author;
+ char *font_name;
+ char *text;
+ char *image_position;
+ char *name;
+ char *macro;
+ STAILQ_ENTRY (lxw_vml_obj) list_pointers;
+
+} lxw_vml_obj;
+
+/**
* @brief Header and footer options.
*
- * Optional parameters used in the worksheet_set_header_opt() and
+ * Optional parameters used in the `worksheet_set_header_opt()` and
* worksheet_set_footer_opt() functions.
*
*/
typedef struct lxw_header_footer_options {
- /** Header or footer margin in inches. Excel default is 0.3. */
+ /** Header or footer margin in inches. Excel default is 0.3. Must by
+ * larger than 0.0. See `worksheet_set_header_opt()`. */
double margin;
+
+ /** The left header image filename, with path if required. This should
+ * have a corresponding `&G/&[Picture]` placeholder in the `&L` section of
+ * the header/footer string. See `worksheet_set_header_opt()`. */
+ const char *image_left;
+
+ /** The center header image filename, with path if required. This should
+ * have a corresponding `&G/&[Picture]` placeholder in the `&C` section of
+ * the header/footer string. See `worksheet_set_header_opt()`. */
+ const char *image_center;
+
+ /** The right header image filename, with path if required. This should
+ * have a corresponding `&G/&[Picture]` placeholder in the `&R` section of
+ * the header/footer string. See `worksheet_set_header_opt()`. */
+ const char *image_right;
+
} lxw_header_footer_options;
/**
* @brief Worksheet protection options.
*/
@@ -635,14 +2050,35 @@
uint8_t no_content;
/** Turn off chartsheet objects. */
uint8_t no_objects;
+} lxw_protection;
+
+/* Internal struct to copy lxw_protection options and internal metadata. */
+typedef struct lxw_protection_obj {
+ uint8_t no_select_locked_cells;
+ uint8_t no_select_unlocked_cells;
+ uint8_t format_cells;
+ uint8_t format_columns;
+ uint8_t format_rows;
+ uint8_t insert_columns;
+ uint8_t insert_rows;
+ uint8_t insert_hyperlinks;
+ uint8_t delete_columns;
+ uint8_t delete_rows;
+ uint8_t sort;
+ uint8_t autofilter;
+ uint8_t pivot_tables;
+ uint8_t scenarios;
+ uint8_t objects;
+ uint8_t no_content;
+ uint8_t no_objects;
uint8_t no_sheet;
uint8_t is_configured;
char hash[5];
-} lxw_protection;
+} lxw_protection_obj;
/**
* @brief Struct to represent a rich string format/string pair.
*
* Arrays of this struct are used to define "rich" multi-format strings that
@@ -656,11 +2092,11 @@
/** The format for a string fragment in a rich string. NULL if the string
* isn't formatted. */
lxw_format *format;
/** The string fragment. */
- char *string;
+ const char *string;
} lxw_rich_string_tuple;
/**
* @brief Struct to represent an Excel worksheet.
*
@@ -670,30 +2106,41 @@
*/
typedef struct lxw_worksheet {
FILE *file;
FILE *optimize_tmpfile;
+ char *optimize_buffer;
+ size_t optimize_buffer_size;
struct lxw_table_rows *table;
struct lxw_table_rows *hyperlinks;
+ struct lxw_table_rows *comments;
struct lxw_cell **array;
struct lxw_merged_ranges *merged_ranges;
struct lxw_selections *selections;
struct lxw_data_validations *data_validations;
- struct lxw_image_data *image_data;
- struct lxw_chart_data *chart_data;
+ struct lxw_cond_format_hash *conditional_formats;
+ struct lxw_image_props *image_props;
+ struct lxw_chart_props *chart_data;
+ struct lxw_drawing_rel_ids *drawing_rel_ids;
+ struct lxw_vml_drawing_rel_ids *vml_drawing_rel_ids;
+ struct lxw_comment_objs *comment_objs;
+ struct lxw_comment_objs *header_image_objs;
+ struct lxw_comment_objs *button_objs;
+ struct lxw_table_objs *table_objs;
+ uint16_t table_count;
lxw_row_t dim_rowmin;
lxw_row_t dim_rowmax;
lxw_col_t dim_colmin;
lxw_col_t dim_colmax;
lxw_sst *sst;
- char *name;
- char *quoted_name;
- char *tmpdir;
+ const char *name;
+ const char *quoted_name;
+ const char *tmpdir;
- uint32_t index;
+ uint16_t index;
uint8_t active;
uint8_t selected;
uint8_t hidden;
uint16_t *active_sheet;
uint16_t *first_sheet;
@@ -741,12 +2188,15 @@
uint8_t right_to_left;
uint8_t screen_gridlines;
uint8_t show_zeros;
uint8_t vcenter;
uint8_t zoom_scale_normal;
+ uint8_t black_white;
uint8_t num_validations;
+ uint8_t has_dynamic_arrays;
char *vba_codename;
+ uint16_t num_buttons;
lxw_color_t tab_color;
double margin_left;
double margin_right;
@@ -762,52 +2212,104 @@
uint8_t default_row_set;
uint8_t outline_row_level;
uint8_t outline_col_level;
uint8_t header_footer_changed;
- char header[LXW_HEADER_FOOTER_MAX];
- char footer[LXW_HEADER_FOOTER_MAX];
+ char *header;
+ char *footer;
struct lxw_repeat_rows repeat_rows;
struct lxw_repeat_cols repeat_cols;
struct lxw_print_area print_area;
struct lxw_autofilter autofilter;
uint16_t merged_range_count;
+ uint16_t max_url_length;
lxw_row_t *hbreaks;
lxw_col_t *vbreaks;
uint16_t hbreaks_count;
uint16_t vbreaks_count;
+ uint32_t drawing_rel_id;
+ uint32_t vml_drawing_rel_id;
struct lxw_rel_tuples *external_hyperlinks;
struct lxw_rel_tuples *external_drawing_links;
struct lxw_rel_tuples *drawing_links;
+ struct lxw_rel_tuples *vml_drawing_links;
+ struct lxw_rel_tuples *external_table_links;
struct lxw_panes panes;
+ char top_left_cell[LXW_MAX_CELL_NAME_LENGTH];
- struct lxw_protection protection;
+ struct lxw_protection_obj protection;
lxw_drawing *drawing;
+ lxw_format *default_url_format;
+ uint8_t has_vml;
+ uint8_t has_comments;
+ uint8_t has_header_vml;
+ uint8_t has_background_image;
+ uint8_t has_buttons;
+ lxw_rel_tuple *external_vml_comment_link;
+ lxw_rel_tuple *external_comment_link;
+ lxw_rel_tuple *external_vml_header_link;
+ lxw_rel_tuple *external_background_link;
+ char *comment_author;
+ char *vml_data_id_str;
+ char *vml_header_id_str;
+ uint32_t vml_shape_id;
+ uint32_t vml_header_id;
+ uint32_t dxf_priority;
+ uint8_t comment_display_default;
+ uint32_t data_bar_2010_index;
+
+ uint8_t has_ignore_errors;
+ char *ignore_number_stored_as_text;
+ char *ignore_eval_error;
+ char *ignore_formula_differs;
+ char *ignore_formula_range;
+ char *ignore_formula_unlocked;
+ char *ignore_empty_cell_reference;
+ char *ignore_list_data_validation;
+ char *ignore_calculated_column;
+ char *ignore_two_digit_text_year;
+
+ uint16_t excel_version;
+
+ lxw_object_properties **header_footer_objs[LXW_HEADER_FOOTER_OBJS_MAX];
+ lxw_object_properties *header_left_object_props;
+ lxw_object_properties *header_center_object_props;
+ lxw_object_properties *header_right_object_props;
+ lxw_object_properties *footer_left_object_props;
+ lxw_object_properties *footer_center_object_props;
+ lxw_object_properties *footer_right_object_props;
+ lxw_object_properties *background_image;
+
+ lxw_filter_rule_obj **filter_rules;
+ lxw_col_t num_filter_rules;
+
STAILQ_ENTRY (lxw_worksheet) list_pointers;
} lxw_worksheet;
/*
* Worksheet initialization data.
*/
typedef struct lxw_worksheet_init_data {
- uint32_t index;
+ uint16_t index;
uint8_t hidden;
uint8_t optimize;
uint16_t *active_sheet;
uint16_t *first_sheet;
lxw_sst *sst;
- char *name;
- char *quoted_name;
- char *tmpdir;
+ const char *name;
+ const char *quoted_name;
+ const char *tmpdir;
+ lxw_format *default_url_format;
+ uint16_t max_url_length;
} lxw_worksheet_init_data;
/* Struct to represent a worksheet row. */
typedef struct lxw_row {
@@ -818,10 +2320,11 @@
uint8_t level;
uint8_t collapsed;
uint8_t row_changed;
uint8_t data_changed;
uint8_t height_changed;
+
struct lxw_table_cells *cells;
/* tree management pointers for tree.h. */
RB_ENTRY (lxw_row) tree_pointers;
} lxw_row;
@@ -830,15 +2333,16 @@
typedef struct lxw_cell {
lxw_row_t row_num;
lxw_col_t col_num;
enum cell_types type;
lxw_format *format;
+ lxw_vml_obj *comment;
union {
double number;
int32_t string_id;
- char *string;
+ const char *string;
} u;
double formula_result;
char *user_data1;
char *user_data2;
@@ -846,20 +2350,30 @@
/* List pointers for tree.h. */
RB_ENTRY (lxw_cell) tree_pointers;
} lxw_cell;
+/* Struct to represent a drawing Target/ID pair. */
+typedef struct lxw_drawing_rel_id {
+ uint32_t id;
+ char *target;
+
+ RB_ENTRY (lxw_drawing_rel_id) tree_pointers;
+} lxw_drawing_rel_id;
+
+
+
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/**
* @brief Write a number to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param number The number to write to the cell.
* @param format A pointer to a Format instance or NULL.
*
@@ -902,11 +2416,11 @@
lxw_col_t col, double number,
lxw_format *format);
/**
* @brief Write a string to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param string String to write to cell.
* @param format A pointer to a Format instance or NULL.
*
@@ -950,11 +2464,11 @@
lxw_col_t col, const char *string,
lxw_format *format);
/**
* @brief Write a formula to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param formula Formula string to write to cell.
* @param format A pointer to a Format instance or NULL.
*
@@ -1003,21 +2517,21 @@
lxw_col_t col, const char *formula,
lxw_format *format);
/**
* @brief Write an array formula to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
- * @param first_row The first row of the range. (All zero indexed.)
- * @param first_col The first column of the range.
- * @param last_row The last row of the range.
- * @param last_col The last col of the range.
- * @param formula Array formula to write to cell.
- * @param format A pointer to a Format instance or NULL.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_row The first row of the range. (All zero indexed.)
+ * @param first_col The first column of the range.
+ * @param last_row The last row of the range.
+ * @param last_col The last col of the range.
+ * @param formula Array formula to write to cell.
+ * @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
- * The `%worksheet_write_array_formula()` function writes an array formula to
+ * The `%worksheet_write_array_formula()` function writes an array formula to
* a cell range. In Excel an array formula is a formula that performs a
* calculation on a set of values.
*
* In Excel an array formula is indicated by a pair of braces around the
* formula: `{=SUM(A1:B1*A2:B2)}`.
@@ -1050,31 +2564,135 @@
lxw_row_t last_row,
lxw_col_t last_col,
const char *formula,
lxw_format *format);
+/**
+ * @brief Write an Excel 365 dynamic array formula to a worksheet range.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_row The first row of the range. (All zero indexed.)
+ * @param first_col The first column of the range.
+ * @param last_row The last row of the range.
+ * @param last_col The last col of the range.
+ * @param formula Dynamic Array formula to write to cell.
+ * @param format A pointer to a Format instance or NULL.
+ *
+ * @return A #lxw_error code.
+ *
+ *
+ * The `%worksheet_write_dynamic_array_formula()` function writes an Excel 365
+ * dynamic array formula to a cell range. Some examples of functions that
+ * return dynamic arrays are:
+ *
+ * - `FILTER`
+ * - `RANDARRAY`
+ * - `SEQUENCE`
+ * - `SORTBY`
+ * - `SORT`
+ * - `UNIQUE`
+ * - `XLOOKUP`
+ * - `XMATCH`
+ *
+ * Dynamic array formulas and their usage in libxlsxwriter is explained in
+ * detail @ref ww_formulas_dynamic_arrays. The following is a example usage:
+ *
+ * @code
+ * worksheet_write_dynamic_array_formula(worksheet, 1, 5, 1, 5,
+ * "=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
+ * NULL);
+ * @endcode
+ *
+ * This formula gives the results shown in the image below.
+ *
+ * @image html dynamic_arrays02.png
+ *
+ * The need for the `_xlfn._xlws.` prefix in the formula is explained in @ref
+ * ww_formulas_future.
+ */
+lxw_error worksheet_write_dynamic_array_formula(lxw_worksheet *worksheet,
+ lxw_row_t first_row,
+ lxw_col_t first_col,
+ lxw_row_t last_row,
+ lxw_col_t last_col,
+ const char *formula,
+ lxw_format *format);
+
+/**
+ * @brief Write an Excel 365 dynamic array formula to a worksheet cell.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param formula Formula string to write to cell.
+ * @param format A pointer to a Format instance or NULL.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_write_dynamic_formula()` function is similar to the
+ * `worksheet_write_dynamic_array_formula()` function, shown above, except
+ * that it writes a dynamic array formula to a single cell, rather than a
+ * range. This is a syntactic shortcut since the array range isn't generally
+ * known for a dynamic range and specifying the initial cell is sufficient for
+ * Excel, as shown in the example below:
+ *
+ * @code
+ * worksheet_write_dynamic_formula(worksheet, 7, 1,
+ * "=_xlfn._xlws.SORT(_xlfn.UNIQUE(B2:B17))",
+ * NULL);
+ * @endcode
+ *
+ * This formula gives the following result:
+ *
+ * @image html dynamic_arrays01.png
+ *
+ * The need for the `_xlfn.` and `_xlfn._xlws.` prefixes in the formula is
+ * explained in @ref ww_formulas_future.
+ */
+lxw_error worksheet_write_dynamic_formula(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ lxw_col_t col,
+ const char *formula,
+ lxw_format *format);
+
lxw_error worksheet_write_array_formula_num(lxw_worksheet *worksheet,
lxw_row_t first_row,
lxw_col_t first_col,
lxw_row_t last_row,
lxw_col_t last_col,
const char *formula,
lxw_format *format,
double result);
+lxw_error worksheet_write_dynamic_array_formula_num(lxw_worksheet *worksheet,
+ lxw_row_t first_row,
+ lxw_col_t first_col,
+ lxw_row_t last_row,
+ lxw_col_t last_col,
+ const char *formula,
+ lxw_format *format,
+ double result);
+
+lxw_error worksheet_write_dynamic_formula_num(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ lxw_col_t col,
+ const char *formula,
+ lxw_format *format,
+ double result);
+
/**
* @brief Write a date or time to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param datetime The datetime to write to the cell.
* @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
- * The `worksheet_write_datetime()` function can be used to write a date or
+ * The `%worksheet_write_datetime()` function can be used to write a date or
* time to the cell specified by `row` and `column`:
*
* @dontinclude dates_and_times02.c
* @skip include
* @until num_format
@@ -1091,89 +2709,133 @@
lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col, lxw_datetime *datetime,
lxw_format *format);
-lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
- lxw_row_t row_num,
- lxw_col_t col_num, const char *url,
- lxw_format *format, const char *string,
- const char *tooltip);
/**
+ * @brief Write a Unix datetime to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
+ * @param unixtime The Unix datetime to write to the cell.
+ * @param format A pointer to a Format instance or NULL.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_write_unixtime()` function can be used to write dates and
+ * times in Unix date format to the cell specified by `row` and
+ * `column`. [Unix Time](https://en.wikipedia.org/wiki/Unix_time) which is a
+ * common integer time format. It is defined as the number of seconds since
+ * the Unix epoch (1970-01-01 00:00 UTC). Negative values can also be used for
+ * dates prior to 1970:
+ *
+ * @dontinclude dates_and_times03.c
+ * @skip 1970
+ * @until 2208988800
+ *
+ * The `format` parameter should be used to apply formatting to the cell using
+ * a @ref format.h "Format" object as shown above. Without a date format the
+ * datetime will appear as a number only.
+ *
+ * The output from this code sample is:
+ *
+ * @image html date_example03.png
+ *
+ * Unixtime is generally represented with a 32 bit `time_t` type which has a
+ * range of approximately 1900-12-14 to 2038-01-19. To access the full Excel
+ * date range of 1900-01-01 to 9999-12-31 this function uses a 64 bit
+ * parameter.
+ *
+ * See @ref working_with_dates for more information about handling dates and
+ * times in libxlsxwriter.
+ */
+lxw_error worksheet_write_unixtime(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ lxw_col_t col, int64_t unixtime,
+ lxw_format *format);
+
+/**
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
* @param url The url to write to the cell.
* @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
*
* The `%worksheet_write_url()` function is used to write a URL/hyperlink to a
* worksheet cell specified by `row` and `column`.
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "http://libxlsxwriter.github.io", NULL);
* @endcode
*
* @image html hyperlinks_short.png
*
* The `format` parameter is used to apply formatting to the cell. This
- * parameter can be `NULL` to indicate no formatting or it can be a @ref
- * format.h "Format" object. The typical worksheet format for a hyperlink is a
- * blue underline:
+ * parameter can be `NULL`, in which case the default Excel blue underlined
+ * hyperlink style will be used. If required a user defined @ref format.h
+ * "Format" object can be used:
+ * underline:
*
* @code
* lxw_format *url_format = workbook_add_format(workbook);
*
* format_set_underline (url_format, LXW_UNDERLINE_SINGLE);
- * format_set_font_color(url_format, LXW_COLOR_BLUE);
+ * format_set_font_color(url_format, LXW_COLOR_RED);
*
* @endcode
*
* The usual web style URI's are supported: `%http://`, `%https://`, `%ftp://`
* and `mailto:` :
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", url_format);
- * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", url_format);
- * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", url_format);
- * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "ftp://www.python.org/", NULL);
+ * worksheet_write_url(worksheet, 1, 0, "http://www.python.org/", NULL);
+ * worksheet_write_url(worksheet, 2, 0, "https://www.python.org/", NULL);
+ * worksheet_write_url(worksheet, 3, 0, "mailto:jmcnamara@cpan.org", NULL);
*
* @endcode
*
* An Excel hyperlink is comprised of two elements: the displayed string and
* the non-displayed link. By default the displayed string is the same as the
* link. However, it is possible to overwrite it with any other
* `libxlsxwriter` type using the appropriate `worksheet_write_*()`
* function. The most common case is to overwrite the displayed link text with
- * another string:
+ * another string. To do this we must also match the default URL format using
+ * `workbook_get_default_url_format()`:
*
* @code
- * // Write a hyperlink but overwrite the displayed string.
- * worksheet_write_url (worksheet, 2, 0, "http://libxlsxwriter.github.io", url_format);
- * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
+ * // Write a hyperlink with the default blue underline format.
+ * worksheet_write_url(worksheet, 2, 0, "http://libxlsxwriter.github.io", NULL);
*
+ * // Get the default url format.
+ * lxw_format *url_format = workbook_get_default_url_format(workbook);
+ *
+ * // Overwrite the hyperlink with a user defined string and default format.
+ * worksheet_write_string(worksheet, 2, 0, "Read the documentation.", url_format);
* @endcode
*
* @image html hyperlinks_short2.png
*
* Two local URIs are supported: `internal:` and `external:`. These are used
* for hyperlinks to internal worksheet references or external workbook and
* worksheet references:
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", url_format);
- * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", url_format);
- * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", url_format);
- * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", url_format);
- * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", url_format);
- * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
- * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", url_format);
- * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", url_format);
- * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "internal:Sheet2!A1", NULL);
+ * worksheet_write_url(worksheet, 1, 0, "internal:Sheet2!B2", NULL);
+ * worksheet_write_url(worksheet, 2, 0, "internal:Sheet2!A1:B2", NULL);
+ * worksheet_write_url(worksheet, 3, 0, "internal:'Sales Data'!A1", NULL);
+ * worksheet_write_url(worksheet, 4, 0, "external:c:\\temp\\foo.xlsx", NULL);
+ * worksheet_write_url(worksheet, 5, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
+ * worksheet_write_url(worksheet, 6, 0, "external:..\\foo.xlsx", NULL);
+ * worksheet_write_url(worksheet, 7, 0, "external:..\\foo.xlsx#Sheet2!A1", NULL);
+ * worksheet_write_url(worksheet, 8, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
*
* @endcode
*
* Worksheet references are typically of the form `Sheet1!A1`. You can also
* link to a worksheet range using the standard Excel notation:
@@ -1181,64 +2843,77 @@
*
* In external links the workbook and worksheet name must be separated by the
* `#` character:
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\foo.xlsx#Sheet2!A1", NULL);
* @endcode
*
* You can also link to a named range in the target worksheet: For example say
* you have a named range called `my_name` in the workbook `c:\temp\foo.xlsx`
* you could link to it as follows:
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "external:c:\\temp\\foo.xlsx#my_name", NULL);
*
* @endcode
*
* Excel requires that worksheet names containing spaces or non alphanumeric
* characters are single quoted as follows:
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "internal:'Sales Data'!A1", NULL);
* @endcode
*
* Links to network files are also supported. Network files normally begin
* with two back slashes as follows `\\NETWORK\etc`. In order to represent
* this in a C string literal the backslashes should be escaped:
* @code
- * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "external:\\\\NET\\share\\foo.xlsx", NULL);
* @endcode
*
*
* Alternatively, you can use Unix style forward slashes. These are
* translated internally to backslashes:
*
* @code
- * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", url_format);
- * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", url_format);
+ * worksheet_write_url(worksheet, 0, 0, "external:c:/temp/foo.xlsx", NULL);
+ * worksheet_write_url(worksheet, 1, 0, "external://NET/share/foo.xlsx", NULL);
*
* @endcode
*
*
* **Note:**
*
* libxlsxwriter will escape the following characters in URLs as required
- * by Excel: `\s " < > \ [ ] ^ { }` unless the URL already contains `%%xx`
- * style escapes. In which case it is assumed that the URL was escaped
- * correctly by the user and will by passed directly to Excel.
+ * by Excel: `\s " < > \ [ ] ^ { }`. Existing URL `%%xx` style escapes in
+ * the string are ignored to allow for user-escaped strings.
*
+ * **Note:**
+ *
+ * The maximum allowable URL length in recent versions of Excel is 2079
+ * characters. In older versions of Excel (and libxlsxwriter <= 0.8.8) the
+ * limit was 255 characters.
*/
lxw_error worksheet_write_url(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col, const char *url,
lxw_format *format);
+ /* Don't document for now since the string option can be achieved by a
+ * subsequent cell worksheet_write() as shown in the docs, and the
+ * tooltip option isn't very useful. */
+lxw_error worksheet_write_url_opt(lxw_worksheet *worksheet,
+ lxw_row_t row_num,
+ lxw_col_t col_num, const char *url,
+ lxw_format *format, const char *string,
+ const char *tooltip);
+
/**
* @brief Write a formatted boolean worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param value The boolean value to write to the cell.
* @param format A pointer to a Format instance or NULL.
*
@@ -1256,11 +2931,11 @@
int value, lxw_format *format);
/**
* @brief Write a formatted blank worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
@@ -1285,24 +2960,25 @@
lxw_error worksheet_write_blank(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
lxw_format *format);
/**
- * @brief Write a formula to a worksheet cell with a user defined result.
+ * @brief Write a formula to a worksheet cell with a user defined numeric
+ * result.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param formula Formula string to write to cell.
* @param format A pointer to a Format instance or NULL.
- * @param result A user defined result for a formula.
+ * @param result A user defined numeric result for the formula.
*
* @return A #lxw_error code.
*
* The `%worksheet_write_formula_num()` function writes a formula or Excel
* function to the cell specified by `row` and `column` with a user defined
- * result:
+ * numeric result:
*
* @code
* // Required as a workaround only.
* worksheet_write_formula_num(worksheet, 0, 0, "=1 + 2", NULL, 3);
* @endcode
@@ -1334,13 +3010,58 @@
lxw_col_t col,
const char *formula,
lxw_format *format, double result);
/**
+ * @brief Write a formula to a worksheet cell with a user defined string
+ * result.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param formula Formula string to write to cell.
+ * @param format A pointer to a Format instance or NULL.
+ * @param result A user defined string result for the formula.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_write_formula_str()` function writes a formula or Excel
+ * function to the cell specified by `row` and `column` with a user defined
+ * string result:
+ *
+ * @code
+ * // The example formula is A & B -> AB.
+ * worksheet_write_formula_str(worksheet, 0, 0, "=\"A\" & \"B\"", NULL, "AB");
+ * @endcode
+ *
+ * The `%worksheet_write_formula_str()` function is similar to the
+ * `%worksheet_write_formula_num()` function except it writes a string result
+ * instead or a numeric result. See `worksheet_write_formula_num()` for more
+ * details on why/when these functions are required.
+ *
+ * One place where the `%worksheet_write_formula_str()` function may be required
+ * is to specify an empty result which will force a recalculation of the formula
+ * when loaded in LibreOffice.
+ *
+ * @code
+ * worksheet_write_formula_str(worksheet, 0, 0, "=Sheet1!$A$1", NULL, "");
+ * @endcode
+ *
+ * See the FAQ @ref faq_formula_zero.
+ *
+ * See also @ref working_with_formulas.
+ */
+lxw_error worksheet_write_formula_str(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ lxw_col_t col,
+ const char *formula,
+ lxw_format *format, const char *result);
+
+/**
* @brief Write a "Rich" multi-format string to a worksheet cell.
*
- * @param worksheet pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param rich_string An array of format/string lxw_rich_string_tuple fragments.
* @param format A pointer to a Format instance or NULL.
*
@@ -1409,26 +3130,113 @@
lxw_col_t col,
lxw_rich_string_tuple *rich_string[],
lxw_format *format);
/**
+ * @brief Write a comment to a worksheet cell.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param string The comment string to be written.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_write_comment()` function is used to add a comment to a
+ * cell. A comment is indicated in Excel by a small red triangle in the upper
+ * right-hand corner of the cell. Moving the cursor over the red triangle will
+ * reveal the comment.
+ *
+ * The following example shows how to add a comment to a cell:
+ *
+ * @code
+ * worksheet_write_comment(worksheet, 0, 0, "This is a comment");
+ * @endcode
+ *
+ * @image html comments1.png
+ *
+ * See also @ref working_with_comments
+ *
+ */
+lxw_error worksheet_write_comment(lxw_worksheet *worksheet,
+ lxw_row_t row, lxw_col_t col,
+ const char *string);
+
+/**
+ * @brief Write a comment to a worksheet cell with options.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param string The comment string to be written.
+ * @param options #lxw_comment_options to control position and format
+ * of the comment.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_write_comment_opt()` function is used to add a comment to a
+ * cell with option that control the position, format and metadata of the
+ * comment. A comment is indicated in Excel by a small red triangle in the
+ * upper right-hand corner of the cell. Moving the cursor over the red
+ * triangle will reveal the comment.
+ *
+ * The following example shows how to add a comment to a cell with options:
+ *
+ * @code
+ * lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_VISIBLE};
+ *
+ * worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello.", &options);
+ * @endcode
+ *
+ * The following options are available in #lxw_comment_options:
+ *
+ * - `author`
+ * - `visible`
+ * - `width`
+ * - `height`
+ * - `x_scale`
+ * - `y_scale`
+ * - `color`
+ * - `font_name`
+ * - `font_size`
+ * - `start_row`
+ * - `start_col`
+ * - `x_offset`
+ * - `y_offset`
+ *
+ * @image html comments2.png
+ *
+ * Comment options are explained in detail in the @ref ww_comments_properties
+ * section of the docs.
+ */
+lxw_error worksheet_write_comment_opt(lxw_worksheet *worksheet,
+ lxw_row_t row, lxw_col_t col,
+ const char *string,
+ lxw_comment_options *options);
+
+/**
* @brief Set the properties for a row of cells.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
- * @param height The row height.
+ * @param height The row height, in character units.
* @param format A pointer to a Format instance or NULL.
*
+ * @return A #lxw_error code.
+ *
* The `%worksheet_set_row()` function is used to change the default
* properties of a row. The most common use for this function is to change the
* height of a row:
*
* @code
* // Set the height of Row 1 to 20.
* worksheet_set_row(worksheet, 0, 20, NULL);
* @endcode
*
+ * The height is specified in character units. To specify the height in pixels
+ * use the `worksheet_set_row_pixels()` function.
+ *
* The other common use for `%worksheet_set_row()` is to set the a @ref
* format.h "Format" for all cells in the row:
*
* @code
* lxw_format *bold = workbook_add_format(workbook);
@@ -1472,10 +3280,12 @@
* @param row The zero indexed row number.
* @param height The row height.
* @param format A pointer to a Format instance or NULL.
* @param options Optional row parameters: hidden, level, collapsed.
*
+ * @return A #lxw_error code.
+ *
* The `%worksheet_set_row_opt()` function is the same as
* `worksheet_set_row()` with an additional `options` parameter.
*
* The `options` parameter is a #lxw_row_col_options struct. It has the
* following members:
@@ -1529,18 +3339,66 @@
double height,
lxw_format *format,
lxw_row_col_options *options);
/**
+ * @brief Set the properties for a row of cells, with the height in pixels.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param pixels The row height in pixels.
+ * @param format A pointer to a Format instance or NULL.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_set_row_pixels()` function is the same as the
+ * `worksheet_set_row()` function except that the height can be set in pixels
+ *
+ * @code
+ * // Set the height of Row 1 to 20 pixels.
+ * worksheet_set_row_pixels(worksheet, 0, 20, NULL);
+ * @endcode
+ *
+ * If you wish to set the format of a row without changing the height you can
+ * pass the default row height in pixels: #LXW_DEF_ROW_HEIGHT_PIXELS.
+ */
+lxw_error worksheet_set_row_pixels(lxw_worksheet *worksheet,
+ lxw_row_t row, uint32_t pixels,
+ lxw_format *format);
+/**
+ * @brief Set the properties for a row of cells, with the height in pixels.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param pixels The row height in pixels.
+ * @param format A pointer to a Format instance or NULL.
+ * @param options Optional row parameters: hidden, level, collapsed.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_set_row_pixels_opt()` function is the same as the
+ * `worksheet_set_row_opt()` function except that the height can be set in
+ * pixels.
+ *
+ */
+lxw_error worksheet_set_row_pixels_opt(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ uint32_t pixels,
+ lxw_format *format,
+ lxw_row_col_options *options);
+
+/**
* @brief Set the properties for one or more columns of cells.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param first_col The zero indexed first column.
* @param last_col The zero indexed last column.
* @param width The width of the column(s).
* @param format A pointer to a Format instance or NULL.
*
+ * @return A #lxw_error code.
+ *
* The `%worksheet_set_column()` function can be used to change the default
* properties of a single column or a range of columns:
*
* @code
* // Width of columns B:D set to 30.
@@ -1573,11 +3431,12 @@
* The `width` parameter sets the column width in the same units used by Excel
* which is: the number of characters in the default font. The default width
* is 8.43 in the default font of Calibri 11. The actual relationship between
* a string width and a column width in Excel is complex. See the
* [following explanation of column widths](https://support.microsoft.com/en-us/kb/214123)
- * from the Microsoft support documentation for more details.
+ * from the Microsoft support documentation for more details. To set the width
+ * in pixels use the `worksheet_set_column_pixels()` function.
*
* There is no way to specify "AutoFit" for a column in the Excel file
* format. This feature is only available at runtime from within Excel. It is
* possible to simulate "AutoFit" in your application by tracking the maximum
* width of the data in the column as your write it and then adjusting the
@@ -1638,10 +3497,12 @@
* @param last_col The zero indexed last column.
* @param width The width of the column(s).
* @param format A pointer to a Format instance or NULL.
* @param options Optional row parameters: hidden, level, collapsed.
*
+ * @return A #lxw_error code.
+ *
* The `%worksheet_set_column_opt()` function is the same as
* `worksheet_set_column()` with an additional `options` parameter.
*
* The `options` parameter is a #lxw_row_col_options struct. It has the
* following members:
@@ -1678,21 +3539,77 @@
double width,
lxw_format *format,
lxw_row_col_options *options);
/**
+ * @brief Set the properties for one or more columns of cells, with the width
+ * in pixels.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_col The zero indexed first column.
+ * @param last_col The zero indexed last column.
+ * @param pixels The width of the column(s) in pixels.
+ * @param format A pointer to a Format instance or NULL.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_set_column_pixels()` function is the same as
+ * `worksheet_set_column()` function except that the width can be set in
+ * pixels:
+ *
+ * @code
+ * // Column width set to 75 pixels, the same as 10 character units.
+ * worksheet_set_column(worksheet, 5, 5, 75, NULL);
+ * @endcode
+ *
+ * @image html set_column_pixels.png
+ *
+ * If you wish to set the format of a column without changing the width you can
+ * pass the default column width in pixels: #LXW_DEF_COL_WIDTH_PIXELS.
+ */
+lxw_error worksheet_set_column_pixels(lxw_worksheet *worksheet,
+ lxw_col_t first_col,
+ lxw_col_t last_col,
+ uint32_t pixels, lxw_format *format);
+
+/**
+ * @brief Set the properties for one or more columns of cells with options,
+ * with the width in pixels.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_col The zero indexed first column.
+ * @param last_col The zero indexed last column.
+ * @param pixels The width of the column(s) in pixels.
+ * @param format A pointer to a Format instance or NULL.
+ * @param options Optional row parameters: hidden, level, collapsed.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_set_column_pixels_opt()` function is the same as the
+ * `worksheet_set_column_opt()` function except that the width can be set in
+ * pixels.
+ *
+ */
+lxw_error worksheet_set_column_pixels_opt(lxw_worksheet *worksheet,
+ lxw_col_t first_col,
+ lxw_col_t last_col,
+ uint32_t pixels,
+ lxw_format *format,
+ lxw_row_col_options *options);
+
+/**
* @brief Insert an image in a worksheet cell.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
* @param filename The image filename, with path if required.
*
* @return A #lxw_error code.
*
* This function can be used to insert a image into a worksheet. The image can
- * be in PNG, JPEG or BMP format:
+ * be in PNG, JPEG, GIF or BMP format:
*
* @code
* worksheet_insert_image(worksheet, 2, 1, "logo.png");
* @endcode
*
@@ -1704,11 +3621,11 @@
* **Note**:
* The scaling of a image may be affected if is crosses a row that has its
* default height changed due to a font that is larger than the default font
* size or that has text wrapping turned on. To avoid this you should
* explicitly set the height of the row using `worksheet_set_row()` if it
- * crosses an inserted image.
+ * crosses an inserted image. See @ref working_with_object_positioning.
*
* BMP images are only supported for backward compatibility. In general it is
* best to avoid BMP images since they aren't compressed. If used, BMP images
* must be 24 bit, true color, bitmaps.
*/
@@ -1727,22 +3644,56 @@
*
* @return A #lxw_error code.
*
* The `%worksheet_insert_image_opt()` function is like
* `worksheet_insert_image()` function except that it takes an optional
- * #lxw_image_options struct to scale and position the image:
+ * #lxw_image_options struct with the following members/options:
*
+ * - `x_offset`: Offset from the left of the cell in pixels.
+ * - `y_offset`: Offset from the top of the cell in pixels.
+ * - `x_scale`: X scale of the image as a decimal.
+ * - `y_scale`: Y scale of the image as a decimal.
+ * - `object_position`: See @ref working_with_object_positioning.
+ * - `description`: Optional description or "Alt text" for the image.
+ * - `decorative`: Optional parameter to mark image as decorative.
+ * - `url`: Add an optional hyperlink to the image.
+ * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
+ *
+ * For example, to scale and position the image:
+ *
* @code
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
+ * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
* .x_scale = 0.5, .y_scale = 0.5};
*
- * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
+ * worksheet_insert_image_opt(worksheet, 2, 1, "logo.png", &options);
*
* @endcode
*
* @image html insert_image_opt.png
*
+ * The `url` field of lxw_image_options can be use to used to add a hyperlink
+ * to an image:
+ *
+ * @code
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara"};
+ *
+ * worksheet_insert_image_opt(worksheet, 3, 1, "logo.png", &options);
+ * @endcode
+ *
+ * The supported URL formats are the same as those supported by the
+ * `worksheet_write_url()` method and the same rules/limits apply.
+ *
+ * The `tip` field of lxw_image_options can be use to used to add a mouseover
+ * tip to the hyperlink:
+ *
+ * @code
+ * lxw_image_options options = {.url = "https://github.com/jmcnamara",
+ .tip = "GitHub"};
+ *
+ * worksheet_insert_image_opt(worksheet, 4, 1, "logo.png", &options);
+ * @endcode
+ *
* @note See the notes about row scaling and BMP images in
* `worksheet_insert_image()` above.
*/
lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
@@ -1793,12 +3744,24 @@
*
* @return A #lxw_error code.
*
* The `%worksheet_insert_image_buffer_opt()` function is like
* `worksheet_insert_image_buffer()` function except that it takes an optional
- * #lxw_image_options struct to scale and position the image:
+ * #lxw_image_options struct * #lxw_image_options struct with the following members/options:
*
+ * - `x_offset`: Offset from the left of the cell in pixels.
+ * - `y_offset`: Offset from the top of the cell in pixels.
+ * - `x_scale`: X scale of the image as a decimal.
+ * - `y_scale`: Y scale of the image as a decimal.
+ * - `object_position`: See @ref working_with_object_positioning.
+ * - `description`: Optional description or "Alt text" for the image.
+ * - `decorative`: Optional parameter to mark image as decorative.
+ * - `url`: Add an optional hyperlink to the image.
+ * - `tip`: Add an optional mouseover tip for a hyperlink to the image.
+ *
+ * For example, to scale and position the image:
+ *
* @code
* lxw_image_options options = {.x_offset = 32, .y_offset = 4,
* .x_scale = 2, .y_scale = 1};
*
* worksheet_insert_image_buffer_opt(worksheet, CELL("B3"), image_buffer, image_size, &options);
@@ -1818,10 +3781,74 @@
const unsigned char *image_buffer,
size_t image_size,
lxw_image_options *options);
/**
+ * @brief Set the background image for a worksheet.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param filename The image filename, with path if required.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_set_background()` function can be used to set the
+ * background image for a worksheet:
+ *
+ * @code
+ * worksheet_set_background(worksheet, "logo.png");
+ * @endcode
+ *
+ * @image html background.png
+ *
+ * The ``set_background()`` method supports all the image formats supported by
+ * `worksheet_insert_image()`.
+ *
+ * Some people use this method to add a watermark background to their
+ * document. However, Microsoft recommends using a header image [to set a
+ * watermark][watermark]. The choice of method depends on whether you want the
+ * watermark to be visible in normal viewing mode or just when the file is
+ * printed. In libxlsxwriter you can get the header watermark effect using
+ * `worksheet_set_header()`:
+ *
+ * @code
+ * lxw_header_footer_options header_options = {.image_center = "watermark.png"};
+ * worksheet_set_header_opt(worksheet, "&C&G", &header_options);
+ * @endcode
+ *
+ * [watermark]:https://support.microsoft.com/en-us/office/add-a-watermark-in-excel-a372182a-d733-484e-825c-18ddf3edf009
+ *
+ */
+lxw_error worksheet_set_background(lxw_worksheet *worksheet,
+ const char *filename);
+
+/**
+ * @brief Set the background image for a worksheet, from a buffer.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param image_buffer Pointer to an array of bytes that holds the image data.
+ * @param image_size The size of the array of bytes.
+ *
+ * @return A #lxw_error code.
+ *
+ * This function can be used to insert a background image into a worksheet
+ * from a memory buffer:
+ *
+ * @code
+ * worksheet_set_background_buffer(worksheet, image_buffer, image_size);
+ * @endcode
+ *
+ * The buffer should be a pointer to an array of unsigned char data with a
+ * specified size.
+ *
+ * See `worksheet_set_background()` for more details.
+ *
+ */
+lxw_error worksheet_set_background_buffer(lxw_worksheet *worksheet,
+ const unsigned char *image_buffer,
+ size_t image_size);
+
+/**
* @brief Insert a chart object into a worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
@@ -1869,30 +3896,27 @@
*
* @return A #lxw_error code.
*
* The `%worksheet_insert_chart_opt()` function is like
* `worksheet_insert_chart()` function except that it takes an optional
- * #lxw_image_options struct to scale and position the image of the chart:
+ * #lxw_chart_options struct to scale and position the chart:
*
* @code
- * lxw_image_options options = {.x_offset = 30, .y_offset = 10,
+ * lxw_chart_options options = {.x_offset = 30, .y_offset = 10,
* .x_scale = 0.5, .y_scale = 0.75};
*
* worksheet_insert_chart_opt(worksheet, 0, 2, chart, &options);
*
* @endcode
*
* @image html chart_line_opt.png
*
- * The #lxw_image_options struct is the same struct used in
- * `worksheet_insert_image_opt()` to position and scale images.
- *
*/
lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
lxw_chart *chart,
- lxw_image_options *user_options);
+ lxw_chart_options *user_options);
/**
* @brief Merge a range of cells.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
@@ -1947,11 +3971,11 @@
*
* // Then overwrite the first cell with a number.
* worksheet_write_number(worksheet, 1, 1, 123, format);
* @endcode
*
- * @note Merged ranges generally don’t work in libxlsxwriter when the Workbook
+ * @note Merged ranges generally don't work in libxlsxwriter when the Workbook
* #lxw_workbook_options `constant_memory` mode is enabled.
*/
lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
lxw_col_t first_col, lxw_row_t last_row,
lxw_col_t last_col, const char *string,
@@ -1973,29 +3997,163 @@
*
* An autofilter is a way of adding drop down lists to the headers of a 2D
* range of worksheet data. This allows users to filter the data based on
* simple criteria so that some data is shown and some is hidden.
*
- * @image html autofilter.png
+ * @image html autofilter3.png
*
* To add an autofilter to a worksheet:
*
* @code
* worksheet_autofilter(worksheet, 0, 0, 50, 3);
*
* // Same as above using the RANGE() macro.
* worksheet_autofilter(worksheet, RANGE("A1:D51"));
* @endcode
*
- * Note: it isn't currently possible to apply filter conditions to the
- * autofilter.
+ * In order to apply a filter condition it is necessary to add filter rules to
+ * the columns using either the `%worksheet_filter_column()`,
+ * `%worksheet_filter_column2()` or `%worksheet_filter_list()` functions:
+ *
+ * - `worksheet_filter_column()`: filter on a single criterion such as "Column ==
+ * East". More complex conditions such as "<=" or ">=" can also be use.
+ *
+ * - `worksheet_filter_column2()`: filter on two criteria such as "Column == East
+ * or Column == West". Complex conditions can also be used.
+ *
+ * - `worksheet_filter_list()`: filter on a list of values such as "Column in (East, West,
+ * North)".
+ *
+ * These functions are explained below. It isn't sufficient to just specify
+ * the filter condition. You must also hide any rows that don't match the
+ * filter condition. See @ref ww_autofilters_data for more details.
+ *
*/
lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
lxw_col_t first_col, lxw_row_t last_row,
lxw_col_t last_col);
/**
+ * @brief Write a filter rule to an autofilter column.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param col The column in the autofilter that the rule applies to.
+ * @param rule The lxw_filter_rule autofilter rule.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `worksheet_filter_column` function can be used to filter columns in a
+ * autofilter range based on single rule conditions:
+ *
+ * @code
+ * lxw_filter_rule filter_rule = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
+ * .value_string = "East"};
+ *
+ * worksheet_filter_column(worksheet, 0, &filter_rule);
+ *@endcode
+ *
+ * @image html autofilter4.png
+ *
+ * The rules and criteria are explained in more detail in @ref
+ * ww_autofilters_criteria in @ref working_with_autofilters.
+ *
+ * The `col` parameter is a zero indexed column number and must refer to a
+ * column in an existing autofilter created with `worksheet_autofilter()`.
+ *
+ * It isn't sufficient to just specify the filter condition. You must also
+ * hide any rows that don't match the filter condition. See @ref
+ * ww_autofilters_data for more details.
+ */
+lxw_error worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col,
+ lxw_filter_rule *rule);
+
+/**
+ * @brief Write two filter rules to an autofilter column.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param col The column in the autofilter that the rules applies to.
+ * @param rule1 First lxw_filter_rule autofilter rule.
+ * @param rule2 Second lxw_filter_rule autofilter rule.
+ * @param and_or A #lxw_filter_operator and/or operator.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `worksheet_filter_column2` function can be used to filter columns in a autofilter
+ * range based on two rule conditions:
+ *
+ * @code
+ * lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
+ * .value_string = "East"};
+ *
+ * lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
+ * .value_string = "South"};
+ *
+ * worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR);
+ * @endcode
+ *
+ * @image html autofilter5.png
+ *
+ * The rules and criteria are explained in more detail in @ref
+ * ww_autofilters_criteria in @ref working_with_autofilters.
+ *
+ * The `col` parameter is a zero indexed column number and must refer to a
+ * column in an existing autofilter created with `worksheet_autofilter()`.
+ *
+ * The `and_or` parameter is either "and (LXW_FILTER_AND)" or "or (LXW_FILTER_OR)".
+ *
+ * It isn't sufficient to just specify the filter condition. You must also
+ * hide any rows that don't match the filter condition. See @ref
+ * ww_autofilters_data for more details.
+ */
+lxw_error worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col,
+ lxw_filter_rule *rule1,
+ lxw_filter_rule *rule2, uint8_t and_or);
+/**
+ * @brief Write multiple string filters to an autofilter column.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param col The column in the autofilter that the rules applies to.
+ * @param list A NULL terminated array of strings to filter on.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `worksheet_filter_column_list()` function can be used specify multiple
+ * string matching criteria. This is a newer type of filter introduced in
+ * Excel 2007. Prior to that it was only possible to have either 1 or 2 filter
+ * conditions, such as the ones used by `worksheet_filter_column()` and
+ * `worksheet_filter_column2()`.
+ *
+ * As an example, consider a column that contains data for the months of the
+ * year. The `%worksheet_filter_list()` function can be used to filter out
+ * data rows for different months:
+ *
+ * @code
+ * char* list[] = {"March", "April", "May", NULL};
+ *
+ * worksheet_filter_list(worksheet, 0, list);
+ * @endcode
+ *
+ * @image html autofilter2.png
+ *
+ *
+ * Note, the array must be NULL terminated to indicate the end of the array of
+ * strings. To filter blanks as part of the list use `Blanks` as a list item:
+ *
+ * @code
+ * char* list[] = {"March", "April", "May", "Blanks", NULL};
+ *
+ * worksheet_filter_list(worksheet, 0, list);
+ * @endcode
+ *
+ * It isn't sufficient to just specify the filter condition. You must also
+ * hide any rows that don't match the filter condition. See @ref
+ * ww_autofilters_data for more details.
+ */
+lxw_error worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col,
+ const char **list);
+
+/**
* @brief Add a data validation to a cell.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param row The zero indexed row number.
* @param col The zero indexed column number.
@@ -2031,11 +4189,11 @@
lxw_error worksheet_data_validation_cell(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
lxw_data_validation *validation);
/**
- * @brief Add a data validation to a range cell.
+ * @brief Add a data validation to a range.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param first_row The first row of the range. (All zero indexed.)
* @param first_col The first column of the range.
* @param last_row The last row of the range.
@@ -2072,10 +4230,153 @@
lxw_col_t first_col,
lxw_row_t last_row,
lxw_col_t last_col,
lxw_data_validation *validation);
+/**
+ * @brief Add a conditional format to a worksheet cell.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param conditional_format A #lxw_conditional_format object to control the
+ * conditional format.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_conditional_format_cell()` function is used to set a
+ * conditional format for a cell in a worksheet:
+ *
+ * @code
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
+ * conditional_format->value = 50;
+ * conditional_format->format = format1;
+ * worksheet_conditional_format_cell(worksheet, CELL("A1"), conditional_format);
+ * @endcode
+ *
+ * The conditional format parameters is specified in #lxw_conditional_format.
+ *
+ * See @ref working_with_conditional_formatting for full details.
+ */
+lxw_error worksheet_conditional_format_cell(lxw_worksheet *worksheet,
+ lxw_row_t row,
+ lxw_col_t col,
+ lxw_conditional_format
+ *conditional_format);
+
+/**
+ * @brief Add a conditional format to a worksheet range.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_row The first row of the range. (All zero indexed.)
+ * @param first_col The first column of the range.
+ * @param last_row The last row of the range.
+ * @param last_col The last col of the range.
+ * @param conditional_format A #lxw_conditional_format object to control the
+ * conditional format.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_conditional_format_cell()` function is used to set a
+ * conditional format for a range of cells in a worksheet:
+ *
+ * @code
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_GREATER_THAN_OR_EQUAL_TO;
+ * conditional_format->value = 50;
+ * conditional_format->format = format1;
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
+ *
+ * conditional_format->type = LXW_CONDITIONAL_TYPE_CELL;
+ * conditional_format->criteria = LXW_CONDITIONAL_CRITERIA_LESS_THAN;
+ * conditional_format->value = 50;
+ * conditional_format->format = format2;
+ * worksheet_conditional_format_range(worksheet1, RANGE("B3:K12"), conditional_format);
+ * @endcode
+ *
+ * Output:
+ *
+ * @image html conditional_format1.png
+ *
+ *
+ * The conditional format parameters is specified in #lxw_conditional_format.
+ *
+ * See @ref working_with_conditional_formatting for full details.
+ */
+lxw_error worksheet_conditional_format_range(lxw_worksheet *worksheet,
+ lxw_row_t first_row,
+ lxw_col_t first_col,
+ lxw_row_t last_row,
+ lxw_col_t last_col,
+ lxw_conditional_format
+ *conditional_format);
+/**
+ * @brief Insert a button object into a worksheet.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The zero indexed row number.
+ * @param col The zero indexed column number.
+ * @param options A #lxw_button_options object to set the button properties.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_insert_button()` function can be used to insert an Excel
+ * form button into a worksheet. This function is generally only useful when
+ * used in conjunction with the `workbook_add_vba_project()` function to tie
+ * the button to a macro from an embedded VBA project:
+ *
+ * @code
+ * lxw_button_options options = {.caption = "Press Me",
+ * .macro = "say_hello"};
+ *
+ * worksheet_insert_button(worksheet, 2, 1, &options);
+ * @endcode
+ *
+ * @image html macros.png
+ *
+ * The button properties are set using the lxw_button_options struct.
+ *
+ * See also @ref working_with_macros
+ */
+lxw_error worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row,
+ lxw_col_t col, lxw_button_options *options);
+
+/**
+ * @brief Add an Excel table to a worksheet.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param first_row The first row of the range. (All zero indexed.)
+ * @param first_col The first column of the range.
+ * @param last_row The last row of the range.
+ * @param last_col The last col of the range.
+ * @param options A #lxw_table_options struct to define the table options.
+ *
+ * @return A #lxw_error code.
+ *
+ * The `%worksheet_add_table()` function is used to add a table to a
+ * worksheet. Tables in Excel are a way of grouping a range of cells into a
+ * single entity that has common formatting or that can be referenced from
+ * formulas. Tables can have column headers, autofilters, total rows, column
+ * formulas and default formatting.
+ *
+ * @code
+ * worksheet_add_table(worksheet, 2, 1, 6, 5, NULL);
+ * @endcode
+ *
+ * Output:
+ *
+ * @image html tables1.png
+ *
+ * See @ref working_with_tables for more detailed usage information and also
+ * @ref tables.c.
+ *
+ */
+lxw_error worksheet_add_table(lxw_worksheet *worksheet, lxw_row_t first_row,
+ lxw_col_t first_col, lxw_row_t last_row,
+ lxw_col_t last_col, lxw_table_options *options);
+
/**
* @brief Make a worksheet the active, i.e., visible worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
@@ -2249,11 +4550,11 @@
double vertical, double horizontal,
lxw_row_t top_row, lxw_col_t left_col);
/**
* @brief Set the selected cell or cells in a worksheet:
*
- * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param worksheet A pointer to a lxw_worksheet instance to be updated.
* @param first_row The first row of the range. (All zero indexed.)
* @param first_col The first column of the range.
* @param last_row The last row of the range.
* @param last_col The last col of the range.
*
@@ -2280,10 +4581,31 @@
void worksheet_set_selection(lxw_worksheet *worksheet,
lxw_row_t first_row, lxw_col_t first_col,
lxw_row_t last_row, lxw_col_t last_col);
/**
+ * @brief Set the first visible cell at the top left of a worksheet.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ * @param row The cell row (zero indexed).
+ * @param col The cell column (zero indexed).
+ *
+ * The `%worksheet_set_top_left_cell()` function can be used to set the
+ * top leftmost visible cell in the worksheet:
+ *
+ * @code
+ * worksheet_set_top_left_cell(worksheet, 31, 26);
+ * worksheet_set_top_left_cell(worksheet, CELL("AA32")); // Same as above.
+ * @endcode
+ *
+ * @image html top_left_cell.png
+ *
+ */
+void worksheet_set_top_left_cell(lxw_worksheet *worksheet, lxw_row_t row,
+ lxw_col_t col);
+
+/**
* @brief Set the page orientation as landscape.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* This function is used to set the orientation of a worksheet's printed page
@@ -2444,11 +4766,15 @@
* | `&U` | | Single underline |
* | `&E` | | Double underline |
* | `&S` | | Strikethrough |
* | `&X` | | Superscript |
* | `&Y` | | Subscript |
+ * | `&[Picture]` | Images | Image placeholder |
+ * | `&G` | | Same as `&[Picture]` |
+ * | `&&` | Miscellaneous | Literal ampersand & |
*
+ * Note: inserting images requires the `worksheet_set_header_opt()` function.
*
* Text in headers and footers can be justified (aligned) to the left, center
* and right by prefixing the text with the control characters `&L`, `&C` and
* `&R`.
*
@@ -2568,30 +4894,29 @@
* how to do that using libxml's xmllint to format the XML for clarity:
*
* @code
*
* $ unzip myfile.xlsm -d myfile
- * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer"
+ * $ xmllint --format `find myfile -name "*.xml" | xargs` | egrep "Header|Footer" | sed 's/&/\&/g'
*
* <headerFooter scaleWithDoc="0">
- * <oddHeader>&L&P</oddHeader>
+ * <oddHeader>&L&P</oddHeader>
* </headerFooter>
*
* @endcode
*
- * Note that in this case you need to unescape the Html. In the above example
- * the header string would be `&L&P`.
- *
* To include a single literal ampersand `&` in a header or footer you should
* use a double ampersand `&&`:
*
* @code
* worksheet_set_header(worksheet, "&CCuriouser && Curiouser - Attorneys at Law");
* @endcode
*
- * Note, the header or footer string must be less than 255 characters. Strings
- * longer than this will not be written.
+ * @note
+ * Excel requires that the header or footer string cannot be longer than 255
+ * characters, including the control characters. Strings longer than this will
+ * not be written.
*
*/
lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
/**
@@ -2614,23 +4939,47 @@
* @param string The header string.
* @param options Header options.
*
* @return A #lxw_error code.
*
- * The syntax of this function is the same as worksheet_set_header() with an
+ * The syntax of this function is the same as `worksheet_set_header()` with an
* additional parameter to specify options for the header.
*
- * Currently, the only available option is the header margin:
+ * The #lxw_header_footer_options options are:
*
+ * - `margin`: Header or footer margin in inches. The value must by larger
+ * than 0.0. The Excel default is 0.3.
+ *
+ * - `image_left`: The left header image filename, with path if required. This
+ * should have a corresponding `&G/&[Picture]` placeholder in the `&L`
+ * section of the header/footer string.
+ *
+ * - `image_center`: The center header image filename, with path if
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
+ * the `&C` section of the header/footer string.
+ *
+ * - `image_right`: The right header image filename, with path if
+ * required. This should have a corresponding `&G/&[Picture]` placeholder in
+ * the `&R` section of the header/footer string.
+ *
* @code
+ * lxw_header_footer_options header_options = { .margin = 0.2 };
*
- * lxw_header_footer_options header_options = { 0.2 };
+ * worksheet_set_header_opt(worksheet, "Some text", &header_options);
+ * @endcode
*
- * worksheet_set_header_opt(worksheet, "Some text", &header_options);
+ * Images can be inserted in the header by specifying the `&[Picture]`
+ * placeholder and a filename/path to the image:
*
+ * @code
+ * lxw_header_footer_options header_options = {.image_left = "logo.png"};
+ *
+ * worksheet_set_header_opt(worksheet, "&L&[Picture]", &header_options);
* @endcode
*
+ * @image html headers_footers.png
+ *
*/
lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
const char *string,
lxw_header_footer_options *options);
@@ -2641,11 +4990,11 @@
* @param string The footer string.
* @param options Footer options.
*
* @return A #lxw_error code.
*
- * The syntax of this function is the same as worksheet_set_header_opt().
+ * The syntax of this function is the same as `worksheet_set_header_opt()`.
*
*/
lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
const char *string,
lxw_header_footer_options *options);
@@ -2982,17 +5331,18 @@
*/
void worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width,
uint16_t height);
/**
- * @brief Set the start page number when printing.
+ * @brief Set the start/first page number when printing.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
- * @param start_page Starting page number.
+ * @param start_page Page number of the starting page when printing.
*
- * The `%worksheet_set_start_page()` function is used to set the number of
- * the starting page when the worksheet is printed out:
+ * The `%worksheet_set_start_page()` function is used to set the number number
+ * of the first page when the worksheet is printed out. It is the same as the
+ * "First Page Number" option in Excel:
*
* @code
* // Start print from page 2.
* worksheet_set_start_page(worksheet, 2);
* @endcode
@@ -3024,10 +5374,22 @@
*
*/
void worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
/**
+ * @brief Set the worksheet to print in black and white
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance to be updated.
+ *
+ * Set the option to print the worksheet in black and white:
+ * @code
+ * worksheet_print_black_and_white(worksheet);
+ * @endcode
+ */
+void worksheet_print_black_and_white(lxw_worksheet *worksheet);
+
+/**
* @brief Display the worksheet cells from right to left for some versions of
* Excel.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
@@ -3239,52 +5601,214 @@
* @brief Set the VBA name for the worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance.
* @param name Name of the worksheet used by VBA.
*
+ * @return A #lxw_error.
+ *
* The `worksheet_set_vba_name()` function can be used to set the VBA name for
* the worksheet. This is sometimes required when a vbaProject macro included
- * via `workbook_add_vba_project()` refers to the worksheet.
+ * via `workbook_add_vba_project()` refers to the worksheet by a name other
+ * than the worksheet name:
*
* @code
* workbook_set_vba_name (workbook, "MyWorkbook");
* worksheet_set_vba_name(worksheet, "MySheet1");
* @endcode
*
* In general Excel uses the worksheet name such as "Sheet1" as the VBA name.
* However, this can be changed in the VBA environment or if the the macro was
* extracted from a foreign language version of Excel.
*
- * @return A #lxw_error.
+ * See also @ref working_with_macros
*/
lxw_error worksheet_set_vba_name(lxw_worksheet *worksheet, const char *name);
+/**
+ * @brief Make all comments in the worksheet visible.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance.
+ *
+ * This `%worksheet_show_comments()` function is used to make all cell
+ * comments visible when a worksheet is opened:
+ *
+ * @code
+ * worksheet_show_comments(worksheet);
+ * @endcode
+ *
+ * Individual comments can be made visible or hidden using the `visible`
+ * option of the #lxw_comment_options struct and the `worksheet_write_comment_opt()`
+ * function (see above and @ref ww_comments_visible).
+ */
+void worksheet_show_comments(lxw_worksheet *worksheet);
+
+/**
+ * @brief Set the default author of the cell comments.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance.
+ * @param author The name of the comment author.
+ *
+ * This `%worksheet_set_comments_author()` function is used to set the
+ * default author of all cell comments:
+ *
+ * @code
+ * worksheet_set_comments_author(worksheet, "Jane Gloriana Villanueva")
+ * @endcode
+ *
+ * Individual authors can be set using the `author` option of the
+ * #lxw_comment_options struct and the `worksheet_write_comment_opt()`
+ * function (see above and @ref ww_comments_author).
+ */
+void worksheet_set_comments_author(lxw_worksheet *worksheet,
+ const char *author);
+
+/**
+ * @brief Ignore various Excel errors/warnings in a worksheet for user
+ * defined ranges.
+ *
+ * @param worksheet Pointer to a lxw_worksheet instance.
+ * @param type The type of error/warning to ignore. See #lxw_ignore_errors.
+ * @param range The range(s) for which the error/warning should be ignored.
+ *
+ * @return A #lxw_error.
+ *
+ *
+ * The `%worksheet_ignore_errors()` function can be used to ignore various
+ * worksheet cell errors/warnings. For example the following code writes a string
+ * that looks like a number:
+ *
+ * @code
+ * worksheet_write_string(worksheet, CELL("D2"), "123", NULL);
+ * @endcode
+ *
+ * This causes Excel to display a small green triangle in the top left hand
+ * corner of the cell to indicate an error/warning:
+ *
+ * @image html ignore_errors1.png
+ *
+ * Sometimes these warnings are useful indicators that there is an issue in
+ * the spreadsheet but sometimes it is preferable to turn them off. Warnings
+ * can be turned off at the Excel level for all workbooks and worksheets by
+ * using the using "Excel options -> Formulas -> Error checking
+ * rules". Alternatively you can turn them off for individual cells in a
+ * worksheet, or ranges of cells, using the `%worksheet_ignore_errors()`
+ * function with different #lxw_ignore_errors options and ranges like this:
+ *
+ * @code
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C3");
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_EVAL_ERROR, "C6");
+ * @endcode
+ *
+ * The range can be a single cell, a range of cells, or multiple cells and ranges
+ * separated by spaces:
+ *
+ * @code
+ * // Single cell.
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6");
+ *
+ * // Or a single range:
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6:G8");
+ *
+ * // Or multiple cells and ranges:
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "C6 E6 G1:G20 J2:J6");
+ * @endcode
+ *
+ * @note Calling `%worksheet_ignore_errors()` more than once for the same
+ * #lxw_ignore_errors type will overwrite the previous range.
+ *
+ * You can turn off warnings for an entire column by specifying the range from
+ * the first cell in the column to the last cell in the column:
+ *
+ * @code
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:A1048576");
+ * @endcode
+ *
+ * Or for the entire worksheet by specifying the range from the first cell in
+ * the worksheet to the last cell in the worksheet:
+ *
+ * @code
+ * worksheet_ignore_errors(worksheet, LXW_IGNORE_NUMBER_STORED_AS_TEXT, "A1:XFD1048576");
+ * @endcode
+ *
+ * The worksheet errors/warnings that can be ignored are:
+ *
+ * - #LXW_IGNORE_NUMBER_STORED_AS_TEXT: Turn off errors/warnings for numbers
+ * stores as text.
+ *
+ * - #LXW_IGNORE_EVAL_ERROR: Turn off errors/warnings for formula errors (such
+ * as divide by zero).
+ *
+ * - #LXW_IGNORE_FORMULA_DIFFERS: Turn off errors/warnings for formulas that
+ * differ from surrounding formulas.
+ *
+ * - #LXW_IGNORE_FORMULA_RANGE: Turn off errors/warnings for formulas that
+ * omit cells in a range.
+ *
+ * - #LXW_IGNORE_FORMULA_UNLOCKED: Turn off errors/warnings for unlocked cells
+ * that contain formulas.
+ *
+ * - #LXW_IGNORE_EMPTY_CELL_REFERENCE: Turn off errors/warnings for formulas
+ * that refer to empty cells.
+ *
+ * - #LXW_IGNORE_LIST_DATA_VALIDATION: Turn off errors/warnings for cells in a
+ * table that do not comply with applicable data validation rules.
+ *
+ * - #LXW_IGNORE_CALCULATED_COLUMN: Turn off errors/warnings for cell formulas
+ * that differ from the column formula.
+ *
+ * - #LXW_IGNORE_TWO_DIGIT_TEXT_YEAR: Turn off errors/warnings for formulas
+ * that contain a two digit text representation of a year.
+ *
+ */
+lxw_error worksheet_ignore_errors(lxw_worksheet *worksheet, uint8_t type,
+ const char *range);
+
lxw_worksheet *lxw_worksheet_new(lxw_worksheet_init_data *init_data);
void lxw_worksheet_free(lxw_worksheet *worksheet);
void lxw_worksheet_assemble_xml_file(lxw_worksheet *worksheet);
void lxw_worksheet_write_single_row(lxw_worksheet *worksheet);
void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
uint32_t image_ref_id, uint32_t drawing_id,
- lxw_image_options *image_data);
+ lxw_object_properties *object_props);
+void lxw_worksheet_prepare_header_image(lxw_worksheet *worksheet,
+ uint32_t image_ref_id,
+ lxw_object_properties *object_props);
+
+void lxw_worksheet_prepare_background(lxw_worksheet *worksheet,
+ uint32_t image_ref_id,
+ lxw_object_properties *object_props);
+
void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
uint32_t chart_ref_id, uint32_t drawing_id,
- lxw_image_options *image_data,
+ lxw_object_properties *object_props,
uint8_t is_chartsheet);
-lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
-lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
+uint32_t lxw_worksheet_prepare_vml_objects(lxw_worksheet *worksheet,
+ uint32_t vml_data_id,
+ uint32_t vml_shape_id,
+ uint32_t vml_drawing_id,
+ uint32_t comment_id);
+void lxw_worksheet_prepare_header_vml_objects(lxw_worksheet *worksheet,
+ uint32_t vml_header_id,
+ uint32_t vml_drawing_id);
+
+void lxw_worksheet_prepare_tables(lxw_worksheet *worksheet,
+ uint32_t table_id);
+
+lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
+lxw_cell *lxw_worksheet_find_cell_in_row(lxw_row *row, lxw_col_t col_num);
/*
- * External functions to call intern XML methods shared with chartsheet.
+ * External functions to call intern XML functions shared with chartsheet.
*/
void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
- lxw_protection *protect);
+ lxw_protection_obj *protect);
void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
/* Declarations required for unit testing. */
@@ -3315,11 +5839,16 @@
STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
- lxw_protection *protect);
+ lxw_protection_obj *protect);
STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
+
+STATIC double _pixels_to_height(double pixels);
+STATIC double _pixels_to_width(double pixels);
+
+STATIC void _worksheet_write_auto_filter(lxw_worksheet *worksheet);
#endif /* TESTING */
/* *INDENT-OFF* */
#ifdef __cplusplus
}