功能: 服务端生成完整报告并保护单任务
- 使用 libxlsxwriter 常量内存导出 Excel\n- 增加全局任务占用提示与原始数据持久化\n- 保留运行时任务数据并更新接口文档
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
@page author Author
|
||||
|
||||
Libxlsxwriter was written by John McNamara.
|
||||
|
||||
- [GitHub](https://github.com/jmcnamara)
|
||||
- [Twitter \@jmcnamara13](https://twitter.com/jmcnamara13)
|
||||
|
||||
|
||||
@section donations Sponsorship and Donations
|
||||
|
||||
I write and maintain a series of open source libraries for creating Excel
|
||||
files. The most commonly used are XlsxWriter in Python, Libxlsxwriter in C and
|
||||
Excel::Writer::XLSX and Spreadsheet::WriteExcel in Perl.
|
||||
|
||||
My aim is to write well documented and well tested code that does what the
|
||||
user needs and doesn't get in their way. You can help make this continue, or
|
||||
show your appreciation for work to date, by becoming a
|
||||
[GitHub Sponsor](https://github.com/sponsors/jmcnamara).
|
||||
|
||||
Or make a one-off donation via
|
||||
[PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ATE9EFWNF7PBJ).
|
||||
|
||||
|
||||
Next: @ref license
|
||||
|
||||
*/
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
|
||||
@page bugs Known Issues and Bugs
|
||||
|
||||
@tableofcontents
|
||||
|
||||
This section lists known issues and bugs and gives some information on
|
||||
how to submit bug reports.
|
||||
|
||||
@section bugs_unreadable Content is Unreadable. Open and Repair
|
||||
|
||||
Very occasionally you may encounter a bug which generates an Excel
|
||||
warning when opening an `libxlsxwriter` file like:
|
||||
|
||||
> Excel could not open file.xlsx because some content is unreadable. Do
|
||||
> you want to open and repair this workbook.
|
||||
|
||||
This ominous sounding message is Excel's standard warning for any validation
|
||||
error in the XML used for the components of the XLSX file.
|
||||
|
||||
If you encounter an issue like this you should open an issue on GitHub with a
|
||||
program to replicate the issue (see below).
|
||||
|
||||
@section bugs_formula_name Formulas displayed as 'NAME?' until edited
|
||||
|
||||
Excel 2010 and 2013 added functions which weren't defined in the original file
|
||||
specification. These functions are referred to as *future* functions. Examples
|
||||
of these functions are `ACOT`, `CHISQ.DIST.RT` , `CONFIDENCE.NORM`, `STDEV.P`,
|
||||
`STDEV.S` and `WORKDAY.INTL`. The full list is given in the
|
||||
[MS XLSX extensions documentation on future functions]
|
||||
(http://msdn.microsoft.com/en-us/library/dd907480%28v=office.12%29.aspx).
|
||||
|
||||
When written using `write_formula()` these functions need to be fully
|
||||
qualified with the `_xlfn.` prefix as they are shown in the MS XLSX
|
||||
documentation link above. For example:
|
||||
|
||||
@code
|
||||
worksheet_write_formula(worksheet, 0, 0,"=_xlfn.STDEV.S(B1:B10)", NULL);
|
||||
@endcode
|
||||
|
||||
See also @ref working_with_formulas.
|
||||
|
||||
@section bugs_formula_zero Formula results displaying as zero in non-Excel applications
|
||||
|
||||
Due to wide range of possible formulas and inter-dependencies between them,
|
||||
`xlsxwriter` doesn't, and realistically cannot, calculate the result of a
|
||||
formula when it is written to an XLSX file. Instead, it 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 several mobile
|
||||
applications, will only display the 0 results.
|
||||
|
||||
If required, it is also possible to specify the calculated result of the
|
||||
formula using the `worksheet_write_formula_num()` function.
|
||||
|
||||
See also @ref working_with_formulas.
|
||||
|
||||
@section bugs_images Images not displayed correctly in Excel 2001 for Mac and non-Excel applications
|
||||
|
||||
Images inserted into worksheets via `worksheet_insert_image()` may not display
|
||||
correctly in Excel 2011 for Mac and non-Excel applications such as OpenOffice
|
||||
and LibreOffice. Specifically the images may looked stretched or squashed.
|
||||
|
||||
This is not an XlsxWriter issue. It also occurs with files created in Excel
|
||||
2007 and Excel 2010.
|
||||
|
||||
|
||||
@section bugs_reporting Reporting Bugs
|
||||
|
||||
Here are some tips on reporting bugs in `libxlsxwriter`.
|
||||
|
||||
@subsection bugs_upgrade Upgrade to the latest version of the library
|
||||
|
||||
The bug you are reporting may already be fixed in the latest version of
|
||||
the module.
|
||||
|
||||
Check the @ref changes section to see what has changed in the latest
|
||||
versions.
|
||||
|
||||
You can check which version of `libxlsxwriter` that you are using by compiling
|
||||
and running the following program:
|
||||
|
||||
@code
|
||||
#include <stdio.h>
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
printf("Libxlsxwriter version = %s\n", lxw_version());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection bugs_docs Read the documentation
|
||||
|
||||
Read or search the `libxlsxwriter` documentation to see if the issue you are
|
||||
encountering is already explained.
|
||||
|
||||
|
||||
@subsection bugs_examples Look at the example programs
|
||||
|
||||
There are many @ref examples in the distribution. Try to identify an example
|
||||
program that corresponds to your query and adapt it to use as a bug report.
|
||||
|
||||
@subsection bugs_issues Use the xlsxwriter Issue tracker
|
||||
|
||||
The [libxlsxwriter issue tracker]
|
||||
(https://github.com/jmcnamara/libxlsxwriter/issues) is on GitHub.
|
||||
|
||||
|
||||
@subsection bugs_tips Tips for submitting a bug report
|
||||
|
||||
1. Describe the problem as clearly and as concisely as possible.
|
||||
2. Include a sample program. This is probably the most important step.
|
||||
It is generally easier to describe a problem in code than in written
|
||||
prose.
|
||||
3. The sample program should be as small as possible to demonstrate the
|
||||
problem. Don't copy and paste large non-relevant sections of your
|
||||
program.
|
||||
|
||||
A sample bug report is shown below. This format helps analyze and respond to
|
||||
the bug report more quickly.
|
||||
|
||||
Issue with SOMETHING
|
||||
|
||||
I am using libxlsxwriter to do SOMETHING but it appears to do SOMETHING ELSE.
|
||||
|
||||
I am using CC version X.Y.Z, OS = uname and libxlsxwriter x.y.z.
|
||||
|
||||
Here is some code that demonstrates the problem:
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("bug_report.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
|
||||
worksheet_write_number(worksheet, 1, 0, 123, NULL);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
|
||||
|
||||
Next: @ref author "The library author"
|
||||
|
||||
*/
|
||||
+1201
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,620 @@
|
||||
##############################################################
|
||||
@example hello.c
|
||||
|
||||
The simplest possible program and spreadsheet. This is a good place to start
|
||||
to see if the libxlsxwriter library is installed and working correctly.
|
||||
|
||||
@image html hello01.png
|
||||
|
||||
##############################################################
|
||||
@example anatomy.c
|
||||
|
||||
Anatomy of a simple libxlsxwriter program where the program is explained line
|
||||
by line with comments.
|
||||
|
||||
@image html anatomy.png
|
||||
|
||||
##############################################################
|
||||
@example demo.c
|
||||
|
||||
A simple example of some of the features of the libxlsxwriter library.
|
||||
|
||||
@image html demo.png
|
||||
|
||||
##############################################################
|
||||
@example format_font.c
|
||||
|
||||
Example of writing some data with font formatting to a simple Excel
|
||||
file using libxlsxwriter.
|
||||
|
||||
@image html format_font.png
|
||||
|
||||
##############################################################
|
||||
@example format_num_format.c
|
||||
|
||||
Example of writing some data with numeric formatting to a simple Excel
|
||||
file using libxlsxwriter.
|
||||
|
||||
@image html format_set_num_format.png
|
||||
|
||||
##############################################################
|
||||
@example tutorial1.c
|
||||
|
||||
A tutorial program which is shown, with explanations, in @ref tutorial01.
|
||||
|
||||
@image html tutorial01.png
|
||||
|
||||
##############################################################
|
||||
@example tutorial2.c
|
||||
|
||||
A tutorial program which is shown, with explanations, in @ref tutorial02.
|
||||
|
||||
@image html tutorial02.png
|
||||
|
||||
##############################################################
|
||||
@example tutorial3.c
|
||||
|
||||
A tutorial program which is shown, with explanations, in @ref tutorial03.
|
||||
|
||||
@image html tutorial03.png
|
||||
|
||||
##############################################################
|
||||
@example dates_and_times01.c
|
||||
|
||||
Example of writing a dates and time in Excel using a number with date
|
||||
formatting. This demonstrates that dates and times in Excel are just formatted
|
||||
real numbers. An easier approach using a lxw_datetime struct is shown in the
|
||||
next example.
|
||||
|
||||
@image html date_example01.png
|
||||
|
||||
##############################################################
|
||||
@example dates_and_times02.c
|
||||
|
||||
Example of writing dates and times in Excel using an lxw_datetime struct and
|
||||
date formatting.
|
||||
|
||||
@image html date_example02.png
|
||||
|
||||
##############################################################
|
||||
@example dates_and_times03.c
|
||||
|
||||
Example of writing dates and times in Excel using Unix datetimes and
|
||||
formatting.
|
||||
|
||||
@image html date_example03.png
|
||||
|
||||
##############################################################
|
||||
@example dates_and_times04.c
|
||||
|
||||
Example of writing dates and times in Excel using different date formats.
|
||||
|
||||
@image html date_example04.png
|
||||
|
||||
##############################################################
|
||||
@example hyperlinks.c
|
||||
|
||||
Example of writing urls/hyperlinks to a worksheet.
|
||||
|
||||
@image html hyperlinks.png
|
||||
|
||||
##############################################################
|
||||
@example rich_strings.c
|
||||
|
||||
Example of writing "rich" multi-format strings to a worksheet.
|
||||
|
||||
@image html rich_strings.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example array_formula.c
|
||||
|
||||
Example of writing array formulas to a worksheet.
|
||||
|
||||
@image html array_formula.png
|
||||
|
||||
##############################################################
|
||||
|
||||
@example dynamic_arrays.c
|
||||
|
||||
Example of writing Excel 365 dynamic array formulas to a worksheet.
|
||||
|
||||
@image html dynamic_arrays01.png
|
||||
|
||||
##############################################################
|
||||
@example utf8.c
|
||||
A simple Unicode UTF-8 example. Note, the source file is UTF-8 encoded.
|
||||
|
||||
@image html utf8.png
|
||||
|
||||
##############################################################
|
||||
@example constant_memory.c
|
||||
|
||||
Example of using libxlsxwriter for writing large files in constant memory
|
||||
mode.
|
||||
|
||||
@image html constant_memory.png
|
||||
|
||||
##############################################################
|
||||
@example output_buffer.c
|
||||
|
||||
Example of using libxlsxwriter to write a workbook file to a memory buffer.
|
||||
|
||||
@image html hello01.png
|
||||
|
||||
##############################################################
|
||||
@example image_buffer.c
|
||||
|
||||
Example of adding an image to a worksheet from a memory buffer.
|
||||
|
||||
@image html image_buffer2.png
|
||||
|
||||
##############################################################
|
||||
@example merge_range.c
|
||||
|
||||
Example of merging cells in a worksheet.
|
||||
|
||||
@image html merge_range.png
|
||||
|
||||
##############################################################
|
||||
@example merge_rich_string.c
|
||||
|
||||
Example of merging cells with a rich string in a worksheet.
|
||||
|
||||
@image html merge_rich.png
|
||||
|
||||
##############################################################
|
||||
@example autofilter.c
|
||||
|
||||
Example of adding autofilters to a worksheets and adding filter conditions.
|
||||
|
||||
@image html autofilter3.png
|
||||
|
||||
##############################################################
|
||||
@example data_validate.c
|
||||
|
||||
Example of adding data validations to a worksheet.
|
||||
|
||||
@image html data_validate4.png
|
||||
|
||||
##############################################################
|
||||
@example conditional_format1.c
|
||||
|
||||
A simple example of how to add a conditional format a
|
||||
libxlsxwriter file. Conditional formatting allows you to apply
|
||||
a format to a cell or a range of cells based on certain criteria.
|
||||
|
||||
@image html conditional_format12.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example conditional_format2.c
|
||||
|
||||
A more comprehensive example of how to add conditional formatting
|
||||
to an libxlsxwriter file. Conditional formatting allows you to
|
||||
apply a format to a cell or a range of cells based on certain
|
||||
criteria.
|
||||
|
||||
@image html conditional_format1.png
|
||||
|
||||
##############################################################
|
||||
|
||||
@example tables.c
|
||||
|
||||
Example of how to add tables to a worksheet. Tables in Excel are used to group
|
||||
rows and columns of data into a single structure that can be referenced in a
|
||||
formula or formatted collectively.
|
||||
|
||||
@image html tables12.png
|
||||
|
||||
##############################################################
|
||||
@example images.c
|
||||
|
||||
Example of adding images to a worksheet.
|
||||
|
||||
@image html images.png
|
||||
|
||||
##############################################################
|
||||
@example headers_footers.c
|
||||
|
||||
Example of adding worksheet headers and footers to worksheets.
|
||||
|
||||
@image html headers_footers.png
|
||||
|
||||
##############################################################
|
||||
@example defined_name.c
|
||||
|
||||
Example of how to create defined names (named ranges) using libxlsxwriter.
|
||||
|
||||
Defined names are used to define descriptive names to represent a value, a
|
||||
single cell or a range of cells in a workbook or worksheet.
|
||||
|
||||
@image html defined_name.png
|
||||
|
||||
##############################################################
|
||||
@example outline.c
|
||||
|
||||
Example of how to generate Excel outlines and grouping.
|
||||
|
||||
@image html outline1.png
|
||||
|
||||
##############################################################
|
||||
@example outline_collapsed.c
|
||||
|
||||
Example of how to generate Excel outlines and grouping. These examples focus
|
||||
mainly on collapsed outlines.
|
||||
|
||||
@image html outline2.png
|
||||
|
||||
##############################################################
|
||||
@example watermark.c
|
||||
|
||||
Example of how to a watermark image for a worksheet using the method suggested
|
||||
in the Microsoft documentation:
|
||||
https://support.microsoft.com/en-us/office/add-a-watermark-in-excel-a372182a-d733-484e-825c-18ddf3edf009
|
||||
|
||||
@image html worksheet_watermark.png
|
||||
|
||||
##############################################################
|
||||
@example background.c
|
||||
|
||||
Example of how to set the background image for a worksheet.
|
||||
|
||||
@image html background.png
|
||||
|
||||
##############################################################
|
||||
@example tab_colors.c
|
||||
|
||||
Example of how to set Excel worksheet tab colors.
|
||||
|
||||
@image html tab_colors.png
|
||||
|
||||
##############################################################
|
||||
@example diagonal_border.c
|
||||
|
||||
Example of how to set a worksheet cell diagonal border.
|
||||
|
||||
@image html diagonal_border.png
|
||||
|
||||
##############################################################
|
||||
@example hide_sheet.c
|
||||
|
||||
Example of how to hide an Excel worksheet.
|
||||
|
||||
@image html hide_sheet.png
|
||||
|
||||
##############################################################
|
||||
@example doc_properties.c
|
||||
|
||||
Example of setting Excel document properties.
|
||||
|
||||
@image html doc_properties.png
|
||||
|
||||
##############################################################
|
||||
@example doc_custom_properties.c
|
||||
|
||||
Example of setting Excel custom document properties, i.e., properties
|
||||
non-standard document properties.
|
||||
|
||||
@image html custom_properties.png
|
||||
|
||||
##############################################################
|
||||
@example worksheet_protection.c
|
||||
|
||||
Example of setting Excel worksheet protection.
|
||||
|
||||
@image html worksheet_protection.png
|
||||
|
||||
##############################################################
|
||||
@example macro.c
|
||||
|
||||
Example adding a VBA macro to a workbook.
|
||||
|
||||
@image html macros.png
|
||||
|
||||
##############################################################
|
||||
@example comments1.c
|
||||
|
||||
A simple example of adding cell comments to a worksheet.
|
||||
|
||||
@image html comments1.png
|
||||
|
||||
##############################################################
|
||||
@example comments2.c
|
||||
|
||||
Another example of adding cell comments to a worksheet. This example
|
||||
demonstrates most of the available comment formatting options.
|
||||
|
||||
@image html comments2.png
|
||||
|
||||
##############################################################
|
||||
@example hide_row_col.c
|
||||
|
||||
Example of hiding rows and columns in an Excel worksheet.
|
||||
|
||||
@image html hide_row_col.png
|
||||
|
||||
##############################################################
|
||||
@example panes.c
|
||||
|
||||
An example of how to create panes in a worksheet, both "freeze" panes and
|
||||
"split" panes.
|
||||
|
||||
@image html panes.png
|
||||
|
||||
##############################################################
|
||||
@example ignore_errors.c
|
||||
|
||||
Example of hiding worksheet errors and warnings.
|
||||
|
||||
@image html ignore_errors2.png
|
||||
|
||||
##############################################################
|
||||
@example lambda.c
|
||||
|
||||
Example of using the new Excel `LAMBDA()` function. It demonstrates how to
|
||||
create a lambda function in Excel and also how to assign a name to it so that
|
||||
it can be called as a user defined function. This particular example converts
|
||||
from Fahrenheit to Celsius.
|
||||
|
||||
@image html lambda01.png
|
||||
|
||||
##############################################################
|
||||
@example chart.c
|
||||
|
||||
An example of creating a simple column chart with 3 data series.
|
||||
|
||||
@image html chart_simple.png
|
||||
|
||||
##############################################################
|
||||
@example chart_area.c
|
||||
|
||||
Example of creating Excel Area charts. Three types of area chart are shown.
|
||||
|
||||
The default area chart:
|
||||
@image html chart_area1.png
|
||||
|
||||
Stacked area chart:
|
||||
@image html chart_area2.png
|
||||
|
||||
Percent stacked area chart:
|
||||
@image html chart_area3.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_bar.c
|
||||
|
||||
Example of creating Excel Bar charts. Three types of bar chart are shown.
|
||||
|
||||
The default bar chart:
|
||||
@image html chart_bar1.png
|
||||
|
||||
Stacked bar chart:
|
||||
@image html chart_bar2.png
|
||||
|
||||
Percent stacked bar chart:
|
||||
@image html chart_bar3.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_column.c
|
||||
|
||||
Example of creating Excel Column charts. Three types of column chart are shown.
|
||||
|
||||
The default column chart:
|
||||
@image html chart_column1.png
|
||||
|
||||
Stacked column chart:
|
||||
@image html chart_column2.png
|
||||
|
||||
Percent stacked column chart:
|
||||
@image html chart_column3.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_line.c
|
||||
|
||||
Example of creating Excel Line charts. Three types of line chart are shown.
|
||||
|
||||
The default line chart:
|
||||
@image html chart_line1.png
|
||||
|
||||
Stacked line chart:
|
||||
@image html chart_line2.png
|
||||
|
||||
Percent stacked line chart:
|
||||
@image html chart_line3.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_scatter.c
|
||||
|
||||
Example of creating Excel Scatter charts. Five types of scatter chart are shown.
|
||||
|
||||
The default scatter chart:
|
||||
@image html chart_scatter1.png
|
||||
|
||||
Straight scatter chart with markers:
|
||||
@image html chart_scatter2.png
|
||||
|
||||
Straight scatter chart:
|
||||
@image html chart_scatter3.png
|
||||
|
||||
Smooth scatter chart with markers:
|
||||
@image html chart_scatter4.png
|
||||
|
||||
Smooth scatter chart:
|
||||
@image html chart_scatter5.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_radar.c
|
||||
|
||||
Example of creating Excel Radar charts. Three types of radar chart are shown.
|
||||
|
||||
The default radar chart:
|
||||
@image html chart_radar1.png
|
||||
|
||||
Radar chart with markers:
|
||||
@image html chart_radar2.png
|
||||
|
||||
Filled radar chart:
|
||||
@image html chart_radar3.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_pie.c
|
||||
|
||||
Examples of creating an Excel Pie chart.
|
||||
|
||||
The default pie chart:
|
||||
@image html chart_pie1.png
|
||||
|
||||
A pie chart with user defined colors:
|
||||
@image html chart_pie2.png
|
||||
|
||||
A pie chart with rotated segments:
|
||||
@image html chart_pie3.png
|
||||
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_doughnut.c
|
||||
|
||||
Example of creating an Excel Doughnut chart.
|
||||
|
||||
The default doughnut chart:
|
||||
@image html chart_doughnut1.png
|
||||
|
||||
It is possible to define chart colors for most types of libxlsxwriter charts
|
||||
via the series formatting functions. However, Pie/Doughnut charts are a
|
||||
special case since each segment is represented as a point so it is necessary
|
||||
to assign formatting to each point in the series.
|
||||
|
||||
Chart 4 shows how to set segment colors and other options.
|
||||
@image html chart_doughnut2.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_clustered.c
|
||||
|
||||
Example of creating a clustered Excel chart where there are two levels of
|
||||
category on the X axis.
|
||||
|
||||
The categories in clustered charts are 2D ranges, instead of the more normal
|
||||
1D ranges. The series are shown as formula strings for clarity but you can
|
||||
also use the a list syntax.
|
||||
|
||||
@image html chart_clustered.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_data_table.c
|
||||
|
||||
Example of creating charts with data tables.
|
||||
|
||||
Chart 1 in the following example is a column chart with default data table:
|
||||
@image html chart_data_table1.png
|
||||
|
||||
|
||||
Chart 2 is a column chart with default data table with legend keys:
|
||||
@image html chart_data_table2.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_data_tools.c
|
||||
|
||||
A demo of an various Excel chart data tools that are available via a
|
||||
libxlsxwriter chart. These include Drop Lines and High-Low Lines.
|
||||
|
||||
|
||||
Chart 1: chart with high-low lines.
|
||||
@image html chart_data_tools5.png
|
||||
|
||||
Chart 2: chart with drop lines.
|
||||
@image html chart_data_tools6.png
|
||||
|
||||
Chart 3: chart with up-down bars.
|
||||
@image html chart_data_tools4.png
|
||||
|
||||
Chart 4: chart with formatted Up-down bars.
|
||||
@image html chart_data_tools7.png
|
||||
|
||||
Chart 5: chart with markers and data labels.
|
||||
@image html chart_data_tools8.png
|
||||
|
||||
Chart 6: chart with error bars.
|
||||
@image html chart_data_tools3.png
|
||||
|
||||
Chart 7: chart with a trendline.
|
||||
@image html chart_data_tools9.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_data_labels.c
|
||||
|
||||
A demo of an various Excel chart data label features that are available via a
|
||||
libxlsxwriter chart, including custom data labels.
|
||||
|
||||
Chart 1: chart with standard data labels.
|
||||
@image html chart_data_labels11.png
|
||||
|
||||
Chart 2: chart with Category and Value data labels.
|
||||
@image html chart_data_labels12.png
|
||||
|
||||
Chart 3: chart with data labels with a user defined font.
|
||||
@image html chart_data_labels13.png
|
||||
|
||||
Chart 4: chart with data labels and formatting.
|
||||
@image html chart_data_labels22.png
|
||||
|
||||
Chart 5: chart with custom string data labels.
|
||||
@image html chart_data_labels14.png
|
||||
|
||||
Chart 6: chart with custom data labels referenced from worksheet cells.
|
||||
@image html chart_data_labels15.png
|
||||
|
||||
Chart 7: chart with a mix of custom and default labels. The items initialized
|
||||
with '{0}' and items without a custom label (points 5 and 6 which come after
|
||||
NULL) will get the default value. We also set a font for the custom items as
|
||||
an extra example.
|
||||
@image html chart_data_labels16.png
|
||||
|
||||
Chart 8: chart with some deleted custom labels and defaults.
|
||||
@image html chart_data_labels17.png
|
||||
|
||||
Chart 9: chart with custom string data labels and formatting.
|
||||
@image html chart_data_labels23.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_fonts.c
|
||||
|
||||
An example of creating a simple chart with different fonts.
|
||||
|
||||
@image html chart_fonts.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_pattern.c
|
||||
|
||||
An example of creating a simple chart with different patterns.
|
||||
|
||||
@image html chart_pattern.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chart_styles.c
|
||||
|
||||
An example showing all 48 default chart styles available in Excel 2007 using
|
||||
the chart `chart_set_style()` method.
|
||||
|
||||
@image html chart_styles.png
|
||||
|
||||
|
||||
##############################################################
|
||||
@example chartsheet.c
|
||||
|
||||
An example of creating a simple bar chart in a chartsheet.
|
||||
|
||||
@image html chartsheet.png
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
|
||||
@page faq Frequently Asked Questions
|
||||
|
||||
@tableofcontents
|
||||
|
||||
The section outlines some answers to some frequently asked questions.
|
||||
|
||||
|
||||
@section faq_template Q. Can Libxlsxwriter use an existing Excel file as a template?
|
||||
|
||||
No.
|
||||
|
||||
Libxlsxwriter is designed only as a file *writer*. It cannot read or modify
|
||||
an existing Excel file.
|
||||
|
||||
|
||||
@section faq_formula_zero Q. Why do my formulas show a zero result in some, non-Excel applications?
|
||||
|
||||
Due to a wide range of possible formulas and the inter-dependencies between
|
||||
them `libxlsxwriter` doesn't, and realistically cannot, calculate the result
|
||||
of a formula when it is written to an XLSX file. Instead, it 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 several mobile
|
||||
applications, will only display the 0 results.
|
||||
|
||||
If required, it is also possible to specify the calculated result of the
|
||||
formula using the worksheet_write_formula_num() function.
|
||||
|
||||
@code
|
||||
worksheet_write_formula_num(worksheet, 0, 0, "=2 + 2", NULL, 4);
|
||||
@endcode
|
||||
|
||||
@note LibreOffice doesn't recalculate Excel formulas that reference other
|
||||
cells by default, in which case you will get the default XlsxWriter value of
|
||||
0. You can work around this by setting the "LibreOffice Preferences ->
|
||||
LibreOffice Calc -> Formula -> Recalculation on File Load" option to "Always
|
||||
recalculate" (see the LibreOffice
|
||||
[documentation](https://help.libreoffice.org/6.4/en-US/text/scalc/01/06080000.html?DbPAR=CALC)). Or,
|
||||
you can set a blank string result in the formula, which will also force
|
||||
recalculation:
|
||||
|
||||
@code
|
||||
worksheet_write_formula_str(worksheet, 0, 0, "=Sheet1!$A$1", NULL, "");
|
||||
@endcode
|
||||
|
||||
|
||||
@section faq_range_format Q. Can I apply a format to a range of cells in one go?
|
||||
|
||||
Currently no. However, it is a planned features to allow cell formats
|
||||
and data to be written separately.
|
||||
|
||||
|
||||
@section faq_msvc Q. Is Visual C++ on Windows supported?
|
||||
|
||||
Yes. See @ref gsg_vcpkg.
|
||||
|
||||
|
||||
@section faq_features Q. Is feature X supported or will it be supported?
|
||||
|
||||
All supported features are documented. In time the feature set may expand to
|
||||
include more of the functionality of the [Python
|
||||
XlsxWriter](https://xlsxwriter.readthedocs.io) module.
|
||||
|
||||
|
||||
@section faq_autofit Q. Is there an "AutoFit" option for columns?
|
||||
|
||||
Unfortunately, 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" by tracking the width of the
|
||||
data in the column as your write it.
|
||||
|
||||
|
||||
@section faq_faq Q. Do people actually ask these questions frequently, or at all?
|
||||
|
||||
Apart from this question, yes.
|
||||
|
||||
Next: @ref bugs
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,778 @@
|
||||
/**
|
||||
@page getting_started Getting Started with libxlsxwriter
|
||||
|
||||
@tableofcontents
|
||||
|
||||
Here are some instructions to get you up and running with the libxlsxwriter
|
||||
library on different OSes.
|
||||
|
||||
|
||||
@section gsg_quick_start Quick-start on Linux
|
||||
|
||||
If you prefer to assemble Ikea furniture first and only read the instructions
|
||||
when you have parts left over then the following minimal set of commands
|
||||
should get you up and running on a Debian like system:
|
||||
|
||||
sudo apt-get install -y zlib1g-dev
|
||||
git clone https://github.com/jmcnamara/libxlsxwriter.git
|
||||
cd libxlsxwriter
|
||||
make
|
||||
sudo make install
|
||||
|
||||
If you read the instructions first and then assemble the furniture you will
|
||||
know how to proceed.
|
||||
|
||||
|
||||
@section gsg_linux Installation on Linux
|
||||
|
||||
@subsection gsg_dependencies Install the dependencies
|
||||
|
||||
The only non-optional dependency when building libxlsxwriter is [Zlib](http://www.zlib.net).
|
||||
|
||||
You can install `zlib` from source as follows:
|
||||
|
||||
curl -O -L http://www.zlib.net/zlib-1.2.11.tar.gz
|
||||
tar zxf zlib-1.2.11.tar.gz
|
||||
cd zlib-1.2.11
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
sudo make install
|
||||
|
||||
Alternatively, you can use your OS packager to install the `zlib` development
|
||||
libraries. For example:
|
||||
|
||||
sudo apt-get install -y zlib1g-dev
|
||||
|
||||
The zlib version must be >= 1.2.8 to avoid compilation issues.
|
||||
|
||||
@note There are optional dependencies that can be installed for testing.
|
||||
See @ref running_the_tests.
|
||||
|
||||
|
||||
@subsection gsg_git Get the source code
|
||||
|
||||
To get the latest version of the source code you can clone the libxlsxwriter
|
||||
repository from GitHub:
|
||||
|
||||
git clone https://github.com/jmcnamara/libxlsxwriter.git
|
||||
|
||||
Alternatively you can get a tarball of the latest source code as follows:
|
||||
|
||||
curl -O -L http://github.com/jmcnamara/libxlsxwriter/archive/master.tar.gz
|
||||
|
||||
|
||||
@subsection gsg_build Build the source code
|
||||
|
||||
Build the source code as follows:
|
||||
|
||||
cd libxlsxwriter
|
||||
make
|
||||
|
||||
This will create a static and dynamic library in the local `./lib` directory:
|
||||
|
||||
ls lib
|
||||
libxlsxwriter.a libxlsxwriter.so
|
||||
|
||||
To see a verbose summary of the compilation steps use `V=1`:
|
||||
|
||||
make V=1
|
||||
|
||||
With CMake you can build the library as follows:
|
||||
|
||||
cd cmake # Or another sub-directory.
|
||||
cmake ..
|
||||
cmake --build .
|
||||
|
||||
@subsection gsg_examples Build the examples
|
||||
|
||||
If there weren't any warnings or errors in the previous step (and there
|
||||
shouldn't have been) then you can build the programs in the `examples`
|
||||
directory and try one of them out:
|
||||
|
||||
# With Make:
|
||||
make examples
|
||||
|
||||
# or CMake:
|
||||
cd cmake
|
||||
cmake .. -DBUILD_EXAMPLES=ON
|
||||
cmake --build .
|
||||
|
||||
# Then:
|
||||
./examples/hello
|
||||
|
||||
This will create a `hello_world.xlsx` file in your current directory. Open the
|
||||
file in a spreadsheet application. The output should look like this: @image
|
||||
html hello01.png
|
||||
|
||||
|
||||
@subsection gsg_install Install the library
|
||||
|
||||
Libxlsxwriter supports a simplified installation scheme for a static and
|
||||
dynamic/shared library and header files.
|
||||
|
||||
sudo make install
|
||||
|
||||
The files are installed to `/usr/local` by default but this can be overridden
|
||||
by using the `PREFIX` environmental variable:
|
||||
|
||||
make install PREFIX=/usr/third_party
|
||||
|
||||
A staging directory can be set with `DESTDIR` which is prepended to all
|
||||
install paths. This is a an occasionally useful feature for packaging:
|
||||
|
||||
make install PREFIX=/usr/third_party DESTDIR=./staging/
|
||||
|
||||
This would build and link the code with `/usr/third_party` as the
|
||||
installation location but actually install to `./staging/usr/third_party`.
|
||||
|
||||
With CMake you can install the library as follows:
|
||||
|
||||
cd cmake
|
||||
cmake ..
|
||||
cmake --build . --target install
|
||||
|
||||
@subsection gsg_using Using the library
|
||||
|
||||
Using your source code editor create a file like the following called
|
||||
`myexcel.c`:
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("myexcel.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
worksheet_write_string(worksheet, row, col, "Hello me!", NULL);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
@endcode
|
||||
|
||||
If you executed the install commands in the previous section then you
|
||||
should be able to compile the program as follows:
|
||||
|
||||
cc myexcel.c -o myexcel -lxlsxwriter
|
||||
|
||||
In some OS environments, or if you changed the `PREFIX` location, you may
|
||||
have to provide explicit `include` and `lib` paths:
|
||||
|
||||
cc myexcel.c -o myexcel -I/usr/local/include -L/usr/local/lib -lxlsxwriter
|
||||
|
||||
You can also use
|
||||
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||
(after installation of the library) to automatically determine the required
|
||||
arguments and paths:
|
||||
|
||||
$ pkg-config --cflags --libs xlsxwriter
|
||||
-I/usr/local/include -L/usr/local/lib -lxlsxwriter -lz
|
||||
|
||||
You can add this information to your compilation as follows:
|
||||
|
||||
cc myexcel.c -o myexcel `pkg-config --cflags --libs xlsxwriter`
|
||||
|
||||
This will create an executable that you can run to generate an Excel
|
||||
spreadsheet:
|
||||
|
||||
./myexcel
|
||||
xdg-open myexcel.xlsx
|
||||
|
||||
If the installation didn't work for you then you can link against the static
|
||||
library you created in the "Build the source code" step:
|
||||
|
||||
cc myexcel.c -o myexcel -I /path/to/libxlsxwriter/include \
|
||||
/path/to/libxlsxwriter/lib/libxlsxwriter.a -lz
|
||||
|
||||
|
||||
@section gsg_macos Installation on macOS and iOS
|
||||
|
||||
The easiest way to install libxlsxwriter for Xcode and iOS is to use the
|
||||
CocoaPods method shown in the next section.
|
||||
|
||||
To install libxlsxwriter from the macOS commandline requires the
|
||||
[Xcode "commandline tools"](https://developer.apple.com/xcode/resources/).
|
||||
You can then follow the same instructions for compiling and installing on
|
||||
Linux, as shown above.
|
||||
|
||||
For commandline access to libxlsxwriter you can also use
|
||||
[brew/homebrew](https://brew.sh), see below.
|
||||
|
||||
|
||||
@subsection gsg_cocoapods Install using CocoaPods for Xcode
|
||||
|
||||
For iOS and macOS projects in Xcode you can install libxlsxwriter using
|
||||
[CocoaPods](https://cocoapods.org).
|
||||
|
||||
Add the following entry to your `Podfile`:
|
||||
|
||||
pod 'libxlsxwriter', '~> 0.9'
|
||||
|
||||
if you are using Swift, you can now add an import:
|
||||
|
||||
import xlsxwriter
|
||||
|
||||
And call its C functions like this:
|
||||
|
||||
let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
|
||||
let fileURL = documentDirectory.appendingPathComponent("hello_world.xlsx")
|
||||
|
||||
let workbook = workbook_new((fileURL.absoluteString.dropFirst(6) as NSString).fileSystemRepresentation)
|
||||
let worksheet = workbook_add_worksheet(workbook, nil)
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", nil)
|
||||
worksheet_write_number(worksheet, 1, 0, 123, nil)
|
||||
workbook_close(workbook)
|
||||
|
||||
For a sample Xcode project that uses the libxlsxwriter cocoapod for iOS and
|
||||
macOS with Objective-C and Swift see [libxlsxwriter Cocoa
|
||||
Examples](https://github.com/lrossi/libxlsxwriterCocoaExamples) or
|
||||
[LibXlsxWriterSwiftSample](https://github.com/FrankenApps/LibXlsxWriterSwiftSample).
|
||||
|
||||
|
||||
@subsection gsg_brew Installation on macOS with homebrew
|
||||
|
||||
On macOS you can also use [brew/homebrew](https://brew.sh):
|
||||
|
||||
brew install libxlsxwriter
|
||||
|
||||
Once installed you can compile and run a libxlsxwriter program as follows:
|
||||
|
||||
cc myexcel.c -o myexcel -I/usr/local/include -L/usr/local/lib -lxlsxwriter
|
||||
./myexcel
|
||||
|
||||
@section gsg_windows Installation on Windows
|
||||
|
||||
There are several ways to compile libxlsxwriter on and for Windows, see below.
|
||||
|
||||
|
||||
@subsection gsg_vcpkg Using vcpkg for Microsoft Visual Studio
|
||||
|
||||
The most convenient way to get the latest release version of libxlsxwriter and
|
||||
integrate it into your Visual Studio build environment is to use the
|
||||
[vcpkg](https://vcpkg.io) tool:
|
||||
|
||||
> vcpkg is a free C/C++ package manager for acquiring and managing
|
||||
> libraries. Choose from over 1500 open source libraries to download and build
|
||||
> in a single step or add your own private libraries to simplify your build
|
||||
> process. Maintained by the Microsoft C++ team and open source contributors.
|
||||
|
||||
|
||||
Install vcpkg and libxlsxwriter as follows in Windows CMD or Powershell:
|
||||
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
bootstrap-vcpkg.bat
|
||||
vcpkg install libxlsxwriter
|
||||
|
||||
You should then see libxlsxwriter installed as follows (note that the required
|
||||
zlib dependency has also been installed):
|
||||
|
||||
vcpkg list
|
||||
|
||||
libxlsxwriter:x86-windows 0.8.6-1 Libxlsxwriter is a C library that ...
|
||||
zlib:x86-windows 1.2.11-5 A compression library
|
||||
|
||||
You can also install libxlsxwriter for other build targets like `x64`
|
||||
|
||||
vcpkg install libxlsxwriter:x64-windows
|
||||
|
||||
vcpkg list
|
||||
|
||||
libxlsxwriter:x64-windows 1.1.4 Libxlsxwriter is a C library that ...
|
||||
libxlsxwriter:x86-windows 1.1.4 Libxlsxwriter is a C library that ...
|
||||
zlib:x64-windows 1.2.11#13 A compression library
|
||||
zlib:x86-windows 1.2.11#13 A compression library
|
||||
|
||||
To use libxlsxwriter from within Visual Studio you can "integrate" it into
|
||||
your environment:
|
||||
|
||||
vcpkg integrate install
|
||||
|
||||
Applied user-wide integration for this vcpkg root.
|
||||
|
||||
All MSBuild C projects can now include libxlsxwriter directly. Linking will
|
||||
also be handled automatically. For example, create a new Win32 Console (or
|
||||
other C/C++) application in Visual Studio:
|
||||
|
||||
File
|
||||
-> New
|
||||
-> Project
|
||||
|
||||
Visual C++
|
||||
-> Win32
|
||||
-> Win32 Console Application
|
||||
|
||||
Replace the empty main with a libxlsxwriter example from the distro. For
|
||||
example:
|
||||
|
||||
@code
|
||||
// Some older versions on Visual Studio may need "stdafx.h".
|
||||
// #include "stdafx.h"
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("hello_world.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
|
||||
worksheet_write_number(worksheet, 1, 0, 123, NULL);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Change the target to "Release" and the architecture to "x86" or "x64"
|
||||
(depending on the version you installed above). You can now "Build Solution".
|
||||
The resulting executable will be put in the output directory with the required
|
||||
"xlsxwriter.dll" and "zlib1.dll" files.
|
||||
|
||||
|
||||
@subsection gsg_cmake_app Using CMake for Microsoft Visual Studio
|
||||
|
||||
For a more manual installation, and for older versions of Microsoft Visual
|
||||
Studio or Windows, you can use CMake as shown below.
|
||||
|
||||
Open a Windows CMD or Command Window and set up your MSVC environment, if
|
||||
required. Something like this:
|
||||
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
|
||||
# Or:
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
|
||||
Then create a work directory and an install directory that the include and
|
||||
library files will be installed to. Set the follow variables to point to the
|
||||
directories:
|
||||
|
||||
set WORK_DIR=C:/Users/Username/tmp
|
||||
set INSTALL_DIR=C:/Users/Username/tmp/install_dir
|
||||
|
||||
Build the Zlib library:
|
||||
|
||||
cd %WORK_DIR%
|
||||
|
||||
git clone https://github.com/madler/zlib.git
|
||||
cd zlib
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. -G "Visual Studio 14 Win64" -DCMAKE_INSTALL_PREFIX:PATH="%INSTALL_DIR%/zlib"
|
||||
|
||||
cmake --build . --config Release --target install
|
||||
|
||||
Build the libxlsxwriter library:
|
||||
|
||||
cd %WORK_DIR%
|
||||
|
||||
git clone https://github.com/jmcnamara/libxlsxwriter.git
|
||||
cd libxlsxwriter
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. -G "Visual Studio 14 Win64" -DCMAKE_INSTALL_PREFIX:PATH="%INSTALL_DIR%/libxlsxwriter" -DZLIB_ROOT:STRING="%INSTALL_DIR%/zlib"
|
||||
|
||||
cmake --build . --config Release --target install
|
||||
|
||||
|
||||
Create a new Win32 Console (or other C/C++) application in Visual Studio:
|
||||
|
||||
File
|
||||
-> New
|
||||
-> Project
|
||||
|
||||
Visual C++
|
||||
-> Win32
|
||||
-> Win32 Console Application
|
||||
|
||||
|
||||
Change the ARCH in the main Dialog to "x64" and the Configuration to "Release"
|
||||
(or to match the parameters to cmake).
|
||||
|
||||
Replace the empty main with a libxlsxwriter example from the distro. Make sure
|
||||
to include "stdafx.h" and "xlsxwriter.h":
|
||||
|
||||
@code
|
||||
#include "stdafx.h" // This may not be required.
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("hello_world.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
|
||||
worksheet_write_number(worksheet, 1, 0, 123, NULL);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Edit the application properties:
|
||||
|
||||
Project
|
||||
-> ConsoleApplication Properties
|
||||
|
||||
Set the libxlsxwriter include path to match the path used above:
|
||||
|
||||
Configuration Properties
|
||||
-> C/C++
|
||||
-> General
|
||||
-> Additional Include Directories
|
||||
|
||||
Set it to the following (or similar path used above):
|
||||
|
||||
C:\Users\Username\tmp\install_dir\libxlsxwriter\include
|
||||
|
||||
Set the linker directories to match the path created above:
|
||||
|
||||
Configuration Properties
|
||||
-> Linker
|
||||
-> General
|
||||
-> Additional Library Directories
|
||||
|
||||
Add the following (or similar paths used above):
|
||||
|
||||
C:\Users\Username\tmp\install_dir\libxlsxwriter\lib\x64\Release
|
||||
C:\Users\Username\tmp\install_dir\zlib\lib
|
||||
|
||||
Set the linker additional libraries to match the zlib and xlsxwriter libs
|
||||
created above:
|
||||
|
||||
Configuration Properties
|
||||
-> Linker
|
||||
-> Input
|
||||
-> Additional Dependencies
|
||||
|
||||
Add the following:
|
||||
|
||||
xlsxwriter.lib
|
||||
zlib.lib
|
||||
|
||||
Build the solution and run the output executable. It should create a
|
||||
hello_world.xlsx file in the same directory you ran it from.
|
||||
|
||||
|
||||
@subsection gsg_ming Installation on Windows using Mingw-w64 and MSYS2
|
||||
|
||||
The libxlsxwriter library can also be compiled on Windows using the
|
||||
[Mingw-w64](http://mingw-w64.org/doku.php) "Minimalist GNU for Windows"
|
||||
toolchain. These tools can be run from the Windows `cmd.exe` but it is
|
||||
recommended to use the [MSYS2](http://msys2.github.io) "Minimal System" Bourne
|
||||
Shell.
|
||||
|
||||
Here are some instructions on how to compile libxlsxwriter with Mingw-w64 and
|
||||
MSYS2:
|
||||
|
||||
# Install MSYS2 64 or 32 bit from http://msys2.github.io/
|
||||
|
||||
# Install the dev tools for libxlsxwriter.
|
||||
pacman -S git gcc make zlib-devel
|
||||
|
||||
# Clone and build libxlsxwriter.
|
||||
git clone https://github.com/jmcnamara/libxlsxwriter.git
|
||||
cd libxlsxwriter/
|
||||
make
|
||||
|
||||
By default the library is installed in `/usr/local` on MinGW/MSYS systems. If
|
||||
you know how to extend your build environments to use that directory then you
|
||||
can just run `make install`. However, it is generally causes less compile/link
|
||||
issues if you install them in the `/usr` directory like this:
|
||||
|
||||
make install PREFIX=/usr
|
||||
|
||||
After compilation you can follow the instructions in the @ref gsg_using
|
||||
section above. When compiling with the library you may also need to link
|
||||
against the zlib library using `-lz`:
|
||||
|
||||
gcc myexcel.c -o myexcel -lxlsxwriter -lz
|
||||
|
||||
It is also possible to use [Cygwin](https://cygwin.com) and the older [MinGW
|
||||
and MSYS](http://mingw.org). Libxlsxwriter has been confirmed to compile and
|
||||
work in all of these environments.
|
||||
|
||||
See also @ref gsg_tmpdir.
|
||||
|
||||
@subsection gsg_qt Installation in Qt-Creator for Windows
|
||||
|
||||
The following external guide shows how to [Build libxlsxwriter inside
|
||||
Qt-Creator for Windows](https://github.com/jmcnamara/libxlsxwriter/issues/270)
|
||||
with step by step instructions.
|
||||
|
||||
@section gsg_bsd Installation on FreeBSD and OpenBSD
|
||||
|
||||
Installation on FreeBSD and OpenBSD is mainly the same as on @ref gsg_linux
|
||||
"Linux". To compile the library @ref gsg_git "get the source code" and build it
|
||||
using **gmake** (not make):
|
||||
|
||||
cd libxlsxwriter
|
||||
gmake
|
||||
|
||||
Then follow the instructions in the Linux section to @ref gsg_install
|
||||
"install" and @ref gsg_using "use" the library.
|
||||
|
||||
Both FreeBSD and OpenBSD come with the zlib development libraries
|
||||
pre-installed so there are no additional dependencies. However, if you have
|
||||
any issues then follow the instructions to @ref gsg_dependencies "install zlib".
|
||||
|
||||
|
||||
@section gsg_compilation_options Compilation Options
|
||||
|
||||
As shown in the previous sections Libxlsxwriter provides both a Make and
|
||||
CMake based build system. The Make build is a straightforward system for
|
||||
building the library and running tests on Unix like systems. The CMake system
|
||||
offers support for more operating systems, cross compilation, and integration
|
||||
with larger CMake builds. In particular it enables building on Windows.
|
||||
|
||||
The following are various compilation targets and options for both build systems:
|
||||
|
||||
| Make | CMake | Description |
|
||||
| :----------------------- | :----------------------------------------- | :-------------------------------------------------------- |
|
||||
| `examples` | `-DBUILD_EXAMPLES=ON` | Build the example |
|
||||
| `test` | `-DBUILD_TESTS=ON` | Build the tests |
|
||||
| `USE_DTOA_LIBRARY=1` | `-DUSE_DTOA_LIBRARY=ON` | Use alternative double in sprintf |
|
||||
| `USE_MEM_FILE=1` | `-DUSE_MEM_FILE=ON` | Use `fmemopen()`/`open_memstream()` instead of temp files |
|
||||
| `USE_OPENSSL_MD5=1` | `-DUSE_OPENSSL_MD5=ON` | Use OpenSSL for MD5 digest |
|
||||
| `USE_NO_MD5=1` | `-DUSE_NO_MD5=ON` | Don't use a MD5 digest |
|
||||
| `USE_SYSTEM_MINIZIP=1` | `-DUSE_SYSTEM_MINIZIP=ON` | Use system minzip library |
|
||||
| `USE_STANDARD_TMPFILE=1` | `-DUSE_STANDARD_TMPFILE=ON` | Use system `tmpfile()` function |
|
||||
| `USE_BIG_ENDIAN=1` | `-DUSE_BIG_ENDIAN=ON` | Build on big endian systems |
|
||||
| `universal_binary` | `-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"` | Create a macOS "Universal Binary" |
|
||||
| | `-DBUILD_SHARED_LIBS=ON` | Build shared library (default on) |
|
||||
| | `-DUSE_STATIC_MSVC_RUNTIME=ON` | Use static msvc runtime library |
|
||||
| | `-DCMAKE_BUILD_TYPE=Release` | Set the build type. |
|
||||
|
||||
|
||||
The compilation options would be used as follows:
|
||||
|
||||
# Make
|
||||
make examples USE_DTOA_LIBRARY=1
|
||||
|
||||
# CMake
|
||||
cd cmake
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DUSE_DTOA_LIBRARY=ON
|
||||
cmake --build . --config Release
|
||||
|
||||
Each of the options are explained below:
|
||||
|
||||
- `examples/BUILD_EXAMPLES`: Builds the @ref examples "example programs".
|
||||
|
||||
- `test/BUILD_TESTS`: Builds the tests (see @ref running_the_tests). With Make
|
||||
the tests are also run once they are compiled. With CMake you can run them
|
||||
using `ctest`.
|
||||
|
||||
- `USE_DTOA_LIBRARY`: See @ref gsg_dtoa "using a double formatting library".
|
||||
|
||||
- `USE_MEM_FILE`: Use fmemopen()/open_memstream() instead of temporary files.
|
||||
This option isn't on by default since it isn't supported on Windows.
|
||||
|
||||
- `USE_OPENSSL_MD5`: Uses OpenSSL to provide a MD5 digest of image files in
|
||||
order to avoid storing duplicates. See @ref gsg_md5.
|
||||
|
||||
- `USE_NO_MD5`: Don't use a MD5 digest of image files in order to remove
|
||||
duplicates. This can be used if you aren't handling image files and don't
|
||||
need the additional function in the library. See @ref gsg_md5.
|
||||
|
||||
- `USE_SYSTEM_MINIZIP`: Uses a system minizip library, rather than the
|
||||
included copy, to create the xlsx zip container. See @ref gsg_minizip.
|
||||
|
||||
- `USE_STANDARD_TMPFILE`: Uses the standard library `tmpfile()` function
|
||||
to handle temp files instead of `tmpfileplus`. See @ref gsg_tmpdir.
|
||||
|
||||
- `USE_BIG_ENDIAN`: Compiles libxlsxwriter on a big endian system. See @ref
|
||||
gsg_endian.
|
||||
|
||||
- `universal_binary/CMAKE_OSX_ARCHITECTURES`: Builds a "universal binary" for
|
||||
both Apple silicon and Intel-based Macs. See @ref gsg_universal.
|
||||
|
||||
- `BUILD_SHARED_LIBS`: Builds a dynamically loading version of the library
|
||||
(`.so`, `.dll` or `.dylib` depending on the operating system).
|
||||
|
||||
- `USE_STATIC_MSVC_RUNTIME`: Sets flags for Microsoft Visual C to use a static
|
||||
MSVC runtime.
|
||||
|
||||
- `CMAKE_BUILD_TYPE`: Sets the build type (generally `Release` or `Debug`).
|
||||
|
||||
You can view, and set, your CMake options from within your build directory
|
||||
using the `ccmake` tool:
|
||||
|
||||
ccmake .
|
||||
|
||||
|
||||
@subsection gsg_dtoa Using a double formatting library
|
||||
|
||||
Excel uses an IEEE 754 doubles for all numeric values. These values are stored
|
||||
in standard `sprintf(...,"%.16G",...)` formatting as numbers like "1234.56" or
|
||||
"456E+123". However in some locales, such as "de_DE" these numbers can be
|
||||
stored with the locale specific decimal place like "1234,56" which causes
|
||||
Excel to give an error when it loads the file.
|
||||
|
||||
It some cases this issue can be resolved by using the `setlocale()` or
|
||||
`uselocale()` functions in your application. Alternatively you can compile
|
||||
libxlsxwriter with support for a third party `dtoa()` (decimal to ascii)
|
||||
function. Currently libxlsxwriter uses the [Milo Yip DTOA
|
||||
library](https://github.com/miloyip/dtoa-benchmark) as an optional
|
||||
compilation. This avoids the locale sprintf issue and it is also 40-50% faster
|
||||
than the standard dtoa for raw numeric data.
|
||||
|
||||
|
||||
@subsection gsg_md5 MD5 functionality for handling duplicate images
|
||||
|
||||
Libxlsxwriter uses a an MD5 digest to avoid including duplicate image files in
|
||||
the xlsx file. By default it uses a third party library, [Openwall
|
||||
MD5](https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5),
|
||||
which is a fast portable implementation of the MD5 Algorithm and which uses
|
||||
the same function prototypes as OpenSSL MD5 digest. See @ref license.
|
||||
|
||||
The Openwall MD5 code is included in the libxlsxwriter repo and compiled in by
|
||||
default. If you don't want to use this code, and the additional license, you
|
||||
can use OpenSSL's MD5 functions dynamically by using the `USE_OPENSSL_MD5`
|
||||
option:
|
||||
|
||||
make USE_OPENSSL_MD5=1
|
||||
|
||||
# or:
|
||||
cmake .. -DUSE_OPENSSL_MD5=ON
|
||||
|
||||
This requires that you have the OpenSSL development libraries installed and on
|
||||
paths known to your compiler.
|
||||
|
||||
If this MD5 functionality isn't required it is possible to compile
|
||||
libxlsxwriter without image de-duplication by using the `USE_NO_MD5=1` option:
|
||||
|
||||
make USE_NO_MD5=1
|
||||
|
||||
# or:
|
||||
cmake .. -DUSE_NO_MD5=ON
|
||||
|
||||
@subsection gsg_minizip Linking against system minizip
|
||||
|
||||
Libxlsxwriter uses the `minizip` component of [Zlib](http://www.zlib.net) to
|
||||
create the xlsx zip file container. The source files for `minizip` are
|
||||
included in the src tree of libxlsxwriter and are statically linked by
|
||||
default.
|
||||
|
||||
If you have a `lminizip` library already installed on your system and prefer
|
||||
to dynamically link against that you can use the following compilation option:
|
||||
|
||||
make USE_SYSTEM_MINIZIP=1
|
||||
|
||||
# or:
|
||||
cmake .. -DUSE_SYSTEM_MINIZIP=ON
|
||||
|
||||
|
||||
@subsection gsg_tmpdir Specifying a TEMP directory for libxlsxwriter
|
||||
|
||||
The libxlsxwriter library creates temporary files in the system `TEMP`
|
||||
directory during assembly of an xlsx file. On Windows this directory may not
|
||||
be writeable by a libxlsxwriter application (although it will try several
|
||||
`TEMP` locations before returning an error). To work around this you can set
|
||||
the `tmpdir` parameter of the #lxw_workbook_options struct and pass it to
|
||||
`workbook_new_opt()`:
|
||||
|
||||
@code
|
||||
lxw_workbook_options options = {.constant_memory = LXW_FALSE,
|
||||
.tmpdir = "C:\\Temp"};
|
||||
|
||||
lxw_workbook *workbook = workbook_new_opt("filename.xlsx", &options);
|
||||
@endcode
|
||||
|
||||
This can also be used on Unix systems where the `TEMP` directory isn't
|
||||
writeable.
|
||||
|
||||
The TEMP file handling with optional temporary directory support is provided
|
||||
by the
|
||||
[Tmpfileplus](http://www.di-mgt.com.au/c_function_to_create_temp_file.html)
|
||||
library which is included in the source tree. If you wish to use the standard
|
||||
library `tmpfile()` function instead you can compile without `tmpfileplus` as
|
||||
follows:
|
||||
|
||||
make USE_STANDARD_TMPFILE=1
|
||||
|
||||
# or:
|
||||
cmake .. -DUSE_STANDARD_TMPFILE=ON
|
||||
|
||||
@note When using the the standard library `tmpfile()` the `tmpdir` parameter,
|
||||
shown above, is ignored.
|
||||
|
||||
@subsection gsg_endian Compiling on Big Endian Architecture
|
||||
|
||||
Libxlsxwriter can be compiled on a big endian system as follows:
|
||||
|
||||
make USE_BIG_ENDIAN=1
|
||||
|
||||
# or:
|
||||
cmake .. -DUSE_BIG_ENDIAN=ON
|
||||
|
||||
@subsection gsg_universal Compiling a universal binary on macOS
|
||||
|
||||
With Xcode 12.2 and later you can compile libxlsxwriter as a "universal
|
||||
binary" for both Apple silicon and Intel-based Macs, i.e., arm64 and x86_64.
|
||||
|
||||
You can compile a universal binary with standard make as follows:
|
||||
|
||||
$ make universal_binary
|
||||
|
||||
# Which gives:
|
||||
$ lipo -archs lib/libxlsxwriter.a
|
||||
x86_64 arm64
|
||||
|
||||
$ lipo -archs lib/libxlsxwriter.dylib
|
||||
x86_64 arm64
|
||||
|
||||
Or with CMake:
|
||||
|
||||
cd cmake
|
||||
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
make
|
||||
|
||||
|
||||
@subsection gsg_minimal Minimal dependency compilation
|
||||
|
||||
As explained in the previous sections Libxlsxwriter includes 3 additional
|
||||
libraries within the `third_party` directory:
|
||||
|
||||
1. `md5`: Used for MD5 hashing to avoid including duplicate images. See @ref
|
||||
gsg_md5.
|
||||
|
||||
2. `minizip`: Uses creating the xlsx zip container (this is part of the zlib
|
||||
code base but generally packaged separately). See @ref gsg_minizip.
|
||||
|
||||
3. `tmpfileplus`: Used mainly to overcome temp file issues on Windows but also
|
||||
used for changing the default temp directory. See @ref gsg_tmpdir.
|
||||
|
||||
These components are included in the libxlsxwriter repository to ensure that
|
||||
the library compiles and runs on as many OSes as possible with the least
|
||||
amount of additional dependencies.
|
||||
|
||||
However, all of these are optional and a minimal version of libxlsxwriter can
|
||||
be compiled without them by relying on external libraries as follows:
|
||||
|
||||
# Make:
|
||||
make USE_OPENSSL_MD5=1 USE_SYSTEM_MINIZIP=1 USE_STANDARD_TMPFILE=1
|
||||
|
||||
# CMake:
|
||||
cd cmake
|
||||
cmake .. -DUSE_OPENSSL_MD5=ON -DUSE_SYSTEM_MINIZIP=ON -DUSE_STANDARD_TMPFILE=ON
|
||||
cmake --build .
|
||||
|
||||
@section gsg_next Next steps
|
||||
|
||||
Once you get libxlsxwriter built and working the next sections will show you
|
||||
how to create some more in-depth examples.
|
||||
|
||||
|
||||
Next: @ref tutorial01
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
|
||||
@page introduction Introduction
|
||||
|
||||
<b>libxlsxwriter</b> is a C library for writing files in the Excel 2007+ XLSX
|
||||
file format.
|
||||
|
||||
It can be used to write text, numbers, formulas and hyperlinks to multiple
|
||||
worksheets and it supports features such as formatting.
|
||||
|
||||
The main advantages of using `libxlsxwriter` are:
|
||||
|
||||
- It has a high degree of fidelity with files produced by Excel. In
|
||||
most cases the files produced are 100% equivalent to files
|
||||
produced by Excel.
|
||||
- It has extensive documentation, example files and tests.
|
||||
|
||||
However:
|
||||
|
||||
- It can only create **new files**. It cannot read or modify
|
||||
existing files.
|
||||
|
||||
Libxlsxwriter is a C port of the Perl
|
||||
[Excel::Writer::XLSX](http://search.cpan.org/~jmcnamara/Excel-Writer-XLSX/)
|
||||
module and the Python [XlsxWriter](https://xlsxwriter.readthedocs.io) module
|
||||
by the same author and is licensed under a FreeBSD @ref license.
|
||||
|
||||
Next: @ref getting_started
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
@mainpage Creating Excel files with C and libxlsxwriter
|
||||
|
||||
<b>Libxlsxwriter</b> is a C library for creating Excel XLSX files.
|
||||
|
||||
@image html demo.png
|
||||
|
||||
@ref demo.c "(Sample code to create the above spreadsheet.)"
|
||||
|
||||
@section mainpage_intro libxlsxwriter
|
||||
|
||||
Libxlsxwriter is a C library that can be used to write text, numbers, formulas
|
||||
and hyperlinks to multiple worksheets in an Excel 2007+ XLSX file. It supports
|
||||
features such as:
|
||||
|
||||
- 100% compatible Excel XLSX files.
|
||||
- Full Excel formatting.
|
||||
- Merged cells.
|
||||
- Defined names.
|
||||
- Autofilters.
|
||||
- Charts.
|
||||
- Data validation and drop down lists.
|
||||
- Conditional formatting.
|
||||
- Worksheet PNG/JPEG/GIF images.
|
||||
- Cell comments.
|
||||
- Support for adding Macros.
|
||||
- Memory optimization mode for writing large files.
|
||||
- Source code available on [GitHub](https://github.com/jmcnamara/libxlsxwriter).
|
||||
- FreeBSD @ref license.
|
||||
- ANSI C.
|
||||
- Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32.
|
||||
- Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin.
|
||||
- Compiles for 32 and 64 bit.
|
||||
- Compiles and works on big and little endian systems.
|
||||
- The only dependency is on `zlib`.
|
||||
|
||||
This document explains how to use the libxlsxwriter library. See the
|
||||
following sections for more information:
|
||||
|
||||
- @ref introduction
|
||||
|
||||
- @ref getting_started
|
||||
|
||||
- @ref tutorial01
|
||||
- @ref tutorial02
|
||||
- @ref tutorial03
|
||||
|
||||
- @ref workbook.h "The Workbook object"
|
||||
- @ref worksheet.h "The Worksheet object"
|
||||
- @ref format.h "The Format object"
|
||||
- @ref chart.h "The Chart object"
|
||||
- @ref chartsheet.h "The Chartsheet object"
|
||||
- @ref utility.h "Utility functions and macros"
|
||||
|
||||
- @ref working_with_formats
|
||||
- @ref working_with_colors
|
||||
- @ref working_with_formulas
|
||||
- @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_tables
|
||||
- @ref working_with_comments
|
||||
- @ref working_with_outlines
|
||||
- @ref working_with_memory
|
||||
- @ref working_with_macros
|
||||
|
||||
- @ref examples
|
||||
- @ref running_the_tests
|
||||
- @ref faq
|
||||
- @ref bugs
|
||||
- @ref author
|
||||
- @ref license
|
||||
- @ref changes
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
@page running_the_tests Running the Test Suite
|
||||
|
||||
@tableofcontents
|
||||
|
||||
This section shows how to set up and run the test suite for libxlsxwriter.
|
||||
|
||||
@section tests_functional Functional Tests
|
||||
|
||||
The functional tests compare the output from libxlsxwriter against xlsx files
|
||||
created in Excel.
|
||||
|
||||
|
||||
The functional tests use the Python module [pytest](http://pytest.org/) as a
|
||||
test runner.
|
||||
|
||||
Install the `pytest` module using one of the following methods:
|
||||
|
||||
sudo apt-get install -y python-pytest
|
||||
# or
|
||||
sudo pip install pytest
|
||||
|
||||
The functional tests can then be run:
|
||||
|
||||
$ cd libxlsxwriter
|
||||
|
||||
$ make test_functional
|
||||
|
||||
=========================== test session starts ===========================
|
||||
collected 749 items
|
||||
|
||||
test/functional/test_array_formula.py::TestCompareXLSXFiles::test_array_formula01 PASSED [ 0%]
|
||||
test/functional/test_array_formula.py::TestCompareXLSXFiles::test_array_formula02 PASSED [ 0%]
|
||||
test/functional/test_array_formula.py::TestCompareXLSXFiles::test_array_formula03 PASSED [ 0%]
|
||||
test/functional/test_array_formula.py::TestCompareXLSXFiles::test_array_formula04 PASSED [ 1%]
|
||||
test/functional/test_autofilter.py::TestCompareXLSXFiles::test_autofilter00 PASSED [ 1%]
|
||||
test/functional/test_autofilter.py::TestCompareXLSXFiles::test_autofilter01 PASSED [ 1%]
|
||||
...
|
||||
test/functional/test_write_data.py::TestCompareXLSXFiles::test_data05 PASSED [ 99%]
|
||||
test/functional/test_write_data.py::TestCompareXLSXFiles::test_data06 PASSED [ 99%]
|
||||
test/functional/test_write_data.py::TestCompareXLSXFiles::test_data07 PASSED [ 99%]
|
||||
test/functional/test_write_data.py::TestCompareXLSXFiles::test_data08 PASSED [ 99%]
|
||||
test/functional/test_write_data.py::TestCompareXLSXFiles::test_data09 PASSED [100%]
|
||||
=========================== 749 passed in 30.60s ===============================
|
||||
|
||||
|
||||
@section tests_ Unit Tests
|
||||
|
||||
The unit tests test the components of the library at the level of individual
|
||||
functions or compilation units.
|
||||
|
||||
The unit tests uses the [ctest](http://github.com/bvdberg/ctest) test
|
||||
framework. This is included as a header file in the `test/unit` directory
|
||||
and doesn't need to be installed.
|
||||
|
||||
The unit tests can then be run as follows:
|
||||
|
||||
$ make test_unit
|
||||
Compiling unit tests ...
|
||||
TEST 1/429 utility:lxw_col_to_name [OK]
|
||||
TEST 2/429 utility:test_datetime_date_and_time [OK]
|
||||
TEST 3/429 utility:test_datetime_date_only [OK]
|
||||
TEST 4/429 utility:test_datetime_date_only_1904 [OK]
|
||||
TEST 5/429 utility:test_datetime_time_only [OK]
|
||||
TEST 6/429 utility:test_unixtime [OK]
|
||||
...
|
||||
TEST 425/429 worksheet:worksheet_table12 [OK]
|
||||
TEST 426/429 worksheet:worksheet_table13 [OK]
|
||||
TEST 427/429 worksheet:worksheet_table14 [OK]
|
||||
TEST 428/429 worksheet:worksheet_table15 [OK]
|
||||
TEST 429/429 table:xml_declaration [OK]
|
||||
|
||||
RESULTS: 429 tests (429 ok, 0 failed, 0 skipped) ran in 153 ms
|
||||
|
||||
Both functional and unit test can be run together:
|
||||
|
||||
$ make test
|
||||
|
||||
@section tests_cmake Testing with CMake
|
||||
|
||||
You can run the unit and functional tests via CMake as follows:
|
||||
|
||||
cd cmake
|
||||
cmake .. -DBUILD_TESTS=ON
|
||||
cmake --build .
|
||||
ctest -V
|
||||
|
||||
@section tests_valgrind Valgrind Tests
|
||||
|
||||
The functional tests and examples can be run under
|
||||
[Valgrind](http://valgrind.org) to verify that there are no memory leaks.
|
||||
|
||||
Install `valgrind` as follows:
|
||||
|
||||
apt-get install -y valgrind
|
||||
|
||||
Then run the tests:
|
||||
|
||||
make test_valgrind
|
||||
|
||||
|
||||
@section tests_ci GitHub Actions Continuous Integration
|
||||
|
||||
Libxlsxwriter is configured to run all these tests with [GitHub Actions
|
||||
Continuous Integration](https://github.com/jmcnamara/libxlsxwriter/actions)
|
||||
for each commit.
|
||||
|
||||
|
||||
Next: @ref faq
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
@page tutorial01 Tutorial 1: Create a simple XLSX file
|
||||
|
||||
Next: @ref tutorial02.
|
||||
|
||||
Let's start by creating a simple spreadsheet using C and the
|
||||
@c libxlsxwriter library.
|
||||
|
||||
Say that we have some data on monthly outgoings that we want to convert
|
||||
into an Excel XLSX file:
|
||||
|
||||
Item | Cost
|
||||
----- | ---:
|
||||
Rent | 1000
|
||||
Gas | 100
|
||||
Food | 300
|
||||
Gym | 50
|
||||
|
||||
To do that we can start with a small program like the following:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skip include
|
||||
@until };
|
||||
@until };
|
||||
@until }
|
||||
@until }
|
||||
|
||||
|
||||
If we run this program we should get a spreadsheet that looks like this:
|
||||
|
||||
@image html tutorial01.png
|
||||
|
||||
This is a simple example but the steps involved are representative of
|
||||
all programs that use @c libxlsxwriter, so let's break it down into separate
|
||||
parts.
|
||||
|
||||
The first step is to include the header for the library:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline include
|
||||
|
||||
Then we need some data to add to the spreadsheet. For the sake of this example
|
||||
we create and initialize some simple data structures. In a real application
|
||||
the input data might come from a database or a file.
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline struct
|
||||
@until };
|
||||
@until };
|
||||
|
||||
|
||||
The next step is to create a workbook object in a @c main block or
|
||||
function using the workbook_new() function which takes the filename
|
||||
that we want to create:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline workbook_new
|
||||
|
||||
|
||||
The workbook object is then used to add a new worksheet via the
|
||||
workbook_add_worksheet() function:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline add_worksheet
|
||||
|
||||
If a `NULL` pointer is used for the worksheet name then a default name will be
|
||||
supplied using the Excel convention of `Sheet1`, `Sheet2`, etc. However we can
|
||||
also specify a name:
|
||||
|
||||
@code
|
||||
worksheet = workbook_add_worksheet(workbook, NULL ); // Defaults to Sheet1.
|
||||
worksheet = workbook_add_worksheet(workbook, "Data"); // Data.
|
||||
worksheet = workbook_add_worksheet(workbook, NULL ); // Defaults to Sheet3.
|
||||
@endcode
|
||||
|
||||
We can then use the worksheet object to write data via the
|
||||
worksheet_write_string() and worksheet_write_number() functions:
|
||||
|
||||
@code
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
|
||||
worksheet_write_number(worksheet, 1, 0, 1234.56, NULL);
|
||||
@endcode
|
||||
|
||||
@note
|
||||
Rows and columns are zero indexed throughout the libxlsxwriter API. Thus, the
|
||||
first cell in a worksheet, `A1`, is equivalent to `(0, 0)`.
|
||||
|
||||
So in our example we iterate over our data and write it out as follows:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline for
|
||||
@until }
|
||||
|
||||
We then add a formula to calculate the total of the items in the second
|
||||
column:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline write_formula
|
||||
|
||||
Finally, we close the Excel file via the close method:
|
||||
|
||||
@dontinclude tutorial1.c
|
||||
@skipline close
|
||||
|
||||
And that's it. We now have a file that can be read by Excel and other
|
||||
spreadsheet applications.
|
||||
|
||||
In the next sections we will see how we can use the @c libxlsxwriter module
|
||||
to add formatting and other Excel features.
|
||||
|
||||
Next: @ref tutorial02.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
@page tutorial02 Tutorial 2: Adding formatting to the XLSX File
|
||||
|
||||
Next: @ref tutorial03.
|
||||
|
||||
In the previous section we created a simple spreadsheet using C and
|
||||
the @c libxlsxwriter library.
|
||||
|
||||
This converted the required data into an Excel file but it looked a
|
||||
little bare. In order to make the information clearer we would like to
|
||||
add some simple formatting, like this:
|
||||
|
||||
@image html tutorial02.png
|
||||
|
||||
The differences here are that we have added **Item** and **Cost** column
|
||||
headers in a bold font, we have formatted the currency in the second
|
||||
column and we have made the **Total** string bold.
|
||||
|
||||
To do this we can extend our program as follows:
|
||||
|
||||
@dontinclude tutorial2.c
|
||||
@skip include
|
||||
@until };
|
||||
@until };
|
||||
@until }
|
||||
@until }
|
||||
|
||||
The main difference between this and the previous program is that we have
|
||||
added two @ref format.h "Format" objects that we can use to format cells in
|
||||
the spreadsheet.
|
||||
|
||||
Format objects represent all of the formatting properties that can be applied
|
||||
to a cell in Excel such as fonts, number formatting, colors and borders. This
|
||||
is explained in more detail in @ref format.h "The Format object" and @ref
|
||||
working_with_formats.
|
||||
|
||||
For now we will avoid getting into the details and just use a limited
|
||||
amount of the format functionality to add some simple formatting:
|
||||
|
||||
@dontinclude tutorial2.c
|
||||
@skipline bold
|
||||
@until num_format
|
||||
|
||||
We can then pass these formats as a parameter to the `worksheet_write*()`
|
||||
functions to format the data in the cell:
|
||||
|
||||
@dontinclude tutorial2.c
|
||||
@skipline Total
|
||||
@skipline SUM
|
||||
|
||||
In the next section we will look at handling more data types.
|
||||
|
||||
Next: @ref tutorial03.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
@page tutorial03 Tutorial 3: Writing different types of data to the XLSX File
|
||||
|
||||
|
||||
In the previous section we created a simple spreadsheet with formatting
|
||||
using C and the @c libxlsxwriter module.
|
||||
|
||||
This time let's extend the data we want to write to include some dates:
|
||||
|
||||
Item | Date | Cost
|
||||
---- | ---------- | ---:
|
||||
Rent | 2013-01-13 | 1000
|
||||
Gas | 2013-01-14 | 100
|
||||
Food | 2013-01-16 | 300
|
||||
Gym | 2013-01-20 | 50
|
||||
|
||||
|
||||
The corresponding spreadsheet will look like this:
|
||||
|
||||
@image html tutorial03.png
|
||||
|
||||
The differences here are that we have added a Date column with
|
||||
formatting and made that column a little wider to accommodate the dates.
|
||||
|
||||
To do this we can extend our program as follows:
|
||||
|
||||
@dontinclude tutorial3.c
|
||||
@skip include
|
||||
@until };
|
||||
@until };
|
||||
@until }
|
||||
@until }
|
||||
|
||||
The main difference between this and the previous program is that we have
|
||||
added a new @ref format.h "Format" object for dates and we have additional
|
||||
handling for the date information.
|
||||
|
||||
We have also extended the data that we are going to write to include a
|
||||
lxw_datetime struct to hold the date information. We will see how that is used
|
||||
shortly.
|
||||
|
||||
@dontinclude tutorial3.c
|
||||
@skipline struct
|
||||
@until };
|
||||
@until };
|
||||
|
||||
|
||||
|
||||
Excel treats different types of input data, such as strings and numbers,
|
||||
differently although it generally does it transparently to the user.
|
||||
Libxlsxwriter tries to emulate this in the `worksheet_write*()` functions by
|
||||
mapping C data types to types that Excel supports.
|
||||
|
||||
- worksheet_write_string()
|
||||
- worksheet_write_number()
|
||||
- worksheet_write_formula()
|
||||
- worksheet_write_datetime()
|
||||
- worksheet_write_blank()
|
||||
|
||||
In this version of our program we have used some of these functions for
|
||||
different types of data:
|
||||
|
||||
@dontinclude tutorial3.c
|
||||
@skipline expenses[i].item
|
||||
@until expenses[i].cost
|
||||
|
||||
The handling of dates is also new to our program.
|
||||
|
||||
Dates and times in Excel are floating point numbers that have a number format
|
||||
applied to display them in the correct format. Libxlsxwriter provides the
|
||||
worksheet_write_datetime() and the lxw_datetime struct help to convert dates
|
||||
and times into Excel date and time numbers.
|
||||
|
||||
The worksheet_write_datetime() function converts the lxw_datetime struct to a
|
||||
number that represents an Excel date but we also need to add the number format
|
||||
to ensure that Excel displays it as as date:
|
||||
|
||||
@dontinclude tutorial3.c
|
||||
@skipline yyyy
|
||||
|
||||
Date handling is explained in more detail in @ref working_with_dates.
|
||||
|
||||
That completes the tutorial section.
|
||||
|
||||
In the next sections we will look at the API in more detail starting
|
||||
with workbook.
|
||||
|
||||
Next: @ref workbook.h "The Workbook object"
|
||||
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
@page working_with_colors Working with Colors
|
||||
|
||||
Throughout libxlsxwriter colors are specified using a Html style RGB
|
||||
integer value. For example with a Format object:
|
||||
|
||||
@code
|
||||
format_set_font_color(format, 0x3030E0);
|
||||
@endcode
|
||||
|
||||
For convenience a limited number of color names are supported:
|
||||
|
||||
@code
|
||||
format_set_font_color(format, LXW_COLOR_RED);
|
||||
@endcode
|
||||
|
||||
The color names and corresponding RRGGBB value are shown below:
|
||||
|
||||
|
||||
Color | Define | Value
|
||||
-------- | --------------------- | ------------------
|
||||
Black | #LXW_COLOR_BLACK | `0x1000000` (note)
|
||||
Blue | #LXW_COLOR_BLUE | `0x0000FF`
|
||||
Brown | #LXW_COLOR_BROWN | `0x800000`
|
||||
Cyan | #LXW_COLOR_CYAN | `0x00FFFF`
|
||||
Gray | #LXW_COLOR_GRAY | `0x808080`
|
||||
Green | #LXW_COLOR_GREEN | `0x008000`
|
||||
Lime | #LXW_COLOR_LIME | `0x00FF00`
|
||||
Magenta | #LXW_COLOR_MAGENTA | `0xFF00FF`
|
||||
Navy | #LXW_COLOR_NAVY | `0x000080`
|
||||
Orange | #LXW_COLOR_ORANGE | `0xFF6600`
|
||||
Pink | #LXW_COLOR_PINK | `0xFF00FF`
|
||||
Purple | #LXW_COLOR_PURPLE | `0x800080`
|
||||
Red | #LXW_COLOR_RED | `0xFF0000`
|
||||
Silver | #LXW_COLOR_SILVER | `0xC0C0C0`
|
||||
White | #LXW_COLOR_WHITE | `0xFFFFFF`
|
||||
Yellow | #LXW_COLOR_YELLOW | `0xFFFF00`
|
||||
|
||||
|
||||
@note Black in Html is actually `0x000000` but `#LXW_COLOR_BLACK` is defined
|
||||
as 0x1000000 to avoid confusion with an undefined or Zero color value. It is
|
||||
converted to the correct Html code internally.
|
||||
|
||||
Next: @ref working_with_formulas
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
@page working_with_comments Working with Cell Comments
|
||||
|
||||
Cell comments are a way of adding notation to cells in Excel. For example:
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("comments1.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_string( worksheet, 0, 0, "Hello" , NULL);
|
||||
|
||||
worksheet_write_comment(worksheet, 0, 0, "This is a comment");
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@image html comments1.png
|
||||
|
||||
|
||||
|
||||
@section ww_comments_properties Setting Comment Properties
|
||||
|
||||
The properties of the cell comment can be modified by passing an optional
|
||||
#lxw_comment_options struct to `worksheet_write_comment_opt()` control the
|
||||
format of the comment. For example:
|
||||
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.x_scale = 1.2, .y_scale = 0.5};
|
||||
|
||||
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`
|
||||
|
||||
The options are explained in detail below and shown in @ref comments2.c.
|
||||
|
||||
@subsection ww_comments_author Cell comments: author
|
||||
|
||||
This `author` option is used to indicate who is the author of the cell
|
||||
comment. Excel displays the author of the comment in the status bar at the
|
||||
bottom of the worksheet. This is usually of interest in corporate environments
|
||||
where several people might review and provide comments to a workbook:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.author = "Ian McEwan"};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Atonement", &options);
|
||||
@endcode
|
||||
|
||||
The default author for all cell comments in a worksheet can be set using
|
||||
the `worksheet_set_comments_author()` function:
|
||||
|
||||
@code
|
||||
worksheet_set_comments_author(worksheet, "Jane Gloriana Villanueva")
|
||||
@endcode
|
||||
|
||||
@subsection ww_comments_visible Cell comments: visible
|
||||
|
||||
The `visible` 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. In libxlsxwriter individual comments can be made visible as
|
||||
follows:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_VISIBLE};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello.", &options);
|
||||
@endcode
|
||||
|
||||
The `visible` property should be set with one of the enum values from
|
||||
#lxw_comment_display_types.
|
||||
|
||||
It is possible to make all comments in a worksheet visible using the
|
||||
`worksheet_show_comments()` worksheet function. Alternatively, if all of the
|
||||
cell comments have been made visible you can hide individual comments:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.visible = LXW_COMMENT_DISPLAY_HIDDEN};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_width Cell comments: width
|
||||
|
||||
The `width` option is used to set the width of the cell comment box explicitly
|
||||
in pixels:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.width = 200};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
The width and height can be adjusted together:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.width = 200, .height = 50};
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_height Cell comments: height
|
||||
|
||||
The `height` option is used to set the height of the cell comment box
|
||||
explicitly in pixels:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.height = 50};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
The width and height can be adjusted together:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.width = 200, .height = 50};
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_x_scale Cell comments: x_scale
|
||||
|
||||
The `x_scale` option is used to set the width of the cell comment box
|
||||
as a factor of the default width:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.x_scale = 2.0};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_y_scale Cell comments: y_scale
|
||||
|
||||
The `y_scale` option is used to set the height of the cell comment box
|
||||
as a factor of the default height:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.y_scale = 2.0};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_color Cell comments: color
|
||||
|
||||
The `color` 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.
|
||||
|
||||
@code
|
||||
lxw_comment_options options1 = {.color = LXW_COLOR_GREEN};
|
||||
lxw_comment_options options2 = {.color = 0xFF6600};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options1);
|
||||
worksheet_write_comment_opt(worksheet, CELL("C7"), "Hello", &options2);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_comments_font_name Cell comments: font_name
|
||||
|
||||
The `font_name` option is used to set the font for the comment:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.font_name = "Courier"};
|
||||
@endcode
|
||||
|
||||
The default font is 'Tahoma'.
|
||||
|
||||
|
||||
@subsection ww_comments_font_size Cell comments: font_size
|
||||
|
||||
The `font_size` option is used to set the font size for the comment:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.font_name = "Courier", .font_size = 10};
|
||||
@endcode
|
||||
|
||||
The default font size is 8.
|
||||
|
||||
|
||||
@subsection ww_comments_start_row Cell comments: start_row
|
||||
|
||||
The `start_row` 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 row is zero indexed:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.start_row = 3, .start_col = 4};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
See @ref ww_comments_notes
|
||||
|
||||
@subsection ww_comments_start_col Cell comments: start_col
|
||||
|
||||
The `start_col` option is used to set the column 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 column is zero indexed:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.start_row = 3, .start_col = 4};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
See @ref ww_comments_notes
|
||||
|
||||
@subsection ww_comments_x_offset Cell comments: x_offset
|
||||
|
||||
The `x_offset` option is used to change the x offset, in pixels, of a
|
||||
comment within a cell:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.x_offset = 30, .y_offset = 12};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
See @ref ww_comments_notes
|
||||
|
||||
@subsection ww_comments_y_offset Cell comments: y_offset
|
||||
|
||||
The `y_offset` option is used to change the y offset, in pixels, of a
|
||||
comment within a cell:
|
||||
|
||||
@code
|
||||
lxw_comment_options options = {.x_offset = 30, .y_offset = 12};
|
||||
|
||||
worksheet_write_comment_opt(worksheet, CELL("C6"), "Hello", &options);
|
||||
@endcode
|
||||
|
||||
See @ref ww_comments_notes
|
||||
|
||||
|
||||
@subsection ww_comments_notes Notes on scaling of cell comments
|
||||
|
||||
<b>Note on options that move a cell position:</b>
|
||||
|
||||
Excel only displays offset cell comments when they are displayed as
|
||||
`visible`. Excel does **not** display hidden cells as displaced when you mouse
|
||||
over them. Please note this when using options that adjust the position of the
|
||||
cell comment such as `start_row`, `start_col`, `x_offset` and `y_offset`.
|
||||
|
||||
<b>Note on row height and comments:</b>
|
||||
|
||||
If you specify the height of a row that contains a comment then libxlsxwriter
|
||||
will adjust the height of the comment to maintain the default or user
|
||||
specified dimensions. However, the height of a row can also be adjusted
|
||||
automatically by Excel if the text wrap property is set or large fonts are
|
||||
used in the cell. This means that the height of the row is unknown to the
|
||||
library at run time and thus the comment box is stretched with the row. Use
|
||||
the `worksheet_set_row()` function to specify the row height explicitly and
|
||||
avoid this problem. See Example 8 of @ref comments2.c.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Next: @ref working_with_memory
|
||||
|
||||
*/
|
||||
+1280
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,503 @@
|
||||
/**
|
||||
@page working_with_data_validation Working with Data Validation
|
||||
|
||||
@tableofcontents
|
||||
|
||||
|
||||
Data validation is a feature of Excel which allows restrictions to be placed
|
||||
on the data that a user enters in a cell and to display associated help and
|
||||
warning messages. It can also be used to restrict input to values in a drop
|
||||
down list.
|
||||
|
||||
A typical use case might be to restrict data in a cell to integer values in a
|
||||
certain range, to provide a help message to indicate the required value and to
|
||||
issue a warning if the input data doesn't meet the stated criteria. In
|
||||
`libxlsxwriter` this can be done as follows:
|
||||
|
||||
@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, CELL("B3"), data_validation);
|
||||
|
||||
@endcode
|
||||
|
||||
@image html data_validate1.png
|
||||
|
||||
If the user inputs a value that doesn't match the specified criteria an error
|
||||
message is displayed:
|
||||
|
||||
@image html data_validate4.png
|
||||
|
||||
|
||||
For more information on data validation see the Microsoft support article
|
||||
[Description and examples of data validation in Excel](http://support.microsoft.com/kb/211485).
|
||||
|
||||
The following sections describe how to use the
|
||||
`worksheet_data_validation_cell()` and `worksheet_data_validation_range()`
|
||||
functions and the various options of #lxw_data_validation.
|
||||
|
||||
|
||||
@section ww_data_validate_functions The data validation functions
|
||||
|
||||
|
||||
The `worksheet_data_validation_cell()` and `worksheet_data_validation_range()`
|
||||
functions are used to construct an Excel data validation.
|
||||
|
||||
The data validation can be applied to a single cell or a range of cells:
|
||||
|
||||
@code
|
||||
worksheet_data_validation_cell( worksheet, 2, 1, data_validation);
|
||||
worksheet_data_validation_range(worksheet, 2, 1, 4, 1, data_validation);
|
||||
|
||||
// Same as above using the CELL() and RANGE() macros.
|
||||
worksheet_data_validation_cell( worksheet, CELL("B3"), data_validation);
|
||||
worksheet_data_validation_range(worksheet, RANGE("B3:B5"), data_validation);
|
||||
|
||||
@endcode
|
||||
|
||||
The lxw_data_validation struct used in these functions is explained below.
|
||||
|
||||
|
||||
@section ww_data_validate_struct The lxw_data_validation struct
|
||||
|
||||
The lxw_data_validation struct is used to set the properties of a data
|
||||
validation. A typical usage would look something like this:
|
||||
|
||||
@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_GREATER_THAN;
|
||||
data_validation->value_number = 10;
|
||||
data_validation->show_input = LXW_VALIDATION_OFF;
|
||||
@endcode
|
||||
|
||||
This example shows the main properties of lxw_data_validation and Excel data
|
||||
validations:
|
||||
|
||||
- `validate`: The type of data to restrict the validation to. In this case it
|
||||
is whole numbers.
|
||||
|
||||
- `criteria`: The criteria by which the data will be evaluated. In this case
|
||||
whether the input is greater than a value.
|
||||
|
||||
- `value`: The value that the criteria applies to. This has several different
|
||||
versions for different types of data. This could also be a `minimum` and
|
||||
`maximum` value if the criteria used is a "BETWEEN" criteria. This is
|
||||
explained in the @ref ww_data_validate_value section below.
|
||||
|
||||
- Other options such as `show_input` or `input_message`. These parameters are
|
||||
explained in the @ref ww_data_validate_options section.
|
||||
|
||||
Note, in the examples in this document the `data_validation` variable is shown
|
||||
as dynamically allocated, however an address of a static or automatic variable
|
||||
could also be used. In these cases make sure that the struct members are
|
||||
initialized to zero before setting other parameters.
|
||||
|
||||
@subsection ww_data_validate_validate validate
|
||||
|
||||
The `validate` parameter is used to set the type of data that you wish to
|
||||
validate:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
@endcode
|
||||
|
||||
It is always required and it has no default value. In Excel the validate
|
||||
parameters are:
|
||||
|
||||
- Whole
|
||||
- Decimal
|
||||
- List
|
||||
- Date
|
||||
- Time
|
||||
- Text Length
|
||||
- Custom
|
||||
- Any
|
||||
|
||||
The equivalent parameters in libxlsxwriter are defined in
|
||||
#lxw_validation_types:
|
||||
|
||||
- #LXW_VALIDATION_TYPE_INTEGER: Restrict cell input to whole/integer numbers
|
||||
only.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_INTEGER_FORMULA: Restrict cell input to whole/integer
|
||||
numbers only, using a cell reference.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_DECIMAL: Restrict cell input to decimal numbers only.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_DECIMAL_FORMULA: Restrict cell input to decimal
|
||||
numbers only, using a cell reference.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_LIST: Restrict cell input to a list of strings in a
|
||||
dropdown.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_LIST_FORMULA: Restrict cell input to a list of strings
|
||||
in a dropdown, using a cell range.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_DATE: Restrict cell input to date values only, using a
|
||||
lxw_datetime type.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_DATE_FORMULA: Restrict cell input to date values only,
|
||||
using a cell reference.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_TIME: Restrict cell input to time values only, using a
|
||||
lxw_datetime type.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_TIME_FORMULA: Restrict cell input to time values only,
|
||||
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 input to strings of
|
||||
defined length, using a cell reference.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_CUSTOM_FORMULA: Restrict cell to input controlled by a
|
||||
custom formula that returns `TRUE/FALSE`.
|
||||
|
||||
- #LXW_VALIDATION_TYPE_ANY: Allow any type of input. Mainly only useful for
|
||||
pop-up messages.
|
||||
|
||||
|
||||
|
||||
@subsection ww_data_validate_criteria criteria
|
||||
|
||||
The `criteria` parameter is used to set the criteria by which the data in the
|
||||
cell is validated. It is almost always required except for the `list`,
|
||||
`custom` and `any` validate options. It has no default value:
|
||||
|
||||
@code
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
@endcode
|
||||
|
||||
|
||||
Allowable values are defined in #lxw_validation_criteria:
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_BETWEEN: Select data between two values.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_NOT_BETWEEN: Select data that is not between two values.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_EQUAL_TO: Select data equal to a value.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_NOT_EQUAL_TO: Select data not equal to a value.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_GREATER_THAN: Select data greater than a value.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_LESS_THAN: Select data less than a value.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_GREATER_THAN_OR_EQUAL_TO: Select data greater than or equal to a value.
|
||||
|
||||
- #LXW_VALIDATION_CRITERIA_LESS_THAN_OR_EQUAL_TO: Select data less than or equal to a value.
|
||||
|
||||
|
||||
The `list`, `custom` and `any` validate options don't require a
|
||||
`criteria`. If you specify one it will be ignored.
|
||||
|
||||
|
||||
@subsection ww_data_validate_value value, minimum, maximum
|
||||
|
||||
The `value` parameters are used to set the limiting value to which the
|
||||
`criteria` is applied. It is always required and it has no default
|
||||
value. There are different types of `value` parameter associated with
|
||||
different types of data. They are:
|
||||
|
||||
`value_number`:
|
||||
|
||||
The `value_number` parameter is used to set the limiting value
|
||||
to which the criteria is applied using a whole or decimal number. It is
|
||||
typically used with #LXW_VALIDATION_TYPE_INTEGER and
|
||||
#LXW_VALIDATION_TYPE_DECIMAL and #LXW_VALIDATION_TYPE_LENGTH.
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
data_validation->value_number = 0;
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_DECIMAL;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
data_validation->value_number = 10.5;
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LENGTH;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
data_validation->value_number = 3;
|
||||
@endcode
|
||||
|
||||
|
||||
`value_formula`:
|
||||
|
||||
The `value_formula` 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
|
||||
#lxw_validation_types types that end in `_FORMULA`:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER_FORMULA;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
data_validation->value_formula = "=E3";
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_TIME_FORMULA;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_EQUAL;
|
||||
data_validation->value_formula = "=H1";
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LIST_FORMULA;
|
||||
data_validation->value_formula = "=$E$4:$G$4";
|
||||
@endcode
|
||||
|
||||
`value_list`:
|
||||
|
||||
The `value_list` 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
|
||||
|
||||
Note, when using the #LXW_VALIDATION_TYPE_LIST validation with a list of
|
||||
strings, like in the last example above, Excel stores the strings internally
|
||||
as a Comma Separated Variable string. The total length for this string,
|
||||
including commas, cannot exceed the Excel limit of 255 characters. For longer
|
||||
sets of data you should use a range reference like the previous example above.
|
||||
|
||||
`value_datetime`:
|
||||
|
||||
The `value_datetime` parameter is used to set the limiting value to which the
|
||||
#LXW_VALIDATION_TYPE_DATE or #LXW_VALIDATION_TYPE_TIME criteria is applied
|
||||
using a #lxw_datetime struct:
|
||||
|
||||
@code
|
||||
lxw_datetime datetime1 = {2017, 9, 24, 0, 0, 0};
|
||||
lxw_datetime datetime2 = { 0, 0, 0, 12, 30, 0};
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_DATE;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_EQUAL;
|
||||
data_validation->value_datetime = datetime1;
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_TIME;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_EQUAL;
|
||||
data_validation->value_datetime = datetime2;
|
||||
@endcode
|
||||
|
||||
The `minimum` and `maximum` parameters are used to set the lower and upper
|
||||
limiting values when the `criteria` is either #LXW_VALIDATION_CRITERIA_BETWEEN
|
||||
or #LXW_VALIDATION_CRITERIA_NOT_BETWEEN. The parameters are:
|
||||
|
||||
- `minimum_number`
|
||||
- `minimum_formula`
|
||||
- `minimum_datetime`
|
||||
- `maximum_number`
|
||||
- `maximum_formula`
|
||||
- `maximum_datetime`
|
||||
|
||||
They are similar to the `value` parameters described above. For example:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 10;
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_NOT_BETWEEN;
|
||||
data_validation->minimum_formula = "=E3";
|
||||
data_validation->maximum_formula = "=F3";
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_DATE;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_datetime = datetime1;
|
||||
data_validation->maximum_datetime = datetime2;
|
||||
@endcode
|
||||
|
||||
@section ww_data_validate_options Data validation options
|
||||
|
||||
|
||||
@subsection ww_data_validate_ignore_blank ignore_blank
|
||||
|
||||
|
||||
The `ignore_blank` parameter is used to toggle on and off the 'Ignore blank'
|
||||
option in the Excel data validation dialog. When the option is on the data
|
||||
validation is not applied to blank data in the cell. It is on by default:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 10;
|
||||
data_validation->ignore_blank = LXW_VALIDATION_OFF;
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_data_validate_dropdown dropdown
|
||||
|
||||
The `dropdown` 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. It is on by default.
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LIST;
|
||||
data_validation->value_list = list;
|
||||
data_validation->dropdown = LXW_VALIDATION_OFF;
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_data_validate_input_title input_title
|
||||
|
||||
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 also displayed. See the `input_message`
|
||||
parameter below.
|
||||
|
||||
The maximum title length is 32 characters.
|
||||
|
||||
|
||||
@subsection ww_data_validate_input_message input_message
|
||||
|
||||
The `input_message` parameter is used to set the input message that is
|
||||
displayed when a cell is entered. It has no default value:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 100;
|
||||
data_validation->input_title = "Enter an integer:";
|
||||
data_validation->input_message = "between 1 and 100";
|
||||
@endcode
|
||||
|
||||
The input message generated from the above example is:
|
||||
|
||||
@image html data_validate3.png
|
||||
|
||||
The message can be split over several lines using newlines. The maximum message
|
||||
length is 255 characters.
|
||||
|
||||
|
||||
@subsection ww_data_validate_show_input show_input
|
||||
|
||||
The `show_input` 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`. It is on by default.
|
||||
|
||||
|
||||
@subsection ww_data_validate_error_title error_title
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@subsection ww_data_validate_error_message error_message
|
||||
|
||||
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". A non-default error message can be displayed as follows:
|
||||
|
||||
@code
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 100;
|
||||
data_validation->input_title = "Enter an integer:";
|
||||
data_validation->input_message = "between 1 and 100";
|
||||
data_validation->error_title = "Input value is not valid!";
|
||||
data_validation->error_message = "It should be an integer between 1 and 100";
|
||||
@endcode
|
||||
|
||||
Which give the following message:
|
||||
|
||||
@image html data_validate2.png
|
||||
|
||||
The message can be split over several lines using newlines. The maximum message
|
||||
length is 255 characters.
|
||||
|
||||
|
||||
@subsection ww_data_validate_error_type error_type
|
||||
|
||||
The `error_type` parameter is used to specify the type of error dialog that is
|
||||
displayed. There are 3 #lxw_validation_error_types options:
|
||||
|
||||
- #LXW_VALIDATION_ERROR_TYPE_STOP, the default.
|
||||
- #LXW_VALIDATION_ERROR_TYPE_WARNING
|
||||
- #LXW_VALIDATION_ERROR_TYPE_INFORMATION
|
||||
|
||||
@subsection ww_data_validate_show_error show_error
|
||||
|
||||
The `show_error` 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`. It is on by default.
|
||||
|
||||
@section ww_data_validate_examples Examples
|
||||
|
||||
@code
|
||||
// Restrict input to an integer between 1 and 10.
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 10;
|
||||
|
||||
// Restrict input to an integer not between 1 and 10 (using cell references).
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_NOT_BETWEEN;
|
||||
data_validation->minimum_formula = "=E3";
|
||||
data_validation->maximum_formula = "=F3";
|
||||
|
||||
// Restrict input to a decimal between 0.1 and 0.5.
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_DECIMAL;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 0.1;
|
||||
data_validation->maximum_number = 0.5;
|
||||
|
||||
// Select a value from a drop down list.
|
||||
char *list[] = {"open", "high", "close", NULL};
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LIST;
|
||||
data_validation->value_list = list;
|
||||
|
||||
// Select a value from a drop down list (using a cell range).
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LIST;
|
||||
data_validation->value_formula = "=$E$4:$G$4";
|
||||
|
||||
// Restrict input to a date between 1/1/2008 and 12/12/2008.
|
||||
lxw_datetime datetime1 = {2008, 1, 1, 0, 0, 0};
|
||||
lxw_datetime datetime2 = {2008, 12, 12, 0, 0, 0};
|
||||
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_DATE;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_datetime = datetime1;
|
||||
data_validation->maximum_datetime = datetime2;
|
||||
|
||||
// Restrict input to a string longer than 3 characters.
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_LENGTH;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_GREATER_THAN;
|
||||
data_validation->value_number = 3;
|
||||
|
||||
// Restrict input to a value if a formula is true.
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_CUSTOM_FORMULA;
|
||||
data_validation->value_formula = "=AND(F5=50,G5=60)";
|
||||
|
||||
// Display a custom info message when integer isn't between 1 and 100.
|
||||
data_validation->validate = LXW_VALIDATION_TYPE_INTEGER;
|
||||
data_validation->criteria = LXW_VALIDATION_CRITERIA_BETWEEN;
|
||||
data_validation->minimum_number = 1;
|
||||
data_validation->maximum_number = 100;
|
||||
data_validation->input_title = "Enter an integer:";
|
||||
data_validation->input_message = "between 1 and 100";
|
||||
data_validation->error_title = "Input value is not valid!";
|
||||
data_validation->error_message = "It should be an integer between 1 and 100";
|
||||
@endcode
|
||||
|
||||
For a full example see @ref data_validate.c.
|
||||
|
||||
Next: @ref working_with_conditional_formatting
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
@page working_with_dates Working with Dates and Times
|
||||
|
||||
@tableofcontents
|
||||
|
||||
Dates and times in Excel are represented by real numbers. For example a date
|
||||
that is displayed in Excel as "Jan 1 2013 12:00 PM" is stored as the number
|
||||
41275.5.
|
||||
|
||||
The integer part of the number stores the number of days since the
|
||||
epoch, which is generally 1900, and the fractional part stores the percentage
|
||||
of the day.
|
||||
|
||||
A date or time in Excel is just like any other number. To display the number
|
||||
as a date you must apply an Excel number format to it. Here is an example:
|
||||
|
||||
@dontinclude dates_and_times01.c
|
||||
@skip include
|
||||
@until return
|
||||
@until }
|
||||
|
||||
@image html date_example01.png
|
||||
|
||||
Some options for creating or converting dates to the correct format are shown
|
||||
below.
|
||||
|
||||
|
||||
@section ww_date_struct Writing datetimes with the lxw_datetime struct
|
||||
|
||||
To make working with dates and times a little easier the `libxlsxwriter`
|
||||
library provides the lxw_datetime struct and the `worksheet_write_datetime()`
|
||||
function.
|
||||
|
||||
The members of the lxw_datetime struct and the range of their values are:
|
||||
|
||||
Member | Value
|
||||
-------- | -----------
|
||||
year | 1900 - 9999
|
||||
month | 1 - 12
|
||||
day | 1 - 31
|
||||
hour | 0 - 23
|
||||
min | 0 - 59
|
||||
sec | 0 - 59.999
|
||||
|
||||
Dates in Excel do not support timezones and the maximum resolution of times is
|
||||
milliseconds.
|
||||
|
||||
If dates or times are required without the other you should initialize the
|
||||
unrequired values to `0`:
|
||||
|
||||
@code
|
||||
// Date and time.
|
||||
lxw_datetime datetime1 = {2014, 11, 25, 17, 45, 5.1};
|
||||
|
||||
// Date only.
|
||||
lxw_datetime datetime2 = {2014, 11, 25, 0, 0, 0};
|
||||
|
||||
// Time only.
|
||||
lxw_datetime datetime3 = {0, 0, 0, 17, 45, 5.1};
|
||||
@endcode
|
||||
|
||||
Using lxw_datetime and worksheet_write_datetime() the previous example can
|
||||
then be re-written as follows:
|
||||
|
||||
@dontinclude dates_and_times02.c
|
||||
@skip include
|
||||
@until return
|
||||
@until }
|
||||
|
||||
The output from this program is the same as the previous example.
|
||||
|
||||
@image html date_example02.png
|
||||
|
||||
|
||||
@section ww_date_unix Writing Unix datetimes
|
||||
|
||||
Another alternative when handling dates is [Unix
|
||||
Time](https://en.wikipedia.org/wiki/Unix_time) which is a common integer time
|
||||
format. It is defined as the number of seconds since the Unix epoch
|
||||
(1970-01-01 00:00 UTC).
|
||||
|
||||
The `worksheet_write_unixtime()` function can be used to write dates and times
|
||||
in this format. Negative values can also be used for dates prior to 1970:
|
||||
|
||||
@dontinclude dates_and_times03.c
|
||||
@skip include
|
||||
@until }
|
||||
|
||||
The output from this program is:
|
||||
|
||||
@image html date_example03.png
|
||||
|
||||
|
||||
@section ww_date_formats Date formatting
|
||||
|
||||
Dates can be formatted using any of the date formats supported by Excel. Here
|
||||
is a longer example that shows the same date in a several different formats:
|
||||
|
||||
@dontinclude dates_and_times04.c
|
||||
@skip include
|
||||
@until return
|
||||
@until }
|
||||
|
||||
@image html date_example04.png
|
||||
|
||||
To get date formats that show up in Excel as a "Date" or "Time" number
|
||||
category see @ref ww_formats_categories.
|
||||
|
||||
Next: @ref working_with_charts
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
@page working_with_formats Working with Formats
|
||||
|
||||
@tableofcontents
|
||||
|
||||
The main functions and properties used to add formatting to a cell are shown
|
||||
in @ref format.h "The Format object". This section provides some additional
|
||||
information about working with formats.
|
||||
|
||||
@section ww_formats_creating Creating and using a Format object
|
||||
|
||||
Formats are created by calling the workbook_add_format() method and properties
|
||||
as set using the various functions shown below:
|
||||
|
||||
@code
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
|
||||
format_set_bold(format);
|
||||
format_set_font_color(format, LXW_COLOR_RED);
|
||||
@endcode
|
||||
|
||||
|
||||
Once a Format object has been created and its properties have been
|
||||
set it can be passed as an argument to the `worksheet_write*()` methods as
|
||||
follows:
|
||||
|
||||
@code
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", format);
|
||||
worksheet_write_number(worksheet, 1, 0, 123.456, format);
|
||||
@endcode
|
||||
|
||||
Formats can also be passed to the worksheet `worksheet_set_row()` and
|
||||
`worksheet_set_column()` methods to define the default formatting properties
|
||||
for a row or column:
|
||||
|
||||
@code
|
||||
worksheet_set_row (worksheet, 2, format, NULL);
|
||||
worksheet_set_column(worksheet, 0, 20, format, NULL);
|
||||
@endcode
|
||||
|
||||
|
||||
@section ww_formats_properties Format methods and Format properties
|
||||
|
||||
The following table shows the Excel format categories and the equivalent
|
||||
`libxlsxwriter` Format function:
|
||||
|
||||
| Category | Description | Method Name |
|
||||
| :-------------- | :------------------- | :--------------------------- |
|
||||
| **Font** | Font type | format_set_font_name() |
|
||||
| ^ | Font size | format_set_font_size() |
|
||||
| ^ | Font color | format_set_font_color() |
|
||||
| ^ | Bold | format_set_bold() |
|
||||
| ^ | Italic | format_set_italic() |
|
||||
| ^ | Underline | format_set_underline() |
|
||||
| ^ | Strikeout | format_set_font_strikeout() |
|
||||
| ^ | Super/Subscript | format_set_font_script() |
|
||||
| **Number** | Numeric format | format_set_num_format() |
|
||||
| **Protection** | Unlock cells | format_set_unlocked() |
|
||||
| ^ | Hide formulas | format_set_hidden() |
|
||||
| **Alignment** | Horizontal align | format_set_align() |
|
||||
| ^ | Vertical align | format_set_align() |
|
||||
| ^ | Rotation | format_set_rotation() |
|
||||
| ^ | Text wrap | format_set_text_wrap() |
|
||||
| ^ | Indentation | format_set_indent() |
|
||||
| ^ | Shrink to fit | format_set_shrink() |
|
||||
| **Pattern** | Cell pattern | format_set_pattern() |
|
||||
| ^ | Background color | format_set_bg_color() |
|
||||
| ^ | Foreground color | format_set_fg_color() |
|
||||
| **Border** | Cell border | format_set_border() |
|
||||
| ^ | Bottom border | format_set_bottom() |
|
||||
| ^ | Top border | format_set_top() |
|
||||
| ^ | Left border | format_set_left() |
|
||||
| ^ | Right border | format_set_right() |
|
||||
| ^ | Border color | format_set_border_color() |
|
||||
| ^ | Bottom color | format_set_bottom_color() |
|
||||
| ^ | Top color | format_set_top_color() |
|
||||
| ^ | Left color | format_set_left_color() |
|
||||
| ^ | Right color | format_set_right_color() |
|
||||
|
||||
|
||||
@section ww_formats_colors Format Colors
|
||||
|
||||
Format property colors are specified using a Html style RGB integer value or a
|
||||
limited number of defined colors:
|
||||
@code
|
||||
format_set_font_color(format1, 0x3030E0);
|
||||
format_set_font_color(format2, LXW_COLOR_RED);
|
||||
@endcode
|
||||
|
||||
See see @ref working_with_colors for more details.
|
||||
|
||||
|
||||
@section ww_formats_default Format Defaults
|
||||
|
||||
The default Excel 2007+ cell format is Calibri 11 with all other properties
|
||||
off.
|
||||
|
||||
In general a format function call without an argument will turn a property on,
|
||||
for example:
|
||||
|
||||
@code
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
|
||||
format_set_bold(format);
|
||||
@endcode
|
||||
|
||||
@section ww_formats_reusing Modifying and Reusing Formats
|
||||
|
||||
Once a format has been created it can be used and reused in
|
||||
`worksheet_write*()` functions across any number of worksheets:
|
||||
|
||||
@code
|
||||
lxw_format *myformat1 = workbook_add_format(workbook);
|
||||
format_set_bold(myformat1);
|
||||
|
||||
worksheet_write_string(worksheet1, 1, 4, "Some text", myformat1);
|
||||
worksheet_write_string(worksheet2, 1, 4, "Some text", myformat1);
|
||||
@endcode
|
||||
|
||||
However, each unique cell format in an `libxlsxwriter` spreadsheet must have a
|
||||
corresponding Format object. It isn't possible to use a Format with a
|
||||
`worksheet_write*()` method and then redefine it for use at a later
|
||||
stage. This is because a Format is applied to a cell not in its current state
|
||||
but in its final state. Consider the following example:
|
||||
|
||||
@code
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
format_set_bold(format);
|
||||
|
||||
worksheet_write_string(worksheet, 0, 0, "Hello", format);
|
||||
|
||||
format_set_italic(format);
|
||||
|
||||
worksheet_write_string(worksheet, 1, 0, "World", format);
|
||||
@endcode
|
||||
|
||||
|
||||
Cell `(0, 0)` is assigned a format which with the font set to bold. However, the
|
||||
italic property is subsequently and used in cell `(1, 0)`. This has the effect
|
||||
of adding italic to any previous uses of `format`. The result in this case is
|
||||
that "Hello" and "World" will both appear as bold and italic.
|
||||
|
||||
|
||||
@section ww_formats_categories Number Format Categories
|
||||
|
||||
The `format_set_num_format()` function shown below, is used to set the number
|
||||
format for numbers used with `worksheet_write_number()`:
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("currency_format.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
lxw_format *currency_format = workbook_add_format(workbook);
|
||||
|
||||
format_set_num_format(currency_format, "$#,##0.00");
|
||||
|
||||
worksheet_write_number(worksheet, 0, 0, 1234.56, currency_format);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
If the number format you use is the same as one of Excel's built in number
|
||||
formats then it will have a number category such as "General", "Number",
|
||||
"Currency", "Accounting", "Date", "Time", "Percentage", "Fraction",
|
||||
"Scientific", "Text", "Special or "Custom". In the case of the example above
|
||||
the formatted output shows up as a Number category:
|
||||
|
||||
@image html currency_format1.png
|
||||
|
||||
If we wanted it to have a different category, such as Currency, then
|
||||
we would have to match the number format string with the number format used by
|
||||
Excel. The easiest way to do this is to open the Number Formatting dialog in
|
||||
Excel and set the format that you want:
|
||||
|
||||
@image html currency_format2.png
|
||||
|
||||
Then, while still in the dialog, change to Custom. The format displayed is the
|
||||
format used by Excel.
|
||||
|
||||
@image html currency_format3.png
|
||||
|
||||
If we put the format that we found (`"[$$-409]#,##0.00"`) into our previous
|
||||
example and rerun it we will get a number format in the Currency category:
|
||||
|
||||
@code
|
||||
include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("currency_format.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
lxw_format *currency_format = workbook_add_format(workbook);
|
||||
|
||||
format_set_num_format(currency_format, "[$$-409]#,##0.00");
|
||||
|
||||
worksheet_write_number(worksheet, 0, 0, 1234.56, currency_format);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here is the output:
|
||||
|
||||
@image html currency_format4.png
|
||||
|
||||
The same process can be used to find format strings for "Date" or
|
||||
"Accountancy" formats.
|
||||
|
||||
|
||||
|
||||
@section ww_formats_locale Number Formats in different locales
|
||||
|
||||
|
||||
As shown in the previous section the `format_set_num_format()` method is used
|
||||
to set the number format for libxlsxwriter formats. A common use case is to
|
||||
set a number format with a "grouping/thousands" separator and a "decimal"
|
||||
point:
|
||||
|
||||
@code
|
||||
include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("number_format.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
lxw_format *number_format = workbook_add_format(workbook);
|
||||
|
||||
format_set_num_format(number_format, "#,##0.00");
|
||||
|
||||
worksheet_write_number(worksheet, 0, 0, 1234.56, number_format);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
In the US locale (and some others) where the number "grouping/thousands"
|
||||
separator is "," and the "decimal" point is "." this would be shown in Excel
|
||||
as:
|
||||
|
||||
@image html currency_format5.png
|
||||
|
||||
In other locales these values may be reversed or different. They are generally
|
||||
set in the "Region" settings of Windows or Mac OS. Excel handles this by
|
||||
storing the number format in the file format in the US locale, in this case
|
||||
`#,##0.00`, but renders it according to the regional settings of the host
|
||||
OS. For example, here is the same, unmodified, output file shown above in a
|
||||
German locale:
|
||||
|
||||
@image html currency_format6.png
|
||||
|
||||
And here is the same file in a Russian locale. Note the use of a space as the
|
||||
"grouping/thousands" separator:
|
||||
|
||||
@image html currency_format7.png
|
||||
|
||||
In order to replicate Excel's behavior all XlsxWriter programs should use US
|
||||
locale formatting which will then be rendered in the settings of your host OS.
|
||||
|
||||
Next: @ref working_with_colors
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,528 @@
|
||||
/**
|
||||
@page working_with_formulas Working with Formulas
|
||||
|
||||
@tableofcontents
|
||||
|
||||
|
||||
In general a formula in Excel can be used directly in the
|
||||
worksheet_write_formula() function:
|
||||
|
||||
@code
|
||||
worksheet_write_formula(worksheet, 0, 0, "=10*B1 + C1", NULL);
|
||||
@endcode
|
||||
|
||||
@image html working_with_formulas1.png
|
||||
|
||||
However, there are a few potential issues and differences that the user should
|
||||
be aware of. These are explained in the following sections.
|
||||
|
||||
|
||||
@section ww_formulas_results Formula Results
|
||||
|
||||
Libxlsxwriter doesn't calculate the result 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 will only display the 0
|
||||
results. Examples of such applications are Excel Viewer, PDF Converters, and
|
||||
some mobile device applications.
|
||||
|
||||
If required, it is also possible to specify the calculated result of the
|
||||
formula using the `result` parameter for
|
||||
`worksheet_worksheet_write_formula_num()`:
|
||||
|
||||
|
||||
@code
|
||||
worksheet_write_formula_num(worksheet, 0, 0, "=2+2", NULL, 4);
|
||||
@endcode
|
||||
|
||||
@section ww_formulas_non_us Non US Excel functions and syntax
|
||||
|
||||
Excel stores formulas in the format of the US English version, regardless
|
||||
of the language or locale of the end-user's version of Excel. Therefore all
|
||||
formula function names written using libxlsxwriter must be in English:
|
||||
|
||||
@code
|
||||
// The following formula syntax is okay.
|
||||
worksheet_write_formula(worksheet, 0, 0, "=SUM(1, 2, 3)", NULL);
|
||||
|
||||
// The following formula syntax is in French. Will cause error on load.
|
||||
worksheet_write_formula(worksheet, 0, 1, "=SOMME(1, 2, 3)", NULL);
|
||||
@endcode
|
||||
|
||||
Also, 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
|
||||
// The following formula syntax is okay.
|
||||
worksheet_write_formula(worksheet, 0, 0, "=SUM(1, 2, 3)", NULL);
|
||||
|
||||
// The following formula use semi-colons. Will cause error on load.
|
||||
worksheet_write_formula(worksheet, 0, 1, "=SUM(1; 2; 3)", NULL);
|
||||
@endcode
|
||||
|
||||
If you have a non-English version of Excel you can use the following
|
||||
multi-lingual [Formula Translator](http://en.excel-translator.de/language/)
|
||||
to help you convert the formula. It can also replace semi-colons with commas.
|
||||
|
||||
|
||||
|
||||
|
||||
@section ww_formulas_dynamic_arrays Dynamic Array support
|
||||
|
||||
Excel introduced the concept of "Dynamic Arrays" and new functions that use
|
||||
them in Office 365. The new functions are:
|
||||
|
||||
- `FILTER`
|
||||
- `RANDARRAY`
|
||||
- `SEQUENCE`
|
||||
- `SORTBY`
|
||||
- `SORT`
|
||||
- `UNIQUE`
|
||||
- `XLOOKUP`
|
||||
- `XMATCH`
|
||||
|
||||
The following special case functions were also added with Dynamic Arrays:
|
||||
|
||||
- `SINGLE`: Explained below in @ref ww_formulas_intersection.
|
||||
- `ANCHORARRAY`: Explained below in @ref ww_formulas_spill.
|
||||
- `LAMBDA` and `LET`: Explained below in @ref ww_formulas_lambda.
|
||||
|
||||
These functions are all "future functions" and need to written in
|
||||
libxlsxwriter as follows:
|
||||
|
||||
- `_xlfn.ANCHORARRAY`
|
||||
- `_xlfn.LAMBDA`
|
||||
- `_xlfn.RANDARRAY`
|
||||
- `_xlfn.SEQUENCE`
|
||||
- `_xlfn.SINGLE`
|
||||
- `_xlfn.SORTBY`
|
||||
- `_xlfn.UNIQUE`
|
||||
- `_xlfn.XLOOKUP`
|
||||
- `_xlfn.XMATCH`
|
||||
- `_xlfn._xlws.FILTER`
|
||||
- `_xlfn._xlws.SORT`
|
||||
|
||||
Future functions are explained in the section below on @ref
|
||||
ww_formulas_future.
|
||||
|
||||
@subsection ww_formulas_intro Dynamic Arrays - An introduction
|
||||
|
||||
Dynamic arrays in Excel are ranges of return values that can change in size
|
||||
based on the results. For example, a function such as `FILTER()` returns an
|
||||
array of values that can vary in size depending on the the filter results:
|
||||
|
||||
@code
|
||||
worksheet_write_dynamic_array_formula(worksheet, RANGE("F2:F2"),
|
||||
"=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
|
||||
NULL);
|
||||
@endcode
|
||||
|
||||
This formula gives the results shown in the image below. The dynamic range
|
||||
here is "F2:I5" but it can vary based on the filter criteria.
|
||||
|
||||
@image html dynamic_arrays02.png
|
||||
|
||||
|
||||
It is also possible to get dynamic array behavior with older Excel
|
||||
functions. For example, the Excel function `"=LEN(A1)"` applies to a single
|
||||
cell and returns a single value but it can also apply to a range of cells and
|
||||
return a range of values using an array formula like `"{=LEN(A1:A3)}"`. This
|
||||
type of "static" array behavior is referred to as a CSE (Ctrl+Shift+Enter)
|
||||
formula and has existed in Excel since early versions. In Office 365 Excel
|
||||
updated and extended this behavior to create the concept of dynamic arrays. In
|
||||
Excel 365 you can now write the previous LEN function as `"=LEN(A1:A3)"` and
|
||||
get a dynamic range of return values. In libxlsxwriter you can use the
|
||||
`worksheet_write_array_formula()` function to get a static/CSE range and
|
||||
`worksheet_write_dynamic_array_formula()` to get a dynamic range. For example:
|
||||
|
||||
@code
|
||||
worksheet_write_dynamic_array_formula(worksheet, RANGE("B1:B3"),
|
||||
"=LEN(A1:A3)",
|
||||
NULL);
|
||||
@endcode
|
||||
|
||||
Which gives the following result:
|
||||
|
||||
@image html intersection03.png
|
||||
|
||||
The difference between the two types of array functions is explained in the
|
||||
Microsoft documentation on [Dynamic array formulas vs. legacy CSE array
|
||||
formulas](https://support.microsoft.com/en-us/office/dynamic-array-formulas-vs-legacy-cse-array-formulas-ca421f1b-fbb2-4c99-9924-df571bd4f1b4). Note
|
||||
the use of the word "legacy" here. This, and the documentation itself, is a
|
||||
clear indication of the future importance of dynamic arrays in Excel.
|
||||
|
||||
For a wider and more general introduction to dynamic arrays see the following:
|
||||
[Dynamic array formulas in Excel](https://exceljet.net/dynamic-array-formulas-in-excel).
|
||||
|
||||
The `worksheet_write_dynamic_array_formula()` function takes a `(first_row,
|
||||
first_col, last_row, last_col)` cell range to define the area that the formula
|
||||
applies to. However, since the range is dynamic this generally won't be known
|
||||
in advance in which case you can specify the range with the same start and end
|
||||
cell. The following range is "F2:F2":
|
||||
|
||||
@code
|
||||
worksheet_write_dynamic_array_formula(worksheet, 1, 5, 1, 5,
|
||||
"=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
|
||||
NULL);
|
||||
@endcode
|
||||
|
||||
As a syntactic shortcut you can use the `worksheet_write_dynamic_formula()`
|
||||
function which only requires the start cell:
|
||||
|
||||
@code
|
||||
worksheet_write_dynamic_formula(worksheet, 1, 5,
|
||||
"=_xlfn._xlws.FILTER(A1:D17,C1:C17=K2)",
|
||||
NULL);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_formulas_intersection Dynamic Arrays - The Implicit Intersection Operator "@"
|
||||
|
||||
The Implicit Intersection Operator, "@", is used by Excel 365 to indicate a
|
||||
position in a formula that is implicitly returning a single value when a range
|
||||
or an array could be returned.
|
||||
|
||||
We can see how this operator works in practice by considering the formula we
|
||||
used in the last section: `=LEN(A1:A3)`. In Excel versions without support for
|
||||
dynamic arrays, i.e. prior to Excel 365, this formula would operate on a
|
||||
single value from the input range and return a single value, like the
|
||||
following in Excel 2011:
|
||||
|
||||
@image html intersection01.png
|
||||
|
||||
There is an implicit conversion here of the range of input values, "A1:A3", to
|
||||
a single value "A1". Since this was the default behavior of older versions of
|
||||
Excel this conversion isn't highlighted in any way. But if you open the same
|
||||
file in Excel 365 it will appear as follows:
|
||||
|
||||
@image html intersection02.png
|
||||
|
||||
The result of the formula is the same (this is important to note) and it still
|
||||
operates on, and returns, a single value. However the formula now contains a
|
||||
"@" operator to show that it is implicitly using a single value from the given
|
||||
range.
|
||||
|
||||
Finally, if you entered this formula in Excel 365, or with
|
||||
`worksheet_write_dynamic_array_formula()` in libxlsxwriter, it would operate
|
||||
on the entire range and return an array of values:
|
||||
|
||||
@image html intersection03.png
|
||||
|
||||
If you are encountering the Implicit Intersection Operator "@" for the first
|
||||
time then it is probably from a point of view of "why is Excel/libxlsxwriter
|
||||
putting @s in my formulas". In practical terms if you encounter this operator,
|
||||
and you don't intend it to be there, then you should probably write the
|
||||
formula as a CSE or dynamic array function using
|
||||
`worksheet_write_array_formula()` or `worksheet_write_dynamic_array_formula()`.
|
||||
|
||||
|
||||
A full explanation of this operator is shown in the Microsoft documentation on
|
||||
the [Implicit intersection operator: \@]
|
||||
(https://support.microsoft.com/en-us/office/implicit-intersection-operator-ce3be07b-0101-4450-a24e-c1c999be2b34?ui=en-us&rs=en-us&ad=us>).
|
||||
|
||||
One important thing to note is that the "@" operator isn't stored with the
|
||||
formula. It is just displayed by Excel 365 when reading "legacy"
|
||||
formulas. However, it is possible to write it to a formula, if necessary,
|
||||
using `_xlfn.SINGLE()`. The unusual cases where this may be necessary are
|
||||
shown in the linked document in the previous paragraph.
|
||||
|
||||
|
||||
@subsection ww_formulas_spill Dynamic Arrays - The Spilled Range Operator "#"
|
||||
|
||||
In the section above on @ref ww_formulas_intro we saw that dynamic array formulas
|
||||
can return variable sized ranges of results. The Excel documentation refers to
|
||||
this as a "Spilled" range/array from the idea that the results spill into the
|
||||
required number of cells. This is explained in the Microsoft documentation on
|
||||
[Dynamic array formulas and spilled array behavior]
|
||||
(https://support.microsoft.com/en-us/office/dynamic-array-formulas-and-spilled-array-behavior-205c6b06-03ba-4151-89a1-87a7eb36e531).
|
||||
|
||||
Since a spilled range is variable in size a new operator is required to refer
|
||||
to the range. This operator is the [Spilled range operator]
|
||||
(https://support.microsoft.com/en-us/office/spilled-range-operator-3dd5899f-bca2-4b9d-a172-3eae9ac22efd)
|
||||
and it is represented by "#". For example, the range `F2#` in the image
|
||||
below is used to refer to a dynamic array returned by `UNIQUE()` in the cell
|
||||
`F2`:
|
||||
|
||||
@image html spill01.png
|
||||
|
||||
Unfortunately, Excel doesn't store the formula like this and in libxlsxwriter
|
||||
you need to use the explicit function `_xlfn.ANCHORARRAY()` to refer to a
|
||||
spilled range. The example in the image above was generated using the
|
||||
following:
|
||||
|
||||
@code
|
||||
// Same as '=COUNTA(F2#)' in Excel.
|
||||
worksheet_write_dynamic_formula(worksheet9, CELL("J2"),
|
||||
"=COUNTA(_xlfn.ANCHORARRAY(F2))",
|
||||
NULL);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_formulas_lambda The Excel 365 LAMBDA() function
|
||||
|
||||
Recent versions of Excel 365 have introduced a powerful new
|
||||
function/feature called `LAMBDA()`. This is similar to
|
||||
[lambda expressions]
|
||||
(https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160)
|
||||
in C++ (and other languages).
|
||||
|
||||
Consider the following Excel example which converts the variable `temp` from Fahrenheit to Celsius:
|
||||
|
||||
LAMBDA(temp, (5/9) * (temp-32))
|
||||
|
||||
This could be called in Excel with an argument:
|
||||
|
||||
=LAMBDA(temp, (5/9) * (temp-32))(212)
|
||||
|
||||
Or assigned to a defined name and called as a user defined function:
|
||||
|
||||
=ToCelsius(212)
|
||||
|
||||
|
||||
An libxlsxwriter example that replicates the described Excel functionality is
|
||||
shown below:
|
||||
|
||||
@code
|
||||
// Write the lambda as a function.
|
||||
worksheet_write_dynamic_formula(worksheet, CELL("A2"),
|
||||
"=_xlfn.LAMBDA(_xlpm.temp, (5/9) * (_xlpm.temp-32))(32)",
|
||||
NULL);
|
||||
|
||||
// Create the lambda function as a defined name and write it as a dynamic formula.
|
||||
workbook_define_name(workbook,
|
||||
"ToCelsius",
|
||||
"=_xlfn.LAMBDA(_xlpm.temp, (5/9) * (_xlpm.temp-32))");
|
||||
|
||||
worksheet_write_dynamic_formula(worksheet, CELL("A3"), "=ToCelsius(212)", NULL);
|
||||
@endcode
|
||||
|
||||
Note, that the formula name must have a "_xlfn." prefix and the parameters in
|
||||
the `LAMBDA()` function must have a "_xlpm." prefix for compatibility with
|
||||
how the formulas are stored in Excel. These prefixes won't show up in the
|
||||
formula, as shown in the image.
|
||||
|
||||
@image html lambda01.png
|
||||
|
||||
The `LET()` function is often used in conjunction with `LAMBDA()` to assign
|
||||
names to calculation results.
|
||||
|
||||
@section ww_formulas_future Formulas added in Excel 2010 and later
|
||||
|
||||
|
||||
Excel 2010 and later versions added functions which weren't defined in the
|
||||
original file specification. These functions are referred to by Microsoft as
|
||||
"Future Functions". Examples of these functions are `ACOT`, `CHISQ.DIST.RT` ,
|
||||
`CONFIDENCE.NORM`, `STDEV.P`, `STDEV.S` and `WORKDAY.INTL`.
|
||||
|
||||
When written using `worksheet_write_formula()` these functions need to be
|
||||
fully qualified with a `_xlfn.` (or other) prefix as they are shown the list
|
||||
below. For example:
|
||||
|
||||
@code
|
||||
worksheet_write_formula(worksheet, 0, 0, "=_xlfn.STDEV.S(B1:B10)", NULL);
|
||||
@endcode
|
||||
|
||||
They will appear without the prefix in Excel:
|
||||
|
||||
@image html working_with_formulas2.png
|
||||
|
||||
The following list is taken from
|
||||
[MS XLSX extensions documentation on future functions](http://msdn.microsoft.com/en-us/library/dd907480%28v=office.12%29.aspx).
|
||||
|
||||
|
||||
| Future Functions |
|
||||
| -------------------------------- |
|
||||
| `_xlfn.ACOT` |
|
||||
| `_xlfn.ACOTH` |
|
||||
| `_xlfn.AGGREGATE` |
|
||||
| `_xlfn.ARABIC` |
|
||||
| `_xlfn.BASE` |
|
||||
| `_xlfn.BETA.DIST` |
|
||||
| `_xlfn.BETA.INV` |
|
||||
| `_xlfn.BINOM.DIST` |
|
||||
| `_xlfn.BINOM.DIST.RANGE` |
|
||||
| `_xlfn.BINOM.INV` |
|
||||
| `_xlfn.BITAND` |
|
||||
| `_xlfn.BITLSHIFT` |
|
||||
| `_xlfn.BITOR` |
|
||||
| `_xlfn.BITRSHIFT` |
|
||||
| `_xlfn.BITXOR` |
|
||||
| `_xlfn.CEILING.MATH` |
|
||||
| `_xlfn.CEILING.PRECISE` |
|
||||
| `_xlfn.CHISQ.DIST` |
|
||||
| `_xlfn.CHISQ.DIST.RT` |
|
||||
| `_xlfn.CHISQ.INV` |
|
||||
| `_xlfn.CHISQ.INV.RT` |
|
||||
| `_xlfn.CHISQ.TEST` |
|
||||
| `_xlfn.COMBINA` |
|
||||
| `_xlfn.CONCAT` |
|
||||
| `_xlfn.CONFIDENCE.NORM` |
|
||||
| `_xlfn.CONFIDENCE.T` |
|
||||
| `_xlfn.COT` |
|
||||
| `_xlfn.COTH` |
|
||||
| `_xlfn.COVARIANCE.P` |
|
||||
| `_xlfn.COVARIANCE.S` |
|
||||
| `_xlfn.CSC` |
|
||||
| `_xlfn.CSCH` |
|
||||
| `_xlfn.DAYS` |
|
||||
| `_xlfn.DECIMAL` |
|
||||
| `ECMA.CEILING` |
|
||||
| `_xlfn.ERF.PRECISE` |
|
||||
| `_xlfn.ERFC.PRECISE` |
|
||||
| `_xlfn.EXPON.DIST` |
|
||||
| `_xlfn.F.DIST` |
|
||||
| `_xlfn.F.DIST.RT` |
|
||||
| `_xlfn.F.INV` |
|
||||
| `_xlfn.F.INV.RT` |
|
||||
| `_xlfn.F.TEST` |
|
||||
| `_xlfn.FILTERXML` |
|
||||
| `_xlfn.FLOOR.MATH` |
|
||||
| `_xlfn.FLOOR.PRECISE` |
|
||||
| `_xlfn.FORECAST.ETS` |
|
||||
| `_xlfn.FORECAST.ETS.CONFINT` |
|
||||
| `_xlfn.FORECAST.ETS.SEASONALITY` |
|
||||
| `_xlfn.FORECAST.ETS.STAT` |
|
||||
| `_xlfn.FORECAST.LINEAR` |
|
||||
| `_xlfn.FORMULATEXT` |
|
||||
| `_xlfn.GAMMA` |
|
||||
| `_xlfn.GAMMA.DIST` |
|
||||
| `_xlfn.GAMMA.INV` |
|
||||
| `_xlfn.GAMMALN.PRECISE` |
|
||||
| `_xlfn.GAUSS` |
|
||||
| `_xlfn.HYPGEOM.DIST` |
|
||||
| `_xlfn.IFNA` |
|
||||
| `_xlfn.IFS` |
|
||||
| `_xlfn.IMCOSH` |
|
||||
| `_xlfn.IMCOT` |
|
||||
| `_xlfn.IMCSC` |
|
||||
| `_xlfn.IMCSCH` |
|
||||
| `_xlfn.IMSEC` |
|
||||
| `_xlfn.IMSECH` |
|
||||
| `_xlfn.IMSINH` |
|
||||
| `_xlfn.IMTAN` |
|
||||
| `_xlfn.ISFORMULA` |
|
||||
| `ISO.CEILING` |
|
||||
| `_xlfn.ISOWEEKNUM` |
|
||||
| `_xlfn.LOGNORM.DIST` |
|
||||
| `_xlfn.LOGNORM.INV` |
|
||||
| `_xlfn.MAXIFS` |
|
||||
| `_xlfn.MINIFS` |
|
||||
| `_xlfn.MODE.MULT` |
|
||||
| `_xlfn.MODE.SNGL` |
|
||||
| `_xlfn.MUNIT` |
|
||||
| `_xlfn.NEGBINOM.DIST` |
|
||||
| `NETWORKDAYS.INTL` |
|
||||
| `_xlfn.NORM.DIST` |
|
||||
| `_xlfn.NORM.INV` |
|
||||
| `_xlfn.NORM.S.DIST` |
|
||||
| `_xlfn.NORM.S.INV` |
|
||||
| `_xlfn.NUMBERVALUE` |
|
||||
| `_xlfn.PDURATION` |
|
||||
| `_xlfn.PERCENTILE.EXC` |
|
||||
| `_xlfn.PERCENTILE.INC` |
|
||||
| `_xlfn.PERCENTRANK.EXC` |
|
||||
| `_xlfn.PERCENTRANK.INC` |
|
||||
| `_xlfn.PERMUTATIONA` |
|
||||
| `_xlfn.PHI` |
|
||||
| `_xlfn.POISSON.DIST` |
|
||||
| `_xlfn.QUARTILE.EXC` |
|
||||
| `_xlfn.QUARTILE.INC` |
|
||||
| `_xlfn.QUERYSTRING` |
|
||||
| `_xlfn.RANK.AVG` |
|
||||
| `_xlfn.RANK.EQ` |
|
||||
| `_xlfn.RRI` |
|
||||
| `_xlfn.SEC` |
|
||||
| `_xlfn.SECH` |
|
||||
| `_xlfn.SHEET` |
|
||||
| `_xlfn.SHEETS` |
|
||||
| `_xlfn.SKEW.P` |
|
||||
| `_xlfn.STDEV.P` |
|
||||
| `_xlfn.STDEV.S` |
|
||||
| `_xlfn.SWITCH` |
|
||||
| `_xlfn.T.DIST` |
|
||||
| `_xlfn.T.DIST.2T` |
|
||||
| `_xlfn.T.DIST.RT` |
|
||||
| `_xlfn.T.INV` |
|
||||
| `_xlfn.T.INV.2T` |
|
||||
| `_xlfn.T.TEST` |
|
||||
| `_xlfn.TEXTJOIN` |
|
||||
| `_xlfn.UNICHAR` |
|
||||
| `_xlfn.UNICODE` |
|
||||
| `_xlfn.VAR.P` |
|
||||
| `_xlfn.VAR.S` |
|
||||
| `_xlfn.WEBSERVICE` |
|
||||
| `_xlfn.WEIBULL.DIST` |
|
||||
| `WORKDAY.INTL` |
|
||||
| `_xlfn.XOR` |
|
||||
| `_xlfn.Z.TEST` |
|
||||
|
||||
|
||||
The dynamic array functions shown in the @ref ww_formulas_dynamic_arrays
|
||||
section above are also future functions:
|
||||
|
||||
|
||||
| Dynamic Array Functions |
|
||||
| -------------------------------- |
|
||||
| `_xlfn.ANCHORARRAY` |
|
||||
| `_xlfn.LAMBDA` |
|
||||
| `_xlfn.RANDARRAY` |
|
||||
| `_xlfn.SEQUENCE` |
|
||||
| `_xlfn.SINGLE` |
|
||||
| `_xlfn.SORTBY` |
|
||||
| `_xlfn.UNIQUE` |
|
||||
| `_xlfn.XLOOKUP` |
|
||||
| `_xlfn.XMATCH` |
|
||||
| `_xlfn._xlws.FILTER` |
|
||||
| `_xlfn._xlws.SORT` |
|
||||
|
||||
|
||||
@section ww_formulas_errors Dealing with formula errors
|
||||
|
||||
If there is an error in the syntax of a formula it is usually displayed in
|
||||
Excel as @c \#NAME?. Alternatively you may get a warning from Excel when the
|
||||
file is loaded. If you encounter an error like this you can debug it as
|
||||
follows:
|
||||
|
||||
1. Ensure the formula is valid in Excel by copying and pasting it into a
|
||||
cell. Note, this should be done in Excel and @b not other applications
|
||||
such as OpenOffice or LibreOffice since they may have slightly different
|
||||
syntax.
|
||||
|
||||
2. Ensure the formula is using comma separators instead of semi-colons, see
|
||||
@ref ww_formulas_non_us above.
|
||||
|
||||
3. Ensure the formula is in English, see @ref ww_formulas_non_us above.
|
||||
|
||||
4. Ensure that the formula doesn't contain an Excel 2010+ future function as
|
||||
listed above (@ref ww_formulas_future). If it does then ensure that the
|
||||
correct prefix is used.
|
||||
|
||||
5. If the function loads in Excel but appears with one or more ``@`` symbols
|
||||
added then it is probably an array function and should be written using
|
||||
`worksheet_write_array_formula()` or
|
||||
`worksheet_write_dynamic_array_formula()` (see the sections above on @ref
|
||||
ww_formulas_dynamic_arrays and @ref ww_formulas_intersection).
|
||||
|
||||
|
||||
Finally if you have completed all the previous steps and still get a
|
||||
@c \#NAME? error you can examine a valid Excel file to see what the correct
|
||||
syntax should be. To do this you should create a valid formula in Excel and
|
||||
save the file. You can then examine the XML in the unzipped file.
|
||||
|
||||
The following shows how to do that using Linux `unzip` and `libxml's
|
||||
[xmllint](http://xmlsoft.org/xmllint.html) to format the XML for clarity:
|
||||
|
||||
$ unzip myfile.xlsx -d myfile
|
||||
$ xmllint --format myfile/xl/worksheets/sheet1.xml | grep '</f>'
|
||||
|
||||
<f>SUM(1, 2, 3)</f>
|
||||
|
||||
|
||||
Next: @ref working_with_dates
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
@page working_with_macros Working with VBA Macros
|
||||
|
||||
@tableofcontents
|
||||
|
||||
This section explains how to add a VBA file containing functions or macros to
|
||||
an libxlsxwriter workbook.
|
||||
|
||||
@dontinclude macro.c
|
||||
@skipline include
|
||||
@until return
|
||||
@skipline }
|
||||
|
||||
|
||||
@image html macros.png
|
||||
|
||||
@section ww_macros_xlsm_format The Excel XLSM file format
|
||||
|
||||
An Excel `xlsm` file is exactly the same as an `xlsx` file except that is
|
||||
contains an additional `vbaProject.bin` file which contains functions and/or
|
||||
macros. Excel uses a different extension to differentiate between the two file
|
||||
formats since files containing macros are usually subject to additional
|
||||
security checks.
|
||||
|
||||
|
||||
@section ww_macros_include How VBA macros are included in libxlsxwriter files
|
||||
|
||||
The `vbaProject.bin` file is a binary OLE COM container. This was the format
|
||||
used in older `xls` versions of Excel prior to Excel 2007. Unlike all of the
|
||||
other components of an xlsx/xlsm file the data isn't stored in XML
|
||||
format. Instead the functions and macros as stored as a pre-parsed binary
|
||||
format. As such it wouldn't be feasible to define macros and create a
|
||||
`vbaProject.bin` file from scratch (at least not in the remaining lifespan and
|
||||
interest levels of the author).
|
||||
|
||||
Instead a workaround is used to extract `vbaProject.bin` files from existing
|
||||
xlsm files and then add these to libxlsxwriter generated files.
|
||||
|
||||
|
||||
@section ww_macros_extract The vba_extract.py utility
|
||||
|
||||
The `vba_extract.py` Python utility is used to extract the `vbaProject.bin`
|
||||
binary from an Excel 2007+ xlsm file. The utility is included in the
|
||||
libxlsxwriter examples directory:
|
||||
|
||||
$ python examples/vba_extract.py macro_file.xlsm
|
||||
Extracted: vbaProject.bin
|
||||
|
||||
You can also install `vba_extract.py` into your system path by installing the
|
||||
Python xlsxwriter module:
|
||||
|
||||
$ pip install xlsxwriter
|
||||
...
|
||||
$ vba_extract.py
|
||||
Utility to extract a vbaProject.bin binary from an
|
||||
Excel 2007+ xlsm macro file ...
|
||||
|
||||
|
||||
@section ww_macros_adding Adding the VBA macros to a libxlsxwriter file
|
||||
|
||||
Once the `vbaProject.bin` file has been extracted it can be added to the
|
||||
libxlsxwriter workbook using the `workbook_add_vba_project()` function:
|
||||
|
||||
@code
|
||||
workbook_add_vba_project(workbook, "./vbaProject.bin");
|
||||
@endcode
|
||||
|
||||
@note The name doesn't have to be `vbaProject.bin`. Any suitable path/name for
|
||||
an existing VBA bin file will do.
|
||||
|
||||
If the VBA file contains functions you can then refer to them in calculations
|
||||
using `worksheet_write_formula()`:
|
||||
|
||||
@code
|
||||
worksheet_write_formula(0, 0, "=MyMortgageCalc(200000, 25)")
|
||||
@endcode
|
||||
|
||||
Excel files that contain functions and macros should use an `xlsm` extension
|
||||
or else Excel will complain and possibly not open the file:
|
||||
|
||||
@code
|
||||
lxw_workbook *workbook = new_workbook("macro.xlsm");
|
||||
@endcode
|
||||
|
||||
It is also possible to assign a macro to a button that is inserted into a
|
||||
worksheet using the `worksheet_insert_button()` function:
|
||||
|
||||
@code
|
||||
lxw_button_options options = {.caption = "Press Me",
|
||||
.macro = "say_hello"};
|
||||
|
||||
worksheet_insert_button(worksheet, 2, 1, &options);
|
||||
@endcode
|
||||
|
||||
See the full example at @ref macro.c.
|
||||
|
||||
It may be necessary to specify a more explicit macro name prefixed by the
|
||||
workbook VBA name as follows:
|
||||
|
||||
|
||||
@code
|
||||
lxw_button_options options = {.caption = "Press Me",
|
||||
.macro = "ThisWorkbook.say_hello"};
|
||||
|
||||
worksheet_insert_button(worksheet, 2, 1, &options);
|
||||
@endcode
|
||||
|
||||
@note Button is the only VBA Control supported by libxlsxwriter and due to the
|
||||
implementation effort required it is unlikely that any other form elements
|
||||
will be added in the future.
|
||||
|
||||
|
||||
@section ww_macros_codenames Setting the VBA codenames
|
||||
|
||||
VBA macros generally refer to workbook and worksheet objects. If the VBA
|
||||
codenames aren't specified explicitly then libxlsxwriter will use the Excel
|
||||
defaults of `ThisWorkbook` and `Sheet1`, `Sheet2` etc.
|
||||
|
||||
If the macro uses other codenames you can set them using the
|
||||
`workbook_set_vba_name()` and `worksheet_set_vba_name()` functions as follows:
|
||||
|
||||
@code
|
||||
// Set the VBA codenames for the workbook and any worksheets.
|
||||
workbook_set_vba_name (workbook, "MyWorkbook");
|
||||
worksheet_set_vba_name(worksheet, "MySheet1");
|
||||
worksheet_set_vba_name(worksheet, "MySheet2");
|
||||
@endcode
|
||||
|
||||
@note This step is particularly important for macros created with non-English
|
||||
versions of Excel.
|
||||
|
||||
You can find the names that are used in the VBA editor or by unzipping the
|
||||
`xlsm` file and grepping the files. The following shows how to do that using
|
||||
[libxml's xmllint](http://xmlsoft.org/xmllint.html) to format the XML for
|
||||
clarity:
|
||||
|
||||
$ unzip myfile.xlsm -d myfile
|
||||
$ xmllint --format `find myfile -name "*.xml" | xargs` | grep "Pr.*codeName"
|
||||
|
||||
<workbookPr codeName="MyWorkbook" defaultThemeVersion="124226"/>
|
||||
<sheetPr codeName="MySheet1"/>
|
||||
|
||||
@note This step is particularly important for macros created with non-English
|
||||
versions of Excel.
|
||||
|
||||
@section ww_macros_debugging What to do if it doesn't work
|
||||
|
||||
The libxlsxwriter test suite contains several tests to ensure that this feature
|
||||
works and there is a working example as shown above. However, there is no
|
||||
guarantee that it will work in all cases. Some effort may be required and some
|
||||
knowledge of VBA will certainly help. If things don't work out here are some
|
||||
things to try:
|
||||
|
||||
1. Start with a simple macro file, ensure that it works and then add complexity.
|
||||
|
||||
2. Check the code names that macros use to refer to the workbook and
|
||||
worksheets (see the previous section above). In general VBA uses a code
|
||||
name of `ThisWorkbook` to refer to the current workbook and the sheet name
|
||||
(such as `Sheet1`) to refer to the worksheets. These are the defaults used
|
||||
by libxlsxwriter. If the macro uses other names, or the macro was extracted
|
||||
from an non-English language version of Excel, then you can specify the
|
||||
appropriate names using the `workbook_set_vba_name()` and
|
||||
`worksheet_set_vba_name()` functions:
|
||||
@code
|
||||
// Set the VBA codenames for the workbook and any worksheets.
|
||||
workbook_set_vba_name (workbook, "MyWorkbook");
|
||||
worksheet_set_vba_name(worksheet, "MySheet1");
|
||||
worksheet_set_vba_name(worksheet, "MySheet2");
|
||||
@endcode
|
||||
|
||||
3. Try to extract the macros from an Excel 2007 file. The method should work
|
||||
with macros from later versions (it was also tested with Excel 2010
|
||||
macros). However there may be features in the macro files of more recent
|
||||
version of Excel that aren't backward compatible.
|
||||
|
||||
|
||||
Next: @ref examples
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
@page working_with_memory Working with Memory and Performance
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@section ww_mem_constant Constant Memory Mode
|
||||
|
||||
By default libxlsxwriter holds all cell data in memory to allow non-sequential
|
||||
data storage. The effect of this is that for large files libxlsxwriter can
|
||||
consume a lot of memory.
|
||||
|
||||
Fortunately, this memory usage can be reduced almost completely by using
|
||||
workbook_new_opt() and the lxw_workbook_options `constant_memory` property:
|
||||
|
||||
@dontinclude constant_memory.c
|
||||
@skipline include
|
||||
@until return
|
||||
@skipline }
|
||||
|
||||
This optimization works by flushing each row after a subsequent row is written.
|
||||
In this way the largest amount of data held in memory for a worksheet is the
|
||||
amount of data required to hold a single row of data.
|
||||
|
||||
If required, this memory usage can be reduced even more by setting
|
||||
`LXW_COL_MAX` in worksheet.c from 16384 down to a value that matches the
|
||||
maximum column that is likely to be encountered.
|
||||
|
||||
The trade-off when using `constant_memory` mode is that data must be added
|
||||
sequentially in row order and you won't be able to take advantage of any
|
||||
functions that manipulate cell data after it is written. For example:
|
||||
|
||||
- In `constant_memory` mode `worksheet_set_row()` can only be used when
|
||||
writing data to the current row. This has an additional knock on effect that
|
||||
images won't scale properly over row heights adjusted with
|
||||
`%worksheet_set_row()`.
|
||||
|
||||
- A merged range set with `worksheet_merge_range()` can only be applied to the
|
||||
current row (which in general isn't very useful).
|
||||
|
||||
@subsection ww_mem_row_order Row Column Order
|
||||
|
||||
Since each new row flushes the previous row, data must be written in sequential
|
||||
row order when `constant_memory` mode is on:
|
||||
|
||||
@code
|
||||
lxw_workbook *workbook = workbook_new_opt("constant_memory.xlsx", &options);
|
||||
...
|
||||
|
||||
// !! Don't use "column x row" order in 'constant_memory' mode. Only
|
||||
// the first column of data will be written.
|
||||
for (col = 0; col < max_col; col++) {
|
||||
for (row = 0; row < max_row; row++) {
|
||||
worksheet_write_number(worksheet, row, col, 123.45, NULL);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ww_mem_temp Constant memory mode and the /tmp directory
|
||||
|
||||
The libxlsxwriter library uses temporary files stored in the system `/tmp`
|
||||
directory prior to creating the final xlsx file. In `constant_memory` mode the
|
||||
library uses additional temporary file storage for worksheet data. This can
|
||||
lead to an issue on OSes that map the `/tmp` directory into memory since it is
|
||||
possible for a libxlsxwriter application to consume the "system" memory via
|
||||
disk usage even though the "process" memory remains constant.
|
||||
|
||||
This is generally only an issue with embedded Linux systems with limited
|
||||
amounts of system memory. In these cases you should use an alternative
|
||||
temporary file location by using the `tmpdir` option of #lxw_workbook_options
|
||||
and workbook_new_opt().
|
||||
|
||||
|
||||
@subsection ww_mem_inline_strings Inline strings
|
||||
|
||||
Another optimization that is used to reduce memory usage in `constant_memory`
|
||||
mode is that cell strings aren't stored in an Excel structure call "shared
|
||||
strings" and instead are written "in-line".
|
||||
|
||||
This is a documented Excel feature that is supported by most spreadsheet
|
||||
applications. However, it isn't supported by some some spreadsheet viewer
|
||||
applications. Also, the size of the output file can increase by 20%-100%
|
||||
depending on the amount of repeated string data.
|
||||
|
||||
|
||||
@section ww_mem_performance Performance
|
||||
|
||||
Currently the library is optimized but not highly optimized. Also, the library
|
||||
is currently single threaded.
|
||||
|
||||
Compiling with the embedded but option dtoa library is 40-50% faster for raw
|
||||
numeric data. See @ref gsg_dtoa.
|
||||
|
||||
Next: @ref working_with_macros
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
@page working_with_object_positioning Working with Object Positioning
|
||||
|
||||
Libxlsxwriter positions worksheet objects such as images and charts in
|
||||
worksheets by calculating precise co-ordinates based on the object size, it's
|
||||
DPI (for images) and any scaling that the user specifies. It also takes into
|
||||
account the heights and widths of the rows and columns that the object
|
||||
crosses. In this way objects maintain their original sizes even if the rows or
|
||||
columns underneath change size or are hidden.
|
||||
|
||||
For example:
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("images.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
// Original image.
|
||||
worksheet_insert_image(worksheet, CELL("B2"), "logo.png");
|
||||
|
||||
// Same as original, despite row/col changes.
|
||||
worksheet_insert_image(worksheet, CELL("E8"), "logo.png");
|
||||
|
||||
// Make column F narrower.
|
||||
worksheet_set_column(worksheet, COLS("F:F"), 2, NULL);
|
||||
|
||||
// Hide row 12 (zero indexed).
|
||||
lxw_row_col_options row_options = {.hidden = LXW_TRUE};
|
||||
worksheet_set_row_opt(worksheet, 11, LXW_DEF_ROW_HEIGHT, NULL, &row_options);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@image html object_position1.png
|
||||
|
||||
As can be seen the inserted images are the same size even though the second
|
||||
image crosses changed rows and columns.
|
||||
|
||||
However, there are two cases where the image scale may change with row or
|
||||
columns changes. These are explained in the next two sections.
|
||||
|
||||
@section ww_object_position_scaling Object scaling due to automatic row height adjustment
|
||||
|
||||
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. In these cases Excel will automatically
|
||||
calculate a row height based on the text when it loads the file. Since this
|
||||
row height isn't available to Libxlsxwriter when it creates the file the object
|
||||
may appear as if it is sized incorrectly. For example::
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("images.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
lxw_format *wrap = workbook_add_format(workbook);
|
||||
format_set_text_wrap(wrap);
|
||||
|
||||
worksheet_write_string(worksheet, CELL("A10"), "Some text that wraps", wrap);
|
||||
|
||||
worksheet_insert_image(worksheet, CELL("B1"), "logo.png");
|
||||
worksheet_insert_image(worksheet, CELL("B10"), "logo.png");
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@image html object_position2.png
|
||||
|
||||
As can be seen the second inserted image is distorted, compared to the first,
|
||||
due to the row being scaled automatically. To avoid this you should explicitly
|
||||
set the height of the row using `worksheet_set_row()` if it crosses an
|
||||
inserted object.
|
||||
|
||||
@section ww_object_position_options Object Positioning with Cell Moving and Sizing
|
||||
|
||||
Excel supports three options for "Object Positioning" within a worksheet:
|
||||
|
||||
@image html object_position3.png
|
||||
|
||||
|
||||
Image and chart objects in Libxlsxwriter emulate these options using the
|
||||
`object_position` parameter in #lxw_image_options and #lxw_chart_options:
|
||||
|
||||
@code
|
||||
lxw_image_options options = {.object_position = LXW_OBJECT_MOVE_AND_SIZE};
|
||||
worksheet_insert_image_opt(worksheet, CELL("E9"), "red.png", &options);
|
||||
@endcode
|
||||
|
||||
Where `object_position` has one of the following allowable values from
|
||||
#lxw_object_position:
|
||||
|
||||
1. #LXW_OBJECT_MOVE_AND_SIZE: Move and size with cells. This is the Excel
|
||||
default for charts.
|
||||
2. #LXW_OBJECT_MOVE_DONT_SIZE: Move but don’t size with cells. This is the
|
||||
Excel default for images.
|
||||
3. #LXW_OBJECT_DONT_MOVE_DONT_SIZE: Don’t move or size with cells.
|
||||
4. #LXW_OBJECT_MOVE_AND_SIZE_AFTER: Same as Option 1 to "move and size with
|
||||
cells" except Libxlsxwriter applies hidden cells after the object is
|
||||
inserted.
|
||||
|
||||
Option 4 appears in Excel as Option 1. However, the worksheet object is sized
|
||||
to take hidden rows or columns into account. This allows the user to hide an
|
||||
image in a cell, possibly as part of an autofilter. For example:
|
||||
|
||||
@code
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = workbook_new("images.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
lxw_image_options image_options = {.object_position = LXW_OBJECT_MOVE_AND_SIZE_AFTER};
|
||||
|
||||
worksheet_insert_image( worksheet, CELL("B4"), "logo.png");
|
||||
worksheet_insert_image_opt(worksheet, CELL("B13"), "logo.png", &image_options);
|
||||
|
||||
// Hide the rows that contain the images.
|
||||
lxw_row_col_options row_options = {.hidden = LXW_TRUE};
|
||||
for (int row_num = 1; row_num < 22; row_num++)
|
||||
worksheet_set_row_opt(worksheet, row_num, LXW_DEF_ROW_HEIGHT, NULL, &row_options);
|
||||
|
||||
workbook_close(workbook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@image html object_position4.png
|
||||
|
||||
In this example the first inserted image is visible over the hidden rows
|
||||
whilst the second image is hidden with the rows. Unhiding the rows in Excel
|
||||
would reveal the second image.
|
||||
|
||||
@section ww_object_position_sizing Image sizing and DPI
|
||||
|
||||
When an image is imported into Excel the DPI (dots per inch) resolution of the
|
||||
image is taken into account. Excel sizes the image according to a base DPI of
|
||||
96 dpi. Therefore an image with a DPI of 72 may appear slightly larger when
|
||||
imported into Excel while an image with a DPI of 200 may appear twice as
|
||||
small. Libxlsxwriter also reads the DPI of the images that the user inserts
|
||||
into a worksheet and stores the image dimensions in the same way that Excel
|
||||
does. If it cannot determine the DPI of the image it uses a default of 96.
|
||||
|
||||
@section ww_object_position_image_issues Reporting issues with image insertion
|
||||
|
||||
A lot of work has gone into ensuring that Libxlsxwriter inserts images into
|
||||
worksheets in exactly the same way that Excel does, even though the required
|
||||
calculations and units are arcane. There are over 80 test cases that check
|
||||
image insertion against files created in Excel to ensure that Libxlsxwriter's
|
||||
handling of images is correct.
|
||||
|
||||
As such, before reporting any issues with image handling in Libxlsxwriter
|
||||
please check how the same image is handled in Excel (not OpenOffice,
|
||||
LibreOffice or other third party applications). If you do report an issue
|
||||
please use the Libxlsxwriter [Issue tracker is on GitHub][issue_tracker] that
|
||||
demonstrates the issue.
|
||||
|
||||
[issue_tracker]: https://github.com/jmcnamara/libxlsxwriter/issues
|
||||
|
||||
Next: @ref working_with_autofilters
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
@page working_with_outlines Working with Outlines and Grouping
|
||||
|
||||
Excel allows you to group rows or columns so that they can be hidden or
|
||||
displayed with a single mouse click. This feature is referred to as Outlines
|
||||
and Grouping.
|
||||
|
||||
Outlines can reduce complex data down to a few salient sub-totals or
|
||||
summaries. For example the following is a worksheet with three outlines.
|
||||
|
||||
@image html outline1.png
|
||||
|
||||
Rows 2 to 11 are grouped at level 1 and rows 2 to 5 and 7 to 10 are grouped at
|
||||
level 2. The lines at the left hand side are called "outline level" bars and
|
||||
the level is shown by the small numeral above the outline.
|
||||
|
||||
Clicking the minus sign on each of the level 2 outlines will collapse and hide
|
||||
the data as shown below.
|
||||
|
||||
@image html outline5.png
|
||||
|
||||
The minus sign changes to a plus sign to indicate that the data in the outline
|
||||
is hidden. This shows the usefulness of outlines: with 2 mouse clicks we have
|
||||
reduced the amount of visual data down to 2 sub-totals and a master total.
|
||||
|
||||
Finally, clicking on the minus sign on the level 1 outline will collapse the
|
||||
remaining rows as follows:
|
||||
|
||||
@image html outline6.png
|
||||
|
||||
|
||||
@section ww_outlines_grouping Outlines and Grouping in libxlsxwriter
|
||||
|
||||
Grouping in `libxlsxwriter` is achieved by setting the outline level via the
|
||||
`worksheet_set_row_opt()` and `worksheet_set_column_opt()` worksheet
|
||||
functions:
|
||||
|
||||
Adjacent row or columns with the same outline level are grouped together into a
|
||||
single outline.
|
||||
|
||||
The `options` parameter is a #lxw_row_col_options struct. It has the following
|
||||
members:
|
||||
|
||||
- `'hidden'`
|
||||
- `'level'`
|
||||
- `'collapsed'`
|
||||
|
||||
Options can be set as follows, for example to set up an outline for rows:
|
||||
|
||||
@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
|
||||
|
||||
Or an outline for columns:
|
||||
|
||||
@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
|
||||
|
||||
|
||||
The following example sets an outline level of 1 for rows 1 to 4
|
||||
(zero-indexed) and columns B to G. The parameters `height`, `width` and
|
||||
`cell_format` are assigned default values:
|
||||
|
||||
@code
|
||||
lxw_row_col_options options1 = {.hidden = 0, .level = 1, .collapsed = 0};
|
||||
|
||||
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_column_opt(worksheet, COLS("B:G"), LXW_DEF_COL_WIDTH, NULL, &options);
|
||||
@endcode
|
||||
|
||||
@image html outline3.png
|
||||
|
||||
Rows and columns can be collapsed by setting the `hidden` member for the
|
||||
hidden rows/columns and setting the `collapsed` member for the row/column that
|
||||
has the collapsed `'+'` symbol:
|
||||
|
||||
@code
|
||||
lxw_row_col_options options1 = {.hidden = 1, .level = 1, .collapsed = 0};
|
||||
lxw_row_col_options options2 = {.hidden = 0, .level = 0, .collapsed = 1};
|
||||
|
||||
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_column_opt(worksheet, COLS("B:G"), LXW_DEF_COL_WIDTH, NULL, &options1);
|
||||
worksheet_set_column_opt(worksheet, COLS("H:H"), LXW_DEF_COL_WIDTH, NULL, &options2);
|
||||
@endcode
|
||||
|
||||
@image html outline7.png
|
||||
|
||||
Excel allows up to 7 outline levels. Therefore the `level` parameter should
|
||||
be in the range `0 <= level <= 7`.
|
||||
|
||||
@image html outline4.png
|
||||
|
||||
Some additional outline properties can be set via the
|
||||
`worksheet_outline_settings()` worksheet function.
|
||||
|
||||
Next: @ref working_with_memory
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,453 @@
|
||||
/**
|
||||
@page working_with_tables Working with Worksheet Tables
|
||||
|
||||
@tableofcontents
|
||||
|
||||
Tables in Excel are a way of grouping a range of cells into a single entity
|
||||
that has common formatting or that can be referenced from formulas. Tables can
|
||||
have column headers, autofilters, total rows, column formulas and default
|
||||
formatting.
|
||||
|
||||
@image html tables12.png
|
||||
|
||||
For a general introduction to this Excel feature see [An Overview of Excel
|
||||
Tables](http://office.microsoft.com/en-us/excel-help/overview-of-excel-tables-HA010048546.aspx)
|
||||
in the Microsoft Office documentation.
|
||||
|
||||
@section ww_tables_add_table Adding a table to a worksheet
|
||||
|
||||
Tables are added to a worksheet using the `worksheet_add_table()` function:
|
||||
|
||||
@code
|
||||
worksheet_add_table(worksheet, 2, 1, 6, 5, NULL);
|
||||
@endcode
|
||||
|
||||
Or more explicitly using the RANGE() macro:
|
||||
|
||||
@code
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), NULL); //Same as above.
|
||||
@endcode
|
||||
|
||||
@image html tables1.png
|
||||
|
||||
The `worksheet_add_table()` `options` parameter should be a pointer to a
|
||||
lxw_table_options struct with the parameters that describe the table options:
|
||||
|
||||
@code
|
||||
worksheet_add_table(worksheet, 2, 1, 6, 5, &options);
|
||||
@endcode
|
||||
|
||||
These options are explained in the sections below. There are no required
|
||||
parameters and the `options` parameter is itself optional, in which case you
|
||||
can specify NULL and get the default table parameters.
|
||||
|
||||
You should take care not to overlap worksheet tables as this is not allowed by
|
||||
Excel and will cause an error when the file is loaded.
|
||||
|
||||
|
||||
@note Tables aren't available in libxlsxwriter when using `constant_memory`
|
||||
mode in `workbook_new_opt()`.
|
||||
|
||||
|
||||
@subsection ww_tables_header_row Parameter: no_header_row
|
||||
|
||||
The `no_header_row` parameter can be used to turn off the header row in the
|
||||
table. It is on by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.no_header_row = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B4:F7"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables4.png
|
||||
|
||||
Without this option the header row will contain default captions such as
|
||||
`Column 1`, ``Column 2``, etc. These captions can be overridden using the
|
||||
`columns` parameter shown below.
|
||||
|
||||
|
||||
@subsection ww_tables_autofilter Parameter: no_autofilter
|
||||
|
||||
The `no_autofilter` parameter can be used to turn off the autofilter in the
|
||||
header row. It is on by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.no_autofilter = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables3.png
|
||||
|
||||
The autofilter is only shown if the `no_header_row` parameter is off (the
|
||||
default). Filter conditions within the table are not supported.
|
||||
|
||||
|
||||
@subsection ww_tables_banded_rows Parameter: no_banded_rows
|
||||
|
||||
The `no_banded_rows` parameter can be used to turn off the rows of alternating
|
||||
color in the table. It is on by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.no_banded_rows = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables6.png
|
||||
|
||||
@subsection ww_tables_banded_columns Parameter: banded_columns
|
||||
|
||||
The `banded_columns` parameter can be used to used to create columns of
|
||||
alternating color in the table. It is off by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.banded_columns = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
The banded columns formatting is shown in the image in the previous section
|
||||
above.
|
||||
|
||||
@subsection ww_tables_first_column Parameter: first_column
|
||||
|
||||
The `first_column` parameter can be used to highlight the first column of the
|
||||
table. The type of highlighting will depend on the `style_type` of the table.
|
||||
It may be bold text or a different color. It is off by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables5.png
|
||||
|
||||
@subsection ww_tables_last_column Parameter: last_column
|
||||
|
||||
The `last_column` parameter can be used to highlight the last column of the
|
||||
table. The type of highlighting will depend on the `style` of the table. It
|
||||
may be bold text or a different color. It is off by default:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.first_column = LXW_TRUE, .last_column = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
The `last_column` formatting is shown in the image in the previous section
|
||||
above.
|
||||
|
||||
|
||||
@subsection ww_tables_style Parameter: style_type and style_type_number
|
||||
|
||||
The `style_type` parameter can be used to set the style of the table, in
|
||||
conjunction with the `style_type_number` parameter:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {
|
||||
.style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
|
||||
.style_type_number = 11,
|
||||
};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
|
||||
@endcode
|
||||
|
||||
|
||||
@image html tables11.png
|
||||
|
||||
There are three types of table style in Excel: Light, Medium and Dark which
|
||||
are represented using the #lxw_table_style_type enum values:
|
||||
|
||||
- #LXW_TABLE_STYLE_TYPE_LIGHT
|
||||
|
||||
- #LXW_TABLE_STYLE_TYPE_MEDIUM
|
||||
|
||||
- #LXW_TABLE_STYLE_TYPE_DARK
|
||||
|
||||
Within those ranges there are between 11 and 28 other style types which can be
|
||||
set with `style_type_number` (depending on the style type). Check Excel to
|
||||
find the style that you want. The dialog with the options laid out in numeric
|
||||
order are shown below:
|
||||
|
||||
@image html tables14.png
|
||||
|
||||
The default table style in Excel is 'Table Style Medium 9' (highlighted with
|
||||
a green border in the image above), which is set by default in libxlsxwriter
|
||||
as:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {
|
||||
.style_type = LXW_TABLE_STYLE_TYPE_MEDIUM,
|
||||
.style_type_number = 9,
|
||||
};
|
||||
@endcode
|
||||
|
||||
You can also turn the table style off by setting it to Light 0:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {
|
||||
.style_type = LXW_TABLE_STYLE_TYPE_LIGHT,
|
||||
.style_type_number = 0,
|
||||
};
|
||||
@endcode
|
||||
|
||||
@image html tables13.png
|
||||
|
||||
|
||||
@subsection ww_tables_name Parameter: name
|
||||
|
||||
The `name` parameter is used to set the name of the table. This parameter is
|
||||
optional and by default tables are named `Table1`, `Table2`, etc. in the
|
||||
worksheet order that they are added.
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.name = "Sales"};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
|
||||
@endcode
|
||||
|
||||
If you override the table name you must ensure that it doesn't clash with an
|
||||
existing table name and that it follows Excel's requirements for table names,
|
||||
see the Microsoft Office documentation on [Naming an Excel
|
||||
Table](https://support.microsoft.com/en-us/office/rename-an-excel-table-fbf49a4f-82a3-43eb-8ba2-44d21233b114).
|
||||
|
||||
|
||||
|
||||
@subsection ww_tables_total_row Parameter: total_row
|
||||
|
||||
The `total_row` parameter can be used to turn on the total row in the last
|
||||
row of a table. It is distinguished from the other rows by a different
|
||||
formatting and also with dropdown `SUBTOTAL` functions:
|
||||
|
||||
@code
|
||||
lxw_table_options options = {.total_row = LXW_TRUE};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables9.png
|
||||
|
||||
The default total row doesn't have any captions or functions. These must by
|
||||
specified via the `columns` parameter below.
|
||||
|
||||
|
||||
@subsection ww_tables_columns Parameter: columns
|
||||
|
||||
The `columns` parameter can be used to set properties for columns within the
|
||||
table.
|
||||
|
||||
@image html tables7.png
|
||||
|
||||
The sub-properties of `lxw_table_column` that can be set are:
|
||||
|
||||
- `lxw_table_column.header`
|
||||
- `lxw_table_column.header_format`
|
||||
- `lxw_table_column.formula`
|
||||
- `lxw_table_column.total_string`
|
||||
- `lxw_table_column.total_function`
|
||||
- `lxw_table_column.total_value`
|
||||
- `lxw_table_column.format`
|
||||
|
||||
The `columns` parameter should be a NULL terminated array of
|
||||
`lxw_table_column` pointers. For example to override the default 'Column n'
|
||||
style table headers:
|
||||
|
||||
@code
|
||||
lxw_table_column col1 = {.header = "Product"};
|
||||
lxw_table_column col2 = {.header = "Quarter 1"};
|
||||
lxw_table_column col3 = {.header = "Quarter 2"};
|
||||
lxw_table_column col4 = {.header = "Quarter 3"};
|
||||
lxw_table_column col5 = {.header = "Quarter 4"};
|
||||
|
||||
lxw_table_column *columns[] = {&col1, &col2, &col3, &col4, &col5, NULL};
|
||||
|
||||
lxw_table_options options = {.columns = columns};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:F7"), &options);
|
||||
@endcode
|
||||
|
||||
If you don't wish to specify properties for a specific column you can pass an
|
||||
empty (but not NULL) struct and the defaults will be applied:
|
||||
|
||||
@code
|
||||
lxw_table_column col1 = {.header = "Product"};
|
||||
lxw_table_column col2 = {.header = "Quarter 1"};
|
||||
lxw_table_column col3 = {0}; // Defaults to Column3.
|
||||
lxw_table_column col4 = {.header = "Quarter 3"};
|
||||
lxw_table_column col5 = {.header = "Quarter 4"};
|
||||
@endcode
|
||||
|
||||
Column formulas can by applied using the column `formula` property:
|
||||
|
||||
@code
|
||||
lxw_table_column col1 = {.header = "Product"};
|
||||
lxw_table_column col2 = {.header = "Quarter 1"};
|
||||
lxw_table_column col3 = {.header = "Quarter 2"};
|
||||
lxw_table_column col4 = {.header = "Quarter 3"};
|
||||
lxw_table_column col5 = {.header = "Quarter 4"};
|
||||
lxw_table_column col6 = {.header = "Year",
|
||||
.formula = "=SUM(Table8[@[Quarter 1]:[Quarter 4]])"};
|
||||
|
||||
lxw_table_column *columns[] = {&col1, &col2, &col3, &col4, &col5, &col6, NULL};
|
||||
|
||||
lxw_table_options options = {.columns = columns};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G7"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables8.png
|
||||
|
||||
The Excel 2007 style `"#This Row"` and Excel 2010 style `"@"` structural
|
||||
references are supported within the formula. However, other Excel 2010
|
||||
additions to structural references aren't supported and formulas should
|
||||
conform to Excel 2007 style formulas. See the Microsoft documentation on
|
||||
[Using structured references with Excel tables]
|
||||
(http://office.microsoft.com/en-us/excel-help/using-structured-references-with-excel-tables-HA010155686.aspx)
|
||||
for details.
|
||||
|
||||
As stated above the `total_row` table parameter turns on the "Total" row in
|
||||
the table but it doesn't populate it with any defaults. Total captions and
|
||||
functions must be specified via the `columns` property and the `total_string`
|
||||
and `total_function` sub properties:
|
||||
|
||||
@code
|
||||
lxw_table_column col1 = {.header = "Product",
|
||||
.total_string = "Totals"};
|
||||
|
||||
lxw_table_column col2 = {.header = "Quarter 1",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM};
|
||||
|
||||
lxw_table_column col3 = {.header = "Quarter 2",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM};
|
||||
|
||||
lxw_table_column col4 = {.header = "Quarter 3",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM};
|
||||
|
||||
lxw_table_column col5 = {.header = "Quarter 4",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM};
|
||||
|
||||
lxw_table_column col6 = {.header = "Year",
|
||||
.formula = "=SUM(Table10[@[Quarter 1]:[Quarter 4]])",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM};
|
||||
|
||||
lxw_table_column *columns[] = {&col1, &col2, &col3, &col4, &col5, &col6, NULL};
|
||||
|
||||
lxw_table_options options = {.total_row = LXW_TRUE, .columns = columns};
|
||||
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
|
||||
@endcode
|
||||
|
||||
The supported totals row `SUBTOTAL` functions are defined in
|
||||
#lxw_table_total_functions:
|
||||
|
||||
- #LXW_TABLE_FUNCTION_AVERAGE
|
||||
- #LXW_TABLE_FUNCTION_COUNT_NUMS
|
||||
- #LXW_TABLE_FUNCTION_COUNT
|
||||
- #LXW_TABLE_FUNCTION_MAX
|
||||
- #LXW_TABLE_FUNCTION_MIN
|
||||
- #LXW_TABLE_FUNCTION_STD_DEV
|
||||
- #LXW_TABLE_FUNCTION_SUM
|
||||
- #LXW_TABLE_FUNCTION_VAR
|
||||
|
||||
User defined functions or formulas aren't supported.
|
||||
|
||||
It is also possible to set a calculated value for the `total_function` using
|
||||
the `total_value` sub property. This is only necessary when creating workbooks
|
||||
for applications that cannot calculate the value of formulas automatically.
|
||||
This is similar to setting the `result` property in
|
||||
`worksheet_write_formula_num()`. See also @ref ww_formulas_results.
|
||||
|
||||
Formatting can also be applied to columns using the `format` and to the header
|
||||
using `header_format` (although you will also need to add it to the data in
|
||||
the column, see the next section):
|
||||
|
||||
@code
|
||||
lxw_table_column col1 = {.header = "Product",
|
||||
.total_string = "Totals"};
|
||||
|
||||
lxw_table_column col2 = {.header = "Quarter 1",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM,
|
||||
.format = currency_format};
|
||||
|
||||
lxw_table_column col3 = {.header = "Quarter 2",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM,
|
||||
.format = currency_format};
|
||||
|
||||
lxw_table_column col4 = {.header = "Quarter 3",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM,
|
||||
.format = currency_format};
|
||||
|
||||
lxw_table_column col5 = {.header = "Quarter 4",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM,
|
||||
.format = currency_format};
|
||||
|
||||
lxw_table_column col6 = {.header = "Year",
|
||||
.formula = "=SUM(Table13[@[Quarter 1]:[Quarter 4]])",
|
||||
.total_function = LXW_TABLE_FUNCTION_SUM,
|
||||
.format = currency_format};
|
||||
|
||||
lxw_table_column *columns[] = {&col1, &col2, &col3, &col4, &col5, &col6, NULL};
|
||||
|
||||
lxw_table_options options = {.total_row = LXW_TRUE, .columns = columns};
|
||||
|
||||
worksheet_add_table(worksheet, RANGE("B3:G8"), &options);
|
||||
@endcode
|
||||
|
||||
@image html tables12.png
|
||||
|
||||
Standard libxlsxwriter lxw_format objects are used for this formatting.
|
||||
However, they should be limited to numerical formats for the columns and
|
||||
simple formatting like text wrap for the headers. Overriding other table
|
||||
formatting may produce inconsistent results. You will also need to apply the
|
||||
same format to any data you write to the column in the table, see the next
|
||||
section.
|
||||
|
||||
|
||||
@section ww_tables_data Adding data to the table
|
||||
|
||||
Once you create a worksheet table you will also need to fill in the data in
|
||||
the rows and columns. This is done with the standard worksheet write()
|
||||
functions. For example the data in the examples above was written as follows:
|
||||
|
||||
@code
|
||||
worksheet_write_string(worksheet, 3, 1, "Apples", NULL);
|
||||
worksheet_write_string(worksheet, 4, 1, "Pears", NULL);
|
||||
worksheet_write_string(worksheet, 5, 1, "Bananas", NULL);
|
||||
worksheet_write_string(worksheet, 6, 1, "Oranges", NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 2, 10000, format);
|
||||
worksheet_write_number(worksheet, 4, 2, 2000, format);
|
||||
worksheet_write_number(worksheet, 5, 2, 6000, format);
|
||||
worksheet_write_number(worksheet, 6, 2, 500, format);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 3, 5000, format);
|
||||
worksheet_write_number(worksheet, 4, 3, 3000, format);
|
||||
worksheet_write_number(worksheet, 5, 3, 6000, format);
|
||||
worksheet_write_number(worksheet, 6, 3, 300, format);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 4, 8000, format);
|
||||
worksheet_write_number(worksheet, 4, 4, 4000, format);
|
||||
worksheet_write_number(worksheet, 5, 4, 6500, format);
|
||||
worksheet_write_number(worksheet, 6, 4, 200, format);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 5, 6000, format);
|
||||
worksheet_write_number(worksheet, 4, 5, 5000, format);
|
||||
worksheet_write_number(worksheet, 5, 5, 6000, format);
|
||||
worksheet_write_number(worksheet, 6, 5, 700, format);
|
||||
@endcode
|
||||
|
||||
@image html tables2.png
|
||||
|
||||
|
||||
@section ww_tables_Example Example
|
||||
|
||||
All of the images shown above are taken from @ref tables.c.
|
||||
|
||||
|
||||
Next: @ref working_with_comments
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user