fast_excel 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +1 -7
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -1
- data/examples/example.rb +2 -0
- data/examples/example_date_time.rb +38 -0
- data/fast_excel.gemspec +2 -2
- data/lib/fast_excel/binding/format.rb +17 -0
- data/lib/fast_excel/binding/workbook.rb +39 -17
- data/lib/fast_excel/binding/worksheet.rb +57 -13
- data/lib/fast_excel/binding.rb +7 -7
- data/lib/fast_excel.rb +27 -20
- data/libxlsxwriter/.github/FUNDING.yml +1 -0
- data/libxlsxwriter/.github/ISSUE_TEMPLATE.md +85 -0
- data/libxlsxwriter/.github/PULL_REQUEST_TEMPLATE.md +130 -0
- data/libxlsxwriter/.github/workflows/cmake_actions.yml +48 -0
- data/libxlsxwriter/.github/workflows/code_style.yml +23 -0
- data/libxlsxwriter/.github/workflows/coverity.yml +22 -0
- data/libxlsxwriter/.github/workflows/make_actions.yml +52 -0
- data/libxlsxwriter/.github/workflows/valgrind.yml +23 -0
- data/libxlsxwriter/.github/workflows/windows_build.yml +54 -0
- data/libxlsxwriter/.github/workflows/zig_build.yml +22 -0
- data/libxlsxwriter/.gitignore +16 -1
- data/libxlsxwriter/.indent.pro +24 -0
- data/libxlsxwriter/CMakeLists.txt +156 -56
- data/libxlsxwriter/CONTRIBUTING.md +2 -2
- data/libxlsxwriter/Changes.txt +344 -2
- data/libxlsxwriter/LICENSE.txt +66 -8
- data/libxlsxwriter/Makefile +151 -54
- data/libxlsxwriter/Package.swift +42 -0
- data/libxlsxwriter/Readme.md +4 -2
- data/libxlsxwriter/build.zig +324 -0
- data/libxlsxwriter/build.zig.zon +11 -0
- data/libxlsxwriter/cmake/FindMINIZIP.cmake +3 -3
- data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +6 -0
- data/libxlsxwriter/include/xlsxwriter/app.h +2 -1
- data/libxlsxwriter/include/xlsxwriter/chart.h +236 -32
- data/libxlsxwriter/include/xlsxwriter/chartsheet.h +7 -7
- data/libxlsxwriter/include/xlsxwriter/comment.h +76 -0
- data/libxlsxwriter/include/xlsxwriter/common.h +111 -50
- data/libxlsxwriter/include/xlsxwriter/content_types.h +8 -1
- data/libxlsxwriter/include/xlsxwriter/core.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/custom.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/drawing.h +11 -20
- data/libxlsxwriter/include/xlsxwriter/format.h +121 -8
- data/libxlsxwriter/include/xlsxwriter/hash_table.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/metadata.h +49 -0
- data/libxlsxwriter/include/xlsxwriter/packager.h +27 -16
- data/libxlsxwriter/include/xlsxwriter/relationships.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/shared_strings.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/styles.h +13 -7
- data/libxlsxwriter/include/xlsxwriter/table.h +51 -0
- data/libxlsxwriter/include/xlsxwriter/theme.h +1 -1
- data/libxlsxwriter/include/xlsxwriter/third_party/emyg_dtoa.h +26 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +27 -25
- data/libxlsxwriter/include/xlsxwriter/third_party/md5.h +45 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +155 -153
- data/libxlsxwriter/include/xlsxwriter/utility.h +70 -8
- data/libxlsxwriter/include/xlsxwriter/vml.h +55 -0
- data/libxlsxwriter/include/xlsxwriter/workbook.h +218 -47
- data/libxlsxwriter/include/xlsxwriter/worksheet.h +2770 -241
- data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +12 -8
- data/libxlsxwriter/include/xlsxwriter.h +4 -2
- data/libxlsxwriter/libxlsxwriter.podspec +8 -5
- data/libxlsxwriter/src/Makefile +58 -21
- data/libxlsxwriter/src/app.c +5 -2
- data/libxlsxwriter/src/chart.c +396 -81
- data/libxlsxwriter/src/chartsheet.c +22 -22
- data/libxlsxwriter/src/comment.c +443 -0
- data/libxlsxwriter/src/content_types.c +40 -1
- data/libxlsxwriter/src/core.c +2 -2
- data/libxlsxwriter/src/custom.c +1 -1
- data/libxlsxwriter/src/drawing.c +160 -40
- data/libxlsxwriter/src/format.c +109 -25
- data/libxlsxwriter/src/hash_table.c +1 -1
- data/libxlsxwriter/src/metadata.c +283 -0
- data/libxlsxwriter/src/packager.c +794 -94
- data/libxlsxwriter/src/relationships.c +1 -1
- data/libxlsxwriter/src/shared_strings.c +2 -4
- data/libxlsxwriter/src/styles.c +353 -58
- data/libxlsxwriter/src/table.c +304 -0
- data/libxlsxwriter/src/theme.c +1 -1
- data/libxlsxwriter/src/utility.c +143 -43
- data/libxlsxwriter/src/vml.c +1062 -0
- data/libxlsxwriter/src/workbook.c +567 -77
- data/libxlsxwriter/src/worksheet.c +6668 -1462
- data/libxlsxwriter/src/xmlwriter.c +95 -5
- data/libxlsxwriter/third_party/dtoa/Makefile +42 -0
- data/libxlsxwriter/third_party/dtoa/emyg_dtoa.c +461 -0
- data/libxlsxwriter/third_party/dtoa/emyg_dtoa.h +26 -0
- data/libxlsxwriter/third_party/md5/Makefile +42 -0
- data/libxlsxwriter/third_party/md5/md5.c +291 -0
- data/libxlsxwriter/third_party/md5/md5.h +45 -0
- data/libxlsxwriter/third_party/minizip/Makefile +3 -8
- data/libxlsxwriter/third_party/minizip/Makefile.orig +8 -4
- data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +1 -1
- data/libxlsxwriter/third_party/minizip/configure.ac +1 -1
- data/libxlsxwriter/third_party/minizip/crypt.h +13 -16
- data/libxlsxwriter/third_party/minizip/ioapi.c +31 -57
- data/libxlsxwriter/third_party/minizip/ioapi.h +31 -23
- data/libxlsxwriter/third_party/minizip/iowin32.c +29 -45
- data/libxlsxwriter/third_party/minizip/iowin32.h +4 -4
- data/libxlsxwriter/third_party/minizip/miniunz.c +29 -56
- data/libxlsxwriter/third_party/minizip/minizip.c +38 -49
- data/libxlsxwriter/third_party/minizip/mztools.c +1 -7
- data/libxlsxwriter/third_party/minizip/unzip.c +202 -342
- data/libxlsxwriter/third_party/minizip/unzip.h +74 -74
- data/libxlsxwriter/third_party/minizip/zip.c +165 -218
- data/libxlsxwriter/third_party/minizip/zip.h +164 -154
- data/libxlsxwriter/third_party/tmpfileplus/Makefile +3 -3
- data/libxlsxwriter/version.txt +1 -1
- data/test/auto_width_test.rb +20 -0
- data/test/default_format_test.rb +1 -1
- data/test/validations_test.rb +3 -3
- data/test/worksheet_test.rb +6 -1
- metadata +33 -7
- data/libxlsxwriter/.travis.yml +0 -37
@@ -0,0 +1,304 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
* table - A library for creating Excel XLSX table files.
|
3
|
+
*
|
4
|
+
* Used in conjunction with the libxlsxwriter library.
|
5
|
+
*
|
6
|
+
* Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include "xlsxwriter/xmlwriter.h"
|
11
|
+
#include "xlsxwriter/worksheet.h"
|
12
|
+
#include "xlsxwriter/table.h"
|
13
|
+
#include "xlsxwriter/utility.h"
|
14
|
+
|
15
|
+
/*
|
16
|
+
* Forward declarations.
|
17
|
+
*/
|
18
|
+
|
19
|
+
/*****************************************************************************
|
20
|
+
*
|
21
|
+
* Private functions.
|
22
|
+
*
|
23
|
+
****************************************************************************/
|
24
|
+
|
25
|
+
/*
|
26
|
+
* Create a new table object.
|
27
|
+
*/
|
28
|
+
lxw_table *
|
29
|
+
lxw_table_new(void)
|
30
|
+
{
|
31
|
+
lxw_table *table = calloc(1, sizeof(lxw_table));
|
32
|
+
GOTO_LABEL_ON_MEM_ERROR(table, mem_error);
|
33
|
+
|
34
|
+
return table;
|
35
|
+
|
36
|
+
mem_error:
|
37
|
+
lxw_table_free(table);
|
38
|
+
return NULL;
|
39
|
+
}
|
40
|
+
|
41
|
+
/*
|
42
|
+
* Free a table object.
|
43
|
+
*/
|
44
|
+
void
|
45
|
+
lxw_table_free(lxw_table *table)
|
46
|
+
{
|
47
|
+
if (!table)
|
48
|
+
return;
|
49
|
+
|
50
|
+
free(table);
|
51
|
+
}
|
52
|
+
|
53
|
+
/*****************************************************************************
|
54
|
+
*
|
55
|
+
* XML functions.
|
56
|
+
*
|
57
|
+
****************************************************************************/
|
58
|
+
|
59
|
+
/*
|
60
|
+
* Write the XML declaration.
|
61
|
+
*/
|
62
|
+
STATIC void
|
63
|
+
_table_xml_declaration(lxw_table *self)
|
64
|
+
{
|
65
|
+
lxw_xml_declaration(self->file);
|
66
|
+
}
|
67
|
+
|
68
|
+
/*
|
69
|
+
* Write the <table> element.
|
70
|
+
*/
|
71
|
+
STATIC void
|
72
|
+
_table_write_table(lxw_table *self)
|
73
|
+
{
|
74
|
+
struct xml_attribute_list attributes;
|
75
|
+
struct xml_attribute *attribute;
|
76
|
+
char xmlns[] =
|
77
|
+
"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
78
|
+
lxw_table_obj *table_obj = self->table_obj;
|
79
|
+
|
80
|
+
LXW_INIT_ATTRIBUTES();
|
81
|
+
|
82
|
+
LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
|
83
|
+
LXW_PUSH_ATTRIBUTES_INT("id", table_obj->id);
|
84
|
+
|
85
|
+
if (table_obj->name)
|
86
|
+
LXW_PUSH_ATTRIBUTES_STR("name", table_obj->name);
|
87
|
+
else
|
88
|
+
LXW_PUSH_ATTRIBUTES_STR("name", "Table1");
|
89
|
+
|
90
|
+
if (table_obj->name)
|
91
|
+
LXW_PUSH_ATTRIBUTES_STR("displayName", table_obj->name);
|
92
|
+
else
|
93
|
+
LXW_PUSH_ATTRIBUTES_STR("displayName", "Table1");
|
94
|
+
|
95
|
+
LXW_PUSH_ATTRIBUTES_STR("ref", table_obj->sqref);
|
96
|
+
|
97
|
+
if (table_obj->no_header_row)
|
98
|
+
LXW_PUSH_ATTRIBUTES_STR("headerRowCount", "0");
|
99
|
+
|
100
|
+
if (table_obj->total_row)
|
101
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowCount", "1");
|
102
|
+
else
|
103
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowShown", "0");
|
104
|
+
|
105
|
+
lxw_xml_start_tag(self->file, "table", &attributes);
|
106
|
+
|
107
|
+
LXW_FREE_ATTRIBUTES();
|
108
|
+
}
|
109
|
+
|
110
|
+
/*
|
111
|
+
* Write the <autoFilter> element.
|
112
|
+
*/
|
113
|
+
STATIC void
|
114
|
+
_table_write_auto_filter(lxw_table *self)
|
115
|
+
{
|
116
|
+
struct xml_attribute_list attributes;
|
117
|
+
struct xml_attribute *attribute;
|
118
|
+
|
119
|
+
if (self->table_obj->no_autofilter)
|
120
|
+
return;
|
121
|
+
|
122
|
+
LXW_INIT_ATTRIBUTES();
|
123
|
+
LXW_PUSH_ATTRIBUTES_STR("ref", self->table_obj->filter_sqref);
|
124
|
+
|
125
|
+
lxw_xml_empty_tag(self->file, "autoFilter", &attributes);
|
126
|
+
|
127
|
+
LXW_FREE_ATTRIBUTES();
|
128
|
+
}
|
129
|
+
|
130
|
+
/*
|
131
|
+
* Write the <tableColumn> element.
|
132
|
+
*/
|
133
|
+
STATIC void
|
134
|
+
_table_write_table_column(lxw_table *self, uint16_t id,
|
135
|
+
lxw_table_column *column)
|
136
|
+
{
|
137
|
+
struct xml_attribute_list attributes;
|
138
|
+
struct xml_attribute *attribute;
|
139
|
+
int32_t dfx_id;
|
140
|
+
|
141
|
+
LXW_INIT_ATTRIBUTES();
|
142
|
+
LXW_PUSH_ATTRIBUTES_INT("id", id);
|
143
|
+
|
144
|
+
LXW_PUSH_ATTRIBUTES_STR("name", column->header);
|
145
|
+
|
146
|
+
if (column->total_string) {
|
147
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowLabel", column->total_string);
|
148
|
+
}
|
149
|
+
else if (column->total_function) {
|
150
|
+
if (column->total_function == LXW_TABLE_FUNCTION_AVERAGE)
|
151
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "average");
|
152
|
+
if (column->total_function == LXW_TABLE_FUNCTION_COUNT_NUMS)
|
153
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "countNums");
|
154
|
+
if (column->total_function == LXW_TABLE_FUNCTION_COUNT)
|
155
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "count");
|
156
|
+
if (column->total_function == LXW_TABLE_FUNCTION_MAX)
|
157
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "max");
|
158
|
+
if (column->total_function == LXW_TABLE_FUNCTION_MIN)
|
159
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "min");
|
160
|
+
if (column->total_function == LXW_TABLE_FUNCTION_STD_DEV)
|
161
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "stdDev");
|
162
|
+
if (column->total_function == LXW_TABLE_FUNCTION_SUM)
|
163
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "sum");
|
164
|
+
if (column->total_function == LXW_TABLE_FUNCTION_VAR)
|
165
|
+
LXW_PUSH_ATTRIBUTES_STR("totalsRowFunction", "var");
|
166
|
+
}
|
167
|
+
|
168
|
+
if (column->format) {
|
169
|
+
dfx_id = lxw_format_get_dxf_index(column->format);
|
170
|
+
LXW_PUSH_ATTRIBUTES_INT("dataDxfId", dfx_id);
|
171
|
+
}
|
172
|
+
|
173
|
+
if (column->formula) {
|
174
|
+
lxw_xml_start_tag(self->file, "tableColumn", &attributes);
|
175
|
+
lxw_xml_data_element(self->file, "calculatedColumnFormula",
|
176
|
+
column->formula, NULL);
|
177
|
+
lxw_xml_end_tag(self->file, "tableColumn");
|
178
|
+
}
|
179
|
+
else {
|
180
|
+
lxw_xml_empty_tag(self->file, "tableColumn", &attributes);
|
181
|
+
}
|
182
|
+
|
183
|
+
LXW_FREE_ATTRIBUTES();
|
184
|
+
}
|
185
|
+
|
186
|
+
/*
|
187
|
+
* Write the <tableColumns> element.
|
188
|
+
*/
|
189
|
+
STATIC void
|
190
|
+
_table_write_table_columns(lxw_table *self)
|
191
|
+
{
|
192
|
+
struct xml_attribute_list attributes;
|
193
|
+
struct xml_attribute *attribute;
|
194
|
+
uint16_t i;
|
195
|
+
uint16_t num_cols = self->table_obj->num_cols;
|
196
|
+
lxw_table_column **columns = self->table_obj->columns;
|
197
|
+
|
198
|
+
LXW_INIT_ATTRIBUTES();
|
199
|
+
LXW_PUSH_ATTRIBUTES_INT("count", num_cols);
|
200
|
+
|
201
|
+
lxw_xml_start_tag(self->file, "tableColumns", &attributes);
|
202
|
+
|
203
|
+
for (i = 0; i < num_cols; i++)
|
204
|
+
_table_write_table_column(self, i + 1, columns[i]);
|
205
|
+
|
206
|
+
lxw_xml_end_tag(self->file, "tableColumns");
|
207
|
+
|
208
|
+
LXW_FREE_ATTRIBUTES();
|
209
|
+
}
|
210
|
+
|
211
|
+
/*
|
212
|
+
* Write the <tableStyleInfo> element.
|
213
|
+
*/
|
214
|
+
STATIC void
|
215
|
+
_table_write_table_style_info(lxw_table *self)
|
216
|
+
{
|
217
|
+
struct xml_attribute_list attributes;
|
218
|
+
struct xml_attribute *attribute;
|
219
|
+
char name[LXW_ATTR_32];
|
220
|
+
lxw_table_obj *table_obj = self->table_obj;
|
221
|
+
|
222
|
+
LXW_INIT_ATTRIBUTES();
|
223
|
+
|
224
|
+
if (table_obj->style_type == LXW_TABLE_STYLE_TYPE_LIGHT) {
|
225
|
+
if (table_obj->style_type_number != 0) {
|
226
|
+
lxw_snprintf(name, LXW_ATTR_32, "TableStyleLight%d",
|
227
|
+
table_obj->style_type_number);
|
228
|
+
LXW_PUSH_ATTRIBUTES_STR("name", name);
|
229
|
+
}
|
230
|
+
}
|
231
|
+
else if (table_obj->style_type == LXW_TABLE_STYLE_TYPE_MEDIUM) {
|
232
|
+
lxw_snprintf(name, LXW_ATTR_32, "TableStyleMedium%d",
|
233
|
+
table_obj->style_type_number);
|
234
|
+
LXW_PUSH_ATTRIBUTES_STR("name", name);
|
235
|
+
}
|
236
|
+
else if (table_obj->style_type == LXW_TABLE_STYLE_TYPE_DARK) {
|
237
|
+
lxw_snprintf(name, LXW_ATTR_32, "TableStyleDark%d",
|
238
|
+
table_obj->style_type_number);
|
239
|
+
LXW_PUSH_ATTRIBUTES_STR("name", name);
|
240
|
+
}
|
241
|
+
else {
|
242
|
+
LXW_PUSH_ATTRIBUTES_STR("name", "TableStyleMedium9");
|
243
|
+
}
|
244
|
+
|
245
|
+
if (table_obj->first_column)
|
246
|
+
LXW_PUSH_ATTRIBUTES_STR("showFirstColumn", "1");
|
247
|
+
else
|
248
|
+
LXW_PUSH_ATTRIBUTES_STR("showFirstColumn", "0");
|
249
|
+
|
250
|
+
if (table_obj->last_column)
|
251
|
+
LXW_PUSH_ATTRIBUTES_STR("showLastColumn", "1");
|
252
|
+
else
|
253
|
+
LXW_PUSH_ATTRIBUTES_STR("showLastColumn", "0");
|
254
|
+
|
255
|
+
if (table_obj->no_banded_rows)
|
256
|
+
LXW_PUSH_ATTRIBUTES_STR("showRowStripes", "0");
|
257
|
+
else
|
258
|
+
LXW_PUSH_ATTRIBUTES_STR("showRowStripes", "1");
|
259
|
+
|
260
|
+
if (table_obj->banded_columns)
|
261
|
+
LXW_PUSH_ATTRIBUTES_STR("showColumnStripes", "1");
|
262
|
+
else
|
263
|
+
LXW_PUSH_ATTRIBUTES_STR("showColumnStripes", "0");
|
264
|
+
|
265
|
+
lxw_xml_empty_tag(self->file, "tableStyleInfo", &attributes);
|
266
|
+
|
267
|
+
LXW_FREE_ATTRIBUTES();
|
268
|
+
}
|
269
|
+
|
270
|
+
/*****************************************************************************
|
271
|
+
*
|
272
|
+
* XML file assembly functions.
|
273
|
+
*
|
274
|
+
****************************************************************************/
|
275
|
+
|
276
|
+
/*
|
277
|
+
* Assemble and write the XML file.
|
278
|
+
*/
|
279
|
+
void
|
280
|
+
lxw_table_assemble_xml_file(lxw_table *self)
|
281
|
+
{
|
282
|
+
/* Write the XML declaration. */
|
283
|
+
_table_xml_declaration(self);
|
284
|
+
|
285
|
+
/* Write the table element. */
|
286
|
+
_table_write_table(self);
|
287
|
+
|
288
|
+
/* Write the autoFilter element. */
|
289
|
+
_table_write_auto_filter(self);
|
290
|
+
|
291
|
+
/* Write the tableColumns element. */
|
292
|
+
_table_write_table_columns(self);
|
293
|
+
|
294
|
+
/* Write the tableStyleInfo element. */
|
295
|
+
_table_write_table_style_info(self);
|
296
|
+
|
297
|
+
lxw_xml_end_tag(self->file, "table");
|
298
|
+
}
|
299
|
+
|
300
|
+
/*****************************************************************************
|
301
|
+
*
|
302
|
+
* Public functions.
|
303
|
+
*
|
304
|
+
****************************************************************************/
|
data/libxlsxwriter/src/theme.c
CHANGED
data/libxlsxwriter/src/utility.c
CHANGED
@@ -3,18 +3,27 @@
|
|
3
3
|
*
|
4
4
|
* Used in conjunction with the libxlsxwriter library.
|
5
5
|
*
|
6
|
-
* Copyright 2014-
|
6
|
+
* Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
7
|
*
|
8
8
|
*/
|
9
9
|
|
10
|
+
#ifdef USE_FMEMOPEN
|
11
|
+
#define _POSIX_C_SOURCE 200809L
|
12
|
+
#endif
|
13
|
+
|
10
14
|
#include <ctype.h>
|
11
15
|
#include <stdio.h>
|
12
16
|
#include <string.h>
|
13
17
|
#include <stdint.h>
|
14
18
|
#include <stdlib.h>
|
15
19
|
#include "xlsxwriter.h"
|
20
|
+
#include "xlsxwriter/common.h"
|
16
21
|
#include "xlsxwriter/third_party/tmpfileplus.h"
|
17
22
|
|
23
|
+
#ifdef USE_DTOA_LIBRARY
|
24
|
+
#include "xlsxwriter/third_party/emyg_dtoa.h"
|
25
|
+
#endif
|
26
|
+
|
18
27
|
char *error_strings[LXW_MAX_ERRNO + 1] = {
|
19
28
|
"No error.",
|
20
29
|
"Memory error, failed to malloc() required memory.",
|
@@ -27,19 +36,20 @@ char *error_strings[LXW_MAX_ERRNO + 1] = {
|
|
27
36
|
"Zip error ZIP_INTERNALERROR while creating the xlsx file.",
|
28
37
|
"File error or unknown zip error when adding sub file to xlsx file.",
|
29
38
|
"Unknown zip error when closing xlsx file.",
|
39
|
+
"Feature is not currently supported in this configuration.",
|
30
40
|
"NULL function parameter ignored.",
|
31
41
|
"Function parameter validation error.",
|
32
42
|
"Worksheet name exceeds Excel's limit of 31 characters.",
|
33
43
|
"Worksheet name cannot contain invalid characters: '[ ] : * ? / \\'",
|
34
44
|
"Worksheet name cannot start or end with an apostrophe.",
|
35
45
|
"Worksheet name is already in use.",
|
36
|
-
"Worksheet name 'History' is reserved by Excel.",
|
37
46
|
"Parameter exceeds Excel's limit of 32 characters.",
|
38
47
|
"Parameter exceeds Excel's limit of 128 characters.",
|
39
48
|
"Parameter exceeds Excel's limit of 255 characters.",
|
40
49
|
"String exceeds Excel's limit of 32,767 characters.",
|
41
50
|
"Error finding internal string index.",
|
42
51
|
"Worksheet row or column index out of range.",
|
52
|
+
"Maximum hyperlink length (2079) exceeded.",
|
43
53
|
"Maximum number of worksheet URLs (65530) exceeded.",
|
44
54
|
"Couldn't read image dimensions or DPI.",
|
45
55
|
"Unknown error number."
|
@@ -62,7 +72,7 @@ lxw_col_to_name(char *col_name, lxw_col_t col_num, uint8_t absolute)
|
|
62
72
|
{
|
63
73
|
uint8_t pos = 0;
|
64
74
|
size_t len;
|
65
|
-
|
75
|
+
size_t i;
|
66
76
|
|
67
77
|
/* Change from 0 index to 1 index. */
|
68
78
|
col_num++;
|
@@ -312,10 +322,11 @@ lxw_name_to_col_2(const char *col_str)
|
|
312
322
|
}
|
313
323
|
|
314
324
|
/*
|
315
|
-
* Convert a lxw_datetime struct to an Excel serial date
|
325
|
+
* Convert a lxw_datetime struct to an Excel serial date, with a 1900
|
326
|
+
* or 1904 epoch.
|
316
327
|
*/
|
317
328
|
double
|
318
|
-
|
329
|
+
lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
|
319
330
|
{
|
320
331
|
int year = datetime->year;
|
321
332
|
int month = datetime->month;
|
@@ -392,7 +403,7 @@ lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904)
|
|
392
403
|
/* Add days for all previous years. */
|
393
404
|
days += range * 365;
|
394
405
|
/* Add 4 year leapdays. */
|
395
|
-
days +=
|
406
|
+
days += range / 4;
|
396
407
|
/* Remove 100 year leapdays. */
|
397
408
|
days -= (range + offset) / 100;
|
398
409
|
/* Add 400 year leapdays. */
|
@@ -407,6 +418,43 @@ lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904)
|
|
407
418
|
return days + seconds;
|
408
419
|
}
|
409
420
|
|
421
|
+
/*
|
422
|
+
* Convert a lxw_datetime struct to an Excel serial date, for the 1900 epoch.
|
423
|
+
*/
|
424
|
+
double
|
425
|
+
lxw_datetime_to_excel_datetime(lxw_datetime *datetime)
|
426
|
+
{
|
427
|
+
return lxw_datetime_to_excel_date_epoch(datetime, LXW_FALSE);
|
428
|
+
}
|
429
|
+
|
430
|
+
/*
|
431
|
+
* Convert a unix datetime (1970/01/01 epoch) to an Excel serial date, with a
|
432
|
+
* 1900 epoch.
|
433
|
+
*/
|
434
|
+
double
|
435
|
+
lxw_unixtime_to_excel_date(int64_t unixtime)
|
436
|
+
{
|
437
|
+
return lxw_unixtime_to_excel_date_epoch(unixtime, LXW_FALSE);
|
438
|
+
}
|
439
|
+
|
440
|
+
/*
|
441
|
+
* Convert a unix datetime (1970/01/01 epoch) to an Excel serial date, with a
|
442
|
+
* 1900 or 1904 epoch.
|
443
|
+
*/
|
444
|
+
double
|
445
|
+
lxw_unixtime_to_excel_date_epoch(int64_t unixtime, uint8_t date_1904)
|
446
|
+
{
|
447
|
+
double excel_datetime = 0.0;
|
448
|
+
double epoch = date_1904 ? 24107.0 : 25568.0;
|
449
|
+
|
450
|
+
excel_datetime = epoch + (unixtime / (24 * 60 * 60.0));
|
451
|
+
|
452
|
+
if (!date_1904 && excel_datetime >= 60.0)
|
453
|
+
excel_datetime = excel_datetime + 1.0;
|
454
|
+
|
455
|
+
return excel_datetime;
|
456
|
+
}
|
457
|
+
|
410
458
|
/* Simple strdup() implementation since it isn't ANSI C. */
|
411
459
|
char *
|
412
460
|
lxw_strdup(const char *str)
|
@@ -524,7 +572,7 @@ lxw_quote_sheetname(const char *str)
|
|
524
572
|
* version if required for safety or portability.
|
525
573
|
*/
|
526
574
|
FILE *
|
527
|
-
lxw_tmpfile(char *tmpdir)
|
575
|
+
lxw_tmpfile(const char *tmpdir)
|
528
576
|
{
|
529
577
|
#ifndef USE_STANDARD_TMPFILE
|
530
578
|
return tmpfileplus(tmpdir, NULL, NULL, 0);
|
@@ -534,34 +582,40 @@ lxw_tmpfile(char *tmpdir)
|
|
534
582
|
#endif
|
535
583
|
}
|
536
584
|
|
585
|
+
/**
|
586
|
+
* Return a memory-backed file if supported, otherwise a temporary one
|
587
|
+
*/
|
588
|
+
FILE *
|
589
|
+
lxw_get_filehandle(char **buf, size_t *size, const char *tmpdir)
|
590
|
+
{
|
591
|
+
static size_t s;
|
592
|
+
if (!size)
|
593
|
+
size = &s;
|
594
|
+
*buf = NULL;
|
595
|
+
*size = 0;
|
596
|
+
#ifdef USE_FMEMOPEN
|
597
|
+
(void) tmpdir;
|
598
|
+
return open_memstream(buf, size);
|
599
|
+
#else
|
600
|
+
return lxw_tmpfile(tmpdir);
|
601
|
+
#endif
|
602
|
+
}
|
603
|
+
|
537
604
|
/*
|
538
|
-
*
|
539
|
-
*
|
540
|
-
* a function of the same name.
|
541
|
-
*
|
542
|
-
* The code below is a simplified example that changes numbers like 123,45 to
|
543
|
-
* 123.45. End-users can replace this with something more rigorous if
|
544
|
-
* required.
|
605
|
+
* Use third party function to handle sprintf of doubles for locale portable
|
606
|
+
* code.
|
545
607
|
*/
|
546
|
-
#ifdef
|
608
|
+
#ifdef USE_DTOA_LIBRARY
|
547
609
|
int
|
548
610
|
lxw_sprintf_dbl(char *data, double number)
|
549
611
|
{
|
550
|
-
|
551
|
-
|
552
|
-
lxw_snprintf(data, LXW_ATTR_32, "%.16g", number);
|
553
|
-
|
554
|
-
/* Replace comma with decimal point. */
|
555
|
-
tmp = strchr(data, ',');
|
556
|
-
if (tmp)
|
557
|
-
*tmp = '.';
|
558
|
-
|
612
|
+
emyg_dtoa(number, data);
|
559
613
|
return 0;
|
560
614
|
}
|
561
615
|
#endif
|
562
616
|
|
563
617
|
/*
|
564
|
-
* Retrieve runtime library version
|
618
|
+
* Retrieve runtime library version.
|
565
619
|
*/
|
566
620
|
const char *
|
567
621
|
lxw_version(void)
|
@@ -570,33 +624,79 @@ lxw_version(void)
|
|
570
624
|
}
|
571
625
|
|
572
626
|
/*
|
573
|
-
*
|
574
|
-
* of OpenOffice.
|
627
|
+
* Retrieve runtime library version ID.
|
575
628
|
*/
|
576
629
|
uint16_t
|
577
|
-
|
630
|
+
lxw_version_id(void)
|
578
631
|
{
|
579
|
-
|
580
|
-
|
581
|
-
uint16_t hash = 0x0000;
|
582
|
-
|
583
|
-
count = strlen(password);
|
632
|
+
return LXW_VERSION_ID;
|
633
|
+
}
|
584
634
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
635
|
+
/*
|
636
|
+
* Hash a worksheet password. Based on the algorithm in ECMA-376-4:2016,
|
637
|
+
* Office Open XML File Formats - Transitional Migration Features,
|
638
|
+
* Additional attributes for workbookProtection element (Part 1, §18.2.29).
|
639
|
+
*/
|
640
|
+
uint16_t
|
641
|
+
lxw_hash_password(const char *password)
|
642
|
+
{
|
643
|
+
uint16_t byte_count = (uint16_t) strlen(password);
|
644
|
+
uint16_t hash = 0;
|
645
|
+
const char *p = &password[byte_count];
|
589
646
|
|
590
|
-
|
591
|
-
|
592
|
-
high_15 = high_15 >> 15;
|
593
|
-
letter = low_15 | high_15;
|
647
|
+
if (!byte_count)
|
648
|
+
return hash;
|
594
649
|
|
595
|
-
|
650
|
+
while (p-- != password) {
|
651
|
+
hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
|
652
|
+
hash ^= *p & 0xFF;
|
596
653
|
}
|
597
654
|
|
598
|
-
hash
|
655
|
+
hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
|
656
|
+
hash ^= byte_count;
|
599
657
|
hash ^= 0xCE4B;
|
600
658
|
|
601
659
|
return hash;
|
602
660
|
}
|
661
|
+
|
662
|
+
/* Make a simple portable version of fopen() for Windows. */
|
663
|
+
#ifdef __MINGW32__
|
664
|
+
#undef _WIN32
|
665
|
+
#endif
|
666
|
+
|
667
|
+
#ifdef _WIN32
|
668
|
+
|
669
|
+
#include <windows.h>
|
670
|
+
|
671
|
+
FILE *
|
672
|
+
lxw_fopen(const char *filename, const char *mode)
|
673
|
+
{
|
674
|
+
int n;
|
675
|
+
wchar_t wide_filename[_MAX_PATH + 1] = L"";
|
676
|
+
wchar_t wide_mode[_MAX_PATH + 1] = L"";
|
677
|
+
|
678
|
+
n = MultiByteToWideChar(CP_UTF8, 0, filename, (int) strlen(filename),
|
679
|
+
wide_filename, _MAX_PATH);
|
680
|
+
|
681
|
+
if (n == 0) {
|
682
|
+
LXW_ERROR("MultiByteToWideChar error: filename");
|
683
|
+
return NULL;
|
684
|
+
}
|
685
|
+
|
686
|
+
n = MultiByteToWideChar(CP_UTF8, 0, mode, (int) strlen(mode),
|
687
|
+
wide_mode, _MAX_PATH);
|
688
|
+
|
689
|
+
if (n == 0) {
|
690
|
+
LXW_ERROR("MultiByteToWideChar error: mode");
|
691
|
+
return NULL;
|
692
|
+
}
|
693
|
+
|
694
|
+
return _wfopen(wide_filename, wide_mode);
|
695
|
+
}
|
696
|
+
#else
|
697
|
+
FILE *
|
698
|
+
lxw_fopen(const char *filename, const char *mode)
|
699
|
+
{
|
700
|
+
return fopen(filename, mode);
|
701
|
+
}
|
702
|
+
#endif
|