Added example and docs for autfilter rules.

Feature request #254
This commit is contained in:
John McNamara 2021-08-08 20:25:35 +01:00
parent 431f4839f9
commit 4234499f8a
13 changed files with 653 additions and 25 deletions

View File

@ -853,6 +853,7 @@ INPUT = src/mainpage.dox \
src/working_with_dates.dox \
src/working_with_charts.dox \
src/working_with_object_position.dox \
src/working_with_autofilters.dox \
src/working_with_data_validation.dox \
src/working_with_conditional_formatting.dox \
src/working_with_comments.dox \

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

BIN
docs/images/autofilter2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
docs/images/autofilter3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
docs/images/autofilter4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
docs/images/autofilter5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -341,9 +341,9 @@ Example of merging cells with a rich string in a worksheet.
</tr>
</table>
Example of adding an autofilter to a worksheet.
Example of adding autofilters to a worksheets and adding filter conditions.
@image html autofilter.png
@image html autofilter3.png

View File

@ -152,9 +152,9 @@ Example of merging cells with a rich string in a worksheet.
##############################################################
@example autofilter.c
Example of adding an autofilter to a worksheet.
Example of adding autofilters to a worksheets and adding filter conditions.
@image html autofilter.png
@image html autofilter3.png
##############################################################
@example data_validate.c

View File

@ -58,6 +58,7 @@ following sections for more information:
- @ref working_with_dates
- @ref working_with_charts
- @ref working_with_object_positioning
- @ref working_with_autofilters
- @ref working_with_data_validation
- @ref working_with_conditional_formatting
- @ref working_with_comments

View File

@ -0,0 +1,217 @@
/**
@page working_with_autofilters Working with Autofilters
@tableofcontents
An autofilter in Excel is a way of filtering a 2D range of data based on some
simple criteria.
@image html autofilter1.png
@section ww_autofilters_range Applying an autofilter
The first step is to apply an autofilter to a cell range in a worksheet using
the worksheet_autofilter() function:
@code
worksheet_autofilter(worksheet, 0, 0, 10, 3);
@endcode
Or more explicitly using the RANGE() macro:
@code
worksheet_autofilter(worksheet, RANGE("A1:D11")); //Same as above.
@endcode
@section ww_autofilters_data Filtering data in an autofilter
The `worksheet_autofilter()` function defines the cell range that the filter
applies to and creates drop-down selectors in the header row.
However, in order to apply a filter condition it is necessary to add filter
rules to the columns using the `%worksheet_filter_column()`,
`%worksheet_filter_column2()` or `%worksheet_filter_list()` functions:
- `worksheet_filter_column()`: filter on a single criterion such as "Column ==
East". More complex conditions such as "<=" or ">=" can also be used.
- `worksheet_filter_column2()`: filter on two criteria such as "Column == East
or Column == West". Complex conditions can also be used.
- `worksheet_filter_list()`: filter on a list of values such as "Column in (East, West,
North)".
For example you could create a filter like "Column A == East" using a
lxw_filter_rule rule and the `worksheet_filter_column()` function like this:
@code
lxw_filter_rule filter_rule = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
worksheet_filter_column(worksheet, 0, &filter_rule);
@endcode
Unfortunately, it isn't sufficient to just specify the filter condition. You
must also hide the rows that don't match the criteria since Excel doesn't do
that automatically when reading a file. With libxlsxwriter you can hide rows
using the `worksheet_set_row_opt()` function with the lxw_row_col_options
`hidden` parameter.
The following is an example of how you might filter a data range to match an
autofilter criteria:
@code
lxw_row_col_options hidden = {.hidden = LXW_TRUE};
lxw_filter_rule filter_rule = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
worksheet_filter_column(worksheet, 0, &filter_rule);
for (i = 0; i < 100; i++) {
// Write some other cell data for a row...
if (strcmp(data[i].region, "East") == 0) {
// Row matches the filter, no further action required.
}
else {
// Hide rows that don't match the filter.
worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
@endcode
Note, the `if()` statement above is written to match the logic of the criteria
in the rule. However you could get the same results with the following
simpler, but reversed, logic:
@code
if (strcmp(data[i].region, "East") != 0) {
worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
@endcode
@section ww_autofilters_criteria Setting a filter criteria for a column
The `worksheet_filter_column()` and `worksheet_filter_column2()` functions can
be used to filter columns in a autofilter range based on simple conditions:
@code
lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN,
.value = 3000};
lxw_filter_rule filter_rule3 = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN,
.value = 8000};
worksheet_filter_column (worksheet, 0, &filter_rule1);
worksheet_filter_column2(worksheet, 2, &filter_rule2, &filter_rule3, LXW_FILTER_AND);
@endcode
The `col` parameter, used in both these functions, is a zero indexed column
number and must refer to a column in an existing autofilter created with
`worksheet_autofilter()`.
The `criteria` parameter in lxw_filter_rule can have one of the following values:
- #LXW_FILTER_CRITERIA_EQUAL_TO: Filter cells equal to a value.
- #LXW_FILTER_CRITERIA_NOT_EQUAL_TO: Filter cells not equal to a value.
- #LXW_FILTER_CRITERIA_GREATER_THAN: Filter cells greater than a value.
- #LXW_FILTER_CRITERIA_LESS_THAN: Filter cells less than a value.
- #LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO: Filter cells greater than or
equal to a value.
- #LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO: Filter cells less than or equal
to a value.
- #LXW_FILTER_CRITERIA_BLANKS: Filter cells that are blank. This does not
require a `.value_string` or `.value` value.
- #LXW_FILTER_CRITERIA_NON_BLANKS: Filter cells that are not blank. This does
not require a `.value_string` or `.value` value.
The `value` parameter is used to set a numeric matching condition while
`value_string` is used to set a string matching condition. Excel also allows
some simple string matching operations:
@code
// Begins with c.
lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "c*"};
// Doesn't begin with c.
lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO,
.value_string = "c*"};
// Ends with c.
lxw_filter_rule filter_rule3 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "*c"};
// Doesn't end with c.
lxw_filter_rule filter_rule4 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO,
.value_string = "*c"};
// Contains c.
lxw_filter_rule filter_rule5 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "*c*"};
// Doesn't contain c.
lxw_filter_rule filter_rule6 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO,
.value_string = "*c*"};
@endcode
You can use "*" to match any character or number and "?" to match any single
character or number. No other regular expression quantifier is supported by
Excel's filters. Excel's regular expression characters can be escaped using
"~".
@section ww_autofilters_list Setting a column list filter
Prior to Excel 2007 it was only possible to have either 1 or 2 filter
conditions such as the ones shown above with the `worksheet_filter_column()`
and `worksheet_filter_column()` functions.
Excel 2007 introduced a new list style filter where it is possible to specify one
or more "or" style criteria. For example if your column contained data for the
months of the year you could filter the data based on certain months:
@image html autofilter2.png
The `worksheet_filter_list()` function can be used to represent these types of
filters:
@code
char* list[] = {"March", "April", "May", NULL};
worksheet_filter_list(worksheet, 0, list);
@endcode
To filter blanks as part of the list use `Blanks` as a list item:
@code
char* list[] = {"March", "April", "May", "Blanks", NULL};
worksheet_filter_list(worksheet, 0, list);
@endcode
As explained above, it isn't sufficient to just specify filters. You must also
hide any rows that don't match the filter condition.
@section ww_autofilters_example Example
For a detailed working example with several different filter types see @ref
autofilter.c.
Next: @ref working_with_data_validation
*/

View File

@ -171,6 +171,6 @@ demonstrates the issue.
[issue_tracker]: https://github.com/jmcnamara/libxlsxwriter/issues
Next: @ref working_with_data_validation
Next: @ref working_with_autofilters
*/

View File

@ -9,14 +9,20 @@
#include "xlsxwriter.h"
void write_worksheet_header(lxw_worksheet *worksheet, lxw_format *header);
int main() {
lxw_workbook *workbook = workbook_new("autofilter.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
uint16_t i;
lxw_workbook *workbook = workbook_new("autofilter.xlsx");
lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet4 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet5 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet6 = workbook_add_worksheet(workbook, NULL);
lxw_worksheet *worksheet7 = workbook_add_worksheet(workbook, NULL);
/* Simple data structure to represent the row data. */
struct row {
char region[16];
char item[16];
@ -77,24 +83,280 @@ int main() {
{"East", "Grape", 6000, "February" }
};
uint16_t i;
lxw_row_col_options hidden = {.hidden = LXW_TRUE};
/* Write the column headers. */
worksheet_write_string(worksheet, 0, 0, "Region", NULL);
worksheet_write_string(worksheet, 0, 1, "Item", NULL);
worksheet_write_string(worksheet, 0, 2, "Volume" , NULL);
worksheet_write_string(worksheet, 0, 3, "Month", NULL);
lxw_format *header = workbook_add_format(workbook);
format_set_bold(header);
/*
* Example 1. Autofilter without conditions.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet1, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet1, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet1, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet1, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet1, i + 1, 3, data[i].month, NULL);
}
/* Add the autofilter. */
worksheet_autofilter(worksheet1, 0, 0, 50, 3);
/*
* Example 2. Autofilter with a filter condition in the first column.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet2, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet2, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet2, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet2, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet2, i + 1, 3, data[i].month, NULL);
/* It isn't sufficient to just apply the filter condition below. We
* must also hide the rows that don't match the criteria since Excel
* doesn't do that automatically. */
if (strcmp(data[i].region, "East") == 0) {
/* Row matches the filter, no further action required. */
}
else {
/* Hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet2, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
/* Note, the if() statement above is written to match the logic of the
* criteria in worksheet_filter_column() below. However you could get
* the same results with the following simpler, but reversed, code:
*
* if (strcmp(data[i].region, "East") != 0) {
* worksheet_set_row_opt(worksheet2, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
* }
*
* The same applies to the Examples 3-6 as well.
*/
}
/* Add the autofilter. */
worksheet_autofilter(worksheet2, 0, 0, 50, 3);
/* Add the filter criteria. */
lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
worksheet_filter_column(worksheet2, 0, &filter_rule2);
/*
* Example 3. Autofilter with a dual filter condition in one of the columns.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet3, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet3, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet3, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet3, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet3, i + 1, 3, data[i].month, NULL);
if (strcmp(data[i].region, "East") == 0 || strcmp(data[i].region, "South") == 0) {
/* Row matches the filter, no further action required. */
}
else {
/* We need to hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet3, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
/* Add the autofilter. */
worksheet_autofilter(worksheet3, 0, 0, 50, 3);
/* Add the filter criteria. */
lxw_filter_rule filter_rule3a = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
lxw_filter_rule filter_rule3b = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "South"};
worksheet_filter_column2(worksheet3, 0, &filter_rule3a, &filter_rule3b, LXW_FILTER_OR);
/*
* Example 4. Autofilter with filter conditions in two columns.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet4, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet4, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet4, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet4, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet4, i + 1, 3, data[i].month, NULL);
if (strcmp(data[i].region, "East") == 0 &&
data[i].volume > 3000 && data[i].volume < 8000)
{
/* Row matches the filter, no further action required. */
}
else {
/* We need to hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet4, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
/* Add the autofilter. */
worksheet_autofilter(worksheet4, 0, 0, 50, 3);
/* Add the filter criteria. */
lxw_filter_rule filter_rule4a = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
.value_string = "East"};
lxw_filter_rule filter_rule4b = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN,
.value = 3000};
lxw_filter_rule filter_rule4c = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN,
.value = 8000};
worksheet_filter_column(worksheet4, 0, &filter_rule4a);
worksheet_filter_column2(worksheet4, 2, &filter_rule4b, &filter_rule4c, LXW_FILTER_AND);
/*
* Example 5. Autofilter with a dual filter condition in one of the columns.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet5, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet5, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet5, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet5, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet5, i + 1, 3, data[i].month, NULL);
if (strcmp(data[i].region, "East") == 0 ||
strcmp(data[i].region, "North") == 0 ||
strcmp(data[i].region, "South") == 0)
{
/* Row matches the filter, no further action required. */
}
else {
/* We need to hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet5, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
/* Add the autofilter. */
worksheet_autofilter(worksheet5, 0, 0, 50, 3);
/* Add the filter criteria. */
char* list[] = {"East", "North", "South", NULL};
worksheet_filter_list(worksheet5, 0, list);
/*
* Example 6. Autofilter with filter for blanks.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet6, header);
/* Simulate one blank cell in the data, to test the filter. */
data[5].region[0] = '\0';
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL);
worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL);
worksheet_write_string(worksheet6, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet6, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet6, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet6, i + 1, 3, data[i].month, NULL);
if (strcmp(data[i].region, "") == 0) {
/* Row matches the filter, no further action required. */
}
else {
/* We need to hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet6, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
/* Add the autofilter. */
worksheet_autofilter(worksheet, 0, 0, 50, 3);
worksheet_autofilter(worksheet6, 0, 0, 50, 3);
/* Add the filter criteria. */
lxw_filter_rule filter_rule6 = {.criteria = LXW_FILTER_CRITERIA_BLANKS};
worksheet_filter_column(worksheet6, 0, &filter_rule6);
/*
* Example 7. Autofilter with filter for non-blanks.
*/
/* Set up the worksheet data. */
write_worksheet_header(worksheet7, header);
/* Write the row data. */
for (i = 0; i < sizeof(data)/sizeof(struct row); i++) {
worksheet_write_string(worksheet7, i + 1, 0, data[i].region, NULL);
worksheet_write_string(worksheet7, i + 1, 1, data[i].item, NULL);
worksheet_write_number(worksheet7, i + 1, 2, data[i].volume, NULL);
worksheet_write_string(worksheet7, i + 1, 3, data[i].month, NULL);
if (strcmp(data[i].region, "") != 0) {
/* Row matches the filter, no further action required. */
}
else {
/* We need to hide rows that don't match the filter. */
worksheet_set_row_opt(worksheet7, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden);
}
}
/* Add the autofilter. */
worksheet_autofilter(worksheet7, 0, 0, 50, 3);
/* Add the filter criteria. */
lxw_filter_rule filter_rule7 = {.criteria = LXW_FILTER_CRITERIA_NON_BLANKS};
worksheet_filter_column(worksheet7, 0, &filter_rule7);
return workbook_close(workbook);
}
void write_worksheet_header(lxw_worksheet *worksheet, lxw_format *header) {
/* Make the columns wider for clarity. */
worksheet_set_column(worksheet, 0, 3, 12, NULL);
/* Write the column headers. */
worksheet_set_row(worksheet, 0, 20, header);
worksheet_write_string(worksheet, 0, 0, "Region", NULL);
worksheet_write_string(worksheet, 0, 1, "Item", NULL);
worksheet_write_string(worksheet, 0, 2, "Volume", NULL);
worksheet_write_string(worksheet, 0, 3, "Month", NULL);
}

View File

@ -568,12 +568,23 @@ enum lxw_filter_criteria {
LXW_FILTER_CRITERIA_NON_BLANKS
};
/**
* @brief And/or operator when using 2 filter rules.
*
* And/or operator conditions when using 2 filter rules with
* worksheet_filter_column2(). In general LXW_FILTER_OR is used with
* LXW_FILTER_CRITERIA_EQUAL_TO and LXW_FILTER_AND is used with the other
* filter criteria.
*/
enum lxw_filter_operator {
/** Logical "and" of 2 filter rules. */
LXW_FILTER_AND,
/** Logical "or" of 2 filter rules. */
LXW_FILTER_OR
};
/* Internal filter types.*/
enum lxw_filter_type {
LXW_FILTER_TYPE_NONE,
@ -1313,11 +1324,23 @@ typedef struct lxw_cond_format_hash_element {
RB_ENTRY (lxw_cond_format_hash_element) tree_pointers;
} lxw_cond_format_hash_element;
/**
* @brief Options for autofilter rules.
*
* Options to define an autofilter rule.
*
*/
typedef struct lxw_filter_rule {
/** The #lxw_filter_criteria to define the rule. */
uint8_t criteria;
double value;
/** String value to which the criteria applies. */
char *value_string;
/** Numeric value to which the criteria applies (if value_string isn't used). */
double value;
} lxw_filter_rule;
typedef struct lxw_filter_rule_obj {
@ -3591,7 +3614,7 @@ lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
* range of worksheet data. This allows users to filter the data based on
* simple criteria so that some data is shown and some is hidden.
*
* @image html autofilter.png
* @image html autofilter3.png
*
* To add an autofilter to a worksheet:
*
@ -3602,20 +3625,144 @@ lxw_error worksheet_merge_range(lxw_worksheet *worksheet, lxw_row_t first_row,
* worksheet_autofilter(worksheet, RANGE("A1:D51"));
* @endcode
*
* Note: it isn't currently possible to apply filter conditions to the
* autofilter.
* In order to apply a filter condition it is necessary to add filter rules to
* the columns using either the `%worksheet_filter_column()`,
* `%worksheet_filter_column2()` or `%worksheet_filter_list()` functions:
*
* - `worksheet_filter_column()`: filter on a single criterion such as "Column ==
* East". More complex conditions such as "<=" or ">=" can also be use.
*
* - `worksheet_filter_column2()`: filter on two criteria such as "Column == East
* or Column == West". Complex conditions can also be used.
*
* - `worksheet_filter_list()`: filter on a list of values such as "Column in (East, West,
* North)".
*
* These functions are explained below. It isn't sufficient to just specify
* the filter condition. You must also hide any rows that don't match the
* filter condition. See @ref ww_autofilters_data for more details.
*
*/
lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row,
lxw_col_t first_col, lxw_row_t last_row,
lxw_col_t last_col);
/**
* @brief Write a filter rule to an autofilter column.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param col The column in the autofilter that the rule applies to.
* @param rule The lxw_filter_rule autofilter rule.
*
* @return A #lxw_error code.
*
* The `worksheet_filter_column` function can be used to filter columns in a
* autofilter range based on single rule conditions:
*
* @code
* lxw_filter_rule filter_rule = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
* .value_string = "East"};
*
* worksheet_filter_column(worksheet, 0, &filter_rule);
*@endcode
*
* @image html autofilter4.png
*
* The rules and criteria are explained in more detail in @ref
* ww_autofilters_criteria in @ref working_with_autofilters.
*
* The `col` parameter is a zero indexed column number and must refer to a
* column in an existing autofilter created with `worksheet_autofilter()`.
*
* It isn't sufficient to just specify the filter condition. You must also
* hide any rows that don't match the filter condition. See @ref
* ww_autofilters_data for more details.
*/
lxw_error worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col,
lxw_filter_rule *rule);
/**
* @brief Write two filter rules to an autofilter column.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param col The column in the autofilter that the rules applies to.
* @param rule1 First lxw_filter_rule autofilter rule.
* @param rule2 Second lxw_filter_rule autofilter rule.
* @param operator A #lxw_filter_operator and/or operator.
*
* @return A #lxw_error code.
*
* The `worksheet_filter_column2` function can be used to filter columns in a autofilter
* range based on two rule conditions:
*
* @code
* lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
* .value_string = "East"};
*
* lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO,
* .value_string = "South"};
*
* worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR);
* @endcode
*
* @image html autofilter5.png
*
* The rules and criteria are explained in more detail in @ref
* ww_autofilters_criteria in @ref working_with_autofilters.
*
* The `col` parameter is a zero indexed column number and must refer to a
* column in an existing autofilter created with `worksheet_autofilter()`.
*
* The `operator` parameter is either "and (LXW_FILTER_AND)" or "or
* (LXW_FILTER_OR)".
*
* It isn't sufficient to just specify the filter condition. You must also
* hide any rows that don't match the filter condition. See @ref
* ww_autofilters_data for more details.
*/
lxw_error worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col,
lxw_filter_rule *rule1,
lxw_filter_rule *rule2, uint8_t operator);
/**
* @brief Write multiple string filters to an autofilter column.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param col The column in the autofilter that the rules applies to.
* @param list Array of strings to filter on.
*
* @return
*
* The `worksheet_filter_column_list()` function can be used specify multiple
* string matching criteria. This is a newer type of filter introduced in
* Excel 2007. Prior to that it was only possible to have either 1 or 2 filter
* conditions, such as the ones used by `worksheet_filter_column()` and
* `worksheet_filter_column2()`.
*
* As an example, consider a column that contains data for the months of the
* year. The `%worksheet_filter_list()` function can be used to filter out
* data rows for different months:
*
* @code
* char* list[] = {"March", "April", "May", NULL};
*
* worksheet_filter_list(worksheet, 0, list);
* @endcode
*
* @image html autofilter2.png
*
*
* To filter blanks as part of the list use `Blanks` as a list item:
*
* @code
* char* list[] = {"March", "April", "May", "Blanks", NULL};
*
* worksheet_filter_list(worksheet, 0, list);
* @endcode
*
* It isn't sufficient to just specify the filter condition. You must also
* hide any rows that don't match the filter condition. See @ref
* ww_autofilters_data for more details.
*/
lxw_error worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col,
char **list);