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
@@ -1,12 +1,49 @@
|
|
1
1
|
/*****************************************************************************
|
2
|
-
* packager - A library for
|
2
|
+
* packager - A library for assembling xml files into an Excel XLSX file.
|
3
3
|
*
|
4
|
-
*
|
4
|
+
* A class for writing the Excel XLSX Packager file.
|
5
5
|
*
|
6
|
-
*
|
6
|
+
* This module is used in conjunction with libxlsxwriter to create an
|
7
|
+
* Excel XLSX container file.
|
8
|
+
*
|
9
|
+
* From Wikipedia: The Open Packaging Conventions (OPC) is a
|
10
|
+
* container-file technology initially created by Microsoft to store
|
11
|
+
* a combination of XML and non-XML files that together form a single
|
12
|
+
* entity such as an Open XML Paper Specification (OpenXPS)
|
13
|
+
* document. http://en.wikipedia.org/wiki/Open_Packaging_Conventions.
|
14
|
+
*
|
15
|
+
* At its simplest an Excel XLSX file contains the following elements::
|
16
|
+
*
|
17
|
+
* ____ [Content_Types].xml
|
18
|
+
* |
|
19
|
+
* |____ docProps
|
20
|
+
* | |____ app.xml
|
21
|
+
* | |____ core.xml
|
22
|
+
* |
|
23
|
+
* |____ xl
|
24
|
+
* | |____ workbook.xml
|
25
|
+
* | |____ worksheets
|
26
|
+
* | | |____ sheet1.xml
|
27
|
+
* | |
|
28
|
+
* | |____ styles.xml
|
29
|
+
* | |
|
30
|
+
* | |____ theme
|
31
|
+
* | | |____ theme1.xml
|
32
|
+
* | |
|
33
|
+
* | |_____rels
|
34
|
+
* | |____ workbook.xml.rels
|
35
|
+
* |
|
36
|
+
* |_____rels
|
37
|
+
* |____ .rels
|
38
|
+
*
|
39
|
+
* The Packager class coordinates the classes that represent the
|
40
|
+
* elements of the package and writes them into the XLSX file.
|
41
|
+
*
|
42
|
+
* Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
7
43
|
*
|
8
44
|
*/
|
9
45
|
|
46
|
+
#include <zlib.h>
|
10
47
|
#include "xlsxwriter/xmlwriter.h"
|
11
48
|
#include "xlsxwriter/packager.h"
|
12
49
|
#include "xlsxwriter/hash_table.h"
|
@@ -15,9 +52,17 @@
|
|
15
52
|
STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
|
16
53
|
const char *filename);
|
17
54
|
|
18
|
-
STATIC lxw_error _add_buffer_to_zip(lxw_packager *self,
|
55
|
+
STATIC lxw_error _add_buffer_to_zip(lxw_packager *self, const char *buffer,
|
19
56
|
size_t buffer_size, const char *filename);
|
20
57
|
|
58
|
+
STATIC lxw_error _add_to_zip(lxw_packager *self, FILE * file,
|
59
|
+
char **buffer, size_t *buffer_size,
|
60
|
+
const char *filename);
|
61
|
+
|
62
|
+
STATIC lxw_error _write_vml_drawing_rels_file(lxw_packager *self,
|
63
|
+
lxw_worksheet *worksheet,
|
64
|
+
uint32_t index);
|
65
|
+
|
21
66
|
/*
|
22
67
|
* Forward declarations.
|
23
68
|
*/
|
@@ -36,7 +81,7 @@ STATIC lxw_error _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
|
36
81
|
#ifdef _WIN32
|
37
82
|
|
38
83
|
/* Silence Windows warning with duplicate symbol for SLIST_ENTRY in local
|
39
|
-
* queue.h and
|
84
|
+
* queue.h and windows.h. */
|
40
85
|
#undef SLIST_ENTRY
|
41
86
|
|
42
87
|
#include <windows.h>
|
@@ -72,21 +117,75 @@ _open_zipfile_win32(const char *filename)
|
|
72
117
|
|
73
118
|
#endif
|
74
119
|
|
120
|
+
STATIC voidpf ZCALLBACK
|
121
|
+
_fopen_memstream(voidpf opaque, const char *filename, int mode)
|
122
|
+
{
|
123
|
+
lxw_packager *packager = (lxw_packager *) opaque;
|
124
|
+
(void) filename;
|
125
|
+
(void) mode;
|
126
|
+
return lxw_get_filehandle(&packager->output_buffer,
|
127
|
+
&packager->output_buffer_size,
|
128
|
+
packager->tmpdir);
|
129
|
+
}
|
130
|
+
|
131
|
+
STATIC int ZCALLBACK
|
132
|
+
_fclose_memstream(voidpf opaque, voidpf stream)
|
133
|
+
{
|
134
|
+
lxw_packager *packager = (lxw_packager *) opaque;
|
135
|
+
FILE *file = (FILE *) stream;
|
136
|
+
long size;
|
137
|
+
|
138
|
+
/* Ensure memstream buffer is updated */
|
139
|
+
if (fflush(file))
|
140
|
+
goto mem_error;
|
141
|
+
|
142
|
+
/* If the memstream is backed by a temporary file, no buffer is created,
|
143
|
+
so create it manually. */
|
144
|
+
if (!packager->output_buffer) {
|
145
|
+
if (fseek(file, 0L, SEEK_END))
|
146
|
+
goto mem_error;
|
147
|
+
|
148
|
+
size = ftell(file);
|
149
|
+
if (size == -1)
|
150
|
+
goto mem_error;
|
151
|
+
|
152
|
+
packager->output_buffer = malloc(size);
|
153
|
+
GOTO_LABEL_ON_MEM_ERROR(packager->output_buffer, mem_error);
|
154
|
+
|
155
|
+
rewind(file);
|
156
|
+
if (fread((void *) packager->output_buffer, size, 1, file) < 1)
|
157
|
+
goto mem_error;
|
158
|
+
|
159
|
+
packager->output_buffer_size = size;
|
160
|
+
}
|
161
|
+
|
162
|
+
return fclose(file);
|
163
|
+
|
164
|
+
mem_error:
|
165
|
+
fclose(file);
|
166
|
+
return EOF;
|
167
|
+
}
|
168
|
+
|
75
169
|
/*
|
76
170
|
* Create a new packager object.
|
77
171
|
*/
|
78
172
|
lxw_packager *
|
79
|
-
lxw_packager_new(const char *filename, char *tmpdir, uint8_t use_zip64)
|
173
|
+
lxw_packager_new(const char *filename, const char *tmpdir, uint8_t use_zip64)
|
80
174
|
{
|
175
|
+
zlib_filefunc_def filefunc;
|
81
176
|
lxw_packager *packager = calloc(1, sizeof(lxw_packager));
|
82
177
|
GOTO_LABEL_ON_MEM_ERROR(packager, mem_error);
|
83
178
|
|
84
179
|
packager->buffer = calloc(1, LXW_ZIP_BUFFER_SIZE);
|
85
180
|
GOTO_LABEL_ON_MEM_ERROR(packager->buffer, mem_error);
|
86
181
|
|
87
|
-
packager->filename =
|
182
|
+
packager->filename = NULL;
|
88
183
|
packager->tmpdir = tmpdir;
|
89
|
-
|
184
|
+
|
185
|
+
if (filename) {
|
186
|
+
packager->filename = lxw_strdup(filename);
|
187
|
+
GOTO_LABEL_ON_MEM_ERROR(packager->filename, mem_error);
|
188
|
+
}
|
90
189
|
|
91
190
|
packager->buffer_size = LXW_ZIP_BUFFER_SIZE;
|
92
191
|
packager->use_zip64 = use_zip64;
|
@@ -102,12 +201,24 @@ lxw_packager_new(const char *filename, char *tmpdir, uint8_t use_zip64)
|
|
102
201
|
packager->zipfile_info.internal_fa = 0;
|
103
202
|
packager->zipfile_info.external_fa = 0;
|
104
203
|
|
204
|
+
packager->output_buffer = NULL;
|
205
|
+
packager->output_buffer_size = 0;
|
206
|
+
|
105
207
|
/* Create a zip container for the xlsx file. */
|
208
|
+
if (packager->filename) {
|
106
209
|
#ifdef _WIN32
|
107
|
-
|
210
|
+
packager->zipfile = _open_zipfile_win32(packager->filename);
|
108
211
|
#else
|
109
|
-
|
212
|
+
packager->zipfile = zipOpen(packager->filename, 0);
|
110
213
|
#endif
|
214
|
+
}
|
215
|
+
else {
|
216
|
+
fill_fopen_filefunc(&filefunc);
|
217
|
+
filefunc.opaque = packager;
|
218
|
+
filefunc.zopen_file = _fopen_memstream;
|
219
|
+
filefunc.zclose_file = _fclose_memstream;
|
220
|
+
packager->zipfile = zipOpen2(packager->filename, 0, NULL, &filefunc);
|
221
|
+
}
|
111
222
|
|
112
223
|
if (packager->zipfile == NULL)
|
113
224
|
goto mem_error;
|
@@ -128,8 +239,8 @@ lxw_packager_free(lxw_packager *packager)
|
|
128
239
|
if (!packager)
|
129
240
|
return;
|
130
241
|
|
131
|
-
free(packager->buffer);
|
132
|
-
free(packager->filename);
|
242
|
+
free((void *) packager->buffer);
|
243
|
+
free((void *) packager->filename);
|
133
244
|
free(packager);
|
134
245
|
}
|
135
246
|
|
@@ -147,16 +258,19 @@ _write_workbook_file(lxw_packager *self)
|
|
147
258
|
lxw_workbook *workbook = self->workbook;
|
148
259
|
lxw_error err;
|
149
260
|
|
150
|
-
|
261
|
+
char *buffer = NULL;
|
262
|
+
size_t buffer_size = 0;
|
263
|
+
workbook->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
151
264
|
if (!workbook->file)
|
152
265
|
return LXW_ERROR_CREATING_TMPFILE;
|
153
266
|
|
154
267
|
lxw_workbook_assemble_xml_file(workbook);
|
155
268
|
|
156
|
-
err =
|
157
|
-
|
158
|
-
|
269
|
+
err = _add_to_zip(self, workbook->file, &buffer, &buffer_size,
|
270
|
+
"xl/workbook.xml");
|
159
271
|
fclose(workbook->file);
|
272
|
+
free(buffer);
|
273
|
+
RETURN_ON_ERROR(err);
|
160
274
|
|
161
275
|
return LXW_NO_ERROR;
|
162
276
|
}
|
@@ -171,6 +285,8 @@ _write_worksheet_files(lxw_packager *self)
|
|
171
285
|
lxw_sheet *sheet;
|
172
286
|
lxw_worksheet *worksheet;
|
173
287
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
288
|
+
char *buffer = NULL;
|
289
|
+
size_t buffer_size = 0;
|
174
290
|
uint32_t index = 1;
|
175
291
|
lxw_error err;
|
176
292
|
|
@@ -186,16 +302,18 @@ _write_worksheet_files(lxw_packager *self)
|
|
186
302
|
if (worksheet->optimize_row)
|
187
303
|
lxw_worksheet_write_single_row(worksheet);
|
188
304
|
|
189
|
-
worksheet->file =
|
305
|
+
worksheet->file = lxw_get_filehandle(&buffer, &buffer_size,
|
306
|
+
self->tmpdir);
|
190
307
|
if (!worksheet->file)
|
191
308
|
return LXW_ERROR_CREATING_TMPFILE;
|
192
309
|
|
193
310
|
lxw_worksheet_assemble_xml_file(worksheet);
|
194
311
|
|
195
|
-
err =
|
196
|
-
|
197
|
-
|
312
|
+
err = _add_to_zip(self, worksheet->file, &buffer, &buffer_size,
|
313
|
+
sheetname);
|
198
314
|
fclose(worksheet->file);
|
315
|
+
free(buffer);
|
316
|
+
RETURN_ON_ERROR(err);
|
199
317
|
}
|
200
318
|
|
201
319
|
return LXW_NO_ERROR;
|
@@ -211,6 +329,8 @@ _write_chartsheet_files(lxw_packager *self)
|
|
211
329
|
lxw_sheet *sheet;
|
212
330
|
lxw_chartsheet *chartsheet;
|
213
331
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
332
|
+
char *buffer = NULL;
|
333
|
+
size_t buffer_size = 0;
|
214
334
|
uint32_t index = 1;
|
215
335
|
lxw_error err;
|
216
336
|
|
@@ -223,16 +343,18 @@ _write_chartsheet_files(lxw_packager *self)
|
|
223
343
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
224
344
|
"xl/chartsheets/sheet%d.xml", index++);
|
225
345
|
|
226
|
-
chartsheet->file =
|
346
|
+
chartsheet->file = lxw_get_filehandle(&buffer, &buffer_size,
|
347
|
+
self->tmpdir);
|
227
348
|
if (!chartsheet->file)
|
228
349
|
return LXW_ERROR_CREATING_TMPFILE;
|
229
350
|
|
230
351
|
lxw_chartsheet_assemble_xml_file(chartsheet);
|
231
352
|
|
232
|
-
err =
|
233
|
-
|
234
|
-
|
353
|
+
err = _add_to_zip(self, chartsheet->file, &buffer, &buffer_size,
|
354
|
+
sheetname);
|
235
355
|
fclose(chartsheet->file);
|
356
|
+
free(buffer);
|
357
|
+
RETURN_ON_ERROR(err);
|
236
358
|
}
|
237
359
|
|
238
360
|
return LXW_NO_ERROR;
|
@@ -247,7 +369,7 @@ _write_image_files(lxw_packager *self)
|
|
247
369
|
lxw_workbook *workbook = self->workbook;
|
248
370
|
lxw_sheet *sheet;
|
249
371
|
lxw_worksheet *worksheet;
|
250
|
-
|
372
|
+
lxw_object_properties *object_props;
|
251
373
|
lxw_error err;
|
252
374
|
FILE *image_stream;
|
253
375
|
|
@@ -260,21 +382,25 @@ _write_image_files(lxw_packager *self)
|
|
260
382
|
else
|
261
383
|
worksheet = sheet->u.worksheet;
|
262
384
|
|
263
|
-
if (STAILQ_EMPTY(worksheet->
|
385
|
+
if (STAILQ_EMPTY(worksheet->image_props))
|
264
386
|
continue;
|
265
387
|
|
266
|
-
STAILQ_FOREACH(
|
388
|
+
STAILQ_FOREACH(object_props, worksheet->image_props, list_pointers) {
|
389
|
+
|
390
|
+
if (object_props->is_duplicate)
|
391
|
+
continue;
|
267
392
|
|
268
393
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
269
|
-
"xl/media/image%d.%s", index++,
|
394
|
+
"xl/media/image%d.%s", index++,
|
395
|
+
object_props->extension);
|
270
396
|
|
271
|
-
if (!
|
397
|
+
if (!object_props->is_image_buffer) {
|
272
398
|
/* Check that the image file exists and can be opened. */
|
273
|
-
image_stream =
|
399
|
+
image_stream = lxw_fopen(object_props->filename, "rb");
|
274
400
|
if (!image_stream) {
|
275
401
|
LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
|
276
402
|
"doesn't exist or can't be opened: %s.",
|
277
|
-
|
403
|
+
object_props->filename);
|
278
404
|
return LXW_ERROR_CREATING_TMPFILE;
|
279
405
|
}
|
280
406
|
|
@@ -283,8 +409,9 @@ _write_image_files(lxw_packager *self)
|
|
283
409
|
}
|
284
410
|
else {
|
285
411
|
err = _add_buffer_to_zip(self,
|
286
|
-
|
287
|
-
|
412
|
+
object_props->image_buffer,
|
413
|
+
object_props->image_buffer_size,
|
414
|
+
filename);
|
288
415
|
}
|
289
416
|
|
290
417
|
RETURN_ON_ERROR(err);
|
@@ -308,7 +435,7 @@ _add_vba_project(lxw_packager *self)
|
|
308
435
|
return LXW_NO_ERROR;
|
309
436
|
|
310
437
|
/* Check that the image file exists and can be opened. */
|
311
|
-
image_stream =
|
438
|
+
image_stream = lxw_fopen(workbook->vba_project, "rb");
|
312
439
|
if (!image_stream) {
|
313
440
|
LXW_WARN_FORMAT1("Error adding vbaProject.bin to xlsx file: "
|
314
441
|
"file doesn't exist or can't be opened: %s.",
|
@@ -323,6 +450,35 @@ _add_vba_project(lxw_packager *self)
|
|
323
450
|
return LXW_NO_ERROR;
|
324
451
|
}
|
325
452
|
|
453
|
+
/*
|
454
|
+
* Write the xl/vbaProjectSignature.bin file.
|
455
|
+
*/
|
456
|
+
STATIC lxw_error
|
457
|
+
_add_vba_project_signature(lxw_packager *self)
|
458
|
+
{
|
459
|
+
lxw_workbook *workbook = self->workbook;
|
460
|
+
lxw_error err;
|
461
|
+
FILE *image_stream;
|
462
|
+
|
463
|
+
if (!workbook->vba_project_signature)
|
464
|
+
return LXW_NO_ERROR;
|
465
|
+
|
466
|
+
/* Check that the image file exists and can be opened. */
|
467
|
+
image_stream = lxw_fopen(workbook->vba_project_signature, "rb");
|
468
|
+
if (!image_stream) {
|
469
|
+
LXW_WARN_FORMAT1("Error adding vbaProjectSignature.bin to xlsx file: "
|
470
|
+
"file doesn't exist or can't be opened: %s.",
|
471
|
+
workbook->vba_project_signature);
|
472
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
473
|
+
}
|
474
|
+
|
475
|
+
err = _add_file_to_zip(self, image_stream, "xl/vbaProjectSignature.bin");
|
476
|
+
fclose(image_stream);
|
477
|
+
RETURN_ON_ERROR(err);
|
478
|
+
|
479
|
+
return LXW_NO_ERROR;
|
480
|
+
}
|
481
|
+
|
326
482
|
/*
|
327
483
|
* Write the chart files.
|
328
484
|
*/
|
@@ -332,6 +488,8 @@ _write_chart_files(lxw_packager *self)
|
|
332
488
|
lxw_workbook *workbook = self->workbook;
|
333
489
|
lxw_chart *chart;
|
334
490
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
491
|
+
char *buffer = NULL;
|
492
|
+
size_t buffer_size = 0;
|
335
493
|
uint32_t index = 1;
|
336
494
|
lxw_error err;
|
337
495
|
|
@@ -340,16 +498,17 @@ _write_chart_files(lxw_packager *self)
|
|
340
498
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
341
499
|
"xl/charts/chart%d.xml", index++);
|
342
500
|
|
343
|
-
chart->file =
|
501
|
+
chart->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
344
502
|
if (!chart->file)
|
345
503
|
return LXW_ERROR_CREATING_TMPFILE;
|
346
504
|
|
347
505
|
lxw_chart_assemble_xml_file(chart);
|
348
506
|
|
349
|
-
err =
|
350
|
-
|
351
|
-
|
507
|
+
err = _add_to_zip(self, chart->file, &buffer, &buffer_size,
|
508
|
+
sheetname);
|
352
509
|
fclose(chart->file);
|
510
|
+
free(buffer);
|
511
|
+
RETURN_ON_ERROR(err);
|
353
512
|
}
|
354
513
|
|
355
514
|
return LXW_NO_ERROR;
|
@@ -383,6 +542,8 @@ _write_drawing_files(lxw_packager *self)
|
|
383
542
|
lxw_worksheet *worksheet;
|
384
543
|
lxw_drawing *drawing;
|
385
544
|
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
545
|
+
char *buffer = NULL;
|
546
|
+
size_t buffer_size = 0;
|
386
547
|
uint32_t index = 1;
|
387
548
|
lxw_error err;
|
388
549
|
|
@@ -398,15 +559,18 @@ _write_drawing_files(lxw_packager *self)
|
|
398
559
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
399
560
|
"xl/drawings/drawing%d.xml", index++);
|
400
561
|
|
401
|
-
drawing->file =
|
562
|
+
drawing->file = lxw_get_filehandle(&buffer, &buffer_size,
|
563
|
+
self->tmpdir);
|
402
564
|
if (!drawing->file)
|
403
565
|
return LXW_ERROR_CREATING_TMPFILE;
|
404
566
|
|
405
567
|
lxw_drawing_assemble_xml_file(drawing);
|
406
|
-
err = _add_file_to_zip(self, drawing->file, filename);
|
407
|
-
RETURN_ON_ERROR(err);
|
408
568
|
|
569
|
+
err = _add_to_zip(self, drawing->file, &buffer, &buffer_size,
|
570
|
+
filename);
|
409
571
|
fclose(drawing->file);
|
572
|
+
free(buffer);
|
573
|
+
RETURN_ON_ERROR(err);
|
410
574
|
}
|
411
575
|
}
|
412
576
|
|
@@ -440,6 +604,263 @@ _get_drawing_count(lxw_packager *self)
|
|
440
604
|
return drawing_count;
|
441
605
|
}
|
442
606
|
|
607
|
+
/*
|
608
|
+
* Write the worksheet table files.
|
609
|
+
*/
|
610
|
+
STATIC lxw_error
|
611
|
+
_write_table_files(lxw_packager *self)
|
612
|
+
{
|
613
|
+
lxw_workbook *workbook = self->workbook;
|
614
|
+
lxw_sheet *sheet;
|
615
|
+
lxw_worksheet *worksheet;
|
616
|
+
lxw_table *table;
|
617
|
+
lxw_table_obj *table_obj;
|
618
|
+
lxw_error err;
|
619
|
+
|
620
|
+
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
621
|
+
char *buffer = NULL;
|
622
|
+
size_t buffer_size = 0;
|
623
|
+
uint32_t index = 1;
|
624
|
+
|
625
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
626
|
+
if (sheet->is_chartsheet)
|
627
|
+
continue;
|
628
|
+
else
|
629
|
+
worksheet = sheet->u.worksheet;
|
630
|
+
|
631
|
+
if (STAILQ_EMPTY(worksheet->table_objs))
|
632
|
+
continue;
|
633
|
+
|
634
|
+
STAILQ_FOREACH(table_obj, worksheet->table_objs, list_pointers) {
|
635
|
+
|
636
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
637
|
+
"xl/tables/table%d.xml", index++);
|
638
|
+
|
639
|
+
table = lxw_table_new();
|
640
|
+
if (!table) {
|
641
|
+
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
642
|
+
RETURN_ON_ERROR(err);
|
643
|
+
}
|
644
|
+
|
645
|
+
table->file = lxw_get_filehandle(&buffer, &buffer_size,
|
646
|
+
self->tmpdir);
|
647
|
+
if (!table->file) {
|
648
|
+
lxw_table_free(table);
|
649
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
650
|
+
}
|
651
|
+
|
652
|
+
table->table_obj = table_obj;
|
653
|
+
|
654
|
+
lxw_table_assemble_xml_file(table);
|
655
|
+
|
656
|
+
err = _add_to_zip(self, table->file, &buffer, &buffer_size,
|
657
|
+
filename);
|
658
|
+
fclose(table->file);
|
659
|
+
free(buffer);
|
660
|
+
lxw_table_free(table);
|
661
|
+
RETURN_ON_ERROR(err);
|
662
|
+
}
|
663
|
+
}
|
664
|
+
|
665
|
+
return LXW_NO_ERROR;
|
666
|
+
}
|
667
|
+
|
668
|
+
/*
|
669
|
+
* Count the table files.
|
670
|
+
*/
|
671
|
+
uint32_t
|
672
|
+
_get_table_count(lxw_packager *self)
|
673
|
+
{
|
674
|
+
lxw_workbook *workbook = self->workbook;
|
675
|
+
lxw_sheet *sheet;
|
676
|
+
lxw_worksheet *worksheet;
|
677
|
+
uint32_t table_count = 0;
|
678
|
+
|
679
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
680
|
+
if (sheet->is_chartsheet)
|
681
|
+
worksheet = sheet->u.chartsheet->worksheet;
|
682
|
+
else
|
683
|
+
worksheet = sheet->u.worksheet;
|
684
|
+
|
685
|
+
table_count += worksheet->table_count;
|
686
|
+
}
|
687
|
+
|
688
|
+
return table_count;
|
689
|
+
}
|
690
|
+
|
691
|
+
/*
|
692
|
+
* Write the comment/header VML files.
|
693
|
+
*/
|
694
|
+
STATIC lxw_error
|
695
|
+
_write_vml_files(lxw_packager *self)
|
696
|
+
{
|
697
|
+
lxw_workbook *workbook = self->workbook;
|
698
|
+
lxw_sheet *sheet;
|
699
|
+
lxw_worksheet *worksheet;
|
700
|
+
lxw_vml *vml;
|
701
|
+
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
702
|
+
char *buffer = NULL;
|
703
|
+
size_t buffer_size = 0;
|
704
|
+
uint32_t index = 1;
|
705
|
+
lxw_error err;
|
706
|
+
|
707
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
708
|
+
if (sheet->is_chartsheet)
|
709
|
+
continue;
|
710
|
+
else
|
711
|
+
worksheet = sheet->u.worksheet;
|
712
|
+
|
713
|
+
if (!worksheet->has_vml && !worksheet->has_header_vml)
|
714
|
+
continue;
|
715
|
+
|
716
|
+
if (worksheet->has_vml) {
|
717
|
+
|
718
|
+
vml = lxw_vml_new();
|
719
|
+
if (!vml)
|
720
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
721
|
+
|
722
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
723
|
+
"xl/drawings/vmlDrawing%d.vml", index++);
|
724
|
+
|
725
|
+
vml->file = lxw_get_filehandle(&buffer, &buffer_size,
|
726
|
+
self->tmpdir);
|
727
|
+
if (!vml->file) {
|
728
|
+
lxw_vml_free(vml);
|
729
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
730
|
+
}
|
731
|
+
|
732
|
+
vml->comment_objs = worksheet->comment_objs;
|
733
|
+
vml->button_objs = worksheet->button_objs;
|
734
|
+
vml->vml_shape_id = worksheet->vml_shape_id;
|
735
|
+
vml->comment_display_default = worksheet->comment_display_default;
|
736
|
+
|
737
|
+
if (worksheet->vml_data_id_str) {
|
738
|
+
vml->vml_data_id_str = worksheet->vml_data_id_str;
|
739
|
+
}
|
740
|
+
else {
|
741
|
+
fclose(vml->file);
|
742
|
+
free(buffer);
|
743
|
+
lxw_vml_free(vml);
|
744
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
745
|
+
}
|
746
|
+
|
747
|
+
lxw_vml_assemble_xml_file(vml);
|
748
|
+
|
749
|
+
err = _add_to_zip(self, vml->file, &buffer, &buffer_size,
|
750
|
+
filename);
|
751
|
+
|
752
|
+
fclose(vml->file);
|
753
|
+
free(buffer);
|
754
|
+
lxw_vml_free(vml);
|
755
|
+
|
756
|
+
RETURN_ON_ERROR(err);
|
757
|
+
}
|
758
|
+
|
759
|
+
if (worksheet->has_header_vml) {
|
760
|
+
|
761
|
+
err = _write_vml_drawing_rels_file(self, worksheet, index);
|
762
|
+
RETURN_ON_ERROR(err);
|
763
|
+
|
764
|
+
vml = lxw_vml_new();
|
765
|
+
if (!vml)
|
766
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
767
|
+
|
768
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
769
|
+
"xl/drawings/vmlDrawing%d.vml", index++);
|
770
|
+
|
771
|
+
vml->file = lxw_get_filehandle(&buffer, &buffer_size,
|
772
|
+
self->tmpdir);
|
773
|
+
if (!vml->file) {
|
774
|
+
lxw_vml_free(vml);
|
775
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
776
|
+
}
|
777
|
+
|
778
|
+
vml->image_objs = worksheet->header_image_objs;
|
779
|
+
vml->vml_shape_id = worksheet->vml_header_id * 1024;
|
780
|
+
|
781
|
+
if (worksheet->vml_header_id_str) {
|
782
|
+
vml->vml_data_id_str = worksheet->vml_header_id_str;
|
783
|
+
}
|
784
|
+
else {
|
785
|
+
fclose(vml->file);
|
786
|
+
free(buffer);
|
787
|
+
lxw_vml_free(vml);
|
788
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
789
|
+
}
|
790
|
+
|
791
|
+
lxw_vml_assemble_xml_file(vml);
|
792
|
+
|
793
|
+
err = _add_to_zip(self, vml->file, &buffer, &buffer_size,
|
794
|
+
filename);
|
795
|
+
|
796
|
+
fclose(vml->file);
|
797
|
+
free(buffer);
|
798
|
+
lxw_vml_free(vml);
|
799
|
+
|
800
|
+
RETURN_ON_ERROR(err);
|
801
|
+
}
|
802
|
+
}
|
803
|
+
|
804
|
+
return LXW_NO_ERROR;
|
805
|
+
}
|
806
|
+
|
807
|
+
/*
|
808
|
+
* Write the comment files.
|
809
|
+
*/
|
810
|
+
STATIC lxw_error
|
811
|
+
_write_comment_files(lxw_packager *self)
|
812
|
+
{
|
813
|
+
lxw_workbook *workbook = self->workbook;
|
814
|
+
lxw_sheet *sheet;
|
815
|
+
lxw_worksheet *worksheet;
|
816
|
+
lxw_comment *comment;
|
817
|
+
char filename[LXW_FILENAME_LENGTH] = { 0 };
|
818
|
+
char *buffer = NULL;
|
819
|
+
size_t buffer_size = 0;
|
820
|
+
uint32_t index = 1;
|
821
|
+
lxw_error err;
|
822
|
+
|
823
|
+
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
824
|
+
if (sheet->is_chartsheet)
|
825
|
+
continue;
|
826
|
+
else
|
827
|
+
worksheet = sheet->u.worksheet;
|
828
|
+
|
829
|
+
if (!worksheet->has_comments)
|
830
|
+
continue;
|
831
|
+
|
832
|
+
comment = lxw_comment_new();
|
833
|
+
if (!comment)
|
834
|
+
return LXW_ERROR_MEMORY_MALLOC_FAILED;
|
835
|
+
|
836
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
837
|
+
"xl/comments%d.xml", index++);
|
838
|
+
|
839
|
+
comment->file = lxw_get_filehandle(&buffer, &buffer_size,
|
840
|
+
self->tmpdir);
|
841
|
+
if (!comment->file) {
|
842
|
+
lxw_comment_free(comment);
|
843
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
844
|
+
}
|
845
|
+
|
846
|
+
comment->comment_objs = worksheet->comment_objs;
|
847
|
+
comment->comment_author = worksheet->comment_author;
|
848
|
+
|
849
|
+
lxw_comment_assemble_xml_file(comment);
|
850
|
+
|
851
|
+
err = _add_to_zip(self, comment->file, &buffer, &buffer_size,
|
852
|
+
filename);
|
853
|
+
|
854
|
+
fclose(comment->file);
|
855
|
+
free(buffer);
|
856
|
+
lxw_comment_free(comment);
|
857
|
+
|
858
|
+
RETURN_ON_ERROR(err);
|
859
|
+
}
|
860
|
+
|
861
|
+
return LXW_NO_ERROR;
|
862
|
+
}
|
863
|
+
|
443
864
|
/*
|
444
865
|
* Write the sharedStrings.xml file.
|
445
866
|
*/
|
@@ -447,22 +868,25 @@ STATIC lxw_error
|
|
447
868
|
_write_shared_strings_file(lxw_packager *self)
|
448
869
|
{
|
449
870
|
lxw_sst *sst = self->workbook->sst;
|
871
|
+
char *buffer = NULL;
|
872
|
+
size_t buffer_size = 0;
|
450
873
|
lxw_error err;
|
451
874
|
|
452
875
|
/* Skip the sharedStrings file if there are no shared strings. */
|
453
876
|
if (!sst->string_count)
|
454
877
|
return LXW_NO_ERROR;
|
455
878
|
|
456
|
-
sst->file =
|
879
|
+
sst->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
457
880
|
if (!sst->file)
|
458
881
|
return LXW_ERROR_CREATING_TMPFILE;
|
459
882
|
|
460
883
|
lxw_sst_assemble_xml_file(sst);
|
461
884
|
|
462
|
-
err =
|
463
|
-
|
464
|
-
|
885
|
+
err = _add_to_zip(self, sst->file, &buffer, &buffer_size,
|
886
|
+
"xl/sharedStrings.xml");
|
465
887
|
fclose(sst->file);
|
888
|
+
free(buffer);
|
889
|
+
RETURN_ON_ERROR(err);
|
466
890
|
|
467
891
|
return LXW_NO_ERROR;
|
468
892
|
}
|
@@ -479,6 +903,8 @@ _write_app_file(lxw_packager *self)
|
|
479
903
|
lxw_chartsheet *chartsheet;
|
480
904
|
lxw_defined_name *defined_name;
|
481
905
|
lxw_app *app;
|
906
|
+
char *buffer = NULL;
|
907
|
+
size_t buffer_size = 0;
|
482
908
|
uint32_t named_range_count = 0;
|
483
909
|
char *autofilter;
|
484
910
|
char *has_range;
|
@@ -491,7 +917,7 @@ _write_app_file(lxw_packager *self)
|
|
491
917
|
goto mem_error;
|
492
918
|
}
|
493
919
|
|
494
|
-
app->file =
|
920
|
+
app->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
495
921
|
if (!app->file) {
|
496
922
|
err = LXW_ERROR_CREATING_TMPFILE;
|
497
923
|
goto mem_error;
|
@@ -545,11 +971,15 @@ _write_app_file(lxw_packager *self)
|
|
545
971
|
/* Set the app/doc properties. */
|
546
972
|
app->properties = workbook->properties;
|
547
973
|
|
974
|
+
app->doc_security = workbook->read_only;
|
975
|
+
|
548
976
|
lxw_app_assemble_xml_file(app);
|
549
977
|
|
550
|
-
err =
|
978
|
+
err = _add_to_zip(self, app->file, &buffer, &buffer_size,
|
979
|
+
"docProps/app.xml");
|
551
980
|
|
552
981
|
fclose(app->file);
|
982
|
+
free(buffer);
|
553
983
|
|
554
984
|
mem_error:
|
555
985
|
lxw_app_free(app);
|
@@ -565,13 +995,15 @@ _write_core_file(lxw_packager *self)
|
|
565
995
|
{
|
566
996
|
lxw_error err = LXW_NO_ERROR;
|
567
997
|
lxw_core *core = lxw_core_new();
|
998
|
+
char *buffer = NULL;
|
999
|
+
size_t buffer_size = 0;
|
568
1000
|
|
569
1001
|
if (!core) {
|
570
1002
|
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
571
1003
|
goto mem_error;
|
572
1004
|
}
|
573
1005
|
|
574
|
-
core->file =
|
1006
|
+
core->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
575
1007
|
if (!core->file) {
|
576
1008
|
err = LXW_ERROR_CREATING_TMPFILE;
|
577
1009
|
goto mem_error;
|
@@ -581,9 +1013,11 @@ _write_core_file(lxw_packager *self)
|
|
581
1013
|
|
582
1014
|
lxw_core_assemble_xml_file(core);
|
583
1015
|
|
584
|
-
err =
|
1016
|
+
err = _add_to_zip(self, core->file, &buffer, &buffer_size,
|
1017
|
+
"docProps/core.xml");
|
585
1018
|
|
586
1019
|
fclose(core->file);
|
1020
|
+
free(buffer);
|
587
1021
|
|
588
1022
|
mem_error:
|
589
1023
|
lxw_core_free(core);
|
@@ -591,6 +1025,47 @@ mem_error:
|
|
591
1025
|
return err;
|
592
1026
|
}
|
593
1027
|
|
1028
|
+
/*
|
1029
|
+
* Write the metadata.xml file.
|
1030
|
+
*/
|
1031
|
+
STATIC lxw_error
|
1032
|
+
_write_metadata_file(lxw_packager *self)
|
1033
|
+
{
|
1034
|
+
lxw_error err = LXW_NO_ERROR;
|
1035
|
+
lxw_metadata *metadata;
|
1036
|
+
char *buffer = NULL;
|
1037
|
+
size_t buffer_size = 0;
|
1038
|
+
|
1039
|
+
if (!self->workbook->has_metadata)
|
1040
|
+
return LXW_NO_ERROR;
|
1041
|
+
|
1042
|
+
metadata = lxw_metadata_new();
|
1043
|
+
|
1044
|
+
if (!metadata) {
|
1045
|
+
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
1046
|
+
goto mem_error;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
metadata->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
1050
|
+
if (!metadata->file) {
|
1051
|
+
err = LXW_ERROR_CREATING_TMPFILE;
|
1052
|
+
goto mem_error;
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
lxw_metadata_assemble_xml_file(metadata);
|
1056
|
+
|
1057
|
+
err = _add_to_zip(self, metadata->file, &buffer, &buffer_size,
|
1058
|
+
"xl/metadata.xml");
|
1059
|
+
|
1060
|
+
fclose(metadata->file);
|
1061
|
+
free(buffer);
|
1062
|
+
|
1063
|
+
mem_error:
|
1064
|
+
lxw_metadata_free(metadata);
|
1065
|
+
|
1066
|
+
return err;
|
1067
|
+
}
|
1068
|
+
|
594
1069
|
/*
|
595
1070
|
* Write the custom.xml file.
|
596
1071
|
*/
|
@@ -598,6 +1073,8 @@ STATIC lxw_error
|
|
598
1073
|
_write_custom_file(lxw_packager *self)
|
599
1074
|
{
|
600
1075
|
lxw_custom *custom;
|
1076
|
+
char *buffer = NULL;
|
1077
|
+
size_t buffer_size = 0;
|
601
1078
|
lxw_error err = LXW_NO_ERROR;
|
602
1079
|
|
603
1080
|
if (STAILQ_EMPTY(self->workbook->custom_properties))
|
@@ -609,7 +1086,7 @@ _write_custom_file(lxw_packager *self)
|
|
609
1086
|
goto mem_error;
|
610
1087
|
}
|
611
1088
|
|
612
|
-
custom->file =
|
1089
|
+
custom->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
613
1090
|
if (!custom->file) {
|
614
1091
|
err = LXW_ERROR_CREATING_TMPFILE;
|
615
1092
|
goto mem_error;
|
@@ -619,9 +1096,11 @@ _write_custom_file(lxw_packager *self)
|
|
619
1096
|
|
620
1097
|
lxw_custom_assemble_xml_file(custom);
|
621
1098
|
|
622
|
-
err =
|
1099
|
+
err = _add_to_zip(self, custom->file, &buffer, &buffer_size,
|
1100
|
+
"docProps/custom.xml");
|
623
1101
|
|
624
1102
|
fclose(custom->file);
|
1103
|
+
free(buffer);
|
625
1104
|
|
626
1105
|
mem_error:
|
627
1106
|
lxw_custom_free(custom);
|
@@ -636,13 +1115,15 @@ _write_theme_file(lxw_packager *self)
|
|
636
1115
|
{
|
637
1116
|
lxw_error err = LXW_NO_ERROR;
|
638
1117
|
lxw_theme *theme = lxw_theme_new();
|
1118
|
+
char *buffer = NULL;
|
1119
|
+
size_t buffer_size = 0;
|
639
1120
|
|
640
1121
|
if (!theme) {
|
641
1122
|
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
642
1123
|
goto mem_error;
|
643
1124
|
}
|
644
1125
|
|
645
|
-
theme->file =
|
1126
|
+
theme->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
646
1127
|
if (!theme->file) {
|
647
1128
|
err = LXW_ERROR_CREATING_TMPFILE;
|
648
1129
|
goto mem_error;
|
@@ -650,9 +1131,11 @@ _write_theme_file(lxw_packager *self)
|
|
650
1131
|
|
651
1132
|
lxw_theme_assemble_xml_file(theme);
|
652
1133
|
|
653
|
-
err =
|
1134
|
+
err = _add_to_zip(self, theme->file, &buffer, &buffer_size,
|
1135
|
+
"xl/theme/theme1.xml");
|
654
1136
|
|
655
1137
|
fclose(theme->file);
|
1138
|
+
free(buffer);
|
656
1139
|
|
657
1140
|
mem_error:
|
658
1141
|
lxw_theme_free(theme);
|
@@ -667,6 +1150,8 @@ STATIC lxw_error
|
|
667
1150
|
_write_styles_file(lxw_packager *self)
|
668
1151
|
{
|
669
1152
|
lxw_styles *styles = lxw_styles_new();
|
1153
|
+
char *buffer = NULL;
|
1154
|
+
size_t buffer_size = 0;
|
670
1155
|
lxw_hash_element *hash_element;
|
671
1156
|
lxw_error err = LXW_NO_ERROR;
|
672
1157
|
|
@@ -690,13 +1175,30 @@ _write_styles_file(lxw_packager *self)
|
|
690
1175
|
STAILQ_INSERT_TAIL(styles->xf_formats, style_format, list_pointers);
|
691
1176
|
}
|
692
1177
|
|
1178
|
+
/* Copy the unique and in-use dxf formats from the workbook to the styles
|
1179
|
+
* dxf_format list. */
|
1180
|
+
LXW_FOREACH_ORDERED(hash_element, self->workbook->used_dxf_formats) {
|
1181
|
+
lxw_format *workbook_format = (lxw_format *) hash_element->value;
|
1182
|
+
lxw_format *style_format = lxw_format_new();
|
1183
|
+
|
1184
|
+
if (!style_format) {
|
1185
|
+
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
1186
|
+
goto mem_error;
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
memcpy(style_format, workbook_format, sizeof(lxw_format));
|
1190
|
+
STAILQ_INSERT_TAIL(styles->dxf_formats, style_format, list_pointers);
|
1191
|
+
}
|
1192
|
+
|
693
1193
|
styles->font_count = self->workbook->font_count;
|
694
1194
|
styles->border_count = self->workbook->border_count;
|
695
1195
|
styles->fill_count = self->workbook->fill_count;
|
696
1196
|
styles->num_format_count = self->workbook->num_format_count;
|
697
1197
|
styles->xf_count = self->workbook->used_xf_formats->unique_count;
|
1198
|
+
styles->dxf_count = self->workbook->used_dxf_formats->unique_count;
|
1199
|
+
styles->has_comments = self->workbook->has_comments;
|
698
1200
|
|
699
|
-
styles->file =
|
1201
|
+
styles->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
700
1202
|
if (!styles->file) {
|
701
1203
|
err = LXW_ERROR_CREATING_TMPFILE;
|
702
1204
|
goto mem_error;
|
@@ -704,9 +1206,11 @@ _write_styles_file(lxw_packager *self)
|
|
704
1206
|
|
705
1207
|
lxw_styles_assemble_xml_file(styles);
|
706
1208
|
|
707
|
-
err =
|
1209
|
+
err = _add_to_zip(self, styles->file, &buffer, &buffer_size,
|
1210
|
+
"xl/styles.xml");
|
708
1211
|
|
709
1212
|
fclose(styles->file);
|
1213
|
+
free(buffer);
|
710
1214
|
|
711
1215
|
mem_error:
|
712
1216
|
lxw_styles_free(styles);
|
@@ -721,6 +1225,8 @@ STATIC lxw_error
|
|
721
1225
|
_write_content_types_file(lxw_packager *self)
|
722
1226
|
{
|
723
1227
|
lxw_content_types *content_types = lxw_content_types_new();
|
1228
|
+
char *buffer = NULL;
|
1229
|
+
size_t buffer_size = 0;
|
724
1230
|
lxw_workbook *workbook = self->workbook;
|
725
1231
|
lxw_sheet *sheet;
|
726
1232
|
char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
|
@@ -729,6 +1235,7 @@ _write_content_types_file(lxw_packager *self)
|
|
729
1235
|
uint32_t chartsheet_index = 1;
|
730
1236
|
uint32_t drawing_count = _get_drawing_count(self);
|
731
1237
|
uint32_t chart_count = _get_chart_count(self);
|
1238
|
+
uint32_t table_count = _get_table_count(self);
|
732
1239
|
lxw_error err = LXW_NO_ERROR;
|
733
1240
|
|
734
1241
|
if (!content_types) {
|
@@ -736,7 +1243,8 @@ _write_content_types_file(lxw_packager *self)
|
|
736
1243
|
goto mem_error;
|
737
1244
|
}
|
738
1245
|
|
739
|
-
content_types->file =
|
1246
|
+
content_types->file = lxw_get_filehandle(&buffer, &buffer_size,
|
1247
|
+
self->tmpdir);
|
740
1248
|
if (!content_types->file) {
|
741
1249
|
err = LXW_ERROR_CREATING_TMPFILE;
|
742
1250
|
goto mem_error;
|
@@ -751,6 +1259,9 @@ _write_content_types_file(lxw_packager *self)
|
|
751
1259
|
if (workbook->has_bmp)
|
752
1260
|
lxw_ct_add_default(content_types, "bmp", "image/bmp");
|
753
1261
|
|
1262
|
+
if (workbook->has_gif)
|
1263
|
+
lxw_ct_add_default(content_types, "gif", "image/gif");
|
1264
|
+
|
754
1265
|
if (workbook->vba_project)
|
755
1266
|
lxw_ct_add_default(content_types, "bin",
|
756
1267
|
"application/vnd.ms-office.vbaProject");
|
@@ -762,6 +1273,10 @@ _write_content_types_file(lxw_packager *self)
|
|
762
1273
|
lxw_ct_add_override(content_types, "/xl/workbook.xml",
|
763
1274
|
LXW_APP_DOCUMENT "spreadsheetml.sheet.main+xml");
|
764
1275
|
|
1276
|
+
if (workbook->vba_project_signature)
|
1277
|
+
lxw_ct_add_override(content_types, "/xl/vbaProjectSignature.bin",
|
1278
|
+
"application/vnd.ms-office.vbaProjectSignature");
|
1279
|
+
|
765
1280
|
STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
|
766
1281
|
if (sheet->is_chartsheet) {
|
767
1282
|
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
@@ -787,17 +1302,37 @@ _write_content_types_file(lxw_packager *self)
|
|
787
1302
|
lxw_ct_add_drawing_name(content_types, filename);
|
788
1303
|
}
|
789
1304
|
|
1305
|
+
for (index = 1; index <= table_count; index++) {
|
1306
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
1307
|
+
"/xl/tables/table%d.xml", index);
|
1308
|
+
lxw_ct_add_table_name(content_types, filename);
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
if (workbook->has_vml)
|
1312
|
+
lxw_ct_add_vml_name(content_types);
|
1313
|
+
|
1314
|
+
for (index = 1; index <= workbook->comment_count; index++) {
|
1315
|
+
lxw_snprintf(filename, LXW_FILENAME_LENGTH,
|
1316
|
+
"/xl/comments%d.xml", index);
|
1317
|
+
lxw_ct_add_comment_name(content_types, filename);
|
1318
|
+
}
|
1319
|
+
|
790
1320
|
if (workbook->sst->string_count)
|
791
1321
|
lxw_ct_add_shared_strings(content_types);
|
792
1322
|
|
793
1323
|
if (!STAILQ_EMPTY(self->workbook->custom_properties))
|
794
1324
|
lxw_ct_add_custom_properties(content_types);
|
795
1325
|
|
1326
|
+
if (workbook->has_metadata)
|
1327
|
+
lxw_ct_add_metadata(content_types);
|
1328
|
+
|
796
1329
|
lxw_content_types_assemble_xml_file(content_types);
|
797
1330
|
|
798
|
-
err =
|
1331
|
+
err = _add_to_zip(self, content_types->file, &buffer, &buffer_size,
|
1332
|
+
"[Content_Types].xml");
|
799
1333
|
|
800
1334
|
fclose(content_types->file);
|
1335
|
+
free(buffer);
|
801
1336
|
|
802
1337
|
mem_error:
|
803
1338
|
lxw_content_types_free(content_types);
|
@@ -812,6 +1347,8 @@ STATIC lxw_error
|
|
812
1347
|
_write_workbook_rels_file(lxw_packager *self)
|
813
1348
|
{
|
814
1349
|
lxw_relationships *rels = lxw_relationships_new();
|
1350
|
+
char *buffer = NULL;
|
1351
|
+
size_t buffer_size = 0;
|
815
1352
|
lxw_workbook *workbook = self->workbook;
|
816
1353
|
lxw_sheet *sheet;
|
817
1354
|
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
@@ -824,7 +1361,7 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
824
1361
|
goto mem_error;
|
825
1362
|
}
|
826
1363
|
|
827
|
-
rels->file =
|
1364
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
828
1365
|
if (!rels->file) {
|
829
1366
|
err = LXW_ERROR_CREATING_TMPFILE;
|
830
1367
|
goto mem_error;
|
@@ -856,11 +1393,16 @@ _write_workbook_rels_file(lxw_packager *self)
|
|
856
1393
|
lxw_add_ms_package_relationship(rels, "/vbaProject",
|
857
1394
|
"vbaProject.bin");
|
858
1395
|
|
1396
|
+
if (workbook->has_metadata)
|
1397
|
+
lxw_add_document_relationship(rels, "/sheetMetadata", "metadata.xml");
|
1398
|
+
|
859
1399
|
lxw_relationships_assemble_xml_file(rels);
|
860
1400
|
|
861
|
-
err =
|
1401
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size,
|
1402
|
+
"xl/_rels/workbook.xml.rels");
|
862
1403
|
|
863
1404
|
fclose(rels->file);
|
1405
|
+
free(buffer);
|
864
1406
|
|
865
1407
|
mem_error:
|
866
1408
|
lxw_free_relationships(rels);
|
@@ -876,6 +1418,8 @@ STATIC lxw_error
|
|
876
1418
|
_write_worksheet_rels_file(lxw_packager *self)
|
877
1419
|
{
|
878
1420
|
lxw_relationships *rels;
|
1421
|
+
char *buffer = NULL;
|
1422
|
+
size_t buffer_size = 0;
|
879
1423
|
lxw_rel_tuple *rel;
|
880
1424
|
lxw_workbook *workbook = self->workbook;
|
881
1425
|
lxw_sheet *sheet;
|
@@ -893,12 +1437,17 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
893
1437
|
index++;
|
894
1438
|
|
895
1439
|
if (STAILQ_EMPTY(worksheet->external_hyperlinks) &&
|
896
|
-
STAILQ_EMPTY(worksheet->external_drawing_links)
|
1440
|
+
STAILQ_EMPTY(worksheet->external_drawing_links) &&
|
1441
|
+
STAILQ_EMPTY(worksheet->external_table_links) &&
|
1442
|
+
!worksheet->external_vml_header_link &&
|
1443
|
+
!worksheet->external_vml_comment_link &&
|
1444
|
+
!worksheet->external_background_link &&
|
1445
|
+
!worksheet->external_comment_link)
|
897
1446
|
continue;
|
898
1447
|
|
899
1448
|
rels = lxw_relationships_new();
|
900
1449
|
|
901
|
-
rels->file =
|
1450
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
902
1451
|
if (!rels->file) {
|
903
1452
|
lxw_free_relationships(rels);
|
904
1453
|
return LXW_ERROR_CREATING_TMPFILE;
|
@@ -914,14 +1463,40 @@ _write_worksheet_rels_file(lxw_packager *self)
|
|
914
1463
|
rel->target_mode);
|
915
1464
|
}
|
916
1465
|
|
1466
|
+
rel = worksheet->external_vml_comment_link;
|
1467
|
+
if (rel)
|
1468
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1469
|
+
rel->target_mode);
|
1470
|
+
|
1471
|
+
rel = worksheet->external_vml_header_link;
|
1472
|
+
if (rel)
|
1473
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1474
|
+
rel->target_mode);
|
1475
|
+
|
1476
|
+
rel = worksheet->external_background_link;
|
1477
|
+
if (rel)
|
1478
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1479
|
+
rel->target_mode);
|
1480
|
+
|
1481
|
+
STAILQ_FOREACH(rel, worksheet->external_table_links, list_pointers) {
|
1482
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1483
|
+
rel->target_mode);
|
1484
|
+
}
|
1485
|
+
|
1486
|
+
rel = worksheet->external_comment_link;
|
1487
|
+
if (rel)
|
1488
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1489
|
+
rel->target_mode);
|
1490
|
+
|
917
1491
|
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
918
1492
|
"xl/worksheets/_rels/sheet%d.xml.rels", index);
|
919
1493
|
|
920
1494
|
lxw_relationships_assemble_xml_file(rels);
|
921
1495
|
|
922
|
-
err =
|
1496
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, sheetname);
|
923
1497
|
|
924
1498
|
fclose(rels->file);
|
1499
|
+
free(buffer);
|
925
1500
|
lxw_free_relationships(rels);
|
926
1501
|
|
927
1502
|
RETURN_ON_ERROR(err);
|
@@ -938,6 +1513,8 @@ STATIC lxw_error
|
|
938
1513
|
_write_chartsheet_rels_file(lxw_packager *self)
|
939
1514
|
{
|
940
1515
|
lxw_relationships *rels;
|
1516
|
+
char *buffer = NULL;
|
1517
|
+
size_t buffer_size = 0;
|
941
1518
|
lxw_rel_tuple *rel;
|
942
1519
|
lxw_workbook *workbook = self->workbook;
|
943
1520
|
lxw_sheet *sheet;
|
@@ -954,13 +1531,12 @@ _write_chartsheet_rels_file(lxw_packager *self)
|
|
954
1531
|
|
955
1532
|
index++;
|
956
1533
|
|
957
|
-
/* TODO. This should never be empty. Put check higher up. */
|
958
1534
|
if (STAILQ_EMPTY(worksheet->external_drawing_links))
|
959
1535
|
continue;
|
960
1536
|
|
961
1537
|
rels = lxw_relationships_new();
|
962
1538
|
|
963
|
-
rels->file =
|
1539
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
964
1540
|
if (!rels->file) {
|
965
1541
|
lxw_free_relationships(rels);
|
966
1542
|
return LXW_ERROR_CREATING_TMPFILE;
|
@@ -981,9 +1557,10 @@ _write_chartsheet_rels_file(lxw_packager *self)
|
|
981
1557
|
|
982
1558
|
lxw_relationships_assemble_xml_file(rels);
|
983
1559
|
|
984
|
-
err =
|
1560
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, sheetname);
|
985
1561
|
|
986
1562
|
fclose(rels->file);
|
1563
|
+
free(buffer);
|
987
1564
|
lxw_free_relationships(rels);
|
988
1565
|
|
989
1566
|
RETURN_ON_ERROR(err);
|
@@ -1000,6 +1577,8 @@ STATIC lxw_error
|
|
1000
1577
|
_write_drawing_rels_file(lxw_packager *self)
|
1001
1578
|
{
|
1002
1579
|
lxw_relationships *rels;
|
1580
|
+
char *buffer = NULL;
|
1581
|
+
size_t buffer_size = 0;
|
1003
1582
|
lxw_rel_tuple *rel;
|
1004
1583
|
lxw_workbook *workbook = self->workbook;
|
1005
1584
|
lxw_sheet *sheet;
|
@@ -1019,7 +1598,7 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
1019
1598
|
|
1020
1599
|
rels = lxw_relationships_new();
|
1021
1600
|
|
1022
|
-
rels->file =
|
1601
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
1023
1602
|
if (!rels->file) {
|
1024
1603
|
lxw_free_relationships(rels);
|
1025
1604
|
return LXW_ERROR_CREATING_TMPFILE;
|
@@ -1036,9 +1615,10 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
1036
1615
|
|
1037
1616
|
lxw_relationships_assemble_xml_file(rels);
|
1038
1617
|
|
1039
|
-
err =
|
1618
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, sheetname);
|
1040
1619
|
|
1041
1620
|
fclose(rels->file);
|
1621
|
+
free(buffer);
|
1042
1622
|
lxw_free_relationships(rels);
|
1043
1623
|
|
1044
1624
|
RETURN_ON_ERROR(err);
|
@@ -1047,6 +1627,93 @@ _write_drawing_rels_file(lxw_packager *self)
|
|
1047
1627
|
return LXW_NO_ERROR;
|
1048
1628
|
}
|
1049
1629
|
|
1630
|
+
/*
|
1631
|
+
* Write the vmlDrawing .rels files for worksheets that contain images in
|
1632
|
+
* headers or footers.
|
1633
|
+
*/
|
1634
|
+
STATIC lxw_error
|
1635
|
+
_write_vml_drawing_rels_file(lxw_packager *self, lxw_worksheet *worksheet,
|
1636
|
+
uint32_t index)
|
1637
|
+
{
|
1638
|
+
lxw_relationships *rels;
|
1639
|
+
char *buffer = NULL;
|
1640
|
+
size_t buffer_size = 0;
|
1641
|
+
lxw_rel_tuple *rel;
|
1642
|
+
char sheetname[LXW_FILENAME_LENGTH] = { 0 };
|
1643
|
+
lxw_error err = LXW_NO_ERROR;
|
1644
|
+
|
1645
|
+
rels = lxw_relationships_new();
|
1646
|
+
|
1647
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
1648
|
+
if (!rels->file) {
|
1649
|
+
lxw_free_relationships(rels);
|
1650
|
+
return LXW_ERROR_CREATING_TMPFILE;
|
1651
|
+
}
|
1652
|
+
|
1653
|
+
STAILQ_FOREACH(rel, worksheet->vml_drawing_links, list_pointers) {
|
1654
|
+
lxw_add_worksheet_relationship(rels, rel->type, rel->target,
|
1655
|
+
rel->target_mode);
|
1656
|
+
|
1657
|
+
}
|
1658
|
+
|
1659
|
+
lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
|
1660
|
+
"xl/drawings/_rels/vmlDrawing%d.vml.rels", index);
|
1661
|
+
|
1662
|
+
lxw_relationships_assemble_xml_file(rels);
|
1663
|
+
|
1664
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, sheetname);
|
1665
|
+
|
1666
|
+
fclose(rels->file);
|
1667
|
+
free(buffer);
|
1668
|
+
lxw_free_relationships(rels);
|
1669
|
+
|
1670
|
+
return err;
|
1671
|
+
}
|
1672
|
+
|
1673
|
+
/*
|
1674
|
+
* Write the vbaProject .rels xml file.
|
1675
|
+
*/
|
1676
|
+
STATIC lxw_error
|
1677
|
+
_write_vba_project_rels_file(lxw_packager *self)
|
1678
|
+
{
|
1679
|
+
lxw_relationships *rels;
|
1680
|
+
lxw_workbook *workbook = self->workbook;
|
1681
|
+
lxw_error err = LXW_NO_ERROR;
|
1682
|
+
char *buffer = NULL;
|
1683
|
+
size_t buffer_size = 0;
|
1684
|
+
|
1685
|
+
if (!workbook->vba_project_signature)
|
1686
|
+
return LXW_NO_ERROR;
|
1687
|
+
|
1688
|
+
rels = lxw_relationships_new();
|
1689
|
+
if (!rels) {
|
1690
|
+
err = LXW_ERROR_MEMORY_MALLOC_FAILED;
|
1691
|
+
goto mem_error;
|
1692
|
+
}
|
1693
|
+
|
1694
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
1695
|
+
if (!rels->file) {
|
1696
|
+
err = LXW_ERROR_CREATING_TMPFILE;
|
1697
|
+
goto mem_error;
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
lxw_add_ms_package_relationship(rels, "/vbaProjectSignature",
|
1701
|
+
"vbaProjectSignature.bin");
|
1702
|
+
|
1703
|
+
lxw_relationships_assemble_xml_file(rels);
|
1704
|
+
|
1705
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size,
|
1706
|
+
"xl/_rels/vbaProject.bin.rels");
|
1707
|
+
|
1708
|
+
fclose(rels->file);
|
1709
|
+
free(buffer);
|
1710
|
+
|
1711
|
+
mem_error:
|
1712
|
+
lxw_free_relationships(rels);
|
1713
|
+
|
1714
|
+
return err;
|
1715
|
+
}
|
1716
|
+
|
1050
1717
|
/*
|
1051
1718
|
* Write the _rels/.rels xml file.
|
1052
1719
|
*/
|
@@ -1054,6 +1721,8 @@ STATIC lxw_error
|
|
1054
1721
|
_write_root_rels_file(lxw_packager *self)
|
1055
1722
|
{
|
1056
1723
|
lxw_relationships *rels = lxw_relationships_new();
|
1724
|
+
char *buffer = NULL;
|
1725
|
+
size_t buffer_size = 0;
|
1057
1726
|
lxw_error err = LXW_NO_ERROR;
|
1058
1727
|
|
1059
1728
|
if (!rels) {
|
@@ -1061,7 +1730,7 @@ _write_root_rels_file(lxw_packager *self)
|
|
1061
1730
|
goto mem_error;
|
1062
1731
|
}
|
1063
1732
|
|
1064
|
-
rels->file =
|
1733
|
+
rels->file = lxw_get_filehandle(&buffer, &buffer_size, self->tmpdir);
|
1065
1734
|
if (!rels->file) {
|
1066
1735
|
err = LXW_ERROR_CREATING_TMPFILE;
|
1067
1736
|
goto mem_error;
|
@@ -1083,9 +1752,10 @@ _write_root_rels_file(lxw_packager *self)
|
|
1083
1752
|
|
1084
1753
|
lxw_relationships_assemble_xml_file(rels);
|
1085
1754
|
|
1086
|
-
err =
|
1755
|
+
err = _add_to_zip(self, rels->file, &buffer, &buffer_size, "_rels/.rels");
|
1087
1756
|
|
1088
1757
|
fclose(rels->file);
|
1758
|
+
free(buffer);
|
1089
1759
|
|
1090
1760
|
mem_error:
|
1091
1761
|
lxw_free_relationships(rels);
|
@@ -1122,12 +1792,12 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
1122
1792
|
fflush(file);
|
1123
1793
|
rewind(file);
|
1124
1794
|
|
1125
|
-
size_read = fread(self->buffer, 1, self->buffer_size, file);
|
1795
|
+
size_read = fread((void *) self->buffer, 1, self->buffer_size, file);
|
1126
1796
|
|
1127
1797
|
while (size_read) {
|
1128
1798
|
|
1129
1799
|
if (size_read < self->buffer_size) {
|
1130
|
-
if (
|
1800
|
+
if (ferror(file)) {
|
1131
1801
|
LXW_ERROR("Error reading member file data");
|
1132
1802
|
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1133
1803
|
}
|
@@ -1141,7 +1811,8 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
1141
1811
|
RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
|
1142
1812
|
}
|
1143
1813
|
|
1144
|
-
size_read =
|
1814
|
+
size_read =
|
1815
|
+
fread((void *) (void *) self->buffer, 1, self->buffer_size, file);
|
1145
1816
|
}
|
1146
1817
|
|
1147
1818
|
error = zipCloseFileInZip(self->zipfile);
|
@@ -1154,8 +1825,8 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename)
|
|
1154
1825
|
}
|
1155
1826
|
|
1156
1827
|
STATIC lxw_error
|
1157
|
-
_add_buffer_to_zip(lxw_packager *self,
|
1158
|
-
|
1828
|
+
_add_buffer_to_zip(lxw_packager *self, const char *buffer, size_t buffer_size,
|
1829
|
+
const char *filename)
|
1159
1830
|
{
|
1160
1831
|
int16_t error = ZIP_OK;
|
1161
1832
|
|
@@ -1190,8 +1861,19 @@ _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
|
|
1190
1861
|
return LXW_NO_ERROR;
|
1191
1862
|
}
|
1192
1863
|
|
1864
|
+
STATIC lxw_error
|
1865
|
+
_add_to_zip(lxw_packager *self, FILE * file, char **buffer,
|
1866
|
+
size_t *buffer_size, const char *filename)
|
1867
|
+
{
|
1868
|
+
/* Flush to ensure buffer is updated when using a memory-backed file. */
|
1869
|
+
fflush(file);
|
1870
|
+
return *buffer ?
|
1871
|
+
_add_buffer_to_zip(self, *buffer, *buffer_size, filename) :
|
1872
|
+
_add_file_to_zip(self, file, filename);
|
1873
|
+
}
|
1874
|
+
|
1193
1875
|
/*
|
1194
|
-
* Write the xml files that make up the
|
1876
|
+
* Write the xml files that make up the XLSX OPC package.
|
1195
1877
|
*/
|
1196
1878
|
lxw_error
|
1197
1879
|
lxw_create_package(lxw_packager *self)
|
@@ -1200,61 +1882,79 @@ lxw_create_package(lxw_packager *self)
|
|
1200
1882
|
int8_t zip_error;
|
1201
1883
|
|
1202
1884
|
error = _write_content_types_file(self);
|
1203
|
-
|
1885
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1204
1886
|
|
1205
1887
|
error = _write_root_rels_file(self);
|
1206
|
-
|
1888
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1207
1889
|
|
1208
1890
|
error = _write_workbook_rels_file(self);
|
1209
|
-
|
1891
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1210
1892
|
|
1211
1893
|
error = _write_worksheet_files(self);
|
1212
|
-
|
1894
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1213
1895
|
|
1214
1896
|
error = _write_chartsheet_files(self);
|
1215
|
-
|
1897
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1216
1898
|
|
1217
1899
|
error = _write_workbook_file(self);
|
1218
|
-
|
1900
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1219
1901
|
|
1220
1902
|
error = _write_chart_files(self);
|
1221
|
-
|
1903
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1222
1904
|
|
1223
1905
|
error = _write_drawing_files(self);
|
1224
|
-
|
1906
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1907
|
+
|
1908
|
+
error = _write_vml_files(self);
|
1909
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1910
|
+
|
1911
|
+
error = _write_comment_files(self);
|
1912
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1913
|
+
|
1914
|
+
error = _write_table_files(self);
|
1915
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1225
1916
|
|
1226
1917
|
error = _write_shared_strings_file(self);
|
1227
|
-
|
1918
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1228
1919
|
|
1229
1920
|
error = _write_custom_file(self);
|
1230
|
-
|
1921
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1231
1922
|
|
1232
1923
|
error = _write_theme_file(self);
|
1233
|
-
|
1924
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1234
1925
|
|
1235
1926
|
error = _write_styles_file(self);
|
1236
|
-
|
1927
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1237
1928
|
|
1238
1929
|
error = _write_worksheet_rels_file(self);
|
1239
|
-
|
1930
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1240
1931
|
|
1241
1932
|
error = _write_chartsheet_rels_file(self);
|
1242
|
-
|
1933
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1243
1934
|
|
1244
1935
|
error = _write_drawing_rels_file(self);
|
1245
|
-
|
1936
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1246
1937
|
|
1247
1938
|
error = _write_image_files(self);
|
1248
|
-
|
1939
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1249
1940
|
|
1250
1941
|
error = _add_vba_project(self);
|
1251
|
-
|
1942
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1943
|
+
|
1944
|
+
error = _add_vba_project_signature(self);
|
1945
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1946
|
+
|
1947
|
+
error = _write_vba_project_rels_file(self);
|
1948
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1252
1949
|
|
1253
1950
|
error = _write_core_file(self);
|
1254
|
-
|
1951
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1952
|
+
|
1953
|
+
error = _write_metadata_file(self);
|
1954
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1255
1955
|
|
1256
1956
|
error = _write_app_file(self);
|
1257
|
-
|
1957
|
+
RETURN_AND_ZIPCLOSE_ON_ERROR(error);
|
1258
1958
|
|
1259
1959
|
zip_error = zipClose(self->zipfile, NULL);
|
1260
1960
|
if (zip_error) {
|