xlsxwriter 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +1 -1
  3. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +55 -5
  4. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
  5. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +6 -0
  6. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +2 -0
  7. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +1 -0
  8. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1 -1
  9. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +3 -1
  10. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +7 -2
  11. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +16 -0
  12. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +122 -24
  13. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +236 -48
  14. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +2 -0
  15. data/ext/xlsxwriter/libxlsxwriter/src/chart.c +40 -4
  16. data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +508 -0
  17. data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +10 -0
  18. data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +100 -3
  19. data/ext/xlsxwriter/libxlsxwriter/src/packager.c +252 -30
  20. data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +16 -2
  21. data/ext/xlsxwriter/libxlsxwriter/src/styles.c +54 -7
  22. data/ext/xlsxwriter/libxlsxwriter/src/utility.c +43 -1
  23. data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +254 -41
  24. data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +381 -65
  25. data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +16 -7
  26. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
  27. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2 -0
  28. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
  29. data/ext/xlsxwriter/workbook.c +9 -6
  30. data/lib/xlsxwriter/version.rb +1 -1
  31. 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,
@@ -77,6 +77,7 @@ typedef struct lxw_drawing {
77
77
  FILE *file;
78
78
 
79
79
  uint8_t embedded;
80
+ uint8_t orientation;
80
81
 
81
82
  struct lxw_drawing_objects *drawing_objects;
82
83
 
@@ -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
- * format_set_num_format(format, 0x0F); // d-mmm-yy
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 LXW_RB_GENERATE_NAMES(name, type, field, cmp) \
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 lxw_rb_generate_names{int unused;}
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 `tempdir` option.
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 `tempdir` option.*
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 Validate a worksheet name.
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 Worksheet name to validate.
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 to the rules
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 = workbook_validate_worksheet_name(workbook, "Foglio");
803
+ * lxw_error err = workbook_validate_sheet_name(workbook, "Foglio");
706
804
  * @endcode
707
805
  *
708
- * This function is called by `workbook_add_worksheet()` but it can be
709
- * explicitly called by the user beforehand to ensure that the worksheet
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 workbook_validate_worksheet_name(lxw_workbook *workbook,
714
- const char *sheetname);
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 1048576
59
- #define LXW_COL_MAX 16384
60
- #define LXW_COL_META_MAX 128
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 65530
63
- #define LXW_PANE_NAME_LENGTH 12 /* bottomRight + 1 */
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 1023
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 a
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 the worksheet
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:** Worksheet level passwords in Excel offer **very** weak
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 and would take several
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