xlsxwriter 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +55 -5
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chartsheet.h +544 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +6 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +1 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +3 -1
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +7 -2
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +16 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +122 -24
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +236 -48
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +2 -0
- data/ext/xlsxwriter/libxlsxwriter/src/chart.c +40 -4
- data/ext/xlsxwriter/libxlsxwriter/src/chartsheet.c +508 -0
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +100 -3
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +252 -30
- data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +16 -2
- data/ext/xlsxwriter/libxlsxwriter/src/styles.c +54 -7
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +43 -1
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +254 -41
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +381 -65
- data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +16 -7
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +10 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +2 -2
- data/ext/xlsxwriter/workbook.c +9 -6
- data/lib/xlsxwriter/version.rb +1 -1
- metadata +5 -4
| @@ -296,6 +296,16 @@ lxw_ct_add_worksheet_name(lxw_content_types *self, const char *name) | |
| 296 296 | 
             
                                    LXW_APP_DOCUMENT "spreadsheetml.worksheet+xml");
         | 
| 297 297 | 
             
            }
         | 
| 298 298 |  | 
| 299 | 
            +
            /*
         | 
| 300 | 
            +
             * Add the name of a chartsheet to the ContentTypes overrides.
         | 
| 301 | 
            +
             */
         | 
| 302 | 
            +
            void
         | 
| 303 | 
            +
            lxw_ct_add_chartsheet_name(lxw_content_types *self, const char *name)
         | 
| 304 | 
            +
            {
         | 
| 305 | 
            +
                lxw_ct_add_override(self, name,
         | 
| 306 | 
            +
                                    LXW_APP_DOCUMENT "spreadsheetml.chartsheet+xml");
         | 
| 307 | 
            +
            }
         | 
| 308 | 
            +
             | 
| 299 309 | 
             
            /*
         | 
| 300 310 | 
             
             * Add the name of a chart to the ContentTypes overrides.
         | 
| 301 311 | 
             
             */
         | 
| @@ -239,7 +239,7 @@ _drawing_write_c_nv_pr(lxw_drawing *self, char *object_name, uint16_t index, | |
| 239 239 | 
             
                LXW_PUSH_ATTRIBUTES_INT("id", index + 1);
         | 
| 240 240 | 
             
                LXW_PUSH_ATTRIBUTES_STR("name", name);
         | 
| 241 241 |  | 
| 242 | 
            -
                if (drawing_object)
         | 
| 242 | 
            +
                if (drawing_object && drawing_object->description)
         | 
| 243 243 | 
             
                    LXW_PUSH_ATTRIBUTES_STR("descr", drawing_object->description);
         | 
| 244 244 |  | 
| 245 245 | 
             
                lxw_xml_empty_tag(self->file, "xdr:cNvPr", &attributes);
         | 
| @@ -489,13 +489,40 @@ _drawing_write_client_data(lxw_drawing *self) | |
| 489 489 | 
             
                lxw_xml_empty_tag(self->file, "xdr:clientData", NULL);
         | 
| 490 490 | 
             
            }
         | 
| 491 491 |  | 
| 492 | 
            +
            /*
         | 
| 493 | 
            +
             * Write the <a:graphicFrameLocks> element.
         | 
| 494 | 
            +
             */
         | 
| 495 | 
            +
            STATIC void
         | 
| 496 | 
            +
            _drawing_write_a_graphic_frame_locks(lxw_drawing *self)
         | 
| 497 | 
            +
            {
         | 
| 498 | 
            +
                struct xml_attribute_list attributes;
         | 
| 499 | 
            +
                struct xml_attribute *attribute;
         | 
| 500 | 
            +
             | 
| 501 | 
            +
                LXW_INIT_ATTRIBUTES();
         | 
| 502 | 
            +
                LXW_PUSH_ATTRIBUTES_INT("noGrp", 1);
         | 
| 503 | 
            +
             | 
| 504 | 
            +
                lxw_xml_empty_tag(self->file, "a:graphicFrameLocks", &attributes);
         | 
| 505 | 
            +
             | 
| 506 | 
            +
                LXW_FREE_ATTRIBUTES();
         | 
| 507 | 
            +
            }
         | 
| 508 | 
            +
             | 
| 492 509 | 
             
            /*
         | 
| 493 510 | 
             
             * Write the <xdr:cNvGraphicFramePr> element.
         | 
| 494 511 | 
             
             */
         | 
| 495 512 | 
             
            STATIC void
         | 
| 496 513 | 
             
            _drawing_write_c_nv_graphic_frame_pr(lxw_drawing *self)
         | 
| 497 514 | 
             
            {
         | 
| 498 | 
            -
                 | 
| 515 | 
            +
                if (self->embedded) {
         | 
| 516 | 
            +
                    lxw_xml_empty_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
         | 
| 517 | 
            +
                }
         | 
| 518 | 
            +
                else {
         | 
| 519 | 
            +
                    lxw_xml_start_tag(self->file, "xdr:cNvGraphicFramePr", NULL);
         | 
| 520 | 
            +
             | 
| 521 | 
            +
                    /* Write the a:graphicFrameLocks element. */
         | 
| 522 | 
            +
                    _drawing_write_a_graphic_frame_locks(self);
         | 
| 523 | 
            +
             | 
| 524 | 
            +
                    lxw_xml_end_tag(self->file, "xdr:cNvGraphicFramePr");
         | 
| 525 | 
            +
                }
         | 
| 499 526 | 
             
            }
         | 
| 500 527 |  | 
| 501 528 | 
             
            /*
         | 
| @@ -705,6 +732,73 @@ _drawing_write_two_cell_anchor(lxw_drawing *self, uint16_t index, | |
| 705 732 | 
             
                LXW_FREE_ATTRIBUTES();
         | 
| 706 733 | 
             
            }
         | 
| 707 734 |  | 
| 735 | 
            +
            /*
         | 
| 736 | 
            +
             * Write the <xdr:ext> element.
         | 
| 737 | 
            +
             */
         | 
| 738 | 
            +
            STATIC void
         | 
| 739 | 
            +
            _drawing_write_ext(lxw_drawing *self, uint32_t cx, uint32_t cy)
         | 
| 740 | 
            +
            {
         | 
| 741 | 
            +
                struct xml_attribute_list attributes;
         | 
| 742 | 
            +
                struct xml_attribute *attribute;
         | 
| 743 | 
            +
             | 
| 744 | 
            +
                LXW_INIT_ATTRIBUTES();
         | 
| 745 | 
            +
                LXW_PUSH_ATTRIBUTES_INT("cx", cx);
         | 
| 746 | 
            +
                LXW_PUSH_ATTRIBUTES_INT("cy", cy);
         | 
| 747 | 
            +
             | 
| 748 | 
            +
                lxw_xml_empty_tag(self->file, "xdr:ext", &attributes);
         | 
| 749 | 
            +
             | 
| 750 | 
            +
                LXW_FREE_ATTRIBUTES();
         | 
| 751 | 
            +
            }
         | 
| 752 | 
            +
             | 
| 753 | 
            +
            /*
         | 
| 754 | 
            +
             * Write the <xdr:pos> element.
         | 
| 755 | 
            +
             */
         | 
| 756 | 
            +
            STATIC void
         | 
| 757 | 
            +
            _drawing_write_pos(lxw_drawing *self, int32_t x, int32_t y)
         | 
| 758 | 
            +
            {
         | 
| 759 | 
            +
                struct xml_attribute_list attributes;
         | 
| 760 | 
            +
                struct xml_attribute *attribute;
         | 
| 761 | 
            +
             | 
| 762 | 
            +
                LXW_INIT_ATTRIBUTES();
         | 
| 763 | 
            +
                LXW_PUSH_ATTRIBUTES_INT("x", x);
         | 
| 764 | 
            +
                LXW_PUSH_ATTRIBUTES_INT("y", y);
         | 
| 765 | 
            +
             | 
| 766 | 
            +
                lxw_xml_empty_tag(self->file, "xdr:pos", &attributes);
         | 
| 767 | 
            +
             | 
| 768 | 
            +
                LXW_FREE_ATTRIBUTES();
         | 
| 769 | 
            +
            }
         | 
| 770 | 
            +
             | 
| 771 | 
            +
            /*
         | 
| 772 | 
            +
             * Write the <xdr:absoluteAnchor> element.
         | 
| 773 | 
            +
             */
         | 
| 774 | 
            +
            STATIC void
         | 
| 775 | 
            +
            _drawing_write_absolute_anchor(lxw_drawing *self)
         | 
| 776 | 
            +
            {
         | 
| 777 | 
            +
                lxw_xml_start_tag(self->file, "xdr:absoluteAnchor", NULL);
         | 
| 778 | 
            +
             | 
| 779 | 
            +
                if (self->orientation == LXW_LANDSCAPE) {
         | 
| 780 | 
            +
                    /* Write the xdr:pos element. */
         | 
| 781 | 
            +
                    _drawing_write_pos(self, 0, 0);
         | 
| 782 | 
            +
             | 
| 783 | 
            +
                    /* Write the xdr:ext element. */
         | 
| 784 | 
            +
                    _drawing_write_ext(self, 9308969, 6078325);
         | 
| 785 | 
            +
                }
         | 
| 786 | 
            +
                else {
         | 
| 787 | 
            +
                    /* Write the xdr:pos element. */
         | 
| 788 | 
            +
                    _drawing_write_pos(self, 0, -47625);
         | 
| 789 | 
            +
             | 
| 790 | 
            +
                    /* Write the xdr:ext element. */
         | 
| 791 | 
            +
                    _drawing_write_ext(self, 6162675, 6124575);
         | 
| 792 | 
            +
                }
         | 
| 793 | 
            +
             | 
| 794 | 
            +
                _drawing_write_graphic_frame(self, 1);
         | 
| 795 | 
            +
             | 
| 796 | 
            +
                /* Write the xdr:clientData element. */
         | 
| 797 | 
            +
                _drawing_write_client_data(self);
         | 
| 798 | 
            +
             | 
| 799 | 
            +
                lxw_xml_end_tag(self->file, "xdr:absoluteAnchor");
         | 
| 800 | 
            +
            }
         | 
| 801 | 
            +
             | 
| 708 802 | 
             
            /*****************************************************************************
         | 
| 709 803 | 
             
             *
         | 
| 710 804 | 
             
             * XML file assembly functions.
         | 
| @@ -733,7 +827,10 @@ lxw_drawing_assemble_xml_file(lxw_drawing *self) | |
| 733 827 | 
             
                        _drawing_write_two_cell_anchor(self, index, drawing_object);
         | 
| 734 828 | 
             
                        index++;
         | 
| 735 829 | 
             
                    }
         | 
| 736 | 
            -
             | 
| 830 | 
            +
                }
         | 
| 831 | 
            +
                else {
         | 
| 832 | 
            +
                    /* Write the xdr:absoluteAnchor element. Mainly for chartsheets. */
         | 
| 833 | 
            +
                    _drawing_write_absolute_anchor(self);
         | 
| 737 834 | 
             
                }
         | 
| 738 835 |  | 
| 739 836 | 
             
                lxw_xml_end_tag(self->file, "xdr:wsDr");
         | 
| @@ -15,6 +15,9 @@ | |
| 15 15 | 
             
            STATIC lxw_error _add_file_to_zip(lxw_packager *self, FILE * file,
         | 
| 16 16 | 
             
                                              const char *filename);
         | 
| 17 17 |  | 
| 18 | 
            +
            STATIC lxw_error _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
         | 
| 19 | 
            +
                                                size_t buffer_size, const char *filename);
         | 
| 20 | 
            +
             | 
| 18 21 | 
             
            /*
         | 
| 19 22 | 
             
             * Forward declarations.
         | 
| 20 23 | 
             
             */
         | 
| @@ -164,12 +167,18 @@ STATIC lxw_error | |
| 164 167 | 
             
            _write_worksheet_files(lxw_packager *self)
         | 
| 165 168 | 
             
            {
         | 
| 166 169 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 170 | 
            +
                lxw_sheet *sheet;
         | 
| 167 171 | 
             
                lxw_worksheet *worksheet;
         | 
| 168 172 | 
             
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 169 173 | 
             
                uint16_t index = 1;
         | 
| 170 174 | 
             
                lxw_error err;
         | 
| 171 175 |  | 
| 172 | 
            -
                STAILQ_FOREACH( | 
| 176 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 177 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 178 | 
            +
                        continue;
         | 
| 179 | 
            +
                    else
         | 
| 180 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 181 | 
            +
             | 
| 173 182 | 
             
                    lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
         | 
| 174 183 | 
             
                                 "xl/worksheets/sheet%d.xml", index++);
         | 
| 175 184 |  | 
| @@ -191,6 +200,43 @@ _write_worksheet_files(lxw_packager *self) | |
| 191 200 | 
             
                return LXW_NO_ERROR;
         | 
| 192 201 | 
             
            }
         | 
| 193 202 |  | 
| 203 | 
            +
            /*
         | 
| 204 | 
            +
             * Write the chartsheet files.
         | 
| 205 | 
            +
             */
         | 
| 206 | 
            +
            STATIC lxw_error
         | 
| 207 | 
            +
            _write_chartsheet_files(lxw_packager *self)
         | 
| 208 | 
            +
            {
         | 
| 209 | 
            +
                lxw_workbook *workbook = self->workbook;
         | 
| 210 | 
            +
                lxw_sheet *sheet;
         | 
| 211 | 
            +
                lxw_chartsheet *chartsheet;
         | 
| 212 | 
            +
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 213 | 
            +
                uint16_t index = 1;
         | 
| 214 | 
            +
                lxw_error err;
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 217 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 218 | 
            +
                        chartsheet = sheet->u.chartsheet;
         | 
| 219 | 
            +
                    else
         | 
| 220 | 
            +
                        continue;
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                    lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
         | 
| 223 | 
            +
                                 "xl/chartsheets/sheet%d.xml", index++);
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                    chartsheet->file = lxw_tmpfile(self->tmpdir);
         | 
| 226 | 
            +
                    if (!chartsheet->file)
         | 
| 227 | 
            +
                        return LXW_ERROR_CREATING_TMPFILE;
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                    lxw_chartsheet_assemble_xml_file(chartsheet);
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                    err = _add_file_to_zip(self, chartsheet->file, sheetname);
         | 
| 232 | 
            +
                    RETURN_ON_ERROR(err);
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                    fclose(chartsheet->file);
         | 
| 235 | 
            +
                }
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                return LXW_NO_ERROR;
         | 
| 238 | 
            +
            }
         | 
| 239 | 
            +
             | 
| 194 240 | 
             
            /*
         | 
| 195 241 | 
             
             * Write the /xl/media/image?.xml files.
         | 
| 196 242 | 
             
             */
         | 
| @@ -198,6 +244,7 @@ STATIC lxw_error | |
| 198 244 | 
             
            _write_image_files(lxw_packager *self)
         | 
| 199 245 | 
             
            {
         | 
| 200 246 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 247 | 
            +
                lxw_sheet *sheet;
         | 
| 201 248 | 
             
                lxw_worksheet *worksheet;
         | 
| 202 249 | 
             
                lxw_image_options *image;
         | 
| 203 250 | 
             
                lxw_error err;
         | 
| @@ -206,7 +253,11 @@ _write_image_files(lxw_packager *self) | |
| 206 253 | 
             
                char filename[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 207 254 | 
             
                uint16_t index = 1;
         | 
| 208 255 |  | 
| 209 | 
            -
                STAILQ_FOREACH( | 
| 256 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 257 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 258 | 
            +
                        continue;
         | 
| 259 | 
            +
                    else
         | 
| 260 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 210 261 |  | 
| 211 262 | 
             
                    if (STAILQ_EMPTY(worksheet->image_data))
         | 
| 212 263 | 
             
                        continue;
         | 
| @@ -216,17 +267,24 @@ _write_image_files(lxw_packager *self) | |
| 216 267 | 
             
                        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
         | 
| 217 268 | 
             
                                     "xl/media/image%d.%s", index++, image->extension);
         | 
| 218 269 |  | 
| 219 | 
            -
                         | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
                             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 270 | 
            +
                        if (!image->is_image_buffer) {
         | 
| 271 | 
            +
                            /* Check that the image file exists and can be opened. */
         | 
| 272 | 
            +
                            image_stream = fopen(image->filename, "rb");
         | 
| 273 | 
            +
                            if (!image_stream) {
         | 
| 274 | 
            +
                                LXW_WARN_FORMAT1("Error adding image to xlsx file: file "
         | 
| 275 | 
            +
                                                 "doesn't exist or can't be opened: %s.",
         | 
| 276 | 
            +
                                                 image->filename);
         | 
| 277 | 
            +
                                return LXW_ERROR_CREATING_TMPFILE;
         | 
| 278 | 
            +
                            }
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                            err = _add_file_to_zip(self, image_stream, filename);
         | 
| 281 | 
            +
                            fclose(image_stream);
         | 
| 282 | 
            +
                        }
         | 
| 283 | 
            +
                        else {
         | 
| 284 | 
            +
                            err = _add_buffer_to_zip(self,
         | 
| 285 | 
            +
                                                     image->image_buffer,
         | 
| 286 | 
            +
                                                     image->image_buffer_size, filename);
         | 
| 226 287 | 
             
                        }
         | 
| 227 | 
            -
             | 
| 228 | 
            -
                        err = _add_file_to_zip(self, image_stream, filename);
         | 
| 229 | 
            -
                        fclose(image_stream);
         | 
| 230 288 |  | 
| 231 289 | 
             
                        RETURN_ON_ERROR(err);
         | 
| 232 290 | 
             
                    }
         | 
| @@ -276,13 +334,19 @@ STATIC lxw_error | |
| 276 334 | 
             
            _write_drawing_files(lxw_packager *self)
         | 
| 277 335 | 
             
            {
         | 
| 278 336 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 337 | 
            +
                lxw_sheet *sheet;
         | 
| 279 338 | 
             
                lxw_worksheet *worksheet;
         | 
| 280 339 | 
             
                lxw_drawing *drawing;
         | 
| 281 340 | 
             
                char filename[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 282 341 | 
             
                uint16_t index = 1;
         | 
| 283 342 | 
             
                lxw_error err;
         | 
| 284 343 |  | 
| 285 | 
            -
                STAILQ_FOREACH( | 
| 344 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 345 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 346 | 
            +
                        worksheet = sheet->u.chartsheet->worksheet;
         | 
| 347 | 
            +
                    else
         | 
| 348 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 349 | 
            +
             | 
| 286 350 | 
             
                    drawing = worksheet->drawing;
         | 
| 287 351 |  | 
| 288 352 | 
             
                    if (drawing) {
         | 
| @@ -340,7 +404,9 @@ STATIC lxw_error | |
| 340 404 | 
             
            _write_app_file(lxw_packager *self)
         | 
| 341 405 | 
             
            {
         | 
| 342 406 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 407 | 
            +
                lxw_sheet *sheet;
         | 
| 343 408 | 
             
                lxw_worksheet *worksheet;
         | 
| 409 | 
            +
                lxw_chartsheet *chartsheet;
         | 
| 344 410 | 
             
                lxw_defined_name *defined_name;
         | 
| 345 411 | 
             
                lxw_app *app;
         | 
| 346 412 | 
             
                uint16_t named_range_count = 0;
         | 
| @@ -361,12 +427,30 @@ _write_app_file(lxw_packager *self) | |
| 361 427 | 
             
                    goto mem_error;
         | 
| 362 428 | 
             
                }
         | 
| 363 429 |  | 
| 364 | 
            -
                 | 
| 430 | 
            +
                if (self->workbook->num_worksheets) {
         | 
| 431 | 
            +
                    lxw_snprintf(number, LXW_ATTR_32, "%d",
         | 
| 432 | 
            +
                                 self->workbook->num_worksheets);
         | 
| 433 | 
            +
                    lxw_app_add_heading_pair(app, "Worksheets", number);
         | 
| 434 | 
            +
                }
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                if (self->workbook->num_chartsheets) {
         | 
| 437 | 
            +
                    lxw_snprintf(number, LXW_ATTR_32, "%d",
         | 
| 438 | 
            +
                                 self->workbook->num_chartsheets);
         | 
| 439 | 
            +
                    lxw_app_add_heading_pair(app, "Charts", number);
         | 
| 440 | 
            +
                }
         | 
| 365 441 |  | 
| 366 | 
            -
                 | 
| 442 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 443 | 
            +
                    if (!sheet->is_chartsheet) {
         | 
| 444 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 445 | 
            +
                        lxw_app_add_part_name(app, worksheet->name);
         | 
| 446 | 
            +
                    }
         | 
| 447 | 
            +
                }
         | 
| 367 448 |  | 
| 368 | 
            -
                STAILQ_FOREACH( | 
| 369 | 
            -
                     | 
| 449 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 450 | 
            +
                    if (sheet->is_chartsheet) {
         | 
| 451 | 
            +
                        chartsheet = sheet->u.chartsheet;
         | 
| 452 | 
            +
                        lxw_app_add_part_name(app, chartsheet->name);
         | 
| 453 | 
            +
                    }
         | 
| 370 454 | 
             
                }
         | 
| 371 455 |  | 
| 372 456 | 
             
                /* Add the Named Ranges parts. */
         | 
| @@ -568,9 +652,11 @@ _write_content_types_file(lxw_packager *self) | |
| 568 652 | 
             
            {
         | 
| 569 653 | 
             
                lxw_content_types *content_types = lxw_content_types_new();
         | 
| 570 654 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 571 | 
            -
                 | 
| 655 | 
            +
                lxw_sheet *sheet;
         | 
| 572 656 | 
             
                char filename[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
         | 
| 573 657 | 
             
                uint16_t index = 1;
         | 
| 658 | 
            +
                uint16_t worksheet_index = 1;
         | 
| 659 | 
            +
                uint16_t chartsheet_index = 1;
         | 
| 574 660 | 
             
                lxw_error err = LXW_NO_ERROR;
         | 
| 575 661 |  | 
| 576 662 | 
             
                if (!content_types) {
         | 
| @@ -593,10 +679,17 @@ _write_content_types_file(lxw_packager *self) | |
| 593 679 | 
             
                if (workbook->has_bmp)
         | 
| 594 680 | 
             
                    lxw_ct_add_default(content_types, "bmp", "image/bmp");
         | 
| 595 681 |  | 
| 596 | 
            -
                STAILQ_FOREACH( | 
| 597 | 
            -
                     | 
| 598 | 
            -
             | 
| 599 | 
            -
             | 
| 682 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 683 | 
            +
                    if (sheet->is_chartsheet) {
         | 
| 684 | 
            +
                        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
         | 
| 685 | 
            +
                                     "/xl/chartsheets/sheet%d.xml", chartsheet_index++);
         | 
| 686 | 
            +
                        lxw_ct_add_chartsheet_name(content_types, filename);
         | 
| 687 | 
            +
                    }
         | 
| 688 | 
            +
                    else {
         | 
| 689 | 
            +
                        lxw_snprintf(filename, LXW_FILENAME_LENGTH,
         | 
| 690 | 
            +
                                     "/xl/worksheets/sheet%d.xml", worksheet_index++);
         | 
| 691 | 
            +
                        lxw_ct_add_worksheet_name(content_types, filename);
         | 
| 692 | 
            +
                    }
         | 
| 600 693 | 
             
                }
         | 
| 601 694 |  | 
| 602 695 | 
             
                for (index = 1; index <= self->chart_count; index++) {
         | 
| @@ -637,9 +730,10 @@ _write_workbook_rels_file(lxw_packager *self) | |
| 637 730 | 
             
            {
         | 
| 638 731 | 
             
                lxw_relationships *rels = lxw_relationships_new();
         | 
| 639 732 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 640 | 
            -
                 | 
| 733 | 
            +
                lxw_sheet *sheet;
         | 
| 641 734 | 
             
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 642 | 
            -
                uint16_t  | 
| 735 | 
            +
                uint16_t worksheet_index = 1;
         | 
| 736 | 
            +
                uint16_t chartsheet_index = 1;
         | 
| 643 737 | 
             
                lxw_error err = LXW_NO_ERROR;
         | 
| 644 738 |  | 
| 645 739 | 
             
                if (!rels) {
         | 
| @@ -653,10 +747,19 @@ _write_workbook_rels_file(lxw_packager *self) | |
| 653 747 | 
             
                    goto mem_error;
         | 
| 654 748 | 
             
                }
         | 
| 655 749 |  | 
| 656 | 
            -
                STAILQ_FOREACH( | 
| 657 | 
            -
                     | 
| 658 | 
            -
             | 
| 659 | 
            -
             | 
| 750 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 751 | 
            +
                    if (sheet->is_chartsheet) {
         | 
| 752 | 
            +
                        lxw_snprintf(sheetname,
         | 
| 753 | 
            +
                                     LXW_FILENAME_LENGTH,
         | 
| 754 | 
            +
                                     "chartsheets/sheet%d.xml", chartsheet_index++);
         | 
| 755 | 
            +
                        lxw_add_document_relationship(rels, "/chartsheet", sheetname);
         | 
| 756 | 
            +
                    }
         | 
| 757 | 
            +
                    else {
         | 
| 758 | 
            +
                        lxw_snprintf(sheetname,
         | 
| 759 | 
            +
                                     LXW_FILENAME_LENGTH,
         | 
| 760 | 
            +
                                     "worksheets/sheet%d.xml", worksheet_index++);
         | 
| 761 | 
            +
                        lxw_add_document_relationship(rels, "/worksheet", sheetname);
         | 
| 762 | 
            +
                    }
         | 
| 660 763 | 
             
                }
         | 
| 661 764 |  | 
| 662 765 | 
             
                lxw_add_document_relationship(rels, "/theme", "theme/theme1.xml");
         | 
| @@ -688,12 +791,17 @@ _write_worksheet_rels_file(lxw_packager *self) | |
| 688 791 | 
             
                lxw_relationships *rels;
         | 
| 689 792 | 
             
                lxw_rel_tuple *rel;
         | 
| 690 793 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 794 | 
            +
                lxw_sheet *sheet;
         | 
| 691 795 | 
             
                lxw_worksheet *worksheet;
         | 
| 692 796 | 
             
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 693 797 | 
             
                uint16_t index = 0;
         | 
| 694 798 | 
             
                lxw_error err;
         | 
| 695 799 |  | 
| 696 | 
            -
                STAILQ_FOREACH( | 
| 800 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 801 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 802 | 
            +
                        continue;
         | 
| 803 | 
            +
                    else
         | 
| 804 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 697 805 |  | 
| 698 806 | 
             
                    index++;
         | 
| 699 807 |  | 
| @@ -735,6 +843,68 @@ _write_worksheet_rels_file(lxw_packager *self) | |
| 735 843 | 
             
                return LXW_NO_ERROR;
         | 
| 736 844 | 
             
            }
         | 
| 737 845 |  | 
| 846 | 
            +
            /*
         | 
| 847 | 
            +
             * Write the chartsheet .rels files for chartsheets that contain links to
         | 
| 848 | 
            +
             * external data such as drawings.
         | 
| 849 | 
            +
             */
         | 
| 850 | 
            +
            STATIC lxw_error
         | 
| 851 | 
            +
            _write_chartsheet_rels_file(lxw_packager *self)
         | 
| 852 | 
            +
            {
         | 
| 853 | 
            +
                lxw_relationships *rels;
         | 
| 854 | 
            +
                lxw_rel_tuple *rel;
         | 
| 855 | 
            +
                lxw_workbook *workbook = self->workbook;
         | 
| 856 | 
            +
                lxw_sheet *sheet;
         | 
| 857 | 
            +
                lxw_worksheet *worksheet;
         | 
| 858 | 
            +
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 859 | 
            +
                uint16_t index = 0;
         | 
| 860 | 
            +
                lxw_error err;
         | 
| 861 | 
            +
             | 
| 862 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 863 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 864 | 
            +
                        worksheet = sheet->u.chartsheet->worksheet;
         | 
| 865 | 
            +
                    else
         | 
| 866 | 
            +
                        continue;
         | 
| 867 | 
            +
             | 
| 868 | 
            +
                    index++;
         | 
| 869 | 
            +
             | 
| 870 | 
            +
                    /* TODO. This should never be empty. Put check higher up. */
         | 
| 871 | 
            +
                    if (STAILQ_EMPTY(worksheet->external_drawing_links))
         | 
| 872 | 
            +
                        continue;
         | 
| 873 | 
            +
             | 
| 874 | 
            +
                    rels = lxw_relationships_new();
         | 
| 875 | 
            +
             | 
| 876 | 
            +
                    rels->file = lxw_tmpfile(self->tmpdir);
         | 
| 877 | 
            +
                    if (!rels->file) {
         | 
| 878 | 
            +
                        lxw_free_relationships(rels);
         | 
| 879 | 
            +
                        return LXW_ERROR_CREATING_TMPFILE;
         | 
| 880 | 
            +
                    }
         | 
| 881 | 
            +
             | 
| 882 | 
            +
                    STAILQ_FOREACH(rel, worksheet->external_hyperlinks, list_pointers) {
         | 
| 883 | 
            +
                        lxw_add_worksheet_relationship(rels, rel->type, rel->target,
         | 
| 884 | 
            +
                                                       rel->target_mode);
         | 
| 885 | 
            +
                    }
         | 
| 886 | 
            +
             | 
| 887 | 
            +
                    STAILQ_FOREACH(rel, worksheet->external_drawing_links, list_pointers) {
         | 
| 888 | 
            +
                        lxw_add_worksheet_relationship(rels, rel->type, rel->target,
         | 
| 889 | 
            +
                                                       rel->target_mode);
         | 
| 890 | 
            +
                    }
         | 
| 891 | 
            +
             | 
| 892 | 
            +
                    lxw_snprintf(sheetname, LXW_FILENAME_LENGTH,
         | 
| 893 | 
            +
                                 "xl/chartsheets/_rels/sheet%d.xml.rels", index);
         | 
| 894 | 
            +
             | 
| 895 | 
            +
                    lxw_relationships_assemble_xml_file(rels);
         | 
| 896 | 
            +
             | 
| 897 | 
            +
                    err = _add_file_to_zip(self, rels->file, sheetname);
         | 
| 898 | 
            +
             | 
| 899 | 
            +
                    fclose(rels->file);
         | 
| 900 | 
            +
                    lxw_free_relationships(rels);
         | 
| 901 | 
            +
             | 
| 902 | 
            +
                    RETURN_ON_ERROR(err);
         | 
| 903 | 
            +
                }
         | 
| 904 | 
            +
             | 
| 905 | 
            +
                return LXW_NO_ERROR;
         | 
| 906 | 
            +
            }
         | 
| 907 | 
            +
             | 
| 738 908 | 
             
            /*
         | 
| 739 909 | 
             
             * Write the drawing .rels files for worksheets that contain charts or
         | 
| 740 910 | 
             
             * drawings.
         | 
| @@ -745,12 +915,17 @@ _write_drawing_rels_file(lxw_packager *self) | |
| 745 915 | 
             
                lxw_relationships *rels;
         | 
| 746 916 | 
             
                lxw_rel_tuple *rel;
         | 
| 747 917 | 
             
                lxw_workbook *workbook = self->workbook;
         | 
| 918 | 
            +
                lxw_sheet *sheet;
         | 
| 748 919 | 
             
                lxw_worksheet *worksheet;
         | 
| 749 920 | 
             
                char sheetname[LXW_FILENAME_LENGTH] = { 0 };
         | 
| 750 921 | 
             
                uint16_t index = 1;
         | 
| 751 922 | 
             
                lxw_error err;
         | 
| 752 923 |  | 
| 753 | 
            -
                STAILQ_FOREACH( | 
| 924 | 
            +
                STAILQ_FOREACH(sheet, workbook->sheets, list_pointers) {
         | 
| 925 | 
            +
                    if (sheet->is_chartsheet)
         | 
| 926 | 
            +
                        worksheet = sheet->u.chartsheet->worksheet;
         | 
| 927 | 
            +
                    else
         | 
| 928 | 
            +
                        worksheet = sheet->u.worksheet;
         | 
| 754 929 |  | 
| 755 930 | 
             
                    if (STAILQ_EMPTY(worksheet->drawing_links))
         | 
| 756 931 | 
             
                        continue;
         | 
| @@ -895,6 +1070,47 @@ _add_file_to_zip(lxw_packager *self, FILE * file, const char *filename) | |
| 895 1070 | 
             
                return LXW_NO_ERROR;
         | 
| 896 1071 | 
             
            }
         | 
| 897 1072 |  | 
| 1073 | 
            +
            STATIC lxw_error
         | 
| 1074 | 
            +
            _add_buffer_to_zip(lxw_packager *self, unsigned char *buffer,
         | 
| 1075 | 
            +
                               size_t buffer_size, const char *filename)
         | 
| 1076 | 
            +
            {
         | 
| 1077 | 
            +
                int16_t error = ZIP_OK;
         | 
| 1078 | 
            +
             | 
| 1079 | 
            +
                error = zipOpenNewFileInZip4_64(self->zipfile,
         | 
| 1080 | 
            +
                                                filename,
         | 
| 1081 | 
            +
                                                &self->zipfile_info,
         | 
| 1082 | 
            +
                                                NULL, 0, NULL, 0, NULL,
         | 
| 1083 | 
            +
                                                Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
         | 
| 1084 | 
            +
                                                -MAX_WBITS, DEF_MEM_LEVEL,
         | 
| 1085 | 
            +
                                                Z_DEFAULT_STRATEGY, NULL, 0, 0, 0, 0);
         | 
| 1086 | 
            +
             | 
| 1087 | 
            +
                if (error != ZIP_OK) {
         | 
| 1088 | 
            +
                    LXW_ERROR("Error adding member to zipfile");
         | 
| 1089 | 
            +
                    RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
         | 
| 1090 | 
            +
                }
         | 
| 1091 | 
            +
             | 
| 1092 | 
            +
                error = zipWriteInFileInZip(self->zipfile,
         | 
| 1093 | 
            +
                                            buffer, (unsigned int) buffer_size);
         | 
| 1094 | 
            +
             | 
| 1095 | 
            +
                if (error < 0) {
         | 
| 1096 | 
            +
                    LXW_ERROR("Error in writing member in the zipfile");
         | 
| 1097 | 
            +
                    RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
         | 
| 1098 | 
            +
                }
         | 
| 1099 | 
            +
             | 
| 1100 | 
            +
                if (error < 0) {
         | 
| 1101 | 
            +
                    RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
         | 
| 1102 | 
            +
                }
         | 
| 1103 | 
            +
                else {
         | 
| 1104 | 
            +
                    error = zipCloseFileInZip(self->zipfile);
         | 
| 1105 | 
            +
                    if (error != ZIP_OK) {
         | 
| 1106 | 
            +
                        LXW_ERROR("Error in closing member in the zipfile");
         | 
| 1107 | 
            +
                        RETURN_ON_ZIP_ERROR(error, LXW_ERROR_ZIP_FILE_ADD);
         | 
| 1108 | 
            +
                    }
         | 
| 1109 | 
            +
                }
         | 
| 1110 | 
            +
             | 
| 1111 | 
            +
                return LXW_NO_ERROR;
         | 
| 1112 | 
            +
            }
         | 
| 1113 | 
            +
             | 
| 898 1114 | 
             
            /*
         | 
| 899 1115 | 
             
             * Write the xml files that make up the XLXS OPC package.
         | 
| 900 1116 | 
             
             */
         | 
| @@ -907,6 +1123,9 @@ lxw_create_package(lxw_packager *self) | |
| 907 1123 | 
             
                error = _write_worksheet_files(self);
         | 
| 908 1124 | 
             
                RETURN_ON_ERROR(error);
         | 
| 909 1125 |  | 
| 1126 | 
            +
                error = _write_chartsheet_files(self);
         | 
| 1127 | 
            +
                RETURN_ON_ERROR(error);
         | 
| 1128 | 
            +
             | 
| 910 1129 | 
             
                error = _write_workbook_file(self);
         | 
| 911 1130 | 
             
                RETURN_ON_ERROR(error);
         | 
| 912 1131 |  | 
| @@ -943,6 +1162,9 @@ lxw_create_package(lxw_packager *self) | |
| 943 1162 | 
             
                error = _write_worksheet_rels_file(self);
         | 
| 944 1163 | 
             
                RETURN_ON_ERROR(error);
         | 
| 945 1164 |  | 
| 1165 | 
            +
                error = _write_chartsheet_rels_file(self);
         | 
| 1166 | 
            +
                RETURN_ON_ERROR(error);
         | 
| 1167 | 
            +
             | 
| 946 1168 | 
             
                error = _write_drawing_rels_file(self);
         | 
| 947 1169 | 
             
                RETURN_ON_ERROR(error);
         | 
| 948 1170 |  |