1 /* 2 * libxlsxwriter 3 * 4 * Copyright 2014-2016, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 */ 6 7 /** 8 * @page workbook_page The Workbook object 9 * 10 * The Workbook is the main object exposed by the libxlsxwriter library. It 11 * represents the entire spreadsheet as you see it in Excel and internally it 12 * represents the Excel file as it is written on disk. 13 * 14 * See @ref workbook.h for full details of the functionality. 15 * 16 * @file workbook.h 17 * 18 * @brief Functions related to creating an Excel xlsx workbook. 19 * 20 * The Workbook is the main object exposed by the libxlsxwriter library. It 21 * represents the entire spreadsheet as you see it in Excel and internally it 22 * represents the Excel file as it is written on disk. 23 * 24 * @code 25 * #include "xlsxwriter.h" 26 * 27 * int main() { 28 * 29 * lxw_workbook *workbook = workbook_new("filename.xlsx"); 30 * lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); 31 * 32 * worksheet_write_string(worksheet, 0, 0, "Hello Excel", NULL); 33 * 34 * return workbook_close(workbook); 35 * } 36 * @endcode 37 * 38 * @image html workbook01.png 39 * 40 */ 41 module xlsxwriter.workbook; 42 43 import core.stdc.stdint; 44 import core.stdc.time; 45 46 import xlsxwriter.worksheet; 47 import xlsxwriter.common; 48 import xlsxwriter.format; 49 import xlsxwriter.chart; 50 51 extern(C): 52 enum LXW_DEFINED_NAME_LENGTH = 128; 53 54 /** 55 * @brief Macro to loop over all the worksheets in a workbook. 56 * 57 * This macro allows you to loop over all the worksheets that have been 58 * added to a workbook. You must provide a lxw_worksheet pointer and 59 * a pointer to the lxw_workbook: 60 * 61 * @code 62 * lxw_workbook *workbook = workbook_new("test.xlsx"); 63 * 64 * lxw_worksheet *worksheet; // Generic worksheet pointer. 65 * 66 * // Worksheet objects used in the program. 67 * lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL); 68 * lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL); 69 * lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, NULL); 70 * 71 * // Iterate over the 3 worksheets and perform the same operation on each. 72 * LXW_FOREACH_WORKSHEET(worksheet, workbook) { 73 * worksheet_write_string(worksheet, 0, 0, "Hello", NULL); 74 * } 75 * @endcode 76 */ 77 /* #define LXW_FOREACH_WORKSHEET(worksheet, workbook) \ */ 78 /* STAILQ_FOREACH((worksheet), (workbook)->worksheets, list_pointers) */ 79 80 /* Struct to represent a defined name. */ 81 /* struct lxw_defined_name { */ 82 /* int16_t index; */ 83 /* uint8_t hidden; */ 84 /* char name[LXW_DEFINED_NAME_LENGTH]; */ 85 /* char app_name[LXW_DEFINED_NAME_LENGTH]; */ 86 /* char formula[LXW_DEFINED_NAME_LENGTH]; */ 87 /* char normalised_name[LXW_DEFINED_NAME_LENGTH]; */ 88 /* char normalised_sheetname[LXW_DEFINED_NAME_LENGTH]; */ 89 90 /* /1* List pointers for queue.h. *1/ */ 91 /* TAILQ_ENTRY (lxw_defined_name) list_pointers; */ 92 /* } lxw_defined_name; */ 93 94 /** 95 * @brief Error codes from workbook functions. 96 */ 97 enum lxw_workbook_error { 98 /** No error */ 99 LXW_ERROR_WORKBOOK_NONE = 0, 100 101 /** Error encountered when creating file */ 102 LXW_ERROR_WORKBOOK_FILE_CREATE, 103 104 /** Error encountered when creating a packager object */ 105 LXW_ERROR_WORKBOOK_PACKAGER, 106 107 /** Error encountered when creating file zip container */ 108 LXW_ERROR_WORKBOOK_ZIP, 109 110 /** Memory error. */ 111 LXW_ERROR_WORKBOOK_MEMORY_ERROR 112 } 113 114 /** 115 * Workbook document properties. 116 */ 117 struct lxw_doc_properties { 118 /** The title of the Excel Document. */ 119 char *title; 120 121 /** The subject of the Excel Document. */ 122 char *subject; 123 124 /** The author of the Excel Document. */ 125 char *author; 126 127 /** The manager field of the Excel Document. */ 128 char *manager; 129 130 /** The company field of the Excel Document. */ 131 char *company; 132 133 /** The category of the Excel Document. */ 134 char *category; 135 136 /** The keywords of the Excel Document. */ 137 char *keywords; 138 139 /** The comment field of the Excel Document. */ 140 char *comments; 141 142 /** The status of the Excel Document. */ 143 char *status; 144 145 /** The hyperlink base url of the Excel Document. */ 146 char *hyperlink_base; 147 148 time_t created; 149 150 } 151 152 /** 153 * @brief Workbook options. 154 * 155 * Optional parameters when creating a new Workbook object via 156 * workbook_new_opt(). 157 * 158 * Currently only the `constant_memory` property is supported: 159 * 160 * * `constant_memory` 161 */ 162 struct lxw_workbook_options { 163 /** Optimize the workbook to use constant memory for worksheets */ 164 uint8_t constant_memory; 165 } 166 167 /** 168 * @brief Struct to represent an Excel workbook. 169 * 170 * The members of the lxw_workbook struct aren't modified directly. Instead 171 * the workbook properties are set by calling the functions shown in 172 * workbook.h. 173 */ 174 struct lxw_workbook {} 175 176 177 /** 178 * @brief Create a new workbook object. 179 * 180 * @param filename The name of the new Excel file to create. 181 * 182 * @return A lxw_workbook instance. 183 * 184 * The `%workbook_new()` constructor is used to create a new Excel workbook 185 * with a given filename: 186 * 187 * @code 188 * lxw_workbook *workbook = workbook_new("filename.xlsx"); 189 * @endcode 190 * 191 * When specifying a filename it is recommended that you use an `.xlsx` 192 * extension or Excel will generate a warning when opening the file. 193 * 194 */ 195 lxw_workbook *workbook_new(const char *filename); 196 197 /** 198 * @brief Create a new workbook object, and set the workbook options. 199 * 200 * @param filename The name of the new Excel file to create. 201 * @param options Workbook options. 202 * 203 * @return A lxw_workbook instance. 204 * 205 * This method is the same as the `workbook_new()` constructor but allows 206 * additional options to be set. 207 * 208 * @code 209 * lxw_workbook_options options = {.constant_memory = 1}; 210 * 211 * lxw_workbook *workbook = workbook_new_opt("filename.xlsx", &options); 212 * @endcode 213 * 214 * Note, in this mode a row of data is written and then discarded when a cell 215 * in a new row is added via one of the worksheet `worksheet_write_*()` 216 * methods. Therefore, once this mode is active, data should be written in 217 * sequential row order. 218 * 219 * See @ref working_with_memory for more details. 220 * 221 */ 222 lxw_workbook *workbook_new_opt(const char *filename, 223 lxw_workbook_options *options); 224 225 /* Deprecated function name for backwards compatibility. */ 226 lxw_workbook *new_workbook(const char *filename); 227 228 /* Deprecated function name for backwards compatibility. */ 229 lxw_workbook *new_workbook_opt(const char *filename, 230 lxw_workbook_options *options); 231 232 /** 233 * @brief Add a new worksheet to a workbook: 234 * 235 * @param workbook Pointer to a lxw_workbook instance. 236 * @param sheetname Optional worksheet name, defaults to Sheet1, etc. 237 * 238 * @return A lxw_worksheet instance. 239 * 240 * The `%workbook_add_worksheet()` method adds a new worksheet to a workbook: 241 * 242 * At least one worksheet should be added to a new workbook: The @ref 243 * worksheet.h "Worksheet" object is used to write data and configure a 244 * worksheet in the workbook. 245 * 246 * The `sheetname` parameter is optional. If it is `NULL` the default 247 * Excel convention will be followed, i.e. Sheet1, Sheet2, etc.: 248 * 249 * @code 250 * worksheet = workbook_add_worksheet(workbook, NULL ); // Sheet1 251 * worksheet = workbook_add_worksheet(workbook, "Foglio2"); // Foglio2 252 * worksheet = workbook_add_worksheet(workbook, "Data"); // Data 253 * worksheet = workbook_add_worksheet(workbook, NULL ); // Sheet4 254 * 255 * @endcode 256 * 257 * @image html workbook02.png 258 * 259 * The worksheet name must be a valid Excel worksheet name, i.e. it must be 260 * less than 32 character and it cannot contain any of the characters: 261 * 262 * / \ [ ] : * ? 263 * 264 * In addition, you cannot use the same, case insensitive, `sheetname` for more 265 * than one worksheet. 266 * 267 */ 268 lxw_worksheet *workbook_add_worksheet(lxw_workbook *workbook, 269 const char *sheetname); 270 271 /** 272 * @brief Create a new @ref format.h "Format" object to formats cells in 273 * worksheets. 274 * 275 * @param workbook Pointer to a lxw_workbook instance. 276 * 277 * @return A lxw_format instance. 278 * 279 * The `workbook_add_format()` function can be used to create new @ref 280 * format.h "Format" objects which are used to apply formatting to a cell. 281 * 282 * @code 283 * // Create the Format. 284 * lxw_format *format = workbook_add_format(workbook); 285 * 286 * // Set some of the format properties. 287 * format_set_bold(format); 288 * format_set_font_color(format, LXW_COLOR_RED); 289 * 290 * // Use the format to change the text format in a cell. 291 * worksheet_write_string(worksheet, 0, 0, "Hello", format); 292 * @endcode 293 * 294 * See @ref format.h "the Format object" and @ref working_with_formats 295 * sections for more details about Format properties and how to set them. 296 * 297 */ 298 lxw_format *workbook_add_format(lxw_workbook *workbook); 299 300 /** 301 * @brief Close the Workbook object and write the XLSX file. 302 * 303 * @param workbook Pointer to a lxw_workbook instance. 304 * 305 * @return A #lxw_workbook_error. 306 * 307 * The `%workbook_close()` function closes a Workbook object, writes the Excel 308 * file to disk, frees any memory allocated internally to the Workbook and 309 * frees the object itself. 310 * 311 * @code 312 * workbook_close(workbook); 313 * @endcode 314 * 315 * The `%workbook_close()` function returns any #lxw_workbook_error error codes 316 * encountered when creating the Excel file. The error code can be returned 317 * from the program main or the calling function: 318 * 319 * @code 320 * return workbook_close(workbook); 321 * @endcode 322 * 323 */ 324 lxw_error workbook_close(lxw_workbook *workbook); 325 326 /** 327 * @brief Set the document properties such as Title, Author etc. 328 * 329 * @param workbook Pointer to a lxw_workbook instance. 330 * @param properties Document properties to set. 331 * 332 * The `%workbook_set_properties` method can be used to set the document 333 * properties of the Excel file created by `libxlsxwriter`. These properties 334 * are visible when you use the `Office Button -> Prepare -> Properties` 335 * option in Excel and are also available to external applications that read 336 * or index windows files. 337 * 338 * The properties that can be set are: 339 * 340 * - `title` 341 * - `subject` 342 * - `author` 343 * - `manager` 344 * - `company` 345 * - `category` 346 * - `keywords` 347 * - `comments` 348 * - `hyperlink_base` 349 * 350 * The properties are specified via a `lxw_doc_properties` struct. All the 351 * members are `char *` and they are all optional. An example of how to create 352 * and pass the properties is: 353 * 354 * @code 355 * // Create a properties structure and set some of the fields. 356 * lxw_doc_properties properties = { 357 * .title = "This is an example spreadsheet", 358 * .subject = "With document properties", 359 * .author = "John McNamara", 360 * .manager = "Dr. Heinz Doofenshmirtz", 361 * .company = "of Wolves", 362 * .category = "Example spreadsheets", 363 * .keywords = "Sample, Example, Properties", 364 * .comments = "Created with libxlsxwriter", 365 * .status = "Quo", 366 * }; 367 * 368 * // Set the properties in the workbook. 369 * workbook_set_properties(workbook, &properties); 370 * @endcode 371 * 372 * @image html doc_properties.png 373 * 374 * @return 0 for success, non-zero on error. 375 */ 376 lxw_error workbook_set_properties(lxw_workbook *workbook, 377 lxw_doc_properties *properties); 378 379 /** 380 * @brief Create a defined name in the workbook to use as a variable. 381 * 382 * @param workbook Pointer to a lxw_workbook instance. 383 * @param name The defined name. 384 * @param formula The cell or range that the defined name refers to. 385 * 386 * @return 0 for success, non-zero on error. 387 * 388 * This method is used to defined a name that can be used to represent a 389 * value, a single cell or a range of cells in a workbook: These defined names 390 * can then be used in formulas: 391 * 392 * @code 393 * workbook_define_name(workbook, "Exchange_rate", "=0.96"); 394 * worksheet_write_formula(worksheet, 2, 1, "=Exchange_rate", NULL); 395 * 396 * @endcode 397 * 398 * @image html defined_name.png 399 * 400 * As in Excel a name defined like this is "global" to the workbook and can be 401 * referred to from any worksheet: 402 * 403 * @code 404 * // Global workbook name. 405 * workbook_define_name(workbook, "Sales", "=Sheet1!$G$1:$H$10"); 406 * @endcode 407 * 408 * It is also possible to define a local/worksheet name by prefixing it with 409 * the sheet name using the syntax `'sheetname!definedname'`: 410 * 411 * @code 412 * // Local worksheet name. 413 * workbook_define_name(workbook, "Sheet2!Sales", "=Sheet2!$G$1:$G$10"); 414 * @endcode 415 * 416 * If the sheet name contains spaces or special characters you must follow the 417 * Excel convention and enclose it in single quotes: 418 * 419 * @code 420 * workbook_define_name(workbook, "'New Data'!Sales", "=Sheet2!$G$1:$G$10"); 421 * @endcode 422 * 423 * The rules for names in Excel are explained in the 424 * [Microsoft Office 425 documentation](http://office.microsoft.com/en-001/excel-help/define-and-use-names-in-formulas-HA010147120.aspx). 426 * 427 */ 428 lxw_error workbook_define_name(lxw_workbook *workbook, const char *name, 429 const char *formula); 430 431 void lxw_workbook_free(lxw_workbook *workbook); 432 void lxw_workbook_assemble_xml_file(lxw_workbook *workbook); 433 void lxw_workbook_set_default_xf_indices(lxw_workbook *workbook); 434 435 /** 436 * @brief Create a new chart to be added to a worksheet: 437 * 438 * @param workbook Pointer to a lxw_workbook instance. 439 * @param chart_type The type of chart to be created. See #lxw_chart_types. 440 * 441 * @return A lxw_chart object. 442 * 443 * The `%workbook_add_chart()` function creates a new chart object that can 444 * be added to a worksheet: 445 * 446 * @code 447 * // Create a chart object. 448 * lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN); 449 * 450 * // Add data series to the chart. 451 * chart_add_series(chart, NULL, "Sheet1!$A$1:$A$5"); 452 * chart_add_series(chart, NULL, "Sheet1!$B$1:$B$5"); 453 * chart_add_series(chart, NULL, "Sheet1!$C$1:$C$5"); 454 * 455 * // Insert the chart into the worksheet 456 * worksheet_insert_chart(worksheet, CELL("B7"), chart); 457 * @endcode 458 * 459 * The available chart types are defined in #lxw_chart_types. The types of 460 * charts that are supported are: 461 * 462 * | Chart type | Description | 463 * | :--------------------------------------- | :------------------------------------ | 464 * | #LXW_CHART_AREA | Area chart. | 465 * | #LXW_CHART_AREA_STACKED | Area chart - stacked. | 466 * | #LXW_CHART_AREA_STACKED_PERCENT | Area chart - percentage stacked. | 467 * | #LXW_CHART_BAR | Bar chart. | 468 * | #LXW_CHART_BAR_STACKED | Bar chart - stacked. | 469 * | #LXW_CHART_BAR_STACKED_PERCENT | Bar chart - percentage stacked. | 470 * | #LXW_CHART_COLUMN | Column chart. | 471 * | #LXW_CHART_COLUMN_STACKED | Column chart - stacked. | 472 * | #LXW_CHART_COLUMN_STACKED_PERCENT | Column chart - percentage stacked. | 473 * | #LXW_CHART_DOUGHNUT | Doughnut chart. | 474 * | #LXW_CHART_LINE | Line chart. | 475 * | #LXW_CHART_PIE | Pie chart. | 476 * | #LXW_CHART_SCATTER | Scatter chart. | 477 * | #LXW_CHART_SCATTER_STRAIGHT | Scatter chart - straight. | 478 * | #LXW_CHART_SCATTER_STRAIGHT_WITH_MARKERS | Scatter chart - straight with markers. | 479 * | #LXW_CHART_SCATTER_SMOOTH | Scatter chart - smooth. | 480 * | #LXW_CHART_SCATTER_SMOOTH_WITH_MARKERS | Scatter chart - smooth with markers. | 481 * | #LXW_CHART_RADAR | Radar chart. | 482 * | #LXW_CHART_RADAR_WITH_MARKERS | Radar chart - with markers. | 483 * | #LXW_CHART_RADAR_FILLED | Radar chart - filled. | 484 * 485 * 486 * 487 * See @ref chart.h for details. 488 */ 489 lxw_chart *workbook_add_chart(lxw_workbook *workbook, uint8_t chart_type);