xlsxwriter 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +55 -5
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +6 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +1 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +3 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +7 -2
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +16 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +122 -24
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +236 -48
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/src/chart.c +40 -4
- data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +508 -0
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +100 -3
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +252 -30
- data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +16 -2
- data/ext/xlsxwriter/libxlsxwriter/src/styles.c +54 -7
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +43 -1
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +254 -41
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +381 -65
- data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +16 -7
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
- data/ext/xlsxwriter/workbook.c +9 -6
- data/lib/xlsxwriter/version.rb +1 -1
- metadata +5 -4
@@ -65,6 +65,9 @@ typedef enum lxw_error {
|
|
65
65
|
/** Error encountered when creating a tmpfile during file assembly. */
|
66
66
|
LXW_ERROR_CREATING_TMPFILE,
|
67
67
|
|
68
|
+
/** Error reading a tmpfile. */
|
69
|
+
LXW_ERROR_READING_TMPFILE,
|
70
|
+
|
68
71
|
/** Zlib error with a file operation while creating xlsx file. */
|
69
72
|
LXW_ERROR_ZIP_FILE_OPERATION,
|
70
73
|
|
@@ -177,6 +180,9 @@ enum lxw_custom_property_types {
|
|
177
180
|
#define LXW_FILENAME_LENGTH 128
|
178
181
|
#define LXW_IGNORE 1
|
179
182
|
|
183
|
+
#define LXW_PORTRAIT 1
|
184
|
+
#define LXW_LANDSCAPE 0
|
185
|
+
|
180
186
|
#define LXW_SCHEMA_MS "http://schemas.microsoft.com/office/2006/relationships"
|
181
187
|
#define LXW_SCHEMA_ROOT "http://schemas.openxmlformats.org"
|
182
188
|
#define LXW_SCHEMA_DRAWING LXW_SCHEMA_ROOT "/drawingml/2006"
|
@@ -46,6 +46,8 @@ void lxw_ct_add_override(lxw_content_types *content_types, const char *key,
|
|
46
46
|
const char *value);
|
47
47
|
void lxw_ct_add_worksheet_name(lxw_content_types *content_types,
|
48
48
|
const char *name);
|
49
|
+
void lxw_ct_add_chartsheet_name(lxw_content_types *content_types,
|
50
|
+
const char *name);
|
49
51
|
void lxw_ct_add_chart_name(lxw_content_types *content_types,
|
50
52
|
const char *name);
|
51
53
|
void lxw_ct_add_drawing_name(lxw_content_types *content_types,
|
@@ -691,7 +691,7 @@ void format_set_num_format(lxw_format *format, const char *num_format);
|
|
691
691
|
*
|
692
692
|
* @code
|
693
693
|
* format = workbook_add_format(workbook);
|
694
|
-
*
|
694
|
+
* format_set_num_format_index(format, 0x0F); // d-mmm-yy
|
695
695
|
* @endcode
|
696
696
|
*
|
697
697
|
* @note
|
@@ -37,6 +37,7 @@ STAILQ_HEAD(sst_order_list, sst_element);
|
|
37
37
|
struct sst_element {
|
38
38
|
uint32_t index;
|
39
39
|
char *string;
|
40
|
+
uint8_t is_rich_string;
|
40
41
|
|
41
42
|
STAILQ_ENTRY (sst_element) sst_order_pointers;
|
42
43
|
RB_ENTRY (sst_element) sst_tree_pointers;
|
@@ -64,7 +65,8 @@ extern "C" {
|
|
64
65
|
|
65
66
|
lxw_sst *lxw_sst_new();
|
66
67
|
void lxw_sst_free(lxw_sst *sst);
|
67
|
-
struct sst_element *lxw_get_sst_index(lxw_sst *sst, const char *string
|
68
|
+
struct sst_element *lxw_get_sst_index(lxw_sst *sst, const char *string,
|
69
|
+
uint8_t is_rich_string);
|
68
70
|
void lxw_sst_assemble_xml_file(lxw_sst *self);
|
69
71
|
|
70
72
|
/* Declarations required for unit testing. */
|
@@ -10,6 +10,7 @@
|
|
10
10
|
#define __LXW_STYLES_H__
|
11
11
|
|
12
12
|
#include <stdint.h>
|
13
|
+
#include <ctype.h>
|
13
14
|
|
14
15
|
#include "format.h"
|
15
16
|
|
@@ -40,6 +41,8 @@ extern "C" {
|
|
40
41
|
lxw_styles *lxw_styles_new();
|
41
42
|
void lxw_styles_free(lxw_styles *styles);
|
42
43
|
void lxw_styles_assemble_xml_file(lxw_styles *self);
|
44
|
+
void lxw_styles_write_string_fragment(lxw_styles *self, char *string);
|
45
|
+
void lxw_styles_write_rich_font(lxw_styles *lxw_styles, lxw_format *format);
|
43
46
|
|
44
47
|
/* Declarations required for unit testing. */
|
45
48
|
#ifdef TESTING
|
@@ -48,10 +51,12 @@ STATIC void _styles_xml_declaration(lxw_styles *self);
|
|
48
51
|
STATIC void _write_style_sheet(lxw_styles *self);
|
49
52
|
STATIC void _write_font_size(lxw_styles *self, double font_size);
|
50
53
|
STATIC void _write_font_color_theme(lxw_styles *self, uint8_t theme);
|
51
|
-
STATIC void _write_font_name(lxw_styles *self, const char *font_name
|
54
|
+
STATIC void _write_font_name(lxw_styles *self, const char *font_name,
|
55
|
+
uint8_t is_rich_string);
|
52
56
|
STATIC void _write_font_family(lxw_styles *self, uint8_t font_family);
|
53
57
|
STATIC void _write_font_scheme(lxw_styles *self, const char *font_scheme);
|
54
|
-
STATIC void _write_font(lxw_styles *self, lxw_format *format
|
58
|
+
STATIC void _write_font(lxw_styles *self, lxw_format *format,
|
59
|
+
uint8_t is_rich_string);
|
55
60
|
STATIC void _write_fonts(lxw_styles *self);
|
56
61
|
STATIC void _write_default_fill(lxw_styles *self, const char *pattern);
|
57
62
|
STATIC void _write_fills(lxw_styles *self);
|
@@ -86,6 +86,20 @@ extern "C" {
|
|
86
86
|
#endif
|
87
87
|
/* *INDENT-ON* */
|
88
88
|
|
89
|
+
/**
|
90
|
+
* @brief Retrieve the library version.
|
91
|
+
*
|
92
|
+
* @return The "X.Y.Z" version string.
|
93
|
+
*
|
94
|
+
* Get the library version as a "X.Y.Z" version string
|
95
|
+
*
|
96
|
+
* @code
|
97
|
+
* printf("Libxlsxwriter version = %s\n", lxw_version());
|
98
|
+
* @endcode
|
99
|
+
*
|
100
|
+
*/
|
101
|
+
const char *lxw_version(void);
|
102
|
+
|
89
103
|
/**
|
90
104
|
* @brief Converts a libxlsxwriter error number to a string.
|
91
105
|
*
|
@@ -163,6 +177,8 @@ int lxw_sprintf_dbl(char *data, double number);
|
|
163
177
|
lxw_snprintf(data, LXW_ATTR_32, "%.16g", number)
|
164
178
|
#endif
|
165
179
|
|
180
|
+
uint16_t lxw_hash_password(const char *password);
|
181
|
+
|
166
182
|
/* *INDENT-OFF* */
|
167
183
|
#ifdef __cplusplus
|
168
184
|
}
|
@@ -46,6 +46,7 @@
|
|
46
46
|
#include <errno.h>
|
47
47
|
|
48
48
|
#include "worksheet.h"
|
49
|
+
#include "chartsheet.h"
|
49
50
|
#include "chart.h"
|
50
51
|
#include "shared_strings.h"
|
51
52
|
#include "hash_table.h"
|
@@ -55,12 +56,27 @@
|
|
55
56
|
|
56
57
|
/* Define the tree.h RB structs for the red-black head types. */
|
57
58
|
RB_HEAD(lxw_worksheet_names, lxw_worksheet_name);
|
59
|
+
RB_HEAD(lxw_chartsheet_names, lxw_chartsheet_name);
|
58
60
|
|
59
61
|
/* Define the queue.h structs for the workbook lists. */
|
62
|
+
STAILQ_HEAD(lxw_sheets, lxw_sheet);
|
60
63
|
STAILQ_HEAD(lxw_worksheets, lxw_worksheet);
|
64
|
+
STAILQ_HEAD(lxw_chartsheets, lxw_chartsheet);
|
61
65
|
STAILQ_HEAD(lxw_charts, lxw_chart);
|
62
66
|
TAILQ_HEAD(lxw_defined_names, lxw_defined_name);
|
63
67
|
|
68
|
+
/* TODO */
|
69
|
+
typedef struct lxw_sheet {
|
70
|
+
uint8_t is_chartsheet;
|
71
|
+
|
72
|
+
union {
|
73
|
+
lxw_worksheet *worksheet;
|
74
|
+
lxw_chartsheet *chartsheet;
|
75
|
+
} u;
|
76
|
+
|
77
|
+
STAILQ_ENTRY (lxw_sheet) list_pointers;
|
78
|
+
} lxw_sheet;
|
79
|
+
|
64
80
|
/* Struct to represent a worksheet name/pointer pair. */
|
65
81
|
typedef struct lxw_worksheet_name {
|
66
82
|
const char *name;
|
@@ -69,18 +85,37 @@ typedef struct lxw_worksheet_name {
|
|
69
85
|
RB_ENTRY (lxw_worksheet_name) tree_pointers;
|
70
86
|
} lxw_worksheet_name;
|
71
87
|
|
88
|
+
/* Struct to represent a chartsheet name/pointer pair. */
|
89
|
+
typedef struct lxw_chartsheet_name {
|
90
|
+
const char *name;
|
91
|
+
lxw_chartsheet *chartsheet;
|
92
|
+
|
93
|
+
RB_ENTRY (lxw_chartsheet_name) tree_pointers;
|
94
|
+
} lxw_chartsheet_name;
|
95
|
+
|
72
96
|
/* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function
|
73
97
|
* warnings and to avoid portability issues with the _unused attribute. */
|
74
|
-
#define
|
75
|
-
RB_GENERATE_INSERT_COLOR(name, type, field, static)
|
76
|
-
RB_GENERATE_REMOVE_COLOR(name, type, field, static)
|
77
|
-
RB_GENERATE_INSERT(name, type, field, cmp, static)
|
78
|
-
RB_GENERATE_REMOVE(name, type, field, static)
|
79
|
-
RB_GENERATE_FIND(name, type, field, cmp, static)
|
80
|
-
RB_GENERATE_NEXT(name, type, field, static)
|
81
|
-
RB_GENERATE_MINMAX(name, type, field, static)
|
82
|
-
/* Add unused struct to allow adding a semicolon */
|
83
|
-
struct
|
98
|
+
#define LXW_RB_GENERATE_WORKSHEET_NAMES(name, type, field, cmp) \
|
99
|
+
RB_GENERATE_INSERT_COLOR(name, type, field, static) \
|
100
|
+
RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
|
101
|
+
RB_GENERATE_INSERT(name, type, field, cmp, static) \
|
102
|
+
RB_GENERATE_REMOVE(name, type, field, static) \
|
103
|
+
RB_GENERATE_FIND(name, type, field, cmp, static) \
|
104
|
+
RB_GENERATE_NEXT(name, type, field, static) \
|
105
|
+
RB_GENERATE_MINMAX(name, type, field, static) \
|
106
|
+
/* Add unused struct to allow adding a semicolon */ \
|
107
|
+
struct lxw_rb_generate_worksheet_names{int unused;}
|
108
|
+
|
109
|
+
#define LXW_RB_GENERATE_CHARTSHEET_NAMES(name, type, field, cmp) \
|
110
|
+
RB_GENERATE_INSERT_COLOR(name, type, field, static) \
|
111
|
+
RB_GENERATE_REMOVE_COLOR(name, type, field, static) \
|
112
|
+
RB_GENERATE_INSERT(name, type, field, cmp, static) \
|
113
|
+
RB_GENERATE_REMOVE(name, type, field, static) \
|
114
|
+
RB_GENERATE_FIND(name, type, field, cmp, static) \
|
115
|
+
RB_GENERATE_NEXT(name, type, field, static) \
|
116
|
+
RB_GENERATE_MINMAX(name, type, field, static) \
|
117
|
+
/* Add unused struct to allow adding a semicolon */ \
|
118
|
+
struct lxw_rb_generate_charsheet_names{int unused;}
|
84
119
|
|
85
120
|
/**
|
86
121
|
* @brief Macro to loop over all the worksheets in a workbook.
|
@@ -181,7 +216,7 @@ typedef struct lxw_doc_properties {
|
|
181
216
|
* to assembling the final XLSX file. The temporary files are created in the
|
182
217
|
* system's temp directory. If the default temporary directory isn't
|
183
218
|
* accessible to your application, or doesn't contain enough space, you can
|
184
|
-
* specify an alternative location using the `
|
219
|
+
* specify an alternative location using the `tmpdir` option.
|
185
220
|
*/
|
186
221
|
typedef struct lxw_workbook_options {
|
187
222
|
/** Optimize the workbook to use constant memory for worksheets */
|
@@ -201,8 +236,11 @@ typedef struct lxw_workbook_options {
|
|
201
236
|
typedef struct lxw_workbook {
|
202
237
|
|
203
238
|
FILE *file;
|
239
|
+
struct lxw_sheets *sheets;
|
204
240
|
struct lxw_worksheets *worksheets;
|
241
|
+
struct lxw_chartsheets *chartsheets;
|
205
242
|
struct lxw_worksheet_names *worksheet_names;
|
243
|
+
struct lxw_chartsheet_names *chartsheet_names;
|
206
244
|
struct lxw_charts *charts;
|
207
245
|
struct lxw_charts *ordered_charts;
|
208
246
|
struct lxw_formats *formats;
|
@@ -215,6 +253,8 @@ typedef struct lxw_workbook {
|
|
215
253
|
lxw_workbook_options options;
|
216
254
|
|
217
255
|
uint16_t num_sheets;
|
256
|
+
uint16_t num_worksheets;
|
257
|
+
uint16_t num_chartsheets;
|
218
258
|
uint16_t first_sheet;
|
219
259
|
uint16_t active_sheet;
|
220
260
|
uint16_t num_xf_formats;
|
@@ -294,7 +334,7 @@ lxw_workbook *workbook_new(const char *filename);
|
|
294
334
|
* to assembling the final XLSX file. The temporary files are created in the
|
295
335
|
* system's temp directory. If the default temporary directory isn't
|
296
336
|
* accessible to your application, or doesn't contain enough space, you can
|
297
|
-
* specify an alternative location using the `
|
337
|
+
* specify an alternative location using the `tmpdir` option.*
|
298
338
|
*
|
299
339
|
* See @ref working_with_memory for more details.
|
300
340
|
*
|
@@ -317,7 +357,7 @@ lxw_workbook *new_workbook_opt(const char *filename,
|
|
317
357
|
*
|
318
358
|
* @return A lxw_worksheet object.
|
319
359
|
*
|
320
|
-
* The `%workbook_add_worksheet()` function adds a new worksheet to a workbook
|
360
|
+
* The `%workbook_add_worksheet()` function adds a new worksheet to a workbook.
|
321
361
|
*
|
322
362
|
* At least one worksheet should be added to a new workbook: The @ref
|
323
363
|
* worksheet.h "Worksheet" object is used to write data and configure a
|
@@ -342,12 +382,52 @@ lxw_workbook *new_workbook_opt(const char *filename,
|
|
342
382
|
* / \ [ ] : * ?
|
343
383
|
*
|
344
384
|
* In addition, you cannot use the same, case insensitive, `sheetname` for more
|
345
|
-
* than one worksheet.
|
385
|
+
* than one worksheet, or chartsheet.
|
346
386
|
*
|
347
387
|
*/
|
348
388
|
lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook,
|
349
389
|
const char *sheetname);
|
350
390
|
|
391
|
+
/**
|
392
|
+
* @brief Add a new chartsheet to a workbook.
|
393
|
+
*
|
394
|
+
* @param workbook Pointer to a lxw_workbook instance.
|
395
|
+
* @param sheetname Optional chartsheet name, defaults to Chart1, etc.
|
396
|
+
*
|
397
|
+
* @return A lxw_chartsheet object.
|
398
|
+
*
|
399
|
+
* The `%workbook_add_chartsheet()` function adds a new chartsheet to a
|
400
|
+
* workbook. The @ref chartsheet.h "Chartsheet" object is like a worksheet
|
401
|
+
* except it displays a chart instead of cell data.
|
402
|
+
*
|
403
|
+
* @image html chartsheet.png
|
404
|
+
*
|
405
|
+
* The `sheetname` parameter is optional. If it is `NULL` the default
|
406
|
+
* Excel convention will be followed, i.e. Chart1, Chart2, etc.:
|
407
|
+
*
|
408
|
+
* @code
|
409
|
+
* chartsheet = workbook_add_chartsheet(workbook, NULL ); // Chart1
|
410
|
+
* chartsheet = workbook_add_chartsheet(workbook, "My Chart"); // My Chart
|
411
|
+
* chartsheet = workbook_add_chartsheet(workbook, NULL ); // Chart3
|
412
|
+
*
|
413
|
+
* @endcode
|
414
|
+
*
|
415
|
+
* The chartsheet name must be a valid Excel worksheet name, i.e. it must be
|
416
|
+
* less than 32 character and it cannot contain any of the characters:
|
417
|
+
*
|
418
|
+
* / \ [ ] : * ?
|
419
|
+
*
|
420
|
+
* In addition, you cannot use the same, case insensitive, `sheetname` for more
|
421
|
+
* than one chartsheet, or worksheet.
|
422
|
+
*
|
423
|
+
* At least one worksheet should be added to a new workbook when creating a
|
424
|
+
* chartsheet in order to provide data for the chart. The @ref worksheet.h
|
425
|
+
* "Worksheet" object is used to write data and configure a worksheet in the
|
426
|
+
* workbook.
|
427
|
+
*/
|
428
|
+
lxw_chartsheet *workbook_add_chartsheet(lxw_workbook *workbook,
|
429
|
+
const char *sheetname);
|
430
|
+
|
351
431
|
/**
|
352
432
|
* @brief Create a new @ref format.h "Format" object to formats cells in
|
353
433
|
* worksheets.
|
@@ -687,31 +767,49 @@ lxw_worksheet *workbook_get_worksheet_by_name(lxw_workbook *workbook,
|
|
687
767
|
const char *name);
|
688
768
|
|
689
769
|
/**
|
690
|
-
* @brief
|
770
|
+
* @brief Get a chartsheet object from its name.
|
771
|
+
*
|
772
|
+
* @param workbook Pointer to a lxw_workbook instance.
|
773
|
+
* @param name chartsheet name.
|
774
|
+
*
|
775
|
+
* @return A lxw_chartsheet object.
|
776
|
+
*
|
777
|
+
* This function returns a lxw_chartsheet object reference based on its name:
|
778
|
+
*
|
779
|
+
* @code
|
780
|
+
* chartsheet = workbook_get_chartsheet_by_name(workbook, "Chart1");
|
781
|
+
* @endcode
|
782
|
+
*
|
783
|
+
*/
|
784
|
+
lxw_chartsheet *workbook_get_chartsheet_by_name(lxw_workbook *workbook,
|
785
|
+
const char *name);
|
786
|
+
|
787
|
+
/**
|
788
|
+
* @brief Validate a worksheet or chartsheet name.
|
691
789
|
*
|
692
790
|
* @param workbook Pointer to a lxw_workbook instance.
|
693
|
-
* @param sheetname
|
791
|
+
* @param sheetname Sheet name to validate.
|
694
792
|
*
|
695
793
|
* @return A #lxw_error.
|
696
794
|
*
|
697
|
-
* This function is used to validate a worksheet name according
|
698
|
-
* used by Excel:
|
795
|
+
* This function is used to validate a worksheet or chartsheet name according
|
796
|
+
* to the rules used by Excel:
|
699
797
|
*
|
700
798
|
* - The name is less than or equal to 31 UTF-8 characters.
|
701
799
|
* - The name doesn't contain any of the characters: ` [ ] : * ? / \ `
|
702
800
|
* - The name isn't already in use.
|
703
801
|
*
|
704
802
|
* @code
|
705
|
-
* lxw_error err =
|
803
|
+
* lxw_error err = workbook_validate_sheet_name(workbook, "Foglio");
|
706
804
|
* @endcode
|
707
805
|
*
|
708
|
-
* This function is called by `workbook_add_worksheet()`
|
709
|
-
*
|
710
|
-
* name is valid.
|
806
|
+
* This function is called by `workbook_add_worksheet()` and
|
807
|
+
* `workbook_add_chartsheet()` but it can be explicitly called by the user
|
808
|
+
* beforehand to ensure that the sheet name is valid.
|
711
809
|
*
|
712
810
|
*/
|
713
|
-
lxw_error
|
714
|
-
|
811
|
+
lxw_error workbook_validate_sheet_name(lxw_workbook *workbook,
|
812
|
+
const char *sheetname);
|
715
813
|
|
716
814
|
void lxw_workbook_free(lxw_workbook *workbook);
|
717
815
|
void lxw_workbook_assemble_xml_file(lxw_workbook *workbook);
|
@@ -53,18 +53,19 @@
|
|
53
53
|
#include "drawing.h"
|
54
54
|
#include "common.h"
|
55
55
|
#include "format.h"
|
56
|
+
#include "styles.h"
|
56
57
|
#include "utility.h"
|
57
58
|
|
58
|
-
#define LXW_ROW_MAX
|
59
|
-
#define LXW_COL_MAX
|
60
|
-
#define LXW_COL_META_MAX
|
59
|
+
#define LXW_ROW_MAX 1048576
|
60
|
+
#define LXW_COL_MAX 16384
|
61
|
+
#define LXW_COL_META_MAX 128
|
61
62
|
#define LXW_HEADER_FOOTER_MAX 255
|
62
|
-
#define LXW_MAX_NUMBER_URLS
|
63
|
-
#define LXW_PANE_NAME_LENGTH
|
63
|
+
#define LXW_MAX_NUMBER_URLS 65530
|
64
|
+
#define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
|
64
65
|
|
65
66
|
/* The Excel 2007 specification says that the maximum number of page
|
66
67
|
* breaks is 1026. However, in practice it is actually 1023. */
|
67
|
-
#define LXW_BREAKS_MAX
|
68
|
+
#define LXW_BREAKS_MAX 1023
|
68
69
|
|
69
70
|
/** Default column width in Excel */
|
70
71
|
#define LXW_DEF_COL_WIDTH (double)8.43
|
@@ -205,6 +206,7 @@ enum cell_types {
|
|
205
206
|
NUMBER_CELL = 1,
|
206
207
|
STRING_CELL,
|
207
208
|
INLINE_STRING_CELL,
|
209
|
+
INLINE_RICH_STRING_CELL,
|
208
210
|
FORMULA_CELL,
|
209
211
|
ARRAY_FORMULA_CELL,
|
210
212
|
BLANK_CELL,
|
@@ -546,6 +548,7 @@ typedef struct lxw_image_options {
|
|
546
548
|
lxw_row_t row;
|
547
549
|
lxw_col_t col;
|
548
550
|
char *filename;
|
551
|
+
char *description;
|
549
552
|
char *url;
|
550
553
|
char *tip;
|
551
554
|
uint8_t anchor;
|
@@ -553,9 +556,11 @@ typedef struct lxw_image_options {
|
|
553
556
|
/* Internal metadata. */
|
554
557
|
FILE *stream;
|
555
558
|
uint8_t image_type;
|
559
|
+
uint8_t is_image_buffer;
|
560
|
+
unsigned char *image_buffer;
|
561
|
+
size_t image_buffer_size;
|
556
562
|
double width;
|
557
563
|
double height;
|
558
|
-
char *short_name;
|
559
564
|
char *extension;
|
560
565
|
double x_dpi;
|
561
566
|
double y_dpi;
|
@@ -623,15 +628,39 @@ typedef struct lxw_protection {
|
|
623
628
|
/** Protect scenarios. */
|
624
629
|
uint8_t scenarios;
|
625
630
|
|
626
|
-
/** Protect drawing objects. */
|
631
|
+
/** Protect drawing objects. Worksheets only. */
|
627
632
|
uint8_t objects;
|
628
633
|
|
634
|
+
/** Turn off chartsheet content protection. */
|
635
|
+
uint8_t no_content;
|
636
|
+
|
637
|
+
/** Turn off chartsheet objects. */
|
638
|
+
uint8_t no_objects;
|
639
|
+
|
629
640
|
uint8_t no_sheet;
|
630
|
-
uint8_t content;
|
631
641
|
uint8_t is_configured;
|
632
642
|
char hash[5];
|
633
643
|
} lxw_protection;
|
634
644
|
|
645
|
+
/**
|
646
|
+
* @brief Struct to represent a rich string format/string pair.
|
647
|
+
*
|
648
|
+
* Arrays of this struct are used to define "rich" multi-format strings that
|
649
|
+
* are passed to `worksheet_write_rich_string()`. Each struct represents a
|
650
|
+
* fragment of the rich multi-format string with a lxw_format to define the
|
651
|
+
* format for the string part. If the string fragment is unformatted then
|
652
|
+
* `NULL` can be used for the format.
|
653
|
+
*/
|
654
|
+
typedef struct lxw_rich_string_tuple {
|
655
|
+
|
656
|
+
/** The format for a string fragment in a rich string. NULL if the string
|
657
|
+
* isn't formatted. */
|
658
|
+
lxw_format *format;
|
659
|
+
|
660
|
+
/** The string fragment. */
|
661
|
+
char *string;
|
662
|
+
} lxw_rich_string_tuple;
|
663
|
+
|
635
664
|
/**
|
636
665
|
* @brief Struct to represent an Excel worksheet.
|
637
666
|
*
|
@@ -668,6 +697,7 @@ typedef struct lxw_worksheet {
|
|
668
697
|
uint8_t hidden;
|
669
698
|
uint16_t *active_sheet;
|
670
699
|
uint16_t *first_sheet;
|
700
|
+
uint8_t is_chartsheet;
|
671
701
|
|
672
702
|
lxw_col_options **col_options;
|
673
703
|
uint16_t col_options_max;
|
@@ -1305,6 +1335,81 @@ lxw_error worksheet_write_formula_num(lxw_worksheet *worksheet,
|
|
1305
1335
|
const char *formula,
|
1306
1336
|
lxw_format *format, double result);
|
1307
1337
|
|
1338
|
+
/**
|
1339
|
+
* @brief Write a "Rich" multi-format string to a worksheet cell.
|
1340
|
+
*
|
1341
|
+
* @param worksheet pointer to a lxw_worksheet instance to be updated.
|
1342
|
+
* @param row The zero indexed row number.
|
1343
|
+
* @param col The zero indexed column number.
|
1344
|
+
* @param rich_string An array of format/string lxw_rich_string_tuple fragments.
|
1345
|
+
* @param format A pointer to a Format instance or NULL.
|
1346
|
+
*
|
1347
|
+
* @return A #lxw_error code.
|
1348
|
+
*
|
1349
|
+
* The `%worksheet_write_rich_string()` function is used to write strings with
|
1350
|
+
* multiple formats. For example to write the string 'This is **bold**
|
1351
|
+
* and this is *italic*' you would use the following:
|
1352
|
+
*
|
1353
|
+
* @code
|
1354
|
+
* lxw_format *bold = workbook_add_format(workbook);
|
1355
|
+
* format_set_bold(bold);
|
1356
|
+
*
|
1357
|
+
* lxw_format *italic = workbook_add_format(workbook);
|
1358
|
+
* format_set_italic(italic);
|
1359
|
+
*
|
1360
|
+
* lxw_rich_string_tuple fragment11 = {.format = NULL, .string = "This is " };
|
1361
|
+
* lxw_rich_string_tuple fragment12 = {.format = bold, .string = "bold" };
|
1362
|
+
* lxw_rich_string_tuple fragment13 = {.format = NULL, .string = " and this is "};
|
1363
|
+
* lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic" };
|
1364
|
+
*
|
1365
|
+
* lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
|
1366
|
+
* &fragment13, &fragment14, NULL};
|
1367
|
+
*
|
1368
|
+
* worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
|
1369
|
+
*
|
1370
|
+
* @endcode
|
1371
|
+
*
|
1372
|
+
* @image html rich_strings_small.png
|
1373
|
+
*
|
1374
|
+
* The basic rule is to break the string into fragments and put a lxw_format
|
1375
|
+
* object before the fragment that you want to format. So if we look at the
|
1376
|
+
* above example again:
|
1377
|
+
*
|
1378
|
+
* This is **bold** and this is *italic*
|
1379
|
+
*
|
1380
|
+
* The would be broken down into 4 fragments:
|
1381
|
+
*
|
1382
|
+
* default: |This is |
|
1383
|
+
* bold: |bold|
|
1384
|
+
* default: | and this is |
|
1385
|
+
* italic: |italic|
|
1386
|
+
*
|
1387
|
+
* This in then converted to the lxw_rich_string_tuple fragments shown in the
|
1388
|
+
* example above. For the default format we use `NULL`.
|
1389
|
+
*
|
1390
|
+
* The fragments are passed to `%worksheet_write_rich_string()` as a `NULL`
|
1391
|
+
* terminated array:
|
1392
|
+
*
|
1393
|
+
* @code
|
1394
|
+
* lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
|
1395
|
+
* &fragment13, &fragment14, NULL};
|
1396
|
+
*
|
1397
|
+
* worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);
|
1398
|
+
*
|
1399
|
+
* @endcode
|
1400
|
+
*
|
1401
|
+
* **Note**:
|
1402
|
+
* Excel doesn't allow the use of two consecutive formats in a rich string or
|
1403
|
+
* an empty string fragment. For either of these conditions a warning is
|
1404
|
+
* raised and the input to `%worksheet_write_rich_string()` is ignored.
|
1405
|
+
*
|
1406
|
+
*/
|
1407
|
+
lxw_error worksheet_write_rich_string(lxw_worksheet *worksheet,
|
1408
|
+
lxw_row_t row,
|
1409
|
+
lxw_col_t col,
|
1410
|
+
lxw_rich_string_tuple *rich_string[],
|
1411
|
+
lxw_format *format);
|
1412
|
+
|
1308
1413
|
/**
|
1309
1414
|
* @brief Set the properties for a row of cells.
|
1310
1415
|
*
|
@@ -1643,6 +1748,77 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
|
|
1643
1748
|
lxw_row_t row, lxw_col_t col,
|
1644
1749
|
const char *filename,
|
1645
1750
|
lxw_image_options *options);
|
1751
|
+
|
1752
|
+
/**
|
1753
|
+
* @brief Insert an image in a worksheet cell, from a memory buffer.
|
1754
|
+
*
|
1755
|
+
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
|
1756
|
+
* @param row The zero indexed row number.
|
1757
|
+
* @param col The zero indexed column number.
|
1758
|
+
* @param image_buffer Pointer to an array of bytes that holds the image data.
|
1759
|
+
* @param image_size The size of the array of bytes.
|
1760
|
+
*
|
1761
|
+
* @return A #lxw_error code.
|
1762
|
+
*
|
1763
|
+
* This function can be used to insert a image into a worksheet from a memory
|
1764
|
+
* buffer:
|
1765
|
+
*
|
1766
|
+
* @code
|
1767
|
+
* worksheet_insert_image_buffer(worksheet, CELL("B3"), image_buffer, image_size);
|
1768
|
+
* @endcode
|
1769
|
+
*
|
1770
|
+
* @image html image_buffer.png
|
1771
|
+
*
|
1772
|
+
* The buffer should be a pointer to an array of unsigned char data with a
|
1773
|
+
* specified size.
|
1774
|
+
*
|
1775
|
+
* See `worksheet_insert_image()` for details about the supported image
|
1776
|
+
* formats, and other image features.
|
1777
|
+
*/
|
1778
|
+
lxw_error worksheet_insert_image_buffer(lxw_worksheet *worksheet,
|
1779
|
+
lxw_row_t row,
|
1780
|
+
lxw_col_t col,
|
1781
|
+
const unsigned char *image_buffer,
|
1782
|
+
size_t image_size);
|
1783
|
+
|
1784
|
+
/**
|
1785
|
+
* @brief Insert an image in a worksheet cell, from a memory buffer.
|
1786
|
+
*
|
1787
|
+
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
|
1788
|
+
* @param row The zero indexed row number.
|
1789
|
+
* @param col The zero indexed column number.
|
1790
|
+
* @param image_buffer Pointer to an array of bytes that holds the image data.
|
1791
|
+
* @param image_size The size of the array of bytes.
|
1792
|
+
* @param options Optional image parameters.
|
1793
|
+
*
|
1794
|
+
* @return A #lxw_error code.
|
1795
|
+
*
|
1796
|
+
* The `%worksheet_insert_image_buffer_opt()` function is like
|
1797
|
+
* `worksheet_insert_image_buffer()` function except that it takes an optional
|
1798
|
+
* #lxw_image_options struct to scale and position the image:
|
1799
|
+
*
|
1800
|
+
* @code
|
1801
|
+
* lxw_image_options options = {.x_offset = 32, .y_offset = 4,
|
1802
|
+
* .x_scale = 2, .y_scale = 1};
|
1803
|
+
*
|
1804
|
+
* worksheet_insert_image_buffer_opt(worksheet, CELL("B3"), image_buffer, image_size, &options);
|
1805
|
+
* @endcode
|
1806
|
+
*
|
1807
|
+
* @image html image_buffer_opt.png
|
1808
|
+
*
|
1809
|
+
* The buffer should be a pointer to an array of unsigned char data with a
|
1810
|
+
* specified size.
|
1811
|
+
*
|
1812
|
+
* See `worksheet_insert_image_buffer_opt()` for details about the supported
|
1813
|
+
* image formats, and other image options.
|
1814
|
+
*/
|
1815
|
+
lxw_error worksheet_insert_image_buffer_opt(lxw_worksheet *worksheet,
|
1816
|
+
lxw_row_t row,
|
1817
|
+
lxw_col_t col,
|
1818
|
+
const unsigned char *image_buffer,
|
1819
|
+
size_t image_size,
|
1820
|
+
lxw_image_options *options);
|
1821
|
+
|
1646
1822
|
/**
|
1647
1823
|
* @brief Insert a chart object into a worksheet.
|
1648
1824
|
*
|
@@ -1653,8 +1829,8 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
|
|
1653
1829
|
*
|
1654
1830
|
* @return A #lxw_error code.
|
1655
1831
|
*
|
1656
|
-
* The `%worksheet_insert_chart()` can be used to insert a chart into
|
1657
|
-
* worksheet. The chart object must be created first using the
|
1832
|
+
* The `%worksheet_insert_chart()` function can be used to insert a chart into
|
1833
|
+
* a worksheet. The chart object must be created first using the
|
1658
1834
|
* `workbook_add_chart()` function and configured using the @ref chart.h
|
1659
1835
|
* functions.
|
1660
1836
|
*
|
@@ -1665,13 +1841,12 @@ lxw_error worksheet_insert_image_opt(lxw_worksheet *worksheet,
|
|
1665
1841
|
* // Add a data series to the chart.
|
1666
1842
|
* chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$6");
|
1667
1843
|
*
|
1668
|
-
* // Insert the chart into the worksheet
|
1844
|
+
* // Insert the chart into the worksheet.
|
1669
1845
|
* worksheet_insert_chart(worksheet, 0, 2, chart);
|
1670
1846
|
* @endcode
|
1671
1847
|
*
|
1672
1848
|
* @image html chart_working.png
|
1673
1849
|
*
|
1674
|
-
*
|
1675
1850
|
* **Note:**
|
1676
1851
|
*
|
1677
1852
|
* A chart may only be inserted into a worksheet once. If several similar
|
@@ -2282,26 +2457,26 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
|
|
2282
2457
|
* @code
|
2283
2458
|
* worksheet_set_header(worksheet, "&LHello");
|
2284
2459
|
*
|
2285
|
-
*
|
2286
|
-
* | |
|
2287
|
-
* | Hello |
|
2288
|
-
* | |
|
2460
|
+
* // ---------------------------------------------------------------
|
2461
|
+
* // | |
|
2462
|
+
* // | Hello |
|
2463
|
+
* // | |
|
2289
2464
|
*
|
2290
2465
|
*
|
2291
2466
|
* worksheet_set_header(worksheet, "&CHello");
|
2292
2467
|
*
|
2293
|
-
*
|
2294
|
-
* | |
|
2295
|
-
* | Hello |
|
2296
|
-
* | |
|
2468
|
+
* // ---------------------------------------------------------------
|
2469
|
+
* // | |
|
2470
|
+
* // | Hello |
|
2471
|
+
* // | |
|
2297
2472
|
*
|
2298
2473
|
*
|
2299
2474
|
* worksheet_set_header(worksheet, "&RHello");
|
2300
2475
|
*
|
2301
|
-
*
|
2302
|
-
* | |
|
2303
|
-
* | Hello |
|
2304
|
-
* | |
|
2476
|
+
* // ---------------------------------------------------------------
|
2477
|
+
* // | |
|
2478
|
+
* // | Hello |
|
2479
|
+
* // | |
|
2305
2480
|
*
|
2306
2481
|
*
|
2307
2482
|
* @endcode
|
@@ -2313,10 +2488,10 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
|
|
2313
2488
|
* @code
|
2314
2489
|
* worksheet_set_header(worksheet, "Hello");
|
2315
2490
|
*
|
2316
|
-
*
|
2317
|
-
* | |
|
2318
|
-
* | Hello |
|
2319
|
-
* | |
|
2491
|
+
* // ---------------------------------------------------------------
|
2492
|
+
* // | |
|
2493
|
+
* // | Hello |
|
2494
|
+
* // | |
|
2320
2495
|
*
|
2321
2496
|
* @endcode
|
2322
2497
|
*
|
@@ -2325,10 +2500,10 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
|
|
2325
2500
|
* @code
|
2326
2501
|
* worksheet_set_header(worksheet, "&LCiao&CBello&RCielo");
|
2327
2502
|
*
|
2328
|
-
*
|
2329
|
-
* | |
|
2330
|
-
* | Ciao Bello Cielo |
|
2331
|
-
* | |
|
2503
|
+
* // ---------------------------------------------------------------
|
2504
|
+
* // | |
|
2505
|
+
* // | Ciao Bello Cielo |
|
2506
|
+
* // | |
|
2332
2507
|
*
|
2333
2508
|
* @endcode
|
2334
2509
|
*
|
@@ -2339,17 +2514,17 @@ void worksheet_set_margins(lxw_worksheet *worksheet, double left,
|
|
2339
2514
|
* @code
|
2340
2515
|
* worksheet_set_header(worksheet, "&CPage &P of &N");
|
2341
2516
|
*
|
2342
|
-
*
|
2343
|
-
* | |
|
2344
|
-
* | Page 1 of 6 |
|
2345
|
-
* | |
|
2517
|
+
* // ---------------------------------------------------------------
|
2518
|
+
* // | |
|
2519
|
+
* // | Page 1 of 6 |
|
2520
|
+
* // | |
|
2346
2521
|
*
|
2347
2522
|
* worksheet_set_header(worksheet, "&CUpdated at &T");
|
2348
2523
|
*
|
2349
|
-
*
|
2350
|
-
* | |
|
2351
|
-
* | Updated at 12:30 PM |
|
2352
|
-
* | |
|
2524
|
+
* // ---------------------------------------------------------------
|
2525
|
+
* // | |
|
2526
|
+
* // | Updated at 12:30 PM |
|
2527
|
+
* // | |
|
2353
2528
|
*
|
2354
2529
|
* @endcode
|
2355
2530
|
*
|
@@ -2889,8 +3064,8 @@ void worksheet_hide_zero(lxw_worksheet *worksheet);
|
|
2889
3064
|
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
|
2890
3065
|
* @param color The tab color.
|
2891
3066
|
*
|
2892
|
-
* The `%worksheet_set_tab_color()` function is used to change the color of
|
2893
|
-
* tab:
|
3067
|
+
* The `%worksheet_set_tab_color()` function is used to change the color of
|
3068
|
+
* the worksheet tab:
|
2894
3069
|
*
|
2895
3070
|
* @code
|
2896
3071
|
* worksheet_set_tab_color(worksheet1, LXW_COLOR_RED);
|
@@ -2973,11 +3148,10 @@ void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
|
|
2973
3148
|
*
|
2974
3149
|
* See also the format_set_unlocked() and format_set_hidden() format functions.
|
2975
3150
|
*
|
2976
|
-
* **Note:**
|
3151
|
+
* **Note:** Sheet level passwords in Excel offer **very** weak
|
2977
3152
|
* protection. They don't encrypt your data and are very easy to
|
2978
3153
|
* deactivate. Full workbook encryption is not supported by `libxlsxwriter`
|
2979
|
-
* since it requires a completely different file format
|
2980
|
-
* man months to implement.
|
3154
|
+
* since it requires a completely different file format.
|
2981
3155
|
*/
|
2982
3156
|
void worksheet_protect(lxw_worksheet *worksheet, const char *password,
|
2983
3157
|
lxw_protection *options);
|
@@ -3072,11 +3246,24 @@ void lxw_worksheet_prepare_image(lxw_worksheet *worksheet,
|
|
3072
3246
|
|
3073
3247
|
void lxw_worksheet_prepare_chart(lxw_worksheet *worksheet,
|
3074
3248
|
uint16_t chart_ref_id, uint16_t drawing_id,
|
3075
|
-
lxw_image_options *image_data
|
3249
|
+
lxw_image_options *image_data,
|
3250
|
+
uint8_t is_chartsheet);
|
3076
3251
|
|
3077
3252
|
lxw_row *lxw_worksheet_find_row(lxw_worksheet *worksheet, lxw_row_t row_num);
|
3078
3253
|
lxw_cell *lxw_worksheet_find_cell(lxw_row *row, lxw_col_t col_num);
|
3079
3254
|
|
3255
|
+
/*
|
3256
|
+
* External functions to call intern XML methods shared with chartsheet.
|
3257
|
+
*/
|
3258
|
+
void lxw_worksheet_write_sheet_views(lxw_worksheet *worksheet);
|
3259
|
+
void lxw_worksheet_write_page_margins(lxw_worksheet *worksheet);
|
3260
|
+
void lxw_worksheet_write_drawings(lxw_worksheet *worksheet);
|
3261
|
+
void lxw_worksheet_write_sheet_protection(lxw_worksheet *worksheet,
|
3262
|
+
lxw_protection *protect);
|
3263
|
+
void lxw_worksheet_write_sheet_pr(lxw_worksheet *worksheet);
|
3264
|
+
void lxw_worksheet_write_page_setup(lxw_worksheet *worksheet);
|
3265
|
+
void lxw_worksheet_write_header_footer(lxw_worksheet *worksheet);
|
3266
|
+
|
3080
3267
|
/* Declarations required for unit testing. */
|
3081
3268
|
#ifdef TESTING
|
3082
3269
|
|
@@ -3106,7 +3293,8 @@ STATIC void _worksheet_write_header_footer(lxw_worksheet *worksheet);
|
|
3106
3293
|
STATIC void _worksheet_write_print_options(lxw_worksheet *worksheet);
|
3107
3294
|
STATIC void _worksheet_write_sheet_pr(lxw_worksheet *worksheet);
|
3108
3295
|
STATIC void _worksheet_write_tab_color(lxw_worksheet *worksheet);
|
3109
|
-
STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet
|
3296
|
+
STATIC void _worksheet_write_sheet_protection(lxw_worksheet *worksheet,
|
3297
|
+
lxw_protection *protect);
|
3110
3298
|
STATIC void _worksheet_write_data_validations(lxw_worksheet *self);
|
3111
3299
|
#endif /* TESTING */
|
3112
3300
|
|