John McNamara 139cd8cc41 Added support for object positioning.
Added support for setting the image or chart object_position
property to specify if they should be moved or sized with cell.

Issue #263
2020-01-19 11:23:58 +00:00

3775 lines
129 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* libxlsxwriter
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
*/
/**
* @page worksheet_page The Worksheet object
*
* The Worksheet object represents an Excel worksheet. It handles
* operations such as writing data to cells or formatting worksheet
* layout.
*
* See @ref worksheet.h for full details of the functionality.
*
* @file worksheet.h
*
* @brief Functions related to adding data and formatting to a worksheet.
*
* The Worksheet object represents an Excel worksheet. It handles
* operations such as writing data to cells or formatting worksheet
* layout.
*
* A Worksheet object isn't created directly. Instead a worksheet is
* created by calling the workbook_add_worksheet() function from a
* Workbook object:
*
* @code
* #include "xlsxwriter.h"
*
* int main() {
*
* lxw_workbook *workbook = workbook_new("filename.xlsx");
* lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
*
* worksheet_write_string(worksheet, 0, 0, "Hello Excel", NULL);
*
* return workbook_close(workbook);
* }
* @endcode
*
*/
#ifndef __LXW_WORKSHEET_H__
#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_IMAGE_BUFFER_SIZE 1024
/* 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 */
#define LXW_DEF_COL_WIDTH (double)8.43
/** Default row height in Excel */
#define LXW_DEF_ROW_HEIGHT (double)15.0
/** Gridline options using in `worksheet_gridlines()`. */
enum lxw_gridlines {
/** Hide screen and print gridlines. */
LXW_HIDE_ALL_GRIDLINES = 0,
/** Show screen gridlines. */
LXW_SHOW_SCREEN_GRIDLINES,
/** Show print gridlines. */
LXW_SHOW_PRINT_GRIDLINES,
/** Show screen and print gridlines. */
LXW_SHOW_ALL_GRIDLINES
};
/** Data validation property values. */
enum lxw_validation_boolean {
LXW_VALIDATION_DEFAULT,
/** Turn a data validation property off. */
LXW_VALIDATION_OFF,
/** Turn a data validation property on. Data validation properties are
* generally on by default. */
LXW_VALIDATION_ON
};
/** Data validation types. */
enum lxw_validation_types {
LXW_VALIDATION_TYPE_NONE,
/** Restrict cell input to whole/integer numbers only. */
LXW_VALIDATION_TYPE_INTEGER,
/** Restrict cell input to whole/integer numbers only, using a cell
* reference. */
LXW_VALIDATION_TYPE_INTEGER_FORMULA,
/** Restrict cell input to decimal numbers only. */
LXW_VALIDATION_TYPE_DECIMAL,
/** Restrict cell input to decimal numbers only, using a cell
* reference. */
LXW_VALIDATION_TYPE_DECIMAL_FORMULA,
/** Restrict cell input to a list of strings in a dropdown. */
LXW_VALIDATION_TYPE_LIST,
/** Restrict cell input to a list of strings in a dropdown, using a
* cell range. */
LXW_VALIDATION_TYPE_LIST_FORMULA,
/** Restrict cell input to date values only, using a lxw_datetime type. */
LXW_VALIDATION_TYPE_DATE,
/** Restrict cell input to date values only, using a cell reference. */
LXW_VALIDATION_TYPE_DATE_FORMULA,
/* Restrict cell input to date values only, as a serial number.
* Undocumented. */
LXW_VALIDATION_TYPE_DATE_NUMBER,
/** Restrict cell input to time values only, using a lxw_datetime type. */
LXW_VALIDATION_TYPE_TIME,
/** Restrict cell input to time values only, using a cell reference. */
LXW_VALIDATION_TYPE_TIME_FORMULA,
/* Restrict cell input to time values only, as a serial number.
* Undocumented. */
LXW_VALIDATION_TYPE_TIME_NUMBER,
/** Restrict cell input to strings of defined length, using a cell
* reference. */
LXW_VALIDATION_TYPE_LENGTH,
/** Restrict cell input to strings of defined length, using a cell
* reference. */
LXW_VALIDATION_TYPE_LENGTH_FORMULA,
/** Restrict cell to input controlled by a custom formula that returns
* `TRUE/FALSE`. */
LXW_VALIDATION_TYPE_CUSTOM_FORMULA,
/** Allow any type of input. Mainly only useful for pop-up messages. */
LXW_VALIDATION_TYPE_ANY
};
/** Data validation criteria uses to control the selection of data. */
enum lxw_validation_criteria {
LXW_VALIDATION_CRITERIA_NONE,
/** Select data between two values. */
LXW_VALIDATION_CRITERIA_BETWEEN,
/** Select data that is not between two values. */
LXW_VALIDATION_CRITERIA_NOT_BETWEEN,
/** Select data equal to a value. */
LXW_VALIDATION_CRITERIA_EQUAL_TO,
/** Select data not equal to a value. */
LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO,
/** Select data greater than a value. */
LXW_VALIDATION_CRITERIA_GREATER_THAN,
/** Select data less than a value. */
LXW_VALIDATION_CRITERIA_LESS_THAN,
/** Select data greater than or equal to a value. */
LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO,
/** Select data less than or equal to a value. */
LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO
};
/** Data validation error types for pop-up messages. */
enum lxw_validation_error_types {
/** Show a "Stop" data validation pop-up message. This is the default. */
LXW_VALIDATION_ERROR_TYPE_STOP,
/** Show an "Error" data validation pop-up message. */
LXW_VALIDATION_ERROR_TYPE_WARNING,
/** 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
};
/** Options to control the positioning of worksheet objects such as images
* or charts. */
enum lxw_object_position {
/** Default positioning for the object. */
LXW_OBJECT_POSITION_DEFAULT,
/** Move and size with the worksheet object with the cells. */
LXW_OBJECT_MOVE_AND_SIZE,
/** Move but don't size with 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
};
enum cell_types {
NUMBER_CELL = 1,
STRING_CELL,
INLINE_STRING_CELL,
INLINE_RICH_STRING_CELL,
FORMULA_CELL,
ARRAY_FORMULA_CELL,
BLANK_CELL,
BOOLEAN_CELL,
COMMENT,
HYPERLINK_URL,
HYPERLINK_INTERNAL,
HYPERLINK_EXTERNAL
};
enum pane_types {
NO_PANES = 0,
FREEZE_PANES,
SPLIT_PANES,
FREEZE_SPLIT_PANES
};
/* 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);
/* Define a RB_TREE struct manually to add extra members. */
struct lxw_table_rows {
struct lxw_row *rbh_root;
struct lxw_row *cached_row;
lxw_row_t cached_row_num;
};
/* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
* warnings and to avoid portability issues with the _unused attribute. */
#define LXW_RB_GENERATE_ROW(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_row{int unused;}
#define LXW_RB_GENERATE_CELL(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_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;}
STAILQ_HEAD(lxw_merged_ranges, lxw_merged_range);
STAILQ_HEAD(lxw_selections, lxw_selection);
STAILQ_HEAD(lxw_data_validations, lxw_data_val_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);
/**
* @brief Options for rows and columns.
*
* Options struct for the worksheet_set_column() and worksheet_set_row()
* functions.
*
* It has the following members:
*
* * `hidden`
* * `level`
* * `collapsed`
*
* The members of this struct are explained in @ref ww_outlines_grouping.
*
*/
typedef struct lxw_row_col_options {
/** 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;
lxw_col_t lastcol;
double width;
lxw_format *format;
uint8_t hidden;
uint8_t level;
uint8_t collapsed;
} lxw_col_options;
typedef struct lxw_merged_range {
lxw_row_t first_row;
lxw_row_t last_row;
lxw_col_t first_col;
lxw_col_t last_col;
STAILQ_ENTRY (lxw_merged_range) list_pointers;
} lxw_merged_range;
typedef struct lxw_repeat_rows {
uint8_t in_use;
lxw_row_t first_row;
lxw_row_t last_row;
} lxw_repeat_rows;
typedef struct lxw_repeat_cols {
uint8_t in_use;
lxw_col_t first_col;
lxw_col_t last_col;
} lxw_repeat_cols;
typedef struct lxw_print_area {
uint8_t in_use;
lxw_row_t first_row;
lxw_row_t last_row;
lxw_col_t first_col;
lxw_col_t last_col;
} lxw_print_area;
typedef struct lxw_autofilter {
uint8_t in_use;
lxw_row_t first_row;
lxw_row_t last_row;
lxw_col_t first_col;
lxw_col_t last_col;
} lxw_autofilter;
typedef struct lxw_panes {
uint8_t type;
lxw_row_t first_row;
lxw_col_t first_col;
lxw_row_t top_row;
lxw_col_t left_col;
double x_split;
double y_split;
} lxw_panes;
typedef struct lxw_selection {
char pane[LXW_PANE_NAME_LENGTH];
char active_cell[LXW_MAX_CELL_RANGE_LENGTH];
char sqref[LXW_MAX_CELL_RANGE_LENGTH];
STAILQ_ENTRY (lxw_selection) list_pointers;
} lxw_selection;
/**
* @brief Worksheet data validation options.
*/
typedef struct lxw_data_validation {
/**
* Set the validation type. Should be a #lxw_validation_types value.
*/
uint8_t validate;
/**
* Set the validation criteria type to select the data. Should be a
* #lxw_validation_criteria value.
*/
uint8_t criteria;
/** Controls whether a data validation is not applied to blank data in the
* cell. Should be a #lxw_validation_boolean value. It is on by
* default.
*/
uint8_t ignore_blank;
/**
* This parameter is used to toggle on and off the 'Show input message
* when cell is selected' option in the Excel data validation dialog. When
* the option is off an input message is not displayed even if it has been
* set using input_message. Should be a #lxw_validation_boolean value. It
* is on by default.
*/
uint8_t show_input;
/**
* This parameter is used to toggle on and off the 'Show error alert
* after invalid data is entered' option in the Excel data validation
* dialog. When the option is off an error message is not displayed even
* if it has been set using error_message. Should be a
* #lxw_validation_boolean value. It is on by default.
*/
uint8_t show_error;
/**
* This parameter is used to specify the type of error dialog that is
* displayed. Should be a #lxw_validation_error_types value.
*/
uint8_t error_type;
/**
* This parameter is used to toggle on and off the 'In-cell dropdown'
* option in the Excel data validation dialog. When the option is on a
* dropdown list will be shown for list validations. Should be a
* #lxw_validation_boolean value. It is on by default.
*/
uint8_t dropdown;
/**
* This parameter is used to set the limiting value to which the criteria
* is applied using a whole or decimal number.
*/
double value_number;
/**
* 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;
/**
* 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:
*
* @code
* char *list[] = {"open", "high", "close", NULL};
*
* data_validation->validate = LXW_VALIDATION_TYPE_LIST;
* data_validation->value_list = list;
* @endcode
*
* The `value_formula` parameter can also be used to specify a list from
* an Excel cell range.
*
* Note, the string list is restricted by Excel to 255 characters,
* including comma separators.
*/
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.
*/
lxw_datetime value_datetime;
/**
* This parameter is the same as `value_number` but for the minimum value
* when a `BETWEEN` criteria is used.
*/
double minimum_number;
/**
* This parameter is the same as `value_formula` but for the minimum value
* when a `BETWEEN` criteria is used.
*/
char *minimum_formula;
/**
* This parameter is the same as `value_datetime` but for the minimum value
* when a `BETWEEN` criteria is used.
*/
lxw_datetime minimum_datetime;
/**
* This parameter is the same as `value_number` but for the maximum value
* when a `BETWEEN` criteria is used.
*/
double maximum_number;
/**
* This parameter is the same as `value_formula` but for the maximum value
* when a `BETWEEN` criteria is used.
*/
char *maximum_formula;
/**
* This parameter is the same as `value_datetime` but for the maximum value
* when a `BETWEEN` criteria is used.
*/
lxw_datetime maximum_datetime;
/**
* The input_title parameter is used to set the title of the input message
* that is displayed when a cell is entered. It has no default value and
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
} 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_val_obj) list_pointers;
} lxw_data_val_obj;
/**
* @brief Options for inserted images.
*
* Options for modifying images inserted via `worksheet_insert_image_opt()`.
*
*/
typedef struct lxw_image_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 image as a decimal. */
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. */
uint8_t object_position;
/** Optional description of the image. Defaults to the image filename
* as in Excel. Set to "" to ignore the description field. */
char *description;
/** Add an optional hyperlink to the image. Follows the same URL rules
* and types as `worksheet_write_url()`. */
char *url;
/** Add an optional mouseover tip for a hyperlink to the image. */
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. */
uint8_t object_position;
} 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 object_position;
FILE *stream;
uint8_t image_type;
uint8_t is_image_buffer;
unsigned 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;
char *md5;
STAILQ_ENTRY (lxw_object_properties) list_pointers;
} lxw_object_properties;
/**
* @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. */
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. */
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;
/* 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;
uint32_t col_absolute;
uint32_t row_absolute;
uint32_t width;
uint32_t height;
lxw_color_t color;
uint8_t font_family;
uint8_t visible;
uint32_t author_id;
double font_size;
struct lxw_drawing_coords from;
struct lxw_drawing_coords to;
char *author;
char *font_name;
char *text;
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
* worksheet_set_footer_opt() functions.
*
*/
typedef struct lxw_header_footer_options {
/** Header or footer margin in inches. Excel default is 0.3. */
double margin;
} lxw_header_footer_options;
/**
* @brief Worksheet protection options.
*/
typedef struct lxw_protection {
/** Turn off selection of locked cells. This in on in Excel by default.*/
uint8_t no_select_locked_cells;
/** Turn off selection of unlocked cells. This in on in Excel by default.*/
uint8_t no_select_unlocked_cells;
/** Prevent formatting of cells. */
uint8_t format_cells;
/** Prevent formatting of columns. */
uint8_t format_columns;
/** Prevent formatting of rows. */
uint8_t format_rows;
/** Prevent insertion of columns. */
uint8_t insert_columns;
/** Prevent insertion of rows. */
uint8_t insert_rows;
/** Prevent insertion of hyperlinks. */
uint8_t insert_hyperlinks;
/** Prevent deletion of columns. */
uint8_t delete_columns;
/** Prevent deletion of rows. */
uint8_t delete_rows;
/** Prevent sorting data. */
uint8_t sort;
/** Prevent filtering data. */
uint8_t autofilter;
/** Prevent insertion of pivot tables. */
uint8_t pivot_tables;
/** Protect scenarios. */
uint8_t scenarios;
/** Protect drawing objects. Worksheets only. */
uint8_t objects;
/** Turn off chartsheet content protection. */
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_obj;
/**
* @brief Struct to represent a rich string format/string pair.
*
* Arrays of this struct are used to define "rich" multi-format strings that
* are passed to `worksheet_write_rich_string()`. Each struct represents a
* fragment of the rich multi-format string with a lxw_format to define the
* format for the string part. If the string fragment is unformatted then
* `NULL` can be used for the format.
*/
typedef struct lxw_rich_string_tuple {
/** 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;
} lxw_rich_string_tuple;
/**
* @brief Struct to represent an Excel worksheet.
*
* The members of the lxw_worksheet struct aren't modified directly. Instead
* the worksheet properties are set by calling the functions shown in
* worksheet.h.
*/
typedef struct lxw_worksheet {
FILE *file;
FILE *optimize_tmpfile;
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_props *image_props;
struct lxw_chart_props *chart_data;
struct lxw_drawing_rel_ids *drawing_rel_ids;
struct lxw_comment_objs *comment_objs;
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;
uint32_t index;
uint8_t active;
uint8_t selected;
uint8_t hidden;
uint16_t *active_sheet;
uint16_t *first_sheet;
uint8_t is_chartsheet;
lxw_col_options **col_options;
uint16_t col_options_max;
double *col_sizes;
uint16_t col_sizes_max;
lxw_format **col_formats;
uint16_t col_formats_max;
uint8_t col_size_changed;
uint8_t row_size_changed;
uint8_t optimize;
struct lxw_row *optimize_row;
uint16_t fit_height;
uint16_t fit_width;
uint16_t horizontal_dpi;
uint16_t hlink_count;
uint16_t page_start;
uint16_t print_scale;
uint16_t rel_count;
uint16_t vertical_dpi;
uint16_t zoom;
uint8_t filter_on;
uint8_t fit_page;
uint8_t hcenter;
uint8_t orientation;
uint8_t outline_changed;
uint8_t outline_on;
uint8_t outline_style;
uint8_t outline_below;
uint8_t outline_right;
uint8_t page_order;
uint8_t page_setup_changed;
uint8_t page_view;
uint8_t paper_size;
uint8_t print_gridlines;
uint8_t print_headers;
uint8_t print_options_changed;
uint8_t right_to_left;
uint8_t screen_gridlines;
uint8_t show_zeros;
uint8_t vcenter;
uint8_t zoom_scale_normal;
uint8_t num_validations;
char *vba_codename;
lxw_color_t tab_color;
double margin_left;
double margin_right;
double margin_top;
double margin_bottom;
double margin_header;
double margin_footer;
double default_row_height;
uint32_t default_row_pixels;
uint32_t default_col_pixels;
uint8_t default_row_zeroed;
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];
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;
struct lxw_rel_tuples *external_hyperlinks;
struct lxw_rel_tuples *external_drawing_links;
struct lxw_rel_tuples *drawing_links;
struct lxw_panes panes;
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;
lxw_rel_tuple *external_vml_comment_link;
lxw_rel_tuple *external_comment_link;
char *comment_author;
char *vml_data_id_str;
uint32_t vml_shape_id;
uint8_t comment_display_default;
STAILQ_ENTRY (lxw_worksheet) list_pointers;
} lxw_worksheet;
/*
* Worksheet initialization data.
*/
typedef struct lxw_worksheet_init_data {
uint32_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;
lxw_format *default_url_format;
uint16_t max_url_length;
} lxw_worksheet_init_data;
/* Struct to represent a worksheet row. */
typedef struct lxw_row {
lxw_row_t row_num;
double height;
lxw_format *format;
uint8_t hidden;
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;
/* Struct to represent a worksheet cell. */
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;
} u;
double formula_result;
char *user_data1;
char *user_data2;
char *sst_string;
/* 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 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.
*
* @return A #lxw_error code.
*
* The `worksheet_write_number()` function writes numeric types to the cell
* specified by `row` and `column`:
*
* @code
* worksheet_write_number(worksheet, 0, 0, 123456, NULL);
* worksheet_write_number(worksheet, 1, 0, 2.3451, NULL);
* @endcode
*
* @image html write_number01.png
*
* The native data type for all numbers in Excel is a IEEE-754 64-bit
* double-precision floating point, which is also the default type used by
* `%worksheet_write_number`.
*
* 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.
*
* @code
* lxw_format *format = workbook_add_format(workbook);
* format_set_num_format(format, "$#,##0.00");
*
* worksheet_write_number(worksheet, 0, 0, 1234.567, format);
* @endcode
*
* @image html write_number02.png
*
* @note Excel doesn't support `NaN`, `Inf` or `-Inf` as a number value. If
* you are writing data that contains these values then your application
* should convert them to a string or handle them in some other way.
*
*/
lxw_error worksheet_write_number(lxw_worksheet *worksheet,
lxw_row_t row,
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 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.
*
* @return A #lxw_error code.
*
* The `%worksheet_write_string()` function writes a string to the cell
* specified by `row` and `column`:
*
* @code
* worksheet_write_string(worksheet, 0, 0, "This phrase is English!", NULL);
* @endcode
*
* @image html write_string01.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:
*
* @code
* lxw_format *format = workbook_add_format(workbook);
* format_set_bold(format);
*
* worksheet_write_string(worksheet, 0, 0, "This phrase is Bold!", format);
* @endcode
*
* @image html write_string02.png
*
* Unicode strings are supported in UTF-8 encoding. This generally requires
* that your source file is UTF-8 encoded or that the data has been read from
* a UTF-8 source:
*
* @code
* worksheet_write_string(worksheet, 0, 0, "Это фраза на русском!", NULL);
* @endcode
*
* @image html write_string03.png
*
*/
lxw_error worksheet_write_string(lxw_worksheet *worksheet,
lxw_row_t row,
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 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_formula()` function writes a formula or function to
* the cell specified by `row` and `column`:
*
* @code
* worksheet_write_formula(worksheet, 0, 0, "=B3 + 6", NULL);
* worksheet_write_formula(worksheet, 1, 0, "=SIN(PI()/4)", NULL);
* worksheet_write_formula(worksheet, 2, 0, "=SUM(A1:A2)", NULL);
* worksheet_write_formula(worksheet, 3, 0, "=IF(A3>1,\"Yes\", \"No\")", NULL);
* worksheet_write_formula(worksheet, 4, 0, "=AVERAGE(1, 2, 3, 4)", NULL);
* worksheet_write_formula(worksheet, 5, 0, "=DATEVALUE(\"1-Jan-2013\")", NULL);
* @endcode
*
* @image html write_formula01.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.
*
* Libxlsxwriter doesn't calculate the value of a formula and instead stores a
* default value of `0`. The correct formula result is displayed in Excel, as
* shown in the example above, since it recalculates the formulas when it loads
* the file. For cases where this is an issue see the
* `worksheet_write_formula_num()` function and the discussion in that section.
*
* Formulas must be written with the US style separator/range operator which
* is a comma (not semi-colon). Therefore a formula with multiple values
* should be written as follows:
*
* @code
* // OK.
* worksheet_write_formula(worksheet, 0, 0, "=SUM(1, 2, 3)", NULL);
*
* // NO. Error on load.
* worksheet_write_formula(worksheet, 1, 0, "=SUM(1; 2; 3)", NULL);
* @endcode
*
* See also @ref working_with_formulas.
*/
lxw_error worksheet_write_formula(lxw_worksheet *worksheet,
lxw_row_t row,
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.
*
* @return A #lxw_error code.
*
* 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)}`.
*
* Array formulas can return a single value or a range or values. For array
* formulas that return a range of values you must specify the range that the
* return values will be written to. This is why this function has `first_`
* and `last_` row/column parameters. The RANGE() macro can also be used to
* specify the range:
*
* @code
* worksheet_write_array_formula(worksheet, 4, 0, 6, 0, "{=TREND(C5:C7,B5:B7)}", NULL);
*
* // Same as above using the RANGE() macro.
* worksheet_write_array_formula(worksheet, RANGE("A5:A7"), "{=TREND(C5:C7,B5:B7)}", NULL);
* @endcode
*
* If the array formula returns a single value then the `first_` and `last_`
* parameters should be the same:
*
* @code
* worksheet_write_array_formula(worksheet, 1, 0, 1, 0, "{=SUM(B1:C1*B2:C2)}", NULL);
* worksheet_write_array_formula(worksheet, RANGE("A2:A2"), "{=SUM(B1:C1*B2:C2)}", NULL);
* @endcode
*
*/
lxw_error worksheet_write_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);
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);
/**
* @brief Write a date or time 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 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
* time to the cell specified by `row` and `column`:
*
* @dontinclude dates_and_times02.c
* @skip include
* @until num_format
* @skip Feb
* @until }
*
* 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.
*
* See @ref working_with_dates for more information about handling dates and
* times in libxlsxwriter.
*/
lxw_error worksheet_write_datetime(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col, lxw_datetime *datetime,
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", NULL);
* @endcode
*
* @image html hyperlinks_short.png
*
* The `format` parameter is used to apply formatting to the cell. This
* 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_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/", 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. To do this we must also match the default URL format using
* `workbook_get_default_url_format()`:
*
* @code
* // 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", 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:
* `Sheet1!A1:B2`.
*
* 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", 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", 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", 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", 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", 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 " < > \ [ ] ^ { }`. 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 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.
*
* @return A #lxw_error code.
*
* Write an Excel boolean to the cell specified by `row` and `column`:
*
* @code
* worksheet_write_boolean(worksheet, 2, 2, 0, my_format);
* @endcode
*
*/
lxw_error worksheet_write_boolean(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
int value, lxw_format *format);
/**
* @brief Write a formatted blank 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 format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
* Write a blank cell specified by `row` and `column`:
*
* @code
* worksheet_write_blank(worksheet, 1, 1, border_format);
* @endcode
*
* This function is used to add formatting to a cell which doesn't contain a
* string or number value.
*
* Excel differentiates between an "Empty" cell and a "Blank" cell. An Empty
* cell is a cell which doesn't contain data or formatting whilst a Blank cell
* doesn't contain data but does contain formatting. Excel stores Blank cells
* but ignores Empty cells.
*
* As such, if you write an empty cell without formatting it is ignored.
*
*/
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.
*
* @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.
*
* @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:
*
* @code
* // Required as a workaround only.
* worksheet_write_formula_num(worksheet, 0, 0, "=1 + 2", NULL, 3);
* @endcode
*
* Libxlsxwriter doesn't calculate the value of a formula and instead stores
* the value `0` as the formula result. It then sets a global flag in the XLSX
* file to say that all formulas and functions should be recalculated when the
* file is opened.
*
* This is the method recommended in the Excel documentation and in general it
* works fine with spreadsheet applications.
*
* However, applications that don't have a facility to calculate formulas,
* such as Excel Viewer, or some mobile applications will only display the `0`
* results.
*
* If required, the `%worksheet_write_formula_num()` function can be used to
* specify a formula and its result.
*
* This function is rarely required and is only provided for compatibility
* with some third party applications. For most applications the
* worksheet_write_formula() function is the recommended way of writing
* formulas.
*
* See also @ref working_with_formulas.
*/
lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col,
const char *formula,
lxw_format *format, double result);
/**
* @brief Write a "Rich" multi-format string 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 rich_string An array of format/string lxw_rich_string_tuple fragments.
* @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
* The `%worksheet_write_rich_string()` function is used to write strings with
* multiple formats. For example to write the string 'This is **bold**
* and this is *italic*' you would use the following:
*
* @code
* lxw_format *bold = workbook_add_format(workbook);
* format_set_bold(bold);
*
* lxw_format *italic = workbook_add_format(workbook);
* format_set_italic(italic);
*
* lxw_rich_string_tuple fragment11 = {.format = NULL, .string = "This is " };
* lxw_rich_string_tuple fragment12 = {.format = bold, .string = "bold" };
* lxw_rich_string_tuple fragment13 = {.format = NULL, .string = " and this is "};
* lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic" };
*
* lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
* &fragment13, &fragment14, NULL};
*
* worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
*
* @endcode
*
* @image html rich_strings_small.png
*
* The basic rule is to break the string into fragments and put a lxw_format
* object before the fragment that you want to format. So if we look at the
* above example again:
*
* This is **bold** and this is *italic*
*
* The would be broken down into 4 fragments:
*
* default: |This is |
* bold: |bold|
* default: | and this is |
* italic: |italic|
*
* This in then converted to the lxw_rich_string_tuple fragments shown in the
* example above. For the default format we use `NULL`.
*
* The fragments are passed to `%worksheet_write_rich_string()` as a `NULL`
* terminated array:
*
* @code
* lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
* &fragment13, &fragment14, NULL};
*
* worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
*
* @endcode
*
* **Note**:
* Excel doesn't allow the use of two consecutive formats in a rich string or
* an empty string fragment. For either of these conditions a warning is
* raised and the input to `%worksheet_write_rich_string()` is ignored.
*
*/
lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
lxw_row_t row,
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 format A pointer to a Format instance or NULL.
*
* 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 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);
* format_set_bold(bold);
*
* // Set the header row to bold.
* worksheet_set_row(worksheet, 0, 15, bold);
* @endcode
*
* If you wish to set the format of a row without changing the height you can
* pass the default row height of #LXW_DEF_ROW_HEIGHT = 15:
*
* @code
* worksheet_set_row(worksheet, 0, LXW_DEF_ROW_HEIGHT, format);
* worksheet_set_row(worksheet, 0, 15, format); // Same as above.
* @endcode
*
* The `format` parameter will be applied to any cells in the row that don't
* have a format. As with Excel the row format is overridden by an explicit
* cell format. For example:
*
* @code
* // Row 1 has format1.
* worksheet_set_row(worksheet, 0, 15, format1);
*
* // Cell A1 in Row 1 defaults to format1.
* worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
*
* // Cell B1 in Row 1 keeps format2.
* worksheet_write_string(worksheet, 0, 1, "Hello", format2);
* @endcode
*
*/
lxw_error worksheet_set_row(lxw_worksheet *worksheet,
lxw_row_t row, double height, lxw_format *format);
/**
* @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 format A pointer to a Format instance or NULL.
* @param options Optional row parameters: hidden, level, collapsed.
*
* 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:
*
* - `hidden`
* - `level`
* - `collapsed`
*
* The `"hidden"` option is used to hide a row. This can be used, for
* example, to hide intermediary steps in a complicated calculation:
*
* @code
* lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
*
* // Hide the fourth and fifth (zero indexed) rows.
* worksheet_set_row_opt(worksheet, 3, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 4, LXW_DEF_ROW_HEIGHT, NULL, &options1);
*
* @endcode
*
* @image html hide_row_col2.png
*
* The `"hidden"`, `"level"`, and `"collapsed"`, options can also be used to
* create Outlines and Grouping. See @ref working_with_outlines.
*
* @code
* // The option structs with the outline level set.
* lxw_row_col_options options1 = {.hidden = 0, .level = 2, .collapsed = 0};
* lxw_row_col_options options2 = {.hidden = 0, .level = 1, .collapsed = 0};
*
*
* // Set the row options with the outline level.
* worksheet_set_row_opt(worksheet, 1, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 2, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 3, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 4, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 5, LXW_DEF_ROW_HEIGHT, NULL, &options2);
*
* worksheet_set_row_opt(worksheet, 6, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 7, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 8, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 9, LXW_DEF_ROW_HEIGHT, NULL, &options1);
* worksheet_set_row_opt(worksheet, 10, LXW_DEF_ROW_HEIGHT, NULL, &options2);
* @endcode
*
* @image html outline1.png
*
*/
lxw_error worksheet_set_row_opt(lxw_worksheet *worksheet,
lxw_row_t row,
double height,
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.
*
* 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.
* worksheet_set_column(worksheet, 1, 3, 30, NULL);
*
* @endcode
*
* If `%worksheet_set_column()` is applied to a single column the value of
* `first_col` and `last_col` should be the same:
*
* @code
* // Width of column B set to 30.
* worksheet_set_column(worksheet, 1, 1, 30, NULL);
*
* @endcode
*
* It is also possible, and generally clearer, to specify a column range using
* the form of `COLS()` macro:
*
* @code
* worksheet_set_column(worksheet, 4, 4, 20, NULL);
* worksheet_set_column(worksheet, 5, 8, 30, NULL);
*
* // Same as the examples above but clearer.
* worksheet_set_column(worksheet, COLS("E:E"), 20, NULL);
* worksheet_set_column(worksheet, COLS("F:H"), 30, NULL);
*
* @endcode
*
* 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.
*
* 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
* column width at the end.
*
* As usual the @ref format.h `format` parameter is optional. If you wish to
* set the format without changing the width you can pass a default column
* width of #LXW_DEF_COL_WIDTH = 8.43:
*
* @code
* lxw_format *bold = workbook_add_format(workbook);
* format_set_bold(bold);
*
* // Set the first column to bold.
* worksheet_set_column(worksheet, 0, 0, LXW_DEF_COL_WIDTH, bold);
* @endcode
*
* The `format` parameter will be applied to any cells in the column that
* don't have a format. For example:
*
* @code
* // Column 1 has format1.
* worksheet_set_column(worksheet, COLS("A:A"), 8.43, format1);
*
* // Cell A1 in column 1 defaults to format1.
* worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
*
* // Cell A2 in column 1 keeps format2.
* worksheet_write_string(worksheet, 1, 0, "Hello", format2);
* @endcode
*
* As in Excel a row format takes precedence over a default column format:
*
* @code
* // Row 1 has format1.
* worksheet_set_row(worksheet, 0, 15, format1);
*
* // Col 1 has format2.
* worksheet_set_column(worksheet, COLS("A:A"), 8.43, format2);
*
* // Cell A1 defaults to format1, the row format.
* worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
*
* // Cell A2 keeps format2, the column format.
* worksheet_write_string(worksheet, 1, 0, "Hello", NULL);
* @endcode
*/
lxw_error worksheet_set_column(lxw_worksheet *worksheet,
lxw_col_t first_col,
lxw_col_t last_col,
double width, lxw_format *format);
/**
* @brief Set the properties for one or more columns of cells with options.
*
* @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.
* @param options Optional row parameters: hidden, level, collapsed.
*
* 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:
*
* - `hidden`
* - `level`
* - `collapsed`
*
* The `"hidden"` option is used to hide a column. This can be used, for
* example, to hide intermediary steps in a complicated calculation:
*
* @code
* lxw_row_col_options options1 = {.hidden = 1, .level = 0, .collapsed = 0};
*
* worksheet_set_column_opt(worksheet, COLS("D:E"), LXW_DEF_COL_WIDTH, NULL, &options1);
* @endcode
*
* @image html hide_row_col3.png
*
* The `"hidden"`, `"level"`, and `"collapsed"`, options can also be used to
* create Outlines and Grouping. See @ref working_with_outlines.
*
* @code
* lxw_row_col_options options1 = {.hidden = 0, .level = 1, .collapsed = 0};
*
* worksheet_set_column_opt(worksheet, COLS("B:G"), 5, NULL, &options1);
* @endcode
*
* @image html outline8.png
*/
lxw_error worksheet_set_column_opt(lxw_worksheet *worksheet,
lxw_col_t first_col,
lxw_col_t last_col,
double width,
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:
*
* @code
* worksheet_insert_image(worksheet, 2, 1, "logo.png");
* @endcode
*
* @image html insert_image.png
*
* The `worksheet_insert_image_opt()` function takes additional optional
* parameters to position and scale the image, see below.
*
* **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.
*
* 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.
*/
lxw_error worksheet_insert_image(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
const char *filename);
/**
* @brief Insert an image in 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 filename The image filename, with path if required.
* @param options Optional image parameters.
*
* @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:
*
* @code
* 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);
*
* @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,
const char *filename,
lxw_image_options *options);
/**
* @brief Insert an image in a worksheet cell, from a memory buffer.
*
* @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 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 image into a worksheet from a memory
* buffer:
*
* @code
* worksheet_insert_image_buffer(worksheet, CELL("B3"), image_buffer, image_size);
* @endcode
*
* @image html image_buffer.png
*
* The buffer should be a pointer to an array of unsigned char data with a
* specified size.
*
* See `worksheet_insert_image()` for details about the supported image
* formats, and other image features.
*/
lxw_error worksheet_insert_image_buffer(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col,
const unsigned char *image_buffer,
size_t image_size);
/**
* @brief Insert an image in a worksheet cell, from a memory buffer.
*
* @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 image_buffer Pointer to an array of bytes that holds the image data.
* @param image_size The size of the array of bytes.
* @param options Optional image parameters.
*
* @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:
*
* @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);
* @endcode
*
* @image html image_buffer_opt.png
*
* The buffer should be a pointer to an array of unsigned char data with a
* specified size.
*
* See `worksheet_insert_image_buffer_opt()` for details about the supported
* image formats, and other image options.
*/
lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
lxw_row_t row,
lxw_col_t col,
const unsigned char *image_buffer,
size_t image_size,
lxw_image_options *options);
/**
* @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.
* @param chart A #lxw_chart object created via workbook_add_chart().
*
* @return A #lxw_error code.
*
* The `%worksheet_insert_chart()` function can be used to insert a chart into
* a worksheet. The chart object must be created first using the
* `workbook_add_chart()` function and configured using the @ref chart.h
* functions.
*
* @code
* // Create a chart object.
* lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
*
* // Add a data series to the chart.
* chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$6");
*
* // Insert the chart into the worksheet.
* worksheet_insert_chart(worksheet, 0, 2, chart);
* @endcode
*
* @image html chart_working.png
*
* **Note:**
*
* A chart may only be inserted into a worksheet once. If several similar
* charts are required then each one must be created separately with
* `%worksheet_insert_chart()`.
*
*/
lxw_error worksheet_insert_chart(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
lxw_chart *chart);
/**
* @brief Insert a chart object into a worksheet, 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 chart A #lxw_chart object created via workbook_add_chart().
* @param user_options Optional chart parameters.
*
* @return A #lxw_error code.
*
* The `%worksheet_insert_chart_opt()` function is like
* `worksheet_insert_chart()` function except that it takes an optional
* #lxw_chart_options struct to scale and position the chart:
*
* @code
* 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
*
*/
lxw_error worksheet_insert_chart_opt(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col,
lxw_chart *chart,
lxw_chart_options *user_options);
/**
* @brief Merge a range of cells.
*
* @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 string String to write to the merged range.
* @param format A pointer to a Format instance or NULL.
*
* @return A #lxw_error code.
*
* The `%worksheet_merge_range()` function allows cells to be merged together
* so that they act as a single area.
*
* Excel generally merges and centers cells at same time. To get similar
* behavior with libxlsxwriter you need to apply a @ref format.h "Format"
* object with the appropriate alignment:
*
* @code
* lxw_format *merge_format = workbook_add_format(workbook);
* format_set_align(merge_format, LXW_ALIGN_CENTER);
*
* worksheet_merge_range(worksheet, 1, 1, 1, 3, "Merged Range", merge_format);
*
* @endcode
*
* It is possible to apply other formatting to the merged cells as well:
*
* @code
* format_set_align (merge_format, LXW_ALIGN_CENTER);
* format_set_align (merge_format, LXW_ALIGN_VERTICAL_CENTER);
* format_set_border (merge_format, LXW_BORDER_DOUBLE);
* format_set_bold (merge_format);
* format_set_bg_color(merge_format, 0xD7E4BC);
*
* worksheet_merge_range(worksheet, 2, 1, 3, 3, "Merged Range", merge_format);
*
* @endcode
*
* @image html merge.png
*
* The `%worksheet_merge_range()` function writes a `char*` string using
* `worksheet_write_string()`. In order to write other data types, such as a
* number or a formula, you can overwrite the first cell with a call to one of
* the other write functions. The same Format should be used as was used in
* the merged range.
*
* @code
* // First write a range with a blank string.
* worksheet_merge_range (worksheet, 1, 1, 1, 3, "", format);
*
* // Then overwrite the first cell with a number.
* worksheet_write_number(worksheet, 1, 1, 123, format);
* @endcode
*
* @note Merged ranges generally dont 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,
lxw_format *format);
/**
* @brief Set the autofilter area in the 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.
*
* @return A #lxw_error code.
*
* The `%worksheet_autofilter()` function allows an autofilter to be added to
* a worksheet.
*
* 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
*
* 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.
*/
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 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.
* @param validation A #lxw_data_validation object to control the validation.
*
* @return A #lxw_error code.
*
* The `%worksheet_data_validation_cell()` function is used to construct an
* Excel data validation or to limit the user input to a dropdown list of
* values:
*
* @code
*
* lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
*
* data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
* data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
* data_validation->minimum_number = 1;
* data_validation->maximum_number = 10;
*
* worksheet_data_validation_cell(worksheet, 2, 1, data_validation);
*
* // Same as above with the CELL() macro.
* worksheet_data_validation_cell(worksheet, CELL("B3"), data_validation);
*
* @endcode
*
* @image html data_validate4.png
*
* Data validation and the various options of #lxw_data_validation are
* described in more detail in @ref working_with_data_validation.
*/
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.
*
* @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 validation A #lxw_data_validation object to control the validation.
*
* @return A #lxw_error code.
*
* The `%worksheet_data_validation_range()` function is the same as the
* `%worksheet_data_validation_cell()`, see above, except the data validation
* is applied to a range of cells:
*
* @code
*
* lxw_data_validation *data_validation = calloc(1, sizeof(lxw_data_validation));
*
* data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
* data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
* data_validation->minimum_number = 1;
* data_validation->maximum_number = 10;
*
* worksheet_data_validation_range(worksheet, 2, 1, 4, 1, data_validation);
*
* // Same as above with the RANGE() macro.
* worksheet_data_validation_range(worksheet, RANGE("B3:B5"), data_validation);
*
* @endcode
*
* Data validation and the various options of #lxw_data_validation are
* described in more detail in @ref working_with_data_validation.
*/
lxw_error worksheet_data_validation_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_data_validation *validation);
/**
* @brief Make a worksheet the active, i.e., visible worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `%worksheet_activate()` function is used to specify which worksheet is
* initially visible in a multi-sheet workbook:
*
* @code
* lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
* lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
* lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL);
*
* worksheet_activate(worksheet3);
* @endcode
*
* @image html worksheet_activate.png
*
* More than one worksheet can be selected via the `worksheet_select()`
* function, see below, however only one worksheet can be active.
*
* The default active worksheet is the first worksheet.
*
*/
void worksheet_activate(lxw_worksheet *worksheet);
/**
* @brief Set a worksheet tab as selected.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `%worksheet_select()` function is used to indicate that a worksheet is
* selected in a multi-sheet workbook:
*
* @code
* worksheet_activate(worksheet1);
* worksheet_select(worksheet2);
* worksheet_select(worksheet3);
*
* @endcode
*
* A selected worksheet has its tab highlighted. Selecting worksheets is a
* way of grouping them together so that, for example, several worksheets
* could be printed in one go. A worksheet that has been activated via the
* `worksheet_activate()` function will also appear as selected.
*
*/
void worksheet_select(lxw_worksheet *worksheet);
/**
* @brief Hide the current worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `%worksheet_hide()` function is used to hide a worksheet:
*
* @code
* worksheet_hide(worksheet2);
* @endcode
*
* You may wish to hide a worksheet in order to avoid confusing a user with
* intermediate data or calculations.
*
* @image html hide_sheet.png
*
* A hidden worksheet can not be activated or selected so this function is
* mutually exclusive with the `worksheet_activate()` and `worksheet_select()`
* functions. In addition, since the first worksheet will default to being the
* active worksheet, you cannot hide the first worksheet without activating
* another sheet:
*
* @code
* worksheet_activate(worksheet2);
* worksheet_hide(worksheet1);
* @endcode
*/
void worksheet_hide(lxw_worksheet *worksheet);
/**
* @brief Set current worksheet as the first visible sheet tab.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `worksheet_activate()` function determines which worksheet is initially
* selected. However, if there are a large number of worksheets the selected
* worksheet may not appear on the screen. To avoid this you can select the
* leftmost visible worksheet tab using `%worksheet_set_first_sheet()`:
*
* @code
* worksheet_set_first_sheet(worksheet19); // First visible worksheet tab.
* worksheet_activate(worksheet20); // First visible worksheet.
* @endcode
*
* This function is not required very often. The default value is the first
* worksheet.
*/
void worksheet_set_first_sheet(lxw_worksheet *worksheet);
/**
* @brief Split and freeze a worksheet into panes.
*
* @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_freeze_panes()` function can be used to divide a worksheet
* into horizontal or vertical regions known as panes and to "freeze" these
* panes so that the splitter bars are not visible.
*
* The parameters `row` and `col` are used to specify the location of the
* split. It should be noted that the split is specified at the top or left of
* a cell and that the function uses zero based indexing. Therefore to freeze
* the first row of a worksheet it is necessary to specify the split at row 2
* (which is 1 as the zero-based index).
*
* You can set one of the `row` and `col` parameters as zero if you do not
* want either a vertical or horizontal split.
*
* Examples:
*
* @code
* worksheet_freeze_panes(worksheet1, 1, 0); // Freeze the first row.
* worksheet_freeze_panes(worksheet2, 0, 1); // Freeze the first column.
* worksheet_freeze_panes(worksheet3, 1, 1); // Freeze first row/column.
*
* @endcode
*
*/
void worksheet_freeze_panes(lxw_worksheet *worksheet,
lxw_row_t row, lxw_col_t col);
/**
* @brief Split a worksheet into panes.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param vertical The position for the vertical split.
* @param horizontal The position for the horizontal split.
*
* The `%worksheet_split_panes()` function can be used to divide a worksheet
* into horizontal or vertical regions known as panes. This function is
* different from the `worksheet_freeze_panes()` function in that the splits
* between the panes will be visible to the user and each pane will have its
* own scroll bars.
*
* The parameters `vertical` and `horizontal` are used to specify the vertical
* and horizontal position of the split. The units for `vertical` and
* `horizontal` are the same as those used by Excel to specify row height and
* column width. However, the vertical and horizontal units are different from
* each other. Therefore you must specify the `vertical` and `horizontal`
* parameters in terms of the row heights and column widths that you have set
* or the default values which are 15 for a row and 8.43 for a column.
*
* Examples:
*
* @code
* worksheet_split_panes(worksheet1, 15, 0); // First row.
* worksheet_split_panes(worksheet2, 0, 8.43); // First column.
* worksheet_split_panes(worksheet3, 15, 8.43); // First row and column.
*
* @endcode
*
*/
void worksheet_split_panes(lxw_worksheet *worksheet,
double vertical, double horizontal);
/* worksheet_freeze_panes() with infrequent options. Undocumented for now. */
void worksheet_freeze_panes_opt(lxw_worksheet *worksheet,
lxw_row_t first_row, lxw_col_t first_col,
lxw_row_t top_row, lxw_col_t left_col,
uint8_t type);
/* worksheet_split_panes() with infrequent options. Undocumented for now. */
void worksheet_split_panes_opt(lxw_worksheet *worksheet,
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 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.
*
*
* The `%worksheet_set_selection()` function can be used to specify which cell
* or range of cells is selected in a worksheet: The most common requirement
* is to select a single cell, in which case the `first_` and `last_`
* parameters should be the same.
*
* The active cell within a selected range is determined by the order in which
* `first_` and `last_` are specified.
*
* Examples:
*
* @code
* worksheet_set_selection(worksheet1, 3, 3, 3, 3); // Cell D4.
* worksheet_set_selection(worksheet2, 3, 3, 6, 6); // Cells D4 to G7.
* worksheet_set_selection(worksheet3, 6, 6, 3, 3); // Cells G7 to D4.
* worksheet_set_selection(worksheet5, RANGE("D4:G7")); // Using the RANGE macro.
*
* @endcode
*
*/
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 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
* to landscape:
*
* @code
* worksheet_set_landscape(worksheet);
* @endcode
*/
void worksheet_set_landscape(lxw_worksheet *worksheet);
/**
* @brief Set the page orientation as portrait.
*
* @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
* to portrait. The default worksheet orientation is portrait, so this
* function isn't generally required:
*
* @code
* worksheet_set_portrait(worksheet);
* @endcode
*/
void worksheet_set_portrait(lxw_worksheet *worksheet);
/**
* @brief Set the page layout to page view mode.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* This function is used to display the worksheet in "Page View/Layout" mode:
*
* @code
* worksheet_set_page_view(worksheet);
* @endcode
*/
void worksheet_set_page_view(lxw_worksheet *worksheet);
/**
* @brief Set the paper type for printing.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param paper_type The Excel paper format type.
*
* This function is used to set the paper format for the printed output of a
* worksheet. The following paper styles are available:
*
*
* Index | Paper format | Paper size
* :------- | :---------------------- | :-------------------
* 0 | Printer default | Printer default
* 1 | Letter | 8 1/2 x 11 in
* 2 | Letter Small | 8 1/2 x 11 in
* 3 | Tabloid | 11 x 17 in
* 4 | Ledger | 17 x 11 in
* 5 | Legal | 8 1/2 x 14 in
* 6 | Statement | 5 1/2 x 8 1/2 in
* 7 | Executive | 7 1/4 x 10 1/2 in
* 8 | A3 | 297 x 420 mm
* 9 | A4 | 210 x 297 mm
* 10 | A4 Small | 210 x 297 mm
* 11 | A5 | 148 x 210 mm
* 12 | B4 | 250 x 354 mm
* 13 | B5 | 182 x 257 mm
* 14 | Folio | 8 1/2 x 13 in
* 15 | Quarto | 215 x 275 mm
* 16 | --- | 10x14 in
* 17 | --- | 11x17 in
* 18 | Note | 8 1/2 x 11 in
* 19 | Envelope 9 | 3 7/8 x 8 7/8
* 20 | Envelope 10 | 4 1/8 x 9 1/2
* 21 | Envelope 11 | 4 1/2 x 10 3/8
* 22 | Envelope 12 | 4 3/4 x 11
* 23 | Envelope 14 | 5 x 11 1/2
* 24 | C size sheet | ---
* 25 | D size sheet | ---
* 26 | E size sheet | ---
* 27 | Envelope DL | 110 x 220 mm
* 28 | Envelope C3 | 324 x 458 mm
* 29 | Envelope C4 | 229 x 324 mm
* 30 | Envelope C5 | 162 x 229 mm
* 31 | Envelope C6 | 114 x 162 mm
* 32 | Envelope C65 | 114 x 229 mm
* 33 | Envelope B4 | 250 x 353 mm
* 34 | Envelope B5 | 176 x 250 mm
* 35 | Envelope B6 | 176 x 125 mm
* 36 | Envelope | 110 x 230 mm
* 37 | Monarch | 3.875 x 7.5 in
* 38 | Envelope | 3 5/8 x 6 1/2 in
* 39 | Fanfold | 14 7/8 x 11 in
* 40 | German Std Fanfold | 8 1/2 x 12 in
* 41 | German Legal Fanfold | 8 1/2 x 13 in
*
* Note, it is likely that not all of these paper types will be available to
* the end user since it will depend on the paper formats that the user's
* printer supports. Therefore, it is best to stick to standard paper types:
*
* @code
* worksheet_set_paper(worksheet1, 1); // US Letter
* worksheet_set_paper(worksheet2, 9); // A4
* @endcode
*
* If you do not specify a paper type the worksheet will print using the
* printer's default paper style.
*/
void worksheet_set_paper(lxw_worksheet *worksheet, uint8_t paper_type);
/**
* @brief Set the worksheet margins for the printed page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param left Left margin in inches. Excel default is 0.7.
* @param right Right margin in inches. Excel default is 0.7.
* @param top Top margin in inches. Excel default is 0.75.
* @param bottom Bottom margin in inches. Excel default is 0.75.
*
* The `%worksheet_set_margins()` function is used to set the margins of the
* worksheet when it is printed. The units are in inches. Specifying `-1` for
* any parameter will give the default Excel value as shown above.
*
* @code
* worksheet_set_margins(worksheet, 1.3, 1.2, -1, -1);
* @endcode
*
*/
void worksheet_set_margins(lxw_worksheet *worksheet, double left,
double right, double top, double bottom);
/**
* @brief Set the printed page header caption.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param string The header string.
*
* @return A #lxw_error code.
*
* Headers and footers are generated using a string which is a combination of
* plain text and control characters.
*
* The available control character are:
*
*
* | Control | Category | Description |
* | --------------- | ------------- | --------------------- |
* | `&L` | Justification | Left |
* | `&C` | | Center |
* | `&R` | | Right |
* | `&P` | Information | Page number |
* | `&N` | | Total number of pages |
* | `&D` | | Date |
* | `&T` | | Time |
* | `&F` | | File name |
* | `&A` | | Worksheet name |
* | `&Z` | | Workbook path |
* | `&fontsize` | Font | Font size |
* | `&"font,style"` | | Font name and style |
* | `&U` | | Single underline |
* | `&E` | | Double underline |
* | `&S` | | Strikethrough |
* | `&X` | | Superscript |
* | `&Y` | | Subscript |
*
*
* 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`.
*
* For example (with ASCII art representation of the results):
*
* @code
* worksheet_set_header(worksheet, "&LHello");
*
* // ---------------------------------------------------------------
* // | |
* // | Hello |
* // | |
*
*
* worksheet_set_header(worksheet, "&CHello");
*
* // ---------------------------------------------------------------
* // | |
* // | Hello |
* // | |
*
*
* worksheet_set_header(worksheet, "&RHello");
*
* // ---------------------------------------------------------------
* // | |
* // | Hello |
* // | |
*
*
* @endcode
*
* For simple text, if you do not specify any justification the text will be
* centered. However, you must prefix the text with `&C` if you specify a font
* name or any other formatting:
*
* @code
* worksheet_set_header(worksheet, "Hello");
*
* // ---------------------------------------------------------------
* // | |
* // | Hello |
* // | |
*
* @endcode
*
* You can have text in each of the justification regions:
*
* @code
* worksheet_set_header(worksheet, "&LCiao&CBello&RCielo");
*
* // ---------------------------------------------------------------
* // | |
* // | Ciao Bello Cielo |
* // | |
*
* @endcode
*
* The information control characters act as variables that Excel will update
* as the workbook or worksheet changes. Times and dates are in the users
* default format:
*
* @code
* worksheet_set_header(worksheet, "&CPage &P of &N");
*
* // ---------------------------------------------------------------
* // | |
* // | Page 1 of 6 |
* // | |
*
* worksheet_set_header(worksheet, "&CUpdated at &T");
*
* // ---------------------------------------------------------------
* // | |
* // | Updated at 12:30 PM |
* // | |
*
* @endcode
*
* You can specify the font size of a section of the text by prefixing it with
* the control character `&n` where `n` is the font size:
*
* @code
* worksheet_set_header(worksheet1, "&C&30Hello Big");
* worksheet_set_header(worksheet2, "&C&10Hello Small");
*
* @endcode
*
* You can specify the font of a section of the text by prefixing it with the
* control sequence `&"font,style"` where `fontname` is a font name such as
* Windows font descriptions: "Regular", "Italic", "Bold" or "Bold Italic":
* "Courier New" or "Times New Roman" and `style` is one of the standard
*
* @code
* worksheet_set_header(worksheet1, "&C&\"Courier New,Italic\"Hello");
* worksheet_set_header(worksheet2, "&C&\"Courier New,Bold Italic\"Hello");
* worksheet_set_header(worksheet3, "&C&\"Times New Roman,Regular\"Hello");
*
* @endcode
*
* It is possible to combine all of these features together to create
* sophisticated headers and footers. As an aid to setting up complicated
* headers and footers you can record a page set-up as a macro in Excel and
* look at the format strings that VBA produces. Remember however that VBA
* uses two double quotes `""` to indicate a single double quote. For the last
* example above the equivalent VBA code looks like this:
*
* @code
* .LeftHeader = ""
* .CenterHeader = "&""Times New Roman,Regular""Hello"
* .RightHeader = ""
*
* @endcode
*
* Alternatively you can inspect the header and footer strings in an Excel
* file by unzipping it and grepping the XML sub-files. The following shows
* 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"
*
* <headerFooter scaleWithDoc="0">
* <oddHeader>&amp;L&amp;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.
*
*/
lxw_error worksheet_set_header(lxw_worksheet *worksheet, const char *string);
/**
* @brief Set the printed page footer caption.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param string The footer string.
*
* @return A #lxw_error code.
*
* The syntax of this function is the same as worksheet_set_header().
*
*/
lxw_error worksheet_set_footer(lxw_worksheet *worksheet, const char *string);
/**
* @brief Set the printed page header caption with additional options.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @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
* additional parameter to specify options for the header.
*
* Currently, the only available option is the header margin:
*
* @code
*
* lxw_header_footer_options header_options = { 0.2 };
*
* worksheet_set_header_opt(worksheet, "Some text", &header_options);
*
* @endcode
*
*/
lxw_error worksheet_set_header_opt(lxw_worksheet *worksheet,
const char *string,
lxw_header_footer_options *options);
/**
* @brief Set the printed page footer caption with additional options.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @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().
*
*/
lxw_error worksheet_set_footer_opt(lxw_worksheet *worksheet,
const char *string,
lxw_header_footer_options *options);
/**
* @brief Set the horizontal page breaks on a worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param breaks Array of page breaks.
*
* @return A #lxw_error code.
*
* The `%worksheet_set_h_pagebreaks()` function adds horizontal page breaks to
* a worksheet. A page break causes all the data that follows it to be printed
* on the next page. Horizontal page breaks act between rows.
*
* The function takes an array of one or more page breaks. The type of the
* array data is @ref lxw_row_t and the last element of the array must be 0:
*
* @code
* lxw_row_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
* lxw_row_t breaks2[] = {20, 40, 60, 80, 0};
*
* worksheet_set_h_pagebreaks(worksheet1, breaks1);
* worksheet_set_h_pagebreaks(worksheet2, breaks2);
* @endcode
*
* To create a page break between rows 20 and 21 you must specify the break at
* row 21. However in zero index notation this is actually row 20:
*
* @code
* // Break between row 20 and 21.
* lxw_row_t breaks[] = {20, 0};
*
* worksheet_set_h_pagebreaks(worksheet, breaks);
* @endcode
*
* There is an Excel limitation of 1023 horizontal page breaks per worksheet.
*
* Note: If you specify the "fit to page" option via the
* `worksheet_fit_to_pages()` function it will override all manual page
* breaks.
*
*/
lxw_error worksheet_set_h_pagebreaks(lxw_worksheet *worksheet,
lxw_row_t breaks[]);
/**
* @brief Set the vertical page breaks on a worksheet.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param breaks Array of page breaks.
*
* @return A #lxw_error code.
*
* The `%worksheet_set_v_pagebreaks()` function adds vertical page breaks to a
* worksheet. A page break causes all the data that follows it to be printed
* on the next page. Vertical page breaks act between columns.
*
* The function takes an array of one or more page breaks. The type of the
* array data is @ref lxw_col_t and the last element of the array must be 0:
*
* @code
* lxw_col_t breaks1[] = {20, 0}; // 1 page break. Zero indicates the end.
* lxw_col_t breaks2[] = {20, 40, 60, 80, 0};
*
* worksheet_set_v_pagebreaks(worksheet1, breaks1);
* worksheet_set_v_pagebreaks(worksheet2, breaks2);
* @endcode
*
* To create a page break between columns 20 and 21 you must specify the break
* at column 21. However in zero index notation this is actually column 20:
*
* @code
* // Break between column 20 and 21.
* lxw_col_t breaks[] = {20, 0};
*
* worksheet_set_v_pagebreaks(worksheet, breaks);
* @endcode
*
* There is an Excel limitation of 1023 vertical page breaks per worksheet.
*
* Note: If you specify the "fit to page" option via the
* `worksheet_fit_to_pages()` function it will override all manual page
* breaks.
*
*/
lxw_error worksheet_set_v_pagebreaks(lxw_worksheet *worksheet,
lxw_col_t breaks[]);
/**
* @brief Set the order in which pages are printed.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `%worksheet_print_across()` function is used to change the default
* print direction. This is referred to by Excel as the sheet "page order":
*
* @code
* worksheet_print_across(worksheet);
* @endcode
*
* The default page order is shown below for a worksheet that extends over 4
* pages. The order is called "down then across":
*
* [1] [3]
* [2] [4]
*
* However, by using the `print_across` function the print order will be
* changed to "across then down":
*
* [1] [2]
* [3] [4]
*
*/
void worksheet_print_across(lxw_worksheet *worksheet);
/**
* @brief Set the worksheet zoom factor.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param scale Worksheet zoom factor.
*
* Set the worksheet zoom factor in the range `10 <= zoom <= 400`:
*
* @code
* worksheet_set_zoom(worksheet1, 50);
* worksheet_set_zoom(worksheet2, 75);
* worksheet_set_zoom(worksheet3, 300);
* worksheet_set_zoom(worksheet4, 400);
* @endcode
*
* The default zoom factor is 100. It isn't possible to set the zoom to
* "Selection" because it is calculated by Excel at run-time.
*
* Note, `%worksheet_zoom()` does not affect the scale of the printed
* page. For that you should use `worksheet_set_print_scale()`.
*/
void worksheet_set_zoom(lxw_worksheet *worksheet, uint16_t scale);
/**
* @brief Set the option to display or hide gridlines on the screen and
* the printed page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param option Gridline option.
*
* Display or hide screen and print gridlines using one of the values of
* @ref lxw_gridlines.
*
* @code
* worksheet_gridlines(worksheet1, LXW_HIDE_ALL_GRIDLINES);
*
* worksheet_gridlines(worksheet2, LXW_SHOW_PRINT_GRIDLINES);
* @endcode
*
* The Excel default is that the screen gridlines are on and the printed
* worksheet is off.
*
*/
void worksheet_gridlines(lxw_worksheet *worksheet, uint8_t option);
/**
* @brief Center the printed page horizontally.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* Center the worksheet data horizontally between the margins on the printed
* page:
*
* @code
* worksheet_center_horizontally(worksheet);
* @endcode
*
*/
void worksheet_center_horizontally(lxw_worksheet *worksheet);
/**
* @brief Center the printed page vertically.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* Center the worksheet data vertically between the margins on the printed
* page:
*
* @code
* worksheet_center_vertically(worksheet);
* @endcode
*
*/
void worksheet_center_vertically(lxw_worksheet *worksheet);
/**
* @brief Set the option to print the row and column headers on the printed
* page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* When printing a worksheet from Excel the row and column headers (the row
* numbers on the left and the column letters at the top) aren't printed by
* default.
*
* This function sets the printer option to print these headers:
*
* @code
* worksheet_print_row_col_headers(worksheet);
* @endcode
*
*/
void worksheet_print_row_col_headers(lxw_worksheet *worksheet);
/**
* @brief Set the number of rows to repeat at the top of each printed page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param first_row First row of repeat range.
* @param last_row Last row of repeat range.
*
* @return A #lxw_error code.
*
* For large Excel documents it is often desirable to have the first row or
* rows of the worksheet print out at the top of each page.
*
* This can be achieved by using this function. The parameters `first_row`
* and `last_row` are zero based:
*
* @code
* worksheet_repeat_rows(worksheet, 0, 0); // Repeat the first row.
* worksheet_repeat_rows(worksheet, 0, 1); // Repeat the first two rows.
* @endcode
*/
lxw_error worksheet_repeat_rows(lxw_worksheet *worksheet, lxw_row_t first_row,
lxw_row_t last_row);
/**
* @brief Set the number of columns to repeat at the top of each printed page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param first_col First column of repeat range.
* @param last_col Last column of repeat range.
*
* @return A #lxw_error code.
*
* For large Excel documents it is often desirable to have the first column or
* columns of the worksheet print out at the left of each page.
*
* This can be achieved by using this function. The parameters `first_col`
* and `last_col` are zero based:
*
* @code
* worksheet_repeat_columns(worksheet, 0, 0); // Repeat the first col.
* worksheet_repeat_columns(worksheet, 0, 1); // Repeat the first two cols.
* @endcode
*/
lxw_error worksheet_repeat_columns(lxw_worksheet *worksheet,
lxw_col_t first_col, lxw_col_t last_col);
/**
* @brief Set the print area for 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.
*
* @return A #lxw_error code.
*
* This function is used to specify the area of the worksheet that will be
* printed. The RANGE() macro is often convenient for this.
*
* @code
* worksheet_print_area(worksheet, 0, 0, 41, 10); // A1:K42.
*
* // Same as:
* worksheet_print_area(worksheet, RANGE("A1:K42"));
* @endcode
*
* In order to set a row or column range you must specify the entire range:
*
* @code
* worksheet_print_area(worksheet, RANGE("A1:H1048576")); // Same as A:H.
* @endcode
*/
lxw_error worksheet_print_area(lxw_worksheet *worksheet, lxw_row_t first_row,
lxw_col_t first_col, lxw_row_t last_row,
lxw_col_t last_col);
/**
* @brief Fit the printed area to a specific number of pages both vertically
* and horizontally.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param width Number of pages horizontally.
* @param height Number of pages vertically.
*
* The `%worksheet_fit_to_pages()` function is used to fit the printed area to
* a specific number of pages both vertically and horizontally. If the printed
* area exceeds the specified number of pages it will be scaled down to
* fit. This ensures that the printed area will always appear on the specified
* number of pages even if the page size or margins change:
*
* @code
* worksheet_fit_to_pages(worksheet1, 1, 1); // Fit to 1x1 pages.
* worksheet_fit_to_pages(worksheet2, 2, 1); // Fit to 2x1 pages.
* worksheet_fit_to_pages(worksheet3, 1, 2); // Fit to 1x2 pages.
* @endcode
*
* The print area can be defined using the `worksheet_print_area()` function
* as described above.
*
* A common requirement is to fit the printed output to `n` pages wide but
* have the height be as long as necessary. To achieve this set the `height`
* to zero:
*
* @code
* // 1 page wide and as long as necessary.
* worksheet_fit_to_pages(worksheet, 1, 0);
* @endcode
*
* **Note**:
*
* - Although it is valid to use both `%worksheet_fit_to_pages()` and
* `worksheet_set_print_scale()` on the same worksheet Excel only allows one
* of these options to be active at a time. The last function call made will
* set the active option.
*
* - The `%worksheet_fit_to_pages()` function will override any manual page
* breaks that are defined in the worksheet.
*
* - When using `%worksheet_fit_to_pages()` it may also be required to set the
* printer paper size using `worksheet_set_paper()` or else Excel will
* default to "US Letter".
*
*/
void worksheet_fit_to_pages(lxw_worksheet *worksheet, uint16_t width,
uint16_t height);
/**
* @brief Set the start page number when printing.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param start_page Starting page number.
*
* The `%worksheet_set_start_page()` function is used to set the number of
* the starting page when the worksheet is printed out:
*
* @code
* // Start print from page 2.
* worksheet_set_start_page(worksheet, 2);
* @endcode
*/
void worksheet_set_start_page(lxw_worksheet *worksheet, uint16_t start_page);
/**
* @brief Set the scale factor for the printed page.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param scale Print scale of worksheet to be printed.
*
* This function sets the scale factor of the printed page. The Scale factor
* must be in the range `10 <= scale <= 400`:
*
* @code
* worksheet_set_print_scale(worksheet1, 75);
* worksheet_set_print_scale(worksheet2, 400);
* @endcode
*
* The default scale factor is 100. Note, `%worksheet_set_print_scale()` does
* not affect the scale of the visible page in Excel. For that you should use
* `worksheet_set_zoom()`.
*
* Note that although it is valid to use both `worksheet_fit_to_pages()` and
* `%worksheet_set_print_scale()` on the same worksheet Excel only allows one
* of these options to be active at a time. The last function call made will
* set the active option.
*
*/
void worksheet_set_print_scale(lxw_worksheet *worksheet, uint16_t scale);
/**
* @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.
*
* The `%worksheet_right_to_left()` function is used to change the default
* direction of the worksheet from left-to-right, with the `A1` cell in the
* top left, to right-to-left, with the `A1` cell in the top right.
*
* @code
* worksheet_right_to_left(worksheet1);
* @endcode
*
* This is useful when creating Arabic, Hebrew or other near or far eastern
* worksheets that use right-to-left as the default direction.
*/
void worksheet_right_to_left(lxw_worksheet *worksheet);
/**
* @brief Hide zero values in worksheet cells.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
*
* The `%worksheet_hide_zero()` function is used to hide any zero values that
* appear in cells:
*
* @code
* worksheet_hide_zero(worksheet1);
* @endcode
*/
void worksheet_hide_zero(lxw_worksheet *worksheet);
/**
* @brief Set the color of the worksheet tab.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param color The tab color.
*
* The `%worksheet_set_tab_color()` function is used to change the color of
* the worksheet tab:
*
* @code
* worksheet_set_tab_color(worksheet1, LXW_COLOR_RED);
* worksheet_set_tab_color(worksheet2, LXW_COLOR_GREEN);
* worksheet_set_tab_color(worksheet3, 0xFF9900); // Orange.
* @endcode
*
* The color should be an RGB integer value, see @ref working_with_colors.
*/
void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
/**
* @brief Protect elements of a worksheet from modification.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param password A worksheet password.
* @param options Worksheet elements to protect.
*
* The `%worksheet_protect()` function protects worksheet elements from modification:
*
* @code
* worksheet_protect(worksheet, "Some Password", options);
* @endcode
*
* The `password` and lxw_protection pointer are both optional:
*
* @code
* worksheet_protect(worksheet1, NULL, NULL);
* worksheet_protect(worksheet2, NULL, my_options);
* worksheet_protect(worksheet3, "password", NULL);
* worksheet_protect(worksheet4, "password", my_options);
* @endcode
*
* Passing a `NULL` password is the same as turning on protection without a
* password. Passing a `NULL` password and `NULL` options, or any other
* combination has the effect of enabling a cell's `locked` and `hidden`
* properties if they have been set.
*
* A *locked* cell cannot be edited and this property is on by default for all
* cells. A *hidden* cell will display the results of a formula but not the
* formula itself. These properties can be set using the format_set_unlocked()
* and format_set_hidden() format functions.
*
* You can specify which worksheet elements you wish to protect by passing a
* lxw_protection pointer in the `options` argument with any or all of the
* following members set:
*
* no_select_locked_cells
* no_select_unlocked_cells
* format_cells
* format_columns
* format_rows
* insert_columns
* insert_rows
* insert_hyperlinks
* delete_columns
* delete_rows
* sort
* autofilter
* pivot_tables
* scenarios
* objects
*
* All parameters are off by default. Individual elements can be protected as
* follows:
*
* @code
* lxw_protection options = {
* .format_cells = 1,
* .insert_hyperlinks = 1,
* .insert_rows = 1,
* .delete_rows = 1,
* .insert_columns = 1,
* .delete_columns = 1,
* };
*
* worksheet_protect(worksheet, NULL, &options);
*
* @endcode
*
* See also the format_set_unlocked() and format_set_hidden() format functions.
*
* **Note:** Sheet level passwords in Excel offer **very** weak
* protection. They don't encrypt your data and are very easy to
* deactivate. Full workbook encryption is not supported by `libxlsxwriter`
* since it requires a completely different file format.
*/
void worksheet_protect(lxw_worksheet *worksheet, const char *password,
lxw_protection *options);
/**
* @brief Set the Outline and Grouping display properties.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param visible Outlines are visible. Optional, defaults to True.
* @param symbols_below Show row outline symbols below the outline bar.
* @param symbols_right Show column outline symbols to the right of outline.
* @param auto_style Use Automatic outline style.
*
* The `%worksheet_outline_settings()` method is used to control the
* appearance of outlines in Excel. Outlines are described the section on
* @ref working_with_outlines.
*
* The `visible` parameter is used to control whether or not outlines are
* visible. Setting this parameter to False will cause all outlines on the
* worksheet to be hidden. They can be un-hidden in Excel by means of the
* "Show Outline Symbols" command button. The default Excel setting is True
* for visible outlines.
*
* The `symbols_below` parameter is used to control whether the row outline
* symbol will appear above or below the outline level bar. The default Excel
* setting is True for symbols to appear below the outline level bar.
*
* The `symbols_right` parameter is used to control whether the column outline
* symbol will appear to the left or the right of the outline level bar. The
* default Excel setting is True for symbols to appear to the right of the
* outline level bar.
*
* The `auto_style` parameter is used to control whether the automatic outline
* generator in Excel uses automatic styles when creating an outline. This has
* no effect on a file generated by XlsxWriter but it does have an effect on
* how the worksheet behaves after it is created. The default Excel setting is
* False for "Automatic Styles" to be turned off.
*
* The default settings for all of these parameters in libxlsxwriter
* correspond to Excel's default parameters and are shown below:
*
* @code
* worksheet_outline_settings(worksheet1, LXW_TRUE, LXW_TRUE, LXW_TRUE, LXW_FALSE);
* @endcode
*
* The worksheet parameters controlled by `worksheet_outline_settings()` are
* rarely used.
*/
void worksheet_outline_settings(lxw_worksheet *worksheet, uint8_t visible,
uint8_t symbols_below, uint8_t symbols_right,
uint8_t auto_style);
/**
* @brief Set the default row properties.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param height Default row height.
* @param hide_unused_rows Hide unused cells.
*
* The `%worksheet_set_default_row()` function is used to set Excel default
* row properties such as the default height and the option to hide unused
* rows. These parameters are an optimization used by Excel to set row
* properties without generating a very large file with an entry for each row.
*
* To set the default row height:
*
* @code
* worksheet_set_default_row(worksheet, 24, LXW_FALSE);
*
* @endcode
*
* To hide unused rows:
*
* @code
* worksheet_set_default_row(worksheet, 15, LXW_TRUE);
* @endcode
*
* Note, in the previous case we use the default height #LXW_DEF_ROW_HEIGHT =
* 15 so the the height remains unchanged.
*/
void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
uint8_t hide_unused_rows);
/**
* @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.
*
* 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 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.
*
* See also @ref working_with_macros
*
* @return A #lxw_error.
*/
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);
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_object_properties *object_props);
void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
uint32_t chart_ref_id, uint32_t drawing_id,
lxw_object_properties *object_props,
uint8_t is_chartsheet);
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);
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.
*/
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_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. */
#ifdef TESTING
STATIC void _worksheet_xml_declaration(lxw_worksheet *worksheet);
STATIC void _worksheet_write_worksheet(lxw_worksheet *worksheet);
STATIC void _worksheet_write_dimension(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_view(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_views(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_format_pr(lxw_worksheet *worksheet);
STATIC void _worksheet_write_sheet_data(lxw_worksheet *worksheet);
STATIC void _worksheet_write_page_margins(lxw_worksheet *worksheet);
STATIC void _worksheet_write_page_setup(lxw_worksheet *worksheet);
STATIC void _worksheet_write_col_info(lxw_worksheet *worksheet,
lxw_col_options *options);
STATIC void _write_row(lxw_worksheet *worksheet, lxw_row *row, char *spans);
STATIC lxw_row *_get_row_list(struct lxw_table_rows *table,
lxw_row_t row_num);
STATIC void _worksheet_write_merge_cell(lxw_worksheet *worksheet,
lxw_merged_range *merged_range);
STATIC void _worksheet_write_merge_cells(lxw_worksheet *worksheet);
STATIC void _worksheet_write_odd_header(lxw_worksheet *worksheet);
STATIC void _worksheet_write_odd_footer(lxw_worksheet *worksheet);
STATIC void _worksheet_write_header_footer(lxw_worksheet *worksheet);
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_obj *protect);
STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
#endif /* TESTING */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* __LXW_WORKSHEET_H__ */