xlsxwriter 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|