xlsxwriter 0.2.0 → 0.2.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/xlsxwriter/chart.c +171 -45
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +19 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +1 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +12 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +8 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +132 -37
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +30 -4
- data/ext/xlsxwriter/libxlsxwriter/src/Makefile +2 -2
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +0 -2
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +12 -12
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +73 -23
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +9 -4
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +117 -14
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +31 -6
- data/ext/xlsxwriter/workbook.c +52 -8
- data/ext/xlsxwriter/worksheet.c +68 -0
- data/lib/xlsxwriter/version.rb +1 -1
- data/test/support/chart_test.rb +17 -0
- data/test/test-chart-area.rb +41 -7
- data/test/test-chart-axis.rb +427 -55
- data/test/test-chart-bar.rb +48 -10
- data/test/test-image.rb +15 -0
- data/test/test-macro.rb +20 -0
- data/test/xlsx-func-testcase.rb +2 -1
- metadata +9 -5
@@ -40,13 +40,13 @@ LXW_RB_GENERATE_CHARTSHEET_NAMES(lxw_chartsheet_names, lxw_chartsheet_name,
|
|
40
40
|
STATIC int
|
41
41
|
_worksheet_name_cmp(lxw_worksheet_name *name1, lxw_worksheet_name *name2)
|
42
42
|
{
|
43
|
-
return
|
43
|
+
return lxw_strcasecmp(name1->name, name2->name);
|
44
44
|
}
|
45
45
|
|
46
46
|
STATIC int
|
47
47
|
_chartsheet_name_cmp(lxw_chartsheet_name *name1, lxw_chartsheet_name *name2)
|
48
48
|
{
|
49
|
-
return
|
49
|
+
return lxw_strcasecmp(name1->name, name2->name);
|
50
50
|
}
|
51
51
|
|
52
52
|
/*
|
@@ -208,6 +208,8 @@ lxw_workbook_free(lxw_workbook *workbook)
|
|
208
208
|
lxw_sst_free(workbook->sst);
|
209
209
|
free(workbook->options.tmpdir);
|
210
210
|
free(workbook->ordered_charts);
|
211
|
+
free(workbook->vba_project);
|
212
|
+
free(workbook->vba_codename);
|
211
213
|
free(workbook);
|
212
214
|
}
|
213
215
|
|
@@ -885,9 +887,9 @@ _prepare_drawings(lxw_workbook *self)
|
|
885
887
|
lxw_sheet *sheet;
|
886
888
|
lxw_worksheet *worksheet;
|
887
889
|
lxw_image_options *image_options;
|
888
|
-
|
889
|
-
|
890
|
-
|
890
|
+
uint32_t chart_ref_id = 0;
|
891
|
+
uint32_t image_ref_id = 0;
|
892
|
+
uint32_t drawing_id = 0;
|
891
893
|
uint8_t is_chartsheet;
|
892
894
|
|
893
895
|
STAILQ_FOREACH(sheet, self->sheets, list_pointers) {
|
@@ -1135,6 +1137,10 @@ _write_file_version(lxw_workbook *self)
|
|
1135
1137
|
LXW_PUSH_ATTRIBUTES_STR("lowestEdited", "4");
|
1136
1138
|
LXW_PUSH_ATTRIBUTES_STR("rupBuild", "4505");
|
1137
1139
|
|
1140
|
+
if (self->vba_project)
|
1141
|
+
LXW_PUSH_ATTRIBUTES_STR("codeName",
|
1142
|
+
"{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}");
|
1143
|
+
|
1138
1144
|
lxw_xml_empty_tag(self->file, "fileVersion", &attributes);
|
1139
1145
|
|
1140
1146
|
LXW_FREE_ATTRIBUTES();
|
@@ -1150,6 +1156,10 @@ _write_workbook_pr(lxw_workbook *self)
|
|
1150
1156
|
struct xml_attribute *attribute;
|
1151
1157
|
|
1152
1158
|
LXW_INIT_ATTRIBUTES();
|
1159
|
+
|
1160
|
+
if (self->vba_codename)
|
1161
|
+
LXW_PUSH_ATTRIBUTES_STR("codeName", self->vba_codename);
|
1162
|
+
|
1153
1163
|
LXW_PUSH_ATTRIBUTES_STR("defaultThemeVersion", "124226");
|
1154
1164
|
|
1155
1165
|
lxw_xml_empty_tag(self->file, "workbookPr", &attributes);
|
@@ -1470,6 +1480,7 @@ workbook_new_opt(const char *filename, lxw_workbook_options *options)
|
|
1470
1480
|
if (options) {
|
1471
1481
|
workbook->options.constant_memory = options->constant_memory;
|
1472
1482
|
workbook->options.tmpdir = lxw_strdup(options->tmpdir);
|
1483
|
+
workbook->options.use_zip64 = options->use_zip64;
|
1473
1484
|
}
|
1474
1485
|
|
1475
1486
|
return workbook;
|
@@ -1717,6 +1728,22 @@ workbook_close(lxw_workbook *self)
|
|
1717
1728
|
worksheet->active = 1;
|
1718
1729
|
}
|
1719
1730
|
|
1731
|
+
/* Set workbook and worksheet VBA codenames if a macro has been added. */
|
1732
|
+
if (self->vba_project) {
|
1733
|
+
if (!self->vba_codename)
|
1734
|
+
workbook_set_vba_name(self, "ThisWorkbook");
|
1735
|
+
|
1736
|
+
STAILQ_FOREACH(sheet, self->sheets, list_pointers) {
|
1737
|
+
if (sheet->is_chartsheet)
|
1738
|
+
continue;
|
1739
|
+
else
|
1740
|
+
worksheet = sheet->u.worksheet;
|
1741
|
+
|
1742
|
+
if (!worksheet->vba_codename)
|
1743
|
+
worksheet_set_vba_name(worksheet, worksheet->name);
|
1744
|
+
}
|
1745
|
+
}
|
1746
|
+
|
1720
1747
|
/* Set the defined names for the worksheets such as Print Titles. */
|
1721
1748
|
_prepare_defined_names(self);
|
1722
1749
|
|
@@ -1727,13 +1754,15 @@ workbook_close(lxw_workbook *self)
|
|
1727
1754
|
_add_chart_cache_data(self);
|
1728
1755
|
|
1729
1756
|
/* Create a packager object to assemble sub-elements into a zip file. */
|
1730
|
-
packager = lxw_packager_new(self->filename,
|
1757
|
+
packager = lxw_packager_new(self->filename,
|
1758
|
+
self->options.tmpdir,
|
1759
|
+
self->options.use_zip64);
|
1731
1760
|
|
1732
1761
|
/* If the packager fails it is generally due to a zip permission error. */
|
1733
1762
|
if (packager == NULL) {
|
1734
1763
|
fprintf(stderr, "[ERROR] workbook_close(): "
|
1735
1764
|
"Error creating '%s'. "
|
1736
|
-
"
|
1765
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1737
1766
|
|
1738
1767
|
error = LXW_ERROR_CREATING_XLSX_FILE;
|
1739
1768
|
goto mem_error;
|
@@ -1749,26 +1778,47 @@ workbook_close(lxw_workbook *self)
|
|
1749
1778
|
if (error == LXW_ERROR_CREATING_TMPFILE) {
|
1750
1779
|
fprintf(stderr, "[ERROR] workbook_close(): "
|
1751
1780
|
"Error creating tmpfile(s) to assemble '%s'. "
|
1752
|
-
"
|
1781
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1753
1782
|
}
|
1754
1783
|
|
1755
|
-
/* If LXW_ERROR_ZIP_FILE_OPERATION then errno is set by
|
1784
|
+
/* If LXW_ERROR_ZIP_FILE_OPERATION then errno is set by zip. */
|
1756
1785
|
if (error == LXW_ERROR_ZIP_FILE_OPERATION) {
|
1757
1786
|
fprintf(stderr, "[ERROR] workbook_close(): "
|
1758
|
-
"
|
1759
|
-
"
|
1787
|
+
"Zip ZIP_ERRNO error while creating xlsx file '%s'. "
|
1788
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1789
|
+
}
|
1790
|
+
|
1791
|
+
/* If LXW_ERROR_ZIP_PARAMETER_ERROR then errno is set by zip. */
|
1792
|
+
if (error == LXW_ERROR_ZIP_PARAMETER_ERROR) {
|
1793
|
+
fprintf(stderr, "[ERROR] workbook_close(): "
|
1794
|
+
"Zip ZIP_PARAMERROR error while creating xlsx file '%s'. "
|
1795
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1796
|
+
}
|
1797
|
+
|
1798
|
+
/* If LXW_ERROR_ZIP_BAD_ZIP_FILE then errno is set by zip. */
|
1799
|
+
if (error == LXW_ERROR_ZIP_BAD_ZIP_FILE) {
|
1800
|
+
fprintf(stderr, "[ERROR] workbook_close(): "
|
1801
|
+
"Zip ZIP_BADZIPFILE error while creating xlsx file '%s'. "
|
1802
|
+
"This may require the use_zip64 option for large files. "
|
1803
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1804
|
+
}
|
1805
|
+
|
1806
|
+
/* If LXW_ERROR_ZIP_INTERNAL_ERROR then errno is set by zip. */
|
1807
|
+
if (error == LXW_ERROR_ZIP_INTERNAL_ERROR) {
|
1808
|
+
fprintf(stderr, "[ERROR] workbook_close(): "
|
1809
|
+
"Zip ZIP_INTERNALERROR error while creating xlsx file '%s'. "
|
1810
|
+
"System error = %s\n", self->filename, strerror(errno));
|
1760
1811
|
}
|
1761
1812
|
|
1762
1813
|
/* The next 2 error conditions don't set errno. */
|
1763
1814
|
if (error == LXW_ERROR_ZIP_FILE_ADD) {
|
1764
1815
|
fprintf(stderr, "[ERROR] workbook_close(): "
|
1765
|
-
"
|
1766
|
-
self->filename);
|
1816
|
+
"Zip error adding file to xlsx file '%s'.\n", self->filename);
|
1767
1817
|
}
|
1768
1818
|
|
1769
1819
|
if (error == LXW_ERROR_ZIP_CLOSE) {
|
1770
1820
|
fprintf(stderr, "[ERROR] workbook_close(): "
|
1771
|
-
"
|
1821
|
+
"Zip error closing xlsx file '%s'.\n", self->filename);
|
1772
1822
|
}
|
1773
1823
|
|
1774
1824
|
mem_error:
|
@@ -2114,6 +2164,14 @@ workbook_validate_sheet_name(lxw_workbook *self, const char *sheetname)
|
|
2114
2164
|
if (strpbrk(sheetname, "[]:*?/\\"))
|
2115
2165
|
return LXW_ERROR_INVALID_SHEETNAME_CHARACTER;
|
2116
2166
|
|
2167
|
+
/* Check that the worksheet doesn't start or end with an apostrophe. */
|
2168
|
+
if (sheetname[0] == '\'' || sheetname[strlen(sheetname) - 1] == '\'')
|
2169
|
+
return LXW_ERROR_SHEETNAME_START_END_APOSTROPHE;
|
2170
|
+
|
2171
|
+
/* Check that the worksheet name isn't the reserved work "History". */
|
2172
|
+
if (lxw_strcasecmp(sheetname, "history") == 0)
|
2173
|
+
return LXW_ERROR_SHEETNAME_RESERVED;
|
2174
|
+
|
2117
2175
|
/* Check if the worksheet name is already in use. */
|
2118
2176
|
if (workbook_get_worksheet_by_name(self, sheetname))
|
2119
2177
|
return LXW_ERROR_SHEETNAME_ALREADY_USED;
|
@@ -2124,3 +2182,48 @@ workbook_validate_sheet_name(lxw_workbook *self, const char *sheetname)
|
|
2124
2182
|
|
2125
2183
|
return LXW_NO_ERROR;
|
2126
2184
|
}
|
2185
|
+
|
2186
|
+
/*
|
2187
|
+
* Add a vbaProject binary to the Excel workbook.
|
2188
|
+
*/
|
2189
|
+
lxw_error
|
2190
|
+
workbook_add_vba_project(lxw_workbook *self, const char *filename)
|
2191
|
+
{
|
2192
|
+
FILE *filehandle;
|
2193
|
+
|
2194
|
+
if (!filename) {
|
2195
|
+
LXW_WARN("workbook_add_vba_project(): "
|
2196
|
+
"filename must be specified.");
|
2197
|
+
return LXW_ERROR_NULL_PARAMETER_IGNORED;
|
2198
|
+
}
|
2199
|
+
|
2200
|
+
/* Check that the vbaProject file exists and can be opened. */
|
2201
|
+
filehandle = fopen(filename, "rb");
|
2202
|
+
if (!filehandle) {
|
2203
|
+
LXW_WARN_FORMAT1("workbook_add_vba_project(): "
|
2204
|
+
"file doesn't exist or can't be opened: %s.",
|
2205
|
+
filename);
|
2206
|
+
return LXW_ERROR_PARAMETER_VALIDATION;
|
2207
|
+
}
|
2208
|
+
fclose(filehandle);
|
2209
|
+
|
2210
|
+
self->vba_project = lxw_strdup(filename);
|
2211
|
+
|
2212
|
+
return LXW_NO_ERROR;
|
2213
|
+
}
|
2214
|
+
|
2215
|
+
/*
|
2216
|
+
* Set the VBA name for the workbook.
|
2217
|
+
*/
|
2218
|
+
lxw_error
|
2219
|
+
workbook_set_vba_name(lxw_workbook *self, const char *name)
|
2220
|
+
{
|
2221
|
+
if (!name) {
|
2222
|
+
LXW_WARN("workbook_set_vba_name(): " "name must be specified.");
|
2223
|
+
return LXW_ERROR_NULL_PARAMETER_IGNORED;
|
2224
|
+
}
|
2225
|
+
|
2226
|
+
self->vba_codename = lxw_strdup(name);
|
2227
|
+
|
2228
|
+
return LXW_NO_ERROR;
|
2229
|
+
}
|
@@ -448,6 +448,7 @@ lxw_worksheet_free(lxw_worksheet *worksheet)
|
|
448
448
|
free(worksheet->vbreaks);
|
449
449
|
free(worksheet->name);
|
450
450
|
free(worksheet->quoted_name);
|
451
|
+
free(worksheet->vba_codename);
|
451
452
|
|
452
453
|
free(worksheet);
|
453
454
|
worksheet = NULL;
|
@@ -1507,7 +1508,8 @@ _worksheet_write_optimized_sheet_data(lxw_worksheet *self)
|
|
1507
1508
|
while (read_size) {
|
1508
1509
|
read_size =
|
1509
1510
|
fread(buffer, 1, LXW_BUFFER_SIZE, self->optimize_tmpfile);
|
1510
|
-
|
1511
|
+
/* Ignore return value. There is no easy way to raise error. */
|
1512
|
+
(void) fwrite(buffer, 1, read_size, self->file);
|
1511
1513
|
}
|
1512
1514
|
|
1513
1515
|
fclose(self->optimize_tmpfile);
|
@@ -1992,7 +1994,7 @@ _worksheet_position_object_emus(lxw_worksheet *self,
|
|
1992
1994
|
*/
|
1993
1995
|
void
|
1994
1996
|
lxw_worksheet_prepare_image(lxw_worksheet *self,
|
1995
|
-
|
1997
|
+
uint32_t image_ref_id, uint32_t drawing_id,
|
1996
1998
|
lxw_image_options *image_data)
|
1997
1999
|
{
|
1998
2000
|
lxw_drawing_object *drawing_object;
|
@@ -2079,8 +2081,8 @@ mem_error:
|
|
2079
2081
|
*/
|
2080
2082
|
void
|
2081
2083
|
lxw_worksheet_prepare_chart(lxw_worksheet *self,
|
2082
|
-
|
2083
|
-
|
2084
|
+
uint32_t chart_ref_id,
|
2085
|
+
uint32_t drawing_id,
|
2084
2086
|
lxw_image_options *image_data,
|
2085
2087
|
uint8_t is_chartsheet)
|
2086
2088
|
{
|
@@ -3147,7 +3149,7 @@ _worksheet_write_sheet_pr(lxw_worksheet *self)
|
|
3147
3149
|
LXW_INIT_ATTRIBUTES();
|
3148
3150
|
|
3149
3151
|
if (self->vba_codename)
|
3150
|
-
|
3152
|
+
LXW_PUSH_ATTRIBUTES_STR("codeName", self->vba_codename);
|
3151
3153
|
|
3152
3154
|
if (self->filter_on)
|
3153
3155
|
LXW_PUSH_ATTRIBUTES_STR("filterMode", "1");
|
@@ -5629,7 +5631,14 @@ worksheet_insert_image_buffer_opt(lxw_worksheet *self,
|
|
5629
5631
|
/* Write the image buffer to a temporary file so we can read the
|
5630
5632
|
* dimensions like an ordinary file. */
|
5631
5633
|
image_stream = lxw_tmpfile(self->tmpdir);
|
5632
|
-
|
5634
|
+
if (!image_stream)
|
5635
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
5636
|
+
|
5637
|
+
if (fwrite(image_buffer, 1, image_size, image_stream) != image_size) {
|
5638
|
+
fclose(image_stream);
|
5639
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
5640
|
+
}
|
5641
|
+
|
5633
5642
|
rewind(image_stream);
|
5634
5643
|
|
5635
5644
|
/* Create a new object to hold the image options. */
|
@@ -6066,3 +6075,19 @@ worksheet_data_validation_cell(lxw_worksheet *self, lxw_row_t row,
|
|
6066
6075
|
return worksheet_data_validation_range(self, row, col,
|
6067
6076
|
row, col, validation);
|
6068
6077
|
}
|
6078
|
+
|
6079
|
+
/*
|
6080
|
+
* Set the VBA name for the worksheet.
|
6081
|
+
*/
|
6082
|
+
lxw_error
|
6083
|
+
worksheet_set_vba_name(lxw_worksheet *self, const char *name)
|
6084
|
+
{
|
6085
|
+
if (!name) {
|
6086
|
+
LXW_WARN("worksheet_set_vba_name(): " "name must be specified.");
|
6087
|
+
return LXW_ERROR_NULL_PARAMETER_IGNORED;
|
6088
|
+
}
|
6089
|
+
|
6090
|
+
self->vba_codename = lxw_strdup(name);
|
6091
|
+
|
6092
|
+
return LXW_NO_ERROR;
|
6093
|
+
}
|
data/ext/xlsxwriter/workbook.c
CHANGED
@@ -31,15 +31,18 @@ workbook_alloc(VALUE klass) {
|
|
31
31
|
}
|
32
32
|
|
33
33
|
/* call-seq:
|
34
|
-
* XlsxWriter::Workbook.new(path, constant_memory: false, tmpdir: nil) -> workbook
|
35
|
-
* XlsxWriter::Workbook.new(path, constant_memory: false, tmpdir: nil) { |wb| block } -> nil
|
36
|
-
* XlsxWriter::Workbook.open(path, constant_memory: false, tmpdir: nil) { |wb| block } -> nil
|
34
|
+
* XlsxWriter::Workbook.new(path, constant_memory: false, tmpdir: nil, use_zip64: false) -> workbook
|
35
|
+
* XlsxWriter::Workbook.new(path, constant_memory: false, tmpdir: nil, use_zip64: false) { |wb| block } -> nil
|
36
|
+
* XlsxWriter::Workbook.open(path, constant_memory: false, tmpdir: nil, use_zip64: false) { |wb| block } -> nil
|
37
37
|
*
|
38
38
|
* Creates a new Xlsx workbook in file +path+ and returns a new Workbook object.
|
39
39
|
*
|
40
40
|
* If +constant_memory+ is set to true workbook data is stored in temporary files
|
41
41
|
* in +tmpdir+, considerably reducing memory consumption for large documents.
|
42
42
|
*
|
43
|
+
* If +use_zip64+ is set to truthy value zip64 extensions are enabled for the resulting xlsx file. It allows
|
44
|
+
* for files in the archive to have size >4GB.
|
45
|
+
*
|
43
46
|
* XlsxWriter::Workbook.open('/tmp/test.xlsx', constant_memory: true) do |wb|
|
44
47
|
* # ... populate the workbook with data ...
|
45
48
|
* end
|
@@ -61,7 +64,8 @@ workbook_init(int argc, VALUE *argv, VALUE self) {
|
|
61
64
|
struct workbook *ptr;
|
62
65
|
lxw_workbook_options options = {
|
63
66
|
.constant_memory = 0,
|
64
|
-
.tmpdir = NULL
|
67
|
+
.tmpdir = NULL,
|
68
|
+
.use_zip64 = 0
|
65
69
|
};
|
66
70
|
|
67
71
|
if (argc < 1 || argc > 2) {
|
@@ -75,6 +79,10 @@ workbook_init(int argc, VALUE *argv, VALUE self) {
|
|
75
79
|
if (!NIL_P(tmpdir))
|
76
80
|
options.tmpdir = RSTRING_PTR(tmpdir);
|
77
81
|
}
|
82
|
+
VALUE use_zip64_ = rb_hash_aref(argv[1], ID2SYM(rb_intern("use_zip64")));
|
83
|
+
if (!NIL_P(use_zip64_) && use_zip64_) {
|
84
|
+
options.use_zip64 = 1;
|
85
|
+
}
|
78
86
|
}
|
79
87
|
|
80
88
|
Data_Get_Struct(self, struct workbook, ptr);
|
@@ -274,6 +282,24 @@ workbook_add_chart_(VALUE self, VALUE type) {
|
|
274
282
|
return chart;
|
275
283
|
}
|
276
284
|
|
285
|
+
/* call-seq:
|
286
|
+
* wb.add_vba_project(filename)
|
287
|
+
*
|
288
|
+
* Adds a vba project to the workbook (has to be extracted from a xlsm file).
|
289
|
+
* Only one file per workbook is allowed. Documents with vba projects should have
|
290
|
+
* extension "xlsm" rather than "xlsx" to avoid reader/editor software warnings.
|
291
|
+
*/
|
292
|
+
VALUE
|
293
|
+
workbook_add_vba_project_(VALUE self, VALUE filename) {
|
294
|
+
struct workbook *ptr;
|
295
|
+
Data_Get_Struct(self, struct workbook, ptr);
|
296
|
+
|
297
|
+
lxw_error err = workbook_add_vba_project(ptr->workbook, StringValueCStr(filename));
|
298
|
+
handle_lxw_error(err);
|
299
|
+
|
300
|
+
return self;
|
301
|
+
}
|
302
|
+
|
277
303
|
/* :nodoc: */
|
278
304
|
VALUE
|
279
305
|
workbook_set_default_xf_indices_(VALUE self) {
|
@@ -283,6 +309,22 @@ workbook_set_default_xf_indices_(VALUE self) {
|
|
283
309
|
return self;
|
284
310
|
}
|
285
311
|
|
312
|
+
/* call-seq:
|
313
|
+
* wb.vba_name = name
|
314
|
+
*
|
315
|
+
* Set the VBA name for the workbook.
|
316
|
+
*/
|
317
|
+
VALUE
|
318
|
+
workbook_set_vba_name_(VALUE self, VALUE name) {
|
319
|
+
struct workbook *ptr;
|
320
|
+
Data_Get_Struct(self, struct workbook, ptr);
|
321
|
+
|
322
|
+
lxw_error err = workbook_set_vba_name(ptr->workbook, StringValueCStr(name));
|
323
|
+
handle_lxw_error(err);
|
324
|
+
|
325
|
+
return name;
|
326
|
+
}
|
327
|
+
|
286
328
|
/* call-seq: wb.properties -> wb_properties
|
287
329
|
*
|
288
330
|
* Returns worbook properties accessor object.
|
@@ -382,14 +424,16 @@ init_xlsxwriter_workbook() {
|
|
382
424
|
rb_define_alias(rb_singleton_class(cWorkbook), "open", "new");
|
383
425
|
rb_define_method(cWorkbook, "initialize", workbook_init, -1);
|
384
426
|
rb_define_method(cWorkbook, "close", workbook_release, 0);
|
385
|
-
rb_define_method(cWorkbook, "add_worksheet", workbook_add_worksheet_, -1);
|
386
|
-
rb_define_method(cWorkbook, "add_format", workbook_add_format_, 2);
|
387
427
|
rb_define_method(cWorkbook, "add_chart", workbook_add_chart_, 1);
|
388
|
-
rb_define_method(cWorkbook, "
|
389
|
-
rb_define_method(cWorkbook, "
|
428
|
+
rb_define_method(cWorkbook, "add_format", workbook_add_format_, 2);
|
429
|
+
rb_define_method(cWorkbook, "add_vba_project", workbook_add_vba_project_, 1);
|
430
|
+
rb_define_method(cWorkbook, "add_worksheet", workbook_add_worksheet_, -1);
|
390
431
|
rb_define_method(cWorkbook, "define_name", workbook_define_name_, 2);
|
432
|
+
rb_define_method(cWorkbook, "properties", workbook_properties_, 0);
|
433
|
+
rb_define_method(cWorkbook, "set_default_xf_indices", workbook_set_default_xf_indices_, 0);
|
391
434
|
rb_define_method(cWorkbook, "validate_sheet_name", workbook_validate_sheet_name_, 1);
|
392
435
|
rb_define_method(cWorkbook, "validate_worksheet_name", workbook_validate_sheet_name_, 1);
|
436
|
+
rb_define_method(cWorkbook, "vba_name=", workbook_set_vba_name_, 1);
|
393
437
|
|
394
438
|
/*
|
395
439
|
* This attribute contains effective font widths used for automatic column
|
data/ext/xlsxwriter/worksheet.c
CHANGED
@@ -624,6 +624,53 @@ worksheet_insert_image_(int argc, VALUE *argv, VALUE self) {
|
|
624
624
|
return self;
|
625
625
|
}
|
626
626
|
|
627
|
+
/* call-seq:
|
628
|
+
* ws.insert_image_buffer(cell, data, options) -> self
|
629
|
+
* ws.insert_image_buffer(row, col, data, options) -> self
|
630
|
+
*
|
631
|
+
* Adds data validation or limits user input to a list of values.
|
632
|
+
*/
|
633
|
+
VALUE
|
634
|
+
worksheet_insert_image_buffer_(int argc, VALUE *argv, VALUE self) {
|
635
|
+
lxw_row_t row;
|
636
|
+
lxw_col_t col;
|
637
|
+
VALUE data = Qnil;
|
638
|
+
VALUE opts = Qnil;
|
639
|
+
lxw_image_options options;
|
640
|
+
char with_options = '\0';
|
641
|
+
|
642
|
+
rb_check_arity(argc, 2, 4);
|
643
|
+
int larg = extract_cell(argc, argv, &row, &col);
|
644
|
+
|
645
|
+
if (larg < argc) {
|
646
|
+
data = argv[larg];
|
647
|
+
++larg;
|
648
|
+
} else {
|
649
|
+
rb_raise(rb_eArgError, "Cannot embed image without data");
|
650
|
+
}
|
651
|
+
|
652
|
+
if (larg < argc) {
|
653
|
+
opts = argv[larg];
|
654
|
+
++larg;
|
655
|
+
}
|
656
|
+
struct worksheet *ptr;
|
657
|
+
Data_Get_Struct(self, struct worksheet, ptr);
|
658
|
+
|
659
|
+
if (!NIL_P(opts)) {
|
660
|
+
options = val_to_lxw_image_options(opts, &with_options);
|
661
|
+
}
|
662
|
+
|
663
|
+
lxw_error error;
|
664
|
+
if (with_options) {
|
665
|
+
error = worksheet_insert_image_buffer_opt(ptr->worksheet, row, col, (const unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data), &options);
|
666
|
+
} else {
|
667
|
+
error = worksheet_insert_image_buffer(ptr->worksheet, row, col, (const unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data));
|
668
|
+
}
|
669
|
+
handle_lxw_error(error);
|
670
|
+
|
671
|
+
return self;
|
672
|
+
}
|
673
|
+
|
627
674
|
/* call-seq:
|
628
675
|
* ws.insert_chart(cell, chart, opts = {}) -> self
|
629
676
|
* ws.insert_chart(row, col, chart, opts = {}) -> self
|
@@ -1485,6 +1532,23 @@ worksheet_data_validation_(int argc, VALUE *argv, VALUE self) {
|
|
1485
1532
|
return self;
|
1486
1533
|
}
|
1487
1534
|
|
1535
|
+
/* call-seq: wb.vba_name = name
|
1536
|
+
*
|
1537
|
+
* Set the VBA name for the worksheet.
|
1538
|
+
*/
|
1539
|
+
VALUE
|
1540
|
+
worksheet_set_vba_name_(VALUE self, VALUE name) {
|
1541
|
+
struct worksheet *ptr;
|
1542
|
+
Data_Get_Struct(self, struct worksheet, ptr);
|
1543
|
+
|
1544
|
+
lxw_error err = worksheet_set_vba_name(ptr->worksheet, StringValueCStr(name));
|
1545
|
+
handle_lxw_error(err);
|
1546
|
+
|
1547
|
+
return name;
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
// Helpers
|
1551
|
+
|
1488
1552
|
lxw_col_t
|
1489
1553
|
value_to_col(VALUE value) {
|
1490
1554
|
switch (TYPE(value)) {
|
@@ -1600,6 +1664,7 @@ val_to_lxw_image_options(VALUE opts, char *with_options) {
|
|
1600
1664
|
SET_IMG_OPT("scale", options.x_scale = options.y_scale = NUM2DBL(val));
|
1601
1665
|
SET_IMG_OPT("x_scale", options.x_scale = NUM2DBL(val));
|
1602
1666
|
SET_IMG_OPT("y_scale", options.y_scale = NUM2DBL(val));
|
1667
|
+
SET_IMG_OPT("description", options.description = StringValueCStr(val));
|
1603
1668
|
return options;
|
1604
1669
|
}
|
1605
1670
|
#undef SET_IMG_OPT
|
@@ -1626,6 +1691,7 @@ init_xlsxwriter_worksheet() {
|
|
1626
1691
|
rb_define_method(cWorksheet, "set_row", worksheet_set_row_, 2);
|
1627
1692
|
rb_define_method(cWorksheet, "set_column", worksheet_set_column_, 3);
|
1628
1693
|
rb_define_method(cWorksheet, "insert_image", worksheet_insert_image_, -1);
|
1694
|
+
rb_define_method(cWorksheet, "insert_image_buffer", worksheet_insert_image_buffer_, -1);
|
1629
1695
|
rb_define_method(cWorksheet, "insert_chart", worksheet_insert_chart_, -1);
|
1630
1696
|
rb_define_method(cWorksheet, "merge_range", worksheet_merge_range_, -1);
|
1631
1697
|
rb_define_method(cWorksheet, "autofilter", worksheet_autofilter_, -1);
|
@@ -1668,6 +1734,8 @@ init_xlsxwriter_worksheet() {
|
|
1668
1734
|
rb_define_method(cWorksheet, "vertical_dpi=", worksheet_set_vertical_dpi_, 1);
|
1669
1735
|
|
1670
1736
|
rb_define_method(cWorksheet, "add_data_validation", worksheet_data_validation_, -1);
|
1737
|
+
rb_define_method(cWorksheet, "vba_name=", worksheet_set_vba_name_, 1);
|
1738
|
+
|
1671
1739
|
rb_define_private_method(cWorksheet, "extract_column", rb_extract_col, 1);
|
1672
1740
|
|
1673
1741
|
#define MAP_LXW_WH_CONST(name, val_name) rb_define_const(cWorksheet, #name, INT2NUM(LXW_##val_name))
|