1 module libxlsxd.worksheet; 2 3 import libxlsxd.types; 4 import libxlsxd.datetime; 5 import libxlsxd.format; 6 import libxlsxd.chart; 7 8 import libxlsxd.xlsxwrap; 9 10 private pure string genWriteOverloads() { 11 import std.array : empty; 12 import std.format : format; 13 string[3][] fun = [ 14 ["String", "string", ""], 15 ["String", "string", "Format"], 16 ["Int", "long", ""], 17 ["Int", "long", "Format"], 18 ["Boolean", "bool", ""], 19 ["Boolean", "bool", "Format"], 20 ["Number", "double", ""], 21 ["Number", "double", "Format"], 22 ["Datetime", "Datetime", ""], 23 ["Datetime", "Datetime", "Format"], 24 ["Formula", "string", ""], 25 ["Formula", "string", "Format"], 26 ["Url", "string", ""], 27 ["Url", "string", "Format"], 28 ["RichString", "lxw_rich_string_tuple**", ""], 29 ["RichString", "lxw_rich_string_tuple**", "Format"], 30 ]; 31 string ret; 32 version(No_Overloads_Or_Templates) { 33 immutable overloads = false; 34 ret ~= `void writeBlank(RowType row, ColType col) { 35 this.writeBlankImpl(row, col, Format(null)); 36 } 37 38 void writeBlankFormat(RowType row, ColType col, Format f) { 39 this.writeBlankImpl(row, col, f); 40 } 41 `; 42 43 } else { 44 immutable overloads = true; 45 ret ~= `void writeBlank(RowType row, ColType col) { 46 this.writeBlankImpl(row, col, Format(null)); 47 } 48 49 void writeBlank(RowType row, ColType col, Format f) { 50 this.writeBlankImpl(row, col, f); 51 } 52 `; 53 } 54 55 foreach(string[3] f; fun) { 56 bool addi = !f[2].empty; 57 ret ~= format("void write%s%s(RowType row, ColType col, %s value%s) {\n", 58 f[0], 59 !overloads && addi ? "Format" : "", 60 f[1], addi ? ", Format f" : "" 61 ); 62 ret ~= format("\tthis.write%sImpl(row, col, value%s);\n}\n\n", 63 f[0], addi ? ", f": ", Format(null)" 64 ); 65 } 66 return ret; 67 } 68 69 struct Worksheet { 70 import std.string : toStringz; 71 import std.exception : enforce; 72 lxw_worksheet* handle; 73 74 this(lxw_worksheet* handle) @nogc nothrow { 75 this.handle = handle; 76 } 77 78 mixin(genWriteOverloads()); 79 80 void write(T)(RowType row, ColType col, T value) { 81 this.write(row, col, value, Format(null)); 82 } 83 84 void write(T)(RowType row, ColType col, T value, Format format) { 85 import std.traits : isIntegral, isFloatingPoint, isSomeString; 86 static if((isFloatingPoint!T || isIntegral!T) && !is(T == bool)) { 87 this.writeNumberImpl(row, col, value, format); 88 } else static if(isSomeString!T) { 89 this.writeStringImpl(row, col, value, format); 90 } else static if(is(T == Datetime)) { 91 this.writeDatetimeImpl(row, col, value, format); 92 } else static if(is(T == bool)) { 93 this.writeBooleanImpl(row, col, value, format); 94 } else { 95 static assert(false, "The function 'write' does not support type 96 '" ~ T.stringof ~ "'"); 97 } 98 } 99 100 size_t writeAndGetWidth(T)(RowType row, ColType col, T value) { 101 return writeAndGetWidth(row, col, value, Format(null)); 102 } 103 104 size_t writeAndGetWidth(T)(RowType row, ColType col, T value, 105 Format format) 106 { 107 import std.traits : isIntegral, isFloatingPoint, isSomeString; 108 import std.conv : to; 109 static if((isFloatingPoint!T || isIntegral!T) && !is(T == bool)) { 110 this.writeNumberImpl(row, col, value, format); 111 return to!string(value).length; 112 } else static if(isSomeString!T) { 113 this.writeStringImpl(row, col, value, format); 114 return value.length; 115 } else static if(is(T == bool)) { 116 this.writeBooleanImpl(row, col, value, format); 117 return value ? 4 : 5; 118 } else { 119 static assert(false, "The function 'writeAndGetWidth' does not " 120 ~ " support type '" ~ T.stringof ~ "'"); 121 } 122 } 123 124 void writeIntImpl(RowType row, ColType col, double num, 125 Format format) 126 { 127 enforce(worksheet_write_number(this.handle, row, col, 128 num, format.handle) == LXW_NO_ERROR); 129 } 130 131 void writeNumberImpl(RowType row, ColType col, double num, 132 Format format) 133 { 134 enforce(worksheet_write_number(this.handle, row, col, 135 num, format.handle) == LXW_NO_ERROR); 136 } 137 138 void writeStringImpl(RowType row, ColType col, string str, Format format) { 139 enforce(worksheet_write_string(this.handle, row, col, 140 toStringz(str), format.handle) == LXW_NO_ERROR); 141 } 142 143 private void writeFormulaImpl(RowType row, ColType col, string formula, 144 Format format) 145 { 146 enforce(worksheet_write_formula(this.handle, row, col, 147 toStringz(formula), format.handle) == LXW_NO_ERROR); 148 } 149 150 void writeArrayFormula(RowType firstRow, ColType firstCol, 151 RowType lastRow, ColType lastCol, string formula) 152 { 153 this.writeArrayFormulaImpl(firstRow, firstCol, lastRow, lastCol, 154 formula, Format(null)); 155 } 156 157 version(No_Overloads_Or_Templates) { 158 void writeArrayFormulaFormat(RowType firstRow, ColType firstCol, 159 RowType lastRow, ColType lastCol, string formula, Format format) 160 { 161 this.writeArrayFormulaImpl(firstRow, firstCol, lastRow, lastCol, 162 formula, format); 163 } 164 } else { 165 void writeArrayFormula(RowType firstRow, ColType firstCol, 166 RowType lastRow, ColType lastCol, string formula, Format format) 167 { 168 this.writeArrayFormulaImpl(firstRow, firstCol, lastRow, lastCol, 169 formula, format); 170 } 171 } 172 173 private void writeArrayFormulaImpl(RowType firstRow, ColType firstCol, 174 RowType lastRow, ColType lastCol, string formula, Format format) 175 { 176 enforce(worksheet_write_array_formula(this.handle, firstRow, 177 firstCol, lastRow, lastCol, toStringz(formula), 178 format.handle) == LXW_NO_ERROR); 179 } 180 181 void writeDatetimeImpl(RowType row, ColType col, Datetime datetime, 182 Format format) 183 { 184 enforce(worksheet_write_datetime(this.handle, row, col, 185 &datetime.handle, format.handle) == LXW_NO_ERROR); 186 } 187 188 void writeUrlImpl(RowType row, ColType col, string url, Format format) { 189 enforce(worksheet_write_url(this.handle, row, col, 190 toStringz(url), format.handle) == LXW_NO_ERROR); 191 } 192 193 void writeBooleanImpl(RowType row, ColType col, bool value, Format format) { 194 enforce(worksheet_write_boolean(this.handle, row, col, 195 value, format.handle) == LXW_NO_ERROR); 196 } 197 198 void writeBlankImpl(RowType row, ColType col, Format format) { 199 enforce(worksheet_write_blank(this.handle, row, col, 200 format.handle) == LXW_NO_ERROR); 201 } 202 203 void writeFormulaNumImpl(RowType row, ColType col, string formula, 204 double value, Format format) 205 { 206 enforce(worksheet_write_formula_num(this.handle, row, 207 col, toStringz(formula), format.handle, value 208 ) 209 == LXW_NO_ERROR 210 ); 211 } 212 213 void writeRichStringImpl(RowType row, ColType col, 214 lxw_rich_string_tuple** rst, Format format) 215 { 216 enforce(worksheet_write_rich_string(this.handle, row, 217 col, rst, format.handle 218 ) 219 == LXW_NO_ERROR 220 ); 221 } 222 223 void setRow(RowType row, double height) { 224 this.setRowImpl(row, height, Format(null)); 225 } 226 227 version(No_Overloads_Or_Templates) { 228 void setRowFormat(RowType row, double height, Format f) { 229 this.setRowImpl(row, height, f); 230 } 231 } else { 232 void setRow(RowType row, double height, Format f) { 233 this.setRowImpl(row, height, f); 234 } 235 } 236 237 private void setRowImpl(RowType row, double height, Format format) { 238 enforce(worksheet_set_row(this.handle, row, height, format.handle) 239 == LXW_NO_ERROR 240 ); 241 } 242 243 void setRowOpt(RowType row, double height, lxw_row_col_options* options) { 244 this.setRowOptImpl(row, height, options, Format(null)); 245 } 246 247 version(No_Overloads_Or_Templates) { 248 void setRowOptFormat(RowType row, double height, 249 lxw_row_col_options* options, Format f) 250 { 251 this.setRowOptImpl(row, height, options, f); 252 } 253 } else { 254 void setRowOpt(RowType row, double height, 255 lxw_row_col_options* options, Format f) 256 { 257 this.setRowOptImpl(row, height, options, f); 258 } 259 } 260 261 private void setRowOptImpl(RowType row, double height, 262 lxw_row_col_options* options, Format format) 263 { 264 enforce(worksheet_set_row_opt(this.handle, row, height, 265 format.handle, options) == LXW_NO_ERROR); 266 } 267 268 void setColumn(ColType firstCol, ColType lastCol, double width) { 269 this.setColumnImpl(firstCol, lastCol, width, Format(null)); 270 } 271 272 version(No_Overloads_Or_Templates) { 273 void setColumnFormat(ColType firstCol, ColType lastCol, double width, 274 Format f) 275 { 276 this.setColumnImpl(firstCol, lastCol, width, f); 277 } 278 } else { 279 void setColumn(ColType firstCol, ColType lastCol, double width, 280 Format f) 281 { 282 this.setColumnImpl(firstCol, lastCol, width, f); 283 } 284 } 285 286 private void setColumnImpl(ColType firstCol, ColType lastCol, double width, 287 Format format) 288 { 289 enforce(worksheet_set_column(this.handle, firstCol, lastCol, 290 width, format.handle 291 ) 292 == LXW_NO_ERROR 293 ); 294 } 295 296 void setColumnOpt(ColType firstCol, ColType lastCol, double width, 297 lxw_row_col_options* options) 298 { 299 this.setColumnOptImpl(firstCol, lastCol, width, options, Format(null)); 300 } 301 302 version(No_Overloads_Or_Templates) { 303 void setColumnOptFormat(ColType firstCol, ColType lastCol, double width, 304 lxw_row_col_options* options, Format f) 305 { 306 this.setColumnOptImpl(firstCol, lastCol, width, options, f); 307 } 308 } else { 309 void setColumnOpt(ColType firstCol, ColType lastCol, double width, 310 lxw_row_col_options* options, Format f) 311 { 312 this.setColumnOptImpl(firstCol, lastCol, width, options, f); 313 } 314 } 315 316 private void setColumnOptImpl(ColType firstCol, ColType lastCol, 317 double width, lxw_row_col_options* options, Format format) 318 { 319 enforce(worksheet_set_column_opt(this.handle, firstCol, lastCol, 320 width, format.handle, options) 321 == LXW_NO_ERROR 322 ); 323 } 324 325 void insertImage(RowType row, ColType col, string filename) { 326 enforce(worksheet_insert_image(this.handle, row, col, 327 toStringz(filename) 328 ) 329 == LXW_NO_ERROR 330 ); 331 } 332 333 void insertImageOpt(RowType row, ColType col, string filename, 334 lxw_image_options* options) 335 { 336 enforce(worksheet_insert_image_opt(this.handle, row, col, 337 toStringz(filename), options 338 ) 339 == LXW_NO_ERROR 340 ); 341 } 342 343 void insertImageBuffer(RowType row, ColType col, const(ubyte)* buf, 344 size_t bufSize) 345 { 346 enforce(worksheet_insert_image_buffer(this.handle, row, 347 col, buf, bufSize 348 ) 349 == LXW_NO_ERROR 350 ); 351 } 352 353 void insertImageBufferOpt(RowType row, ColType col, const(ubyte)* buf, 354 size_t bufSize, lxw_image_options* options) 355 { 356 enforce(worksheet_insert_image_buffer_opt(this.handle, row, 357 col, buf, bufSize, options 358 ) 359 == LXW_NO_ERROR 360 ); 361 } 362 363 void insertChart(RowType row, ColType col, Chart chart) { 364 enforce(worksheet_insert_chart(this.handle, row, col, 365 chart.handle) == LXW_NO_ERROR); 366 } 367 368 void insertChartOpt(RowType row, ColType col, Chart chart, 369 lxw_image_options* options) 370 { 371 enforce(worksheet_insert_chart_opt(this.handle, row, 372 col, chart.handle, options 373 ) 374 == LXW_NO_ERROR 375 ); 376 } 377 378 void mergeRange(RowType firstRow, ColType firstCol, RowType lastRow, 379 ColType lastCol, string str) 380 { 381 this.mergeRangeImpl(firstRow, firstCol, lastRow, 382 lastCol, str, Format(null)); 383 } 384 385 version(No_Overloads_Or_Templates) { 386 void mergeRangeFormat(RowType firstRow, ColType firstCol, 387 RowType lastRow, ColType lastCol, string str, Format f) 388 { 389 this.mergeRangeImpl(firstRow, firstCol, lastRow, 390 lastCol, str, f); 391 } 392 } else { 393 void mergeRange(RowType firstRow, ColType firstCol, RowType lastRow, 394 ColType lastCol, string str, Format f) 395 { 396 this.mergeRangeImpl(firstRow, firstCol, lastRow, 397 lastCol, str, f); 398 } 399 } 400 401 private void mergeRangeImpl(RowType firstRow, ColType firstCol, 402 RowType lastRow, ColType lastCol, string str, Format format) 403 { 404 enforce(worksheet_merge_range(this.handle, firstRow, firstCol, 405 lastRow, lastCol, toStringz(str), format.handle 406 ) 407 == LXW_NO_ERROR 408 ); 409 } 410 411 void autofilter(RowType firstRow, ColType firstCol, RowType lastRow, 412 ColType lastCol) { 413 enforce(worksheet_autofilter(this.handle, firstRow, firstCol, 414 lastRow, lastCol) == LXW_NO_ERROR); 415 } 416 417 void dataValidationCell(RowType row, ColType col, 418 lxw_data_validation* validator) 419 { 420 enforce(worksheet_data_validation_cell(this.handle, row, 421 col, validator 422 ) 423 == LXW_NO_ERROR 424 ); 425 } 426 427 void dataValidationRange(RowType firstRow, ColType firstCol, 428 RowType lastRow, ColType lastCol, lxw_data_validation* validator) 429 { 430 enforce(worksheet_data_validation_range(this.handle, firstRow, 431 firstCol, lastRow, lastCol, validator 432 ) 433 == LXW_NO_ERROR 434 ); 435 } 436 437 void activate() @nogc nothrow { 438 worksheet_activate(this.handle); 439 } 440 441 void select() @nogc nothrow { 442 worksheet_select(this.handle); 443 } 444 445 void hide() @nogc nothrow { 446 worksheet_hide(this.handle); 447 } 448 449 void setFirstSheet() @nogc nothrow { 450 worksheet_set_first_sheet(this.handle); 451 } 452 453 void freezePanes(RowType row, ColType col) @nogc nothrow { 454 worksheet_freeze_panes(this.handle, row, col); 455 } 456 457 void splitPanes(double vertical, double horizontal) @nogc nothrow { 458 worksheet_split_panes(this.handle, vertical, horizontal); 459 } 460 461 void setSelection(RowType firstRow, ColType firstCol, RowType lastRow, 462 ColType lastCol) @nogc nothrow 463 { 464 worksheet_set_selection(this.handle, firstRow, firstCol, lastRow, 465 lastCol 466 ); 467 } 468 469 void setLandscape() @nogc nothrow { 470 worksheet_set_landscape(this.handle); 471 } 472 473 void setPortrait() @nogc nothrow { 474 worksheet_set_portrait(this.handle); 475 } 476 477 void setPageView() @nogc nothrow { 478 worksheet_set_page_view(this.handle); 479 } 480 481 void setPaper(ubyte paperType) @nogc nothrow { 482 worksheet_set_paper(this.handle, paperType); 483 } 484 485 void setMargins(double left, double right, double top, double bottom) 486 @nogc nothrow 487 { 488 worksheet_set_margins(this.handle, left, right, top, bottom); 489 } 490 491 void setHeader(string header) { 492 enforce(worksheet_set_header(this.handle, toStringz(header)) 493 == LXW_NO_ERROR 494 ); 495 } 496 497 void setFooter(string footer) { 498 enforce(worksheet_set_footer(this.handle, toStringz(footer)) 499 == LXW_NO_ERROR 500 ); 501 } 502 503 void setHeaderOpt(string header, lxw_header_footer_options* options) { 504 enforce(worksheet_set_header_opt(this.handle, toStringz(header), 505 options 506 ) 507 == LXW_NO_ERROR 508 ); 509 } 510 511 void setFooterOpt(string footer, lxw_header_footer_options* options) { 512 enforce(worksheet_set_footer_opt(this.handle, toStringz(footer), 513 options 514 ) 515 == LXW_NO_ERROR 516 ); 517 } 518 519 void setHPagebreaks(RowType[] row) { 520 enforce(worksheet_set_h_pagebreaks(this.handle, row.ptr) 521 == LXW_NO_ERROR 522 ); 523 } 524 525 void setVPagebreaks(ColType[] col) { 526 enforce(worksheet_set_v_pagebreaks(this.handle, col.ptr) 527 == LXW_NO_ERROR 528 ); 529 } 530 531 void printAcross() @nogc nothrow { 532 worksheet_print_across(this.handle); 533 } 534 535 void setZoom(ushort scale) @nogc nothrow { 536 worksheet_set_zoom(this.handle, scale); 537 } 538 539 void gridlines(ubyte option) @nogc nothrow { 540 worksheet_gridlines(this.handle, option); 541 } 542 543 void centerHorizontally() @nogc nothrow { 544 worksheet_center_horizontally(this.handle); 545 } 546 547 void centerVertically() @nogc nothrow { 548 worksheet_center_vertically(this.handle); 549 550 } 551 void printRowColHeaders() @nogc nothrow { 552 worksheet_print_row_col_headers(this.handle); 553 } 554 555 void repeatRows(RowType firstRow, RowType lastRow) { 556 enforce(worksheet_repeat_rows(this.handle, firstRow, lastRow) == 557 LXW_NO_ERROR); 558 } 559 560 void repeatColumns(ColType firstCol, ColType lastCol) { 561 enforce(worksheet_repeat_columns(this.handle, firstCol, lastCol) 562 == LXW_NO_ERROR 563 ); 564 } 565 566 void printArea(RowType firstRow, ColType firstCol, RowType lastRow, 567 ColType lastCol) 568 { 569 enforce(worksheet_print_area(this.handle, firstRow, firstCol, lastRow, 570 lastCol 571 ) 572 == LXW_NO_ERROR 573 ); 574 } 575 576 void fitToPages(ushort width, ushort height) @nogc nothrow { 577 worksheet_fit_to_pages(this.handle, width, height); 578 } 579 580 void setStartPage(ushort startPage) @nogc nothrow { 581 worksheet_set_start_page(this.handle, startPage); 582 } 583 584 void setPrintScale(ushort scale) @nogc nothrow { 585 worksheet_set_print_scale(this.handle, scale); 586 } 587 588 void rightToLeft() @nogc nothrow { 589 worksheet_right_to_left(this.handle); 590 } 591 592 void hideZero() @nogc nothrow { 593 worksheet_hide_zero(this.handle); 594 } 595 596 void setTabColor(lxw_color_t color) @nogc nothrow { 597 worksheet_set_tab_color(this.handle, color); 598 } 599 600 void protect(string password, lxw_protection* options) { 601 worksheet_protect(this.handle, toStringz(password), options); 602 } 603 604 void outlineSettings(ubyte visible, ubyte symbolsBelow, 605 ubyte symbolsRight, ubyte autoStyle) @nogc nothrow 606 { 607 worksheet_outline_settings(this.handle, visible, symbolsBelow, 608 symbolsRight, autoStyle); 609 } 610 611 void setDefaultRow(double height, ubyte hideUnusedRows) @nogc nothrow { 612 worksheet_set_default_row(this.handle, height, hideUnusedRows); 613 } 614 }