fast_excel 0.2.2 → 0.4.0

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 (100) hide show
  1. checksums.yaml +5 -5
  2. data/.dockerignore +2 -0
  3. data/.gitignore +7 -0
  4. data/.travis.yml +32 -9
  5. data/CHANGELOG.md +36 -1
  6. data/Dockerfile.test +17 -0
  7. data/Gemfile +2 -1
  8. data/Gemfile.lock +33 -24
  9. data/LICENSE +21 -0
  10. data/Makefile +13 -0
  11. data/README.md +177 -40
  12. data/Rakefile +11 -1
  13. data/benchmarks/1k_rows.rb +17 -4
  14. data/benchmarks/20k_rows.rb +4 -0
  15. data/benchmarks/auto_width.rb +37 -0
  16. data/benchmarks/init.rb +14 -2
  17. data/benchmarks/memory.rb +8 -0
  18. data/benchmarks/profiler.rb +27 -0
  19. data/benchmarks/write_value.rb +62 -0
  20. data/examples/example.rb +3 -3
  21. data/examples/example_auto_width.rb +26 -0
  22. data/examples/example_filters.rb +36 -0
  23. data/examples/example_formula.rb +1 -3
  24. data/examples/example_hyperlink.rb +20 -0
  25. data/ext/fast_excel/extconf.rb +3 -0
  26. data/ext/fast_excel/text_width_ext.c +460 -0
  27. data/fast_excel.gemspec +3 -4
  28. data/letters.html +114 -0
  29. data/lib/fast_excel.rb +131 -25
  30. data/lib/fast_excel/binding.rb +33 -21
  31. data/lib/fast_excel/binding/chart.rb +20 -1
  32. data/lib/fast_excel/binding/format.rb +11 -4
  33. data/lib/fast_excel/binding/workbook.rb +10 -2
  34. data/lib/fast_excel/binding/worksheet.rb +44 -27
  35. data/libxlsxwriter/.gitignore +1 -0
  36. data/libxlsxwriter/.indent.pro +8 -0
  37. data/libxlsxwriter/.travis.yml +12 -0
  38. data/libxlsxwriter/CMakeLists.txt +338 -0
  39. data/libxlsxwriter/CONTRIBUTING.md +1 -1
  40. data/libxlsxwriter/Changes.txt +162 -0
  41. data/libxlsxwriter/LICENSE.txt +65 -4
  42. data/libxlsxwriter/Makefile +33 -11
  43. data/libxlsxwriter/Readme.md +3 -1
  44. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +2 -1
  45. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +2 -2
  46. data/libxlsxwriter/include/xlsxwriter.h +2 -2
  47. data/libxlsxwriter/include/xlsxwriter/app.h +2 -2
  48. data/libxlsxwriter/include/xlsxwriter/chart.h +164 -13
  49. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
  50. data/libxlsxwriter/include/xlsxwriter/common.h +35 -6
  51. data/libxlsxwriter/include/xlsxwriter/content_types.h +5 -2
  52. data/libxlsxwriter/include/xlsxwriter/core.h +2 -2
  53. data/libxlsxwriter/include/xlsxwriter/custom.h +2 -2
  54. data/libxlsxwriter/include/xlsxwriter/drawing.h +3 -2
  55. data/libxlsxwriter/include/xlsxwriter/format.h +8 -8
  56. data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
  57. data/libxlsxwriter/include/xlsxwriter/packager.h +18 -8
  58. data/libxlsxwriter/include/xlsxwriter/relationships.h +2 -2
  59. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +5 -3
  60. data/libxlsxwriter/include/xlsxwriter/styles.h +10 -5
  61. data/libxlsxwriter/include/xlsxwriter/theme.h +2 -2
  62. data/libxlsxwriter/include/xlsxwriter/utility.h +35 -5
  63. data/libxlsxwriter/include/xlsxwriter/workbook.h +234 -57
  64. data/libxlsxwriter/include/xlsxwriter/worksheet.h +780 -91
  65. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +4 -2
  66. data/libxlsxwriter/libxlsxwriter.podspec +4 -2
  67. data/libxlsxwriter/src/Makefile +31 -6
  68. data/libxlsxwriter/src/app.c +2 -2
  69. data/libxlsxwriter/src/chart.c +116 -23
  70. data/libxlsxwriter/src/chartsheet.c +508 -0
  71. data/libxlsxwriter/src/content_types.c +12 -4
  72. data/libxlsxwriter/src/core.c +11 -11
  73. data/libxlsxwriter/src/custom.c +3 -3
  74. data/libxlsxwriter/src/drawing.c +114 -17
  75. data/libxlsxwriter/src/format.c +5 -5
  76. data/libxlsxwriter/src/hash_table.c +1 -1
  77. data/libxlsxwriter/src/packager.c +378 -61
  78. data/libxlsxwriter/src/relationships.c +2 -2
  79. data/libxlsxwriter/src/shared_strings.c +18 -4
  80. data/libxlsxwriter/src/styles.c +59 -12
  81. data/libxlsxwriter/src/theme.c +2 -2
  82. data/libxlsxwriter/src/utility.c +93 -6
  83. data/libxlsxwriter/src/workbook.c +379 -61
  84. data/libxlsxwriter/src/worksheet.c +1240 -174
  85. data/libxlsxwriter/src/xmlwriter.c +18 -9
  86. data/libxlsxwriter/third_party/minizip/Makefile +6 -1
  87. data/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
  88. data/libxlsxwriter/third_party/minizip/zip.c +2 -0
  89. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
  90. data/libxlsxwriter/version.txt +1 -1
  91. data/test/auto_width_test.rb +19 -0
  92. data/test/date_test.rb +34 -0
  93. data/test/format_test.rb +8 -0
  94. data/test/reopen_test.rb +22 -0
  95. data/test/test_helper.rb +8 -5
  96. data/test/text_width_test.rb +80 -0
  97. data/test/tmpfile_test.rb +1 -0
  98. data/test/validations_test.rb +47 -0
  99. data/test/worksheet_test.rb +44 -1
  100. metadata +33 -9
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libxlsxwriter
3
3
  *
4
- * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
4
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
5
  *
6
6
  * xmlwriter - A libxlsxwriter library for creating Excel XLSX
7
7
  * XML files.
@@ -22,7 +22,7 @@
22
22
  #include <stdio.h>
23
23
  #include <stdlib.h>
24
24
  #include <stdint.h>
25
- #include "common.h"
25
+ #include "utility.h"
26
26
 
27
27
  #define LXW_MAX_ATTRIBUTE_LENGTH 256
28
28
  #define LXW_ATTR_32 32
@@ -165,6 +165,8 @@ void lxw_xml_data_element(FILE * xmlfile,
165
165
  const char *data,
166
166
  struct xml_attribute_list *attributes);
167
167
 
168
+ void lxw_xml_rich_si_element(FILE * xmlfile, const char *string);
169
+
168
170
  char *lxw_escape_control_characters(const char *string);
169
171
 
170
172
  char *lxw_escape_data(const char *data);
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = "libxlsxwriter"
3
- s.version = "0.6.9"
3
+ s.version = "0.8.6"
4
4
  s.summary = "Libxlsxwriter: A C library for creating Excel XLSX files."
5
5
  s.ios.deployment_target = "6.0"
6
6
  s.osx.deployment_target = "10.8"
@@ -16,6 +16,7 @@ Pod::Spec.new do |s|
16
16
  * Defined names.
17
17
  * Autofilters.
18
18
  * Charts.
19
+ * Data validation and drop down lists.
19
20
  * Worksheet PNG/JPEG images.
20
21
  * Memory optimisation mode for writing large files.
21
22
  * Source code available on [GitHub](https://github.com/jmcnamara/libxlsxwriter).
@@ -24,6 +25,7 @@ Pod::Spec.new do |s|
24
25
  * Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32.
25
26
  * Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin.
26
27
  * Compiles for 32 and 64 bit.
28
+ * Compiles and works on big and little endian systems.
27
29
  * The only dependency is on `zlib`.
28
30
  DESC
29
31
 
@@ -36,7 +38,7 @@ Pod::Spec.new do |s|
36
38
  s.source_files = "src/**/*.c", "third_party/**/{zip.c,ioapi.c,tmpfileplus.c}", "include/**/*.h"
37
39
 
38
40
  s.header_dir = "xlsxwriter"
39
- s.header_mappings_dir = "include/xlsxwriter"
41
+ s.header_mappings_dir = "include"
40
42
  s.library = "z"
41
43
  s.compiler_flags = "-DNOCRYPT=1", "-DNOUNCRYPT=1"
42
44
  s.pod_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '${PODS_ROOT}/libxlsxwriter/include' }
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Makefile for libxlsxwriter library.
4
4
  #
5
- # Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
5
+ # Copyright 2014-2019, John McNamara, jmcnamara@cpan.org
6
6
  #
7
7
 
8
8
  # Keep the output quiet by default.
@@ -15,8 +15,17 @@ endif
15
15
  OBJS_DIR = .
16
16
  INC_DIR = ../include
17
17
 
18
- # The minizip directory.
18
+ LIBS = -lz
19
+
20
+ ifdef USE_SYSTEM_MINIZIP
21
+ LIBS += -lminizip
22
+ CFLAGS += -DUSE_SYSTEM_MINIZIP
23
+ else
24
+ # Use the local copy of minizip.
19
25
  MINIZIP_DIR = ../third_party/minizip
26
+ MINIZIP_OBJ = $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o
27
+ MINIZIP_SO = $(MINIZIP_DIR)/ioapi.so $(MINIZIP_DIR)/zip.so
28
+ endif
20
29
 
21
30
 
22
31
  ifdef USE_STANDARD_TMPFILE
@@ -29,9 +38,25 @@ TMPFILEPLUS_OBJ = $(TMPFILEPLUS_DIR)/tmpfileplus.o
29
38
  TMPFILEPLUS_SO = $(TMPFILEPLUS_DIR)/tmpfileplus.so
30
39
  endif
31
40
 
41
+ # Set flag for big endian architecture.
42
+ ifdef USE_BIG_ENDIAN
43
+ CFLAGS += -DLXW_BIG_ENDIAN
44
+ endif
45
+
46
+ # Use a user-defined double number formatting function.
47
+ ifdef USE_DOUBLE_FUNCTION
48
+ CFLAGS += -DUSE_DOUBLE_FUNCTION
49
+ endif
50
+
32
51
  # Flags passed to compiler.
33
52
  CFLAGS += -g -O3 -Wall -Wextra -pedantic -ansi
34
53
 
54
+ # Fix for modified zconf.h on Gentoo.
55
+ ifneq (,$(findstring gentoo, $(shell uname -sr)))
56
+ CFLAGS += -DOF=_Z_OF
57
+ endif
58
+
59
+
35
60
  # Ignore icc remarks about inlining limits.
36
61
  ifeq ($(CC),icc)
37
62
  CFLAGS +=-diag-disable=11074,11076
@@ -97,7 +122,7 @@ test_lib : libxlsxwriter_test.a
97
122
 
98
123
  # The static library.
99
124
  $(LIBXLSXWRITER_A) : $(OBJS)
100
- $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o $(TMPFILEPLUS_OBJ) $^
125
+ $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_OBJ) $(TMPFILEPLUS_OBJ) $^
101
126
 
102
127
  # The dynamic library.
103
128
  ifeq ($(findstring m32,$(CFLAGS)),m32)
@@ -105,11 +130,11 @@ ARCH = -m32
105
130
  endif
106
131
 
107
132
  $(LIBXLSXWRITER_SO) : $(SOBJS)
108
- $(Q)$(CC) $(SOFLAGS) $(ARCH) -o $@ $(MINIZIP_DIR)/ioapi.so $(MINIZIP_DIR)/zip.so $(TMPFILEPLUS_SO) $^ -lz
133
+ $(Q)$(CC) $(LDFLAGS) $(SOFLAGS) $(ARCH) -o $@ $(MINIZIP_SO) $(TMPFILEPLUS_SO) $^ $(LIBS)
109
134
 
110
135
  # The test library.
111
136
  $(LIBXLSXWRITER_TO) : $(TOBJS)
112
- $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o $(TMPFILEPLUS_OBJ) $^
137
+ $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_OBJ) $(TMPFILEPLUS_OBJ) $^
113
138
 
114
139
  # Minimal target for quick compile without creating the libs.
115
140
  test_compile : $(OBJS)
@@ -119,7 +144,7 @@ test_compile : $(OBJS)
119
144
  $(Q)$(CC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $<
120
145
 
121
146
  %.so : %.c $(HDRS)
122
- $(Q)$(CC) $(FPIC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
147
+ $(Q)$(CC) $(FPIC) -I$(INC_DIR) $(LDFLAGS) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
123
148
 
124
149
  %.to : %.c $(HDRS)
125
150
  $(Q)$(CC) -g -O3 -DTESTING -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -25,7 +25,7 @@
25
25
  * Create a new app object.
26
26
  */
27
27
  lxw_app *
28
- lxw_app_new()
28
+ lxw_app_new(void)
29
29
  {
30
30
  lxw_app *app = calloc(1, sizeof(lxw_app));
31
31
  GOTO_LABEL_ON_MEM_ERROR(app, mem_error);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * Copyright 2014-2019, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
7
  *
8
8
  */
9
9
 
@@ -311,13 +311,21 @@ _chart_convert_font_args(lxw_chart_font *user_font)
311
311
  font = calloc(1, sizeof(struct lxw_chart_font));
312
312
  RETURN_ON_MEM_ERROR(font, NULL);
313
313
 
314
- memcpy(font, user_font, sizeof(lxw_chart_font));
315
-
314
+ /* Copy the user supplied properties. */
316
315
  font->name = lxw_strdup(user_font->name);
316
+ font->size = user_font->size;
317
+ font->bold = user_font->bold;
318
+ font->italic = user_font->italic;
319
+ font->underline = user_font->underline;
320
+ font->rotation = user_font->rotation;
321
+ font->color = user_font->color;
322
+ font->pitch_family = user_font->pitch_family;
323
+ font->charset = user_font->charset;
324
+ font->baseline = user_font->baseline;
317
325
 
318
326
  /* Convert font size units. */
319
- if (font->size)
320
- font->size = font->size * 100;
327
+ if (font->size > 0.0)
328
+ font->size = font->size * 100.0;
321
329
 
322
330
  /* Convert rotation into 60,000ths of a degree. */
323
331
  if (font->rotation)
@@ -345,7 +353,12 @@ _chart_convert_line_args(lxw_chart_line *user_line)
345
353
  line = calloc(1, sizeof(struct lxw_chart_line));
346
354
  RETURN_ON_MEM_ERROR(line, NULL);
347
355
 
348
- memcpy(line, user_line, sizeof(lxw_chart_line));
356
+ /* Copy the user supplied properties. */
357
+ line->color = user_line->color;
358
+ line->none = user_line->none;
359
+ line->width = user_line->width;
360
+ line->dash_type = user_line->dash_type;
361
+ line->transparency = user_line->transparency;
349
362
 
350
363
  if (line->color) {
351
364
  line->color = lxw_format_check_color(line->color);
@@ -372,7 +385,10 @@ _chart_convert_fill_args(lxw_chart_fill *user_fill)
372
385
  fill = calloc(1, sizeof(struct lxw_chart_fill));
373
386
  RETURN_ON_MEM_ERROR(fill, NULL);
374
387
 
375
- memcpy(fill, user_fill, sizeof(lxw_chart_fill));
388
+ /* Copy the user supplied properties. */
389
+ fill->color = user_fill->color;
390
+ fill->none = user_fill->none;
391
+ fill->transparency = user_fill->transparency;
376
392
 
377
393
  if (fill->color) {
378
394
  fill->color = lxw_format_check_color(fill->color);
@@ -409,7 +425,10 @@ _chart_convert_pattern_args(lxw_chart_pattern *user_pattern)
409
425
  pattern = calloc(1, sizeof(struct lxw_chart_pattern));
410
426
  RETURN_ON_MEM_ERROR(pattern, NULL);
411
427
 
412
- memcpy(pattern, user_pattern, sizeof(lxw_chart_pattern));
428
+ /* Copy the user supplied properties. */
429
+ pattern->fg_color = user_pattern->fg_color;
430
+ pattern->bg_color = user_pattern->bg_color;
431
+ pattern->type = user_pattern->type;
413
432
 
414
433
  pattern->fg_color = lxw_format_check_color(pattern->fg_color);
415
434
  pattern->has_fg_color = LXW_TRUE;
@@ -424,8 +443,6 @@ _chart_convert_pattern_args(lxw_chart_pattern *user_pattern)
424
443
  pattern->has_bg_color = LXW_TRUE;
425
444
  }
426
445
 
427
- pattern->type = user_pattern->type;
428
-
429
446
  return pattern;
430
447
  }
431
448
 
@@ -556,6 +573,15 @@ _chart_xml_declaration(lxw_chart *self)
556
573
  lxw_xml_declaration(self->file);
557
574
  }
558
575
 
576
+ /*
577
+ * Write the <c:protection> element.
578
+ */
579
+ STATIC void
580
+ _chart_write_protection(lxw_chart *self)
581
+ {
582
+ lxw_xml_empty_tag(self->file, "c:protection", NULL);
583
+ }
584
+
559
585
  /*
560
586
  * Write the <c:chartSpace> element.
561
587
  */
@@ -836,8 +862,8 @@ _chart_write_a_def_rpr(lxw_chart *self, lxw_chart_font *font)
836
862
  use_font_default = !(has_color || has_latin || font->baseline == -1);
837
863
 
838
864
  /* Set the font attributes. */
839
- if (font->size)
840
- LXW_PUSH_ATTRIBUTES_INT("sz", font->size);
865
+ if (font->size > 0.0)
866
+ LXW_PUSH_ATTRIBUTES_DBL("sz", font->size);
841
867
 
842
868
  if (use_font_default || font->bold)
843
869
  LXW_PUSH_ATTRIBUTES_INT("b", font->bold & 0x1);
@@ -908,8 +934,8 @@ _chart_write_a_r_pr(lxw_chart *self, lxw_chart_font *font)
908
934
  use_font_default = !(has_color || has_latin || font->baseline == -1);
909
935
 
910
936
  /* Set the font attributes. */
911
- if (font->size)
912
- LXW_PUSH_ATTRIBUTES_INT("sz", font->size);
937
+ if (font->size > 0.0)
938
+ LXW_PUSH_ATTRIBUTES_DBL("sz", font->size);
913
939
 
914
940
  if (use_font_default || font->bold)
915
941
  LXW_PUSH_ATTRIBUTES_INT("b", font->bold & 0x1);
@@ -1137,7 +1163,7 @@ _chart_write_v_num(lxw_chart *self, double number)
1137
1163
  {
1138
1164
  char data[LXW_ATTR_32];
1139
1165
 
1140
- lxw_snprintf(data, LXW_ATTR_32, "%.16g", number);
1166
+ lxw_sprintf_dbl(data, number);
1141
1167
 
1142
1168
  lxw_xml_data_element(self->file, "c:v", data, NULL);
1143
1169
  }
@@ -3184,13 +3210,19 @@ _chart_write_auto(lxw_chart *self)
3184
3210
  * Write the <c:lblAlgn> element.
3185
3211
  */
3186
3212
  STATIC void
3187
- _chart_write_label_align(lxw_chart *self)
3213
+ _chart_write_label_align(lxw_chart *self, lxw_chart_axis *axis)
3188
3214
  {
3189
3215
  struct xml_attribute_list attributes;
3190
3216
  struct xml_attribute *attribute;
3191
3217
 
3192
3218
  LXW_INIT_ATTRIBUTES();
3193
- LXW_PUSH_ATTRIBUTES_STR("val", "ctr");
3219
+
3220
+ if (axis->label_align == LXW_CHART_AXIS_LABEL_ALIGN_LEFT)
3221
+ LXW_PUSH_ATTRIBUTES_STR("val", "l");
3222
+ else if (axis->label_align == LXW_CHART_AXIS_LABEL_ALIGN_RIGHT)
3223
+ LXW_PUSH_ATTRIBUTES_STR("val", "r");
3224
+ else
3225
+ LXW_PUSH_ATTRIBUTES_STR("val", "ctr");
3194
3226
 
3195
3227
  lxw_xml_empty_tag(self->file, "c:lblAlgn", &attributes);
3196
3228
 
@@ -3568,6 +3600,9 @@ _chart_write_legend(lxw_chart *self)
3568
3600
  case LXW_CHART_LEGEND_BOTTOM:
3569
3601
  _chart_write_legend_pos(self, "b");
3570
3602
  break;
3603
+ case LXW_CHART_LEGEND_TOP_RIGHT:
3604
+ _chart_write_legend_pos(self, "tr");
3605
+ break;
3571
3606
  case LXW_CHART_LEGEND_OVERLAY_RIGHT:
3572
3607
  _chart_write_legend_pos(self, "r");
3573
3608
  has_overlay = LXW_TRUE;
@@ -3576,6 +3611,10 @@ _chart_write_legend(lxw_chart *self)
3576
3611
  _chart_write_legend_pos(self, "l");
3577
3612
  has_overlay = LXW_TRUE;
3578
3613
  break;
3614
+ case LXW_CHART_LEGEND_OVERLAY_TOP_RIGHT:
3615
+ _chart_write_legend_pos(self, "tr");
3616
+ has_overlay = LXW_TRUE;
3617
+ break;
3579
3618
  default:
3580
3619
  _chart_write_legend_pos(self, "r");
3581
3620
  }
@@ -4074,7 +4113,7 @@ _chart_write_cat_axis(lxw_chart *self)
4074
4113
  _chart_write_auto(self);
4075
4114
 
4076
4115
  /* Write the c:lblAlgn element. */
4077
- _chart_write_label_align(self);
4116
+ _chart_write_label_align(self, self->x_axis);
4078
4117
 
4079
4118
  /* Write the c:lblOffset element. */
4080
4119
  _chart_write_label_offset(self);
@@ -4565,6 +4604,10 @@ _chart_write_pie_plot_area(lxw_chart *self)
4565
4604
  /* Write subclass chart type elements for primary and secondary axes. */
4566
4605
  self->write_chart_type(self);
4567
4606
 
4607
+ /* Write the c:spPr element for the plotarea formatting. */
4608
+ _chart_write_sp_pr(self, self->plotarea_line, self->plotarea_fill,
4609
+ self->plotarea_pattern);
4610
+
4568
4611
  lxw_xml_end_tag(self->file, "c:plotArea");
4569
4612
  }
4570
4613
 
@@ -4907,6 +4950,10 @@ lxw_chart_assemble_xml_file(lxw_chart *self)
4907
4950
  /* Write the c:style element. */
4908
4951
  _chart_write_style(self);
4909
4952
 
4953
+ /* Write the c:protection element. */
4954
+ if (self->is_protected)
4955
+ _chart_write_protection(self);
4956
+
4910
4957
  /* Write the c:chart element. */
4911
4958
  _chart_write_chart(self);
4912
4959
 
@@ -4915,7 +4962,8 @@ lxw_chart_assemble_xml_file(lxw_chart *self)
4915
4962
  self->chartarea_pattern);
4916
4963
 
4917
4964
  /* Write the c:printSettings element. */
4918
- _chart_write_print_settings(self);
4965
+ if (!self->is_chartsheet)
4966
+ _chart_write_print_settings(self);
4919
4967
 
4920
4968
  lxw_xml_end_tag(self->file, "c:chartSpace");
4921
4969
  }
@@ -5384,7 +5432,8 @@ chart_series_set_labels_percentage(lxw_chart_series *series)
5384
5432
  * Set an data labels number format.
5385
5433
  */
5386
5434
  void
5387
- chart_series_set_labels_num_format(lxw_chart_series *series, char *num_format)
5435
+ chart_series_set_labels_num_format(lxw_chart_series *series,
5436
+ const char *num_format)
5388
5437
  {
5389
5438
  if (!num_format)
5390
5439
  return;
@@ -5531,7 +5580,7 @@ chart_series_set_trendline_intercept(lxw_chart_series *series,
5531
5580
  * Set a line type for a series trendline.
5532
5581
  */
5533
5582
  void
5534
- chart_series_set_trendline_name(lxw_chart_series *series, char *name)
5583
+ chart_series_set_trendline_name(lxw_chart_series *series, const char *name)
5535
5584
  {
5536
5585
  if (!name)
5537
5586
  return;
@@ -5558,6 +5607,24 @@ chart_series_set_trendline_line(lxw_chart_series *series,
5558
5607
  series->trendline_line = _chart_convert_line_args(line);
5559
5608
  }
5560
5609
 
5610
+ /*
5611
+ * Set the X or Y error bars from a chart series.
5612
+ */
5613
+ lxw_series_error_bars *
5614
+ chart_series_get_error_bars(lxw_chart_series *series,
5615
+ lxw_chart_error_bar_axis axis_type)
5616
+ {
5617
+ if (!series)
5618
+ return NULL;
5619
+
5620
+ if (axis_type == LXW_CHART_ERROR_BAR_AXIS_X)
5621
+ return series->x_error_bars;
5622
+ else if (axis_type == LXW_CHART_ERROR_BAR_AXIS_Y)
5623
+ return series->y_error_bars;
5624
+ else
5625
+ return NULL;
5626
+ }
5627
+
5561
5628
  /*
5562
5629
  * Set the error bars and type for a chart series.
5563
5630
  */
@@ -5622,6 +5689,23 @@ chart_series_set_error_bars_line(lxw_series_error_bars *error_bars,
5622
5689
  error_bars->line = _chart_convert_line_args(line);
5623
5690
  }
5624
5691
 
5692
+ /*
5693
+ * Get an axis pointer from a chart.
5694
+ */
5695
+ lxw_chart_axis *
5696
+ chart_axis_get(lxw_chart *self, lxw_chart_axis_type axis_type)
5697
+ {
5698
+ if (!self)
5699
+ return NULL;
5700
+
5701
+ if (axis_type == LXW_CHART_AXIS_TYPE_X)
5702
+ return self->x_axis;
5703
+ else if (axis_type == LXW_CHART_AXIS_TYPE_Y)
5704
+ return self->y_axis;
5705
+ else
5706
+ return NULL;
5707
+ }
5708
+
5625
5709
  /*
5626
5710
  * Set an axis caption.
5627
5711
  */
@@ -5638,7 +5722,7 @@ chart_axis_set_name(lxw_chart_axis *axis, const char *name)
5638
5722
  }
5639
5723
 
5640
5724
  /*
5641
- * Set an axis caption, with a range instead or a formula..
5725
+ * Set an axis caption, with a range instead or a formula.
5642
5726
  */
5643
5727
  void
5644
5728
  chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname,
@@ -5687,7 +5771,7 @@ chart_axis_set_num_font(lxw_chart_axis *axis, lxw_chart_font *font)
5687
5771
  * Set an axis number format.
5688
5772
  */
5689
5773
  void
5690
- chart_axis_set_num_format(lxw_chart_axis *axis, char *num_format)
5774
+ chart_axis_set_num_format(lxw_chart_axis *axis, const char *num_format)
5691
5775
  {
5692
5776
  if (!num_format)
5693
5777
  return;
@@ -5983,6 +6067,15 @@ chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis,
5983
6067
  axis->minor_gridlines.visible = LXW_TRUE;
5984
6068
  }
5985
6069
 
6070
+ /*
6071
+ * Set the chart axis label alignment.
6072
+ */
6073
+ void
6074
+ chart_axis_set_label_align(lxw_chart_axis *axis, uint8_t align)
6075
+ {
6076
+ axis->label_align = align;
6077
+ }
6078
+
5986
6079
  /*
5987
6080
  * Set the chart title.
5988
6081
  */