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.
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