[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * ODS file writer. 19 * The xml used here is derived from output of LibreOffice 3.6.4 20 * 21 * The design is based on Excel writer abstraction by Eloy Lafuente and others. 22 * 23 * @package core 24 * @copyright 2006 Petr Skoda {@link http://skodak.org} 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 31 /** 32 * ODS workbook abstraction. 33 * 34 * @package core 35 * @copyright 2006 Petr Skoda {@link http://skodak.org} 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class MoodleODSWorkbook { 39 protected $worksheets = array(); 40 protected $filename; 41 42 public function __construct($filename) { 43 $this->filename = $filename; 44 } 45 46 /** 47 * Create one Moodle Worksheet. 48 * 49 * @param string $name Name of the sheet 50 * @return MoodleODSWorksheet 51 */ 52 public function add_worksheet($name = '') { 53 $ws = new MoodleODSWorksheet($name, $this->worksheets); 54 $this->worksheets[] = $ws; 55 return $ws; 56 } 57 58 /** 59 * Create one Moodle Format. 60 * 61 * @param array $properties array of properties [name]=value; 62 * valid names are set_XXXX existing 63 * functions without the set_ part 64 * i.e: [bold]=1 for set_bold(1)...Optional! 65 * @return MoodleODSFormat 66 */ 67 public function add_format($properties = array()) { 68 return new MoodleODSFormat($properties); 69 } 70 71 /** 72 * Close the Moodle Workbook. 73 */ 74 public function close() { 75 $writer = new MoodleODSWriter($this->worksheets); 76 $contents = $writer->get_file_content(); 77 78 send_file($contents, $this->filename, 0, 0, true, true, $writer->get_ods_mimetype()); 79 } 80 81 /** 82 * Not required to use. 83 * @param string $filename Name of the downloaded file 84 */ 85 public function send($filename) { 86 $this->filename = $filename; 87 } 88 89 } 90 91 92 /** 93 * ODS Cell abstraction. 94 * 95 * @package core 96 * @copyright 2013 Petr Skoda {@link http://skodak.org} 97 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 98 */ 99 class MoodleODSCell { 100 public $value; 101 public $type; 102 public $format; 103 public $formula; 104 } 105 106 107 /** 108 * ODS Worksheet abstraction. 109 * 110 * @package core 111 * @copyright 2006 Petr Skoda {@link http://skodak.org} 112 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 113 */ 114 class MoodleODSWorksheet { 115 public $data = array(); 116 public $columns = array(); 117 public $rows = array(); 118 public $showgrid = true; 119 public $name; 120 121 /** 122 * Constructs one Moodle Worksheet. 123 * 124 * @param string $name The name of the file 125 * @param array $worksheets existing worksheets 126 */ 127 public function __construct($name, array $worksheets) { 128 // Replace any characters in the name that Excel cannot cope with. 129 $name = strtr($name, '[]*/\?:', ' '); 130 131 if ($name === '') { 132 // Name is required! 133 $name = 'Sheet'.(count($worksheets)+1); 134 } 135 136 $this->name = $name; 137 } 138 139 /** 140 * Write one string somewhere in the worksheet. 141 * 142 * @param integer $row Zero indexed row 143 * @param integer $col Zero indexed column 144 * @param string $str The string to write 145 * @param mixed $format The XF format for the cell 146 */ 147 public function write_string($row, $col, $str, $format = null) { 148 if (!isset($this->data[$row][$col])) { 149 $this->data[$row][$col] = new MoodleODSCell(); 150 } 151 if (is_array($format)) { 152 $format = new MoodleODSFormat($format); 153 } 154 $this->data[$row][$col]->value = $str; 155 $this->data[$row][$col]->type = 'string'; 156 $this->data[$row][$col]->format = $format; 157 $this->data[$row][$col]->formula = null; 158 } 159 160 /** 161 * Write one number somewhere in the worksheet. 162 * 163 * @param integer $row Zero indexed row 164 * @param integer $col Zero indexed column 165 * @param float $num The number to write 166 * @param mixed $format The XF format for the cell 167 */ 168 public function write_number($row, $col, $num, $format = null) { 169 if (!isset($this->data[$row][$col])) { 170 $this->data[$row][$col] = new MoodleODSCell(); 171 } 172 if (is_array($format)) { 173 $format = new MoodleODSFormat($format); 174 } 175 $this->data[$row][$col]->value = $num; 176 $this->data[$row][$col]->type = 'float'; 177 $this->data[$row][$col]->format = $format; 178 $this->data[$row][$col]->formula = null; 179 } 180 181 /** 182 * Write one url somewhere in the worksheet. 183 * 184 * @param integer $row Zero indexed row 185 * @param integer $col Zero indexed column 186 * @param string $url The url to write 187 * @param mixed $format The XF format for the cell 188 */ 189 public function write_url($row, $col, $url, $format = null) { 190 if (!isset($this->data[$row][$col])) { 191 $this->data[$row][$col] = new MoodleODSCell(); 192 } 193 if (is_array($format)) { 194 $format = new MoodleODSFormat($format); 195 } 196 $this->data[$row][$col]->value = $url; 197 $this->data[$row][$col]->type = 'string'; 198 $this->data[$row][$col]->format = $format; 199 $this->data[$row][$col]->formula = null; 200 } 201 202 /** 203 * Write one date somewhere in the worksheet. 204 * 205 * @param integer $row Zero indexed row 206 * @param integer $col Zero indexed column 207 * @param string $date The url to write 208 * @param mixed $format The XF format for the cell 209 */ 210 public function write_date($row, $col, $date, $format = null) { 211 if (!isset($this->data[$row][$col])) { 212 $this->data[$row][$col] = new MoodleODSCell(); 213 } 214 if (is_array($format)) { 215 $format = new MoodleODSFormat($format); 216 } 217 $this->data[$row][$col]->value = $date; 218 $this->data[$row][$col]->type = 'date'; 219 $this->data[$row][$col]->format = $format; 220 $this->data[$row][$col]->formula = null; 221 } 222 223 /** 224 * Write one formula somewhere in the worksheet. 225 * 226 * @param integer $row Zero indexed row 227 * @param integer $col Zero indexed column 228 * @param string $formula The formula to write 229 * @param mixed $format The XF format for the cell 230 */ 231 public function write_formula($row, $col, $formula, $format = null) { 232 if (!isset($this->data[$row][$col])) { 233 $this->data[$row][$col] = new MoodleODSCell(); 234 } 235 if (is_array($format)) { 236 $format = new MoodleODSFormat($format); 237 } 238 $this->data[$row][$col]->formula = $formula; 239 $this->data[$row][$col]->format = $format; 240 $this->data[$row][$col]->value = null; 241 $this->data[$row][$col]->format = null; 242 } 243 244 /** 245 * Write one blank somewhere in the worksheet. 246 * 247 * @param integer $row Zero indexed row 248 * @param integer $col Zero indexed column 249 * @param mixed $format The XF format for the cell 250 */ 251 public function write_blank($row, $col, $format = null) { 252 if (is_array($format)) { 253 $format = new MoodleODSFormat($format); 254 } 255 $this->write_string($row, $col, '', $format); 256 } 257 258 /** 259 * Write anything somewhere in the worksheet, 260 * type will be automatically detected. 261 * 262 * @param integer $row Zero indexed row 263 * @param integer $col Zero indexed column 264 * @param mixed $token What we are writing 265 * @param mixed $format The XF format for the cell 266 */ 267 public function write($row, $col, $token, $format = null) { 268 // Analyse what are we trying to send. 269 if (preg_match("/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/", $token)) { 270 // Match number 271 return $this->write_number($row, $col, $token, $format); 272 } elseif (preg_match("/^[fh]tt?p:\/\//", $token)) { 273 // Match http or ftp URL 274 return $this->write_url($row, $col, $token, '', $format); 275 } elseif (preg_match("/^mailto:/", $token)) { 276 // Match mailto: 277 return $this->write_url($row, $col, $token, '', $format); 278 } elseif (preg_match("/^(?:in|ex)ternal:/", $token)) { 279 // Match internal or external sheet link 280 return $this->write_url($row, $col, $token, '', $format); 281 } elseif (preg_match("/^=/", $token)) { 282 // Match formula 283 return $this->write_formula($row, $col, $token, $format); 284 } elseif (preg_match("/^@/", $token)) { 285 // Match formula 286 return $this->write_formula($row, $col, $token, $format); 287 } elseif ($token == '') { 288 // Match blank 289 return $this->write_blank($row, $col, $format); 290 } else { 291 // Default: match string 292 return $this->write_string($row, $col, $token, $format); 293 } 294 } 295 296 /** 297 * Sets the height (and other settings) of one row. 298 * 299 * @param integer $row The row to set 300 * @param integer $height Height we are giving to the row (null to set just format without setting the height) 301 * @param mixed $format The optional format we are giving to the row 302 * @param bool $hidden The optional hidden attribute 303 * @param integer $level The optional outline level (0-7) 304 */ 305 public function set_row($row, $height, $format = null, $hidden = false, $level = 0) { 306 if (is_array($format)) { 307 $format = new MoodleODSFormat($format); 308 } 309 if ($level < 0) { 310 $level = 0; 311 } else if ($level > 7) { 312 $level = 7; 313 } 314 if (!isset($this->rows[$row])) { 315 $this->rows[$row] = new stdClass(); 316 } 317 if (isset($height)) { 318 $this->rows[$row]->height = $height; 319 } 320 $this->rows[$row]->format = $format; 321 $this->rows[$row]->hidden = $hidden; 322 $this->rows[$row]->level = $level; 323 } 324 325 /** 326 * Sets the width (and other settings) of one column. 327 * 328 * @param integer $firstcol first column on the range 329 * @param integer $lastcol last column on the range 330 * @param integer $width width to set (null to set just format without setting the width) 331 * @param mixed $format The optional format to apply to the columns 332 * @param bool $hidden The optional hidden attribute 333 * @param integer $level The optional outline level (0-7) 334 */ 335 public function set_column($firstcol, $lastcol, $width, $format = null, $hidden = false, $level = 0) { 336 if (is_array($format)) { 337 $format = new MoodleODSFormat($format); 338 } 339 if ($level < 0) { 340 $level = 0; 341 } else if ($level > 7) { 342 $level = 7; 343 } 344 for($i=$firstcol; $i<=$lastcol; $i++) { 345 if (!isset($this->columns[$i])) { 346 $this->columns[$i] = new stdClass(); 347 } 348 if (isset($width)) { 349 $this->columns[$i]->width = $width*6.15; // 6.15 is a magic constant here! 350 } 351 $this->columns[$i]->format = $format; 352 $this->columns[$i]->hidden = $hidden; 353 $this->columns[$i]->level = $level; 354 } 355 } 356 357 /** 358 * Set the option to hide gridlines on the printed page. 359 */ 360 public function hide_gridlines() { 361 // Not implemented - always off. 362 } 363 364 /** 365 * Set the option to hide gridlines on the worksheet (as seen on the screen). 366 */ 367 public function hide_screen_gridlines() { 368 $this->showgrid = false; 369 } 370 371 /** 372 * Insert a 24bit bitmap image in a worksheet. 373 * 374 * @param integer $row The row we are going to insert the bitmap into 375 * @param integer $col The column we are going to insert the bitmap into 376 * @param string $bitmap The bitmap filename 377 * @param integer $x The horizontal position (offset) of the image inside the cell. 378 * @param integer $y The vertical position (offset) of the image inside the cell. 379 * @param integer $scale_x The horizontal scale 380 * @param integer $scale_y The vertical scale 381 */ 382 public function insert_bitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) { 383 // Not implemented. 384 } 385 386 /** 387 * Merges the area given by its arguments. 388 * 389 * @param integer $first_row First row of the area to merge 390 * @param integer $first_col First column of the area to merge 391 * @param integer $last_row Last row of the area to merge 392 * @param integer $last_col Last column of the area to merge 393 */ 394 public function merge_cells($first_row, $first_col, $last_row, $last_col) { 395 if ($first_row > $last_row or $first_col > $last_col) { 396 return; 397 } 398 399 if (!isset($this->data[$first_row][$first_col])) { 400 $this->data[$first_row][$first_col] = new MoodleODSCell(); 401 } 402 403 $this->data[$first_row][$first_col]->merge = array('rows'=>($last_row-$first_row+1), 'columns'=>($last_col-$first_col+1)); 404 } 405 } 406 407 408 /** 409 * ODS cell format abstraction. 410 * 411 * @package core 412 * @copyright 2006 Petr Skoda {@link http://skodak.org} 413 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 414 */ 415 class MoodleODSFormat { 416 public $id; 417 public $properties = array(); 418 419 /** 420 * Constructs one Moodle Format. 421 * 422 * @param array $properties 423 */ 424 public function __construct($properties = array()) { 425 static $fid = 1; 426 427 $this->id = $fid++; 428 429 foreach($properties as $property => $value) { 430 if (method_exists($this, "set_$property")) { 431 $aux = 'set_'.$property; 432 $this->$aux($value); 433 } 434 } 435 } 436 437 /** 438 * Set the size of the text in the format (in pixels). 439 * By default all texts in generated sheets are 10pt. 440 * 441 * @param integer $size Size of the text (in points) 442 */ 443 public function set_size($size) { 444 $this->properties['size'] = $size; 445 } 446 447 /** 448 * Set weight of the format. 449 * 450 * @param integer $weight Weight for the text, 0 maps to 400 (normal text), 451 * 1 maps to 700 (bold text). Valid range is: 100-1000. 452 * It's Optional, default is 1 (bold). 453 */ 454 public function set_bold($weight = 1) { 455 if ($weight == 1) { 456 $weight = 700; 457 } 458 $this->properties['bold'] = ($weight > 400); 459 } 460 461 /** 462 * Set underline of the format. 463 * 464 * @param integer $underline The value for underline. Possible values are: 465 * 1 => underline, 2 => double underline 466 */ 467 public function set_underline($underline = 1) { 468 if ($underline == 1) { 469 $this->properties['underline'] = 1; 470 } else if ($underline == 2) { 471 $this->properties['underline'] = 2; 472 } else { 473 unset($this->properties['underline']); 474 } 475 } 476 477 /** 478 * Set italic of the format. 479 */ 480 public function set_italic() { 481 $this->properties['italic'] = true; 482 } 483 484 /** 485 * Set strikeout of the format 486 */ 487 public function set_strikeout() { 488 $this->properties['strikeout'] = true; 489 } 490 491 /** 492 * Set outlining of the format. 493 */ 494 public function set_outline() { 495 // Not implemented. 496 } 497 498 /** 499 * Set shadow of the format. 500 */ 501 public function set_shadow() { 502 // Not implemented. 503 } 504 505 /** 506 * Set the script of the text. 507 * 508 * @param integer $script The value for script type. Possible values are: 509 * 1 => superscript, 2 => subscript 510 */ 511 public function set_script($script) { 512 if ($script == 1) { 513 $this->properties['super_script'] = true; 514 unset($this->properties['sub_script']); 515 516 } else if ($script == 2) { 517 $this->properties['sub_script'] = true; 518 unset($this->properties['super_script']); 519 520 } else { 521 unset($this->properties['sub_script']); 522 unset($this->properties['super_script']); 523 } 524 } 525 526 /** 527 * Set color of the format. 528 * 529 * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]) 530 */ 531 public function set_color($color) { 532 $this->properties['color'] = $this->parse_color($color); 533 } 534 535 /** 536 * Not used. 537 * 538 * @param mixed $color 539 */ 540 public function set_fg_color($color) { 541 // Not implemented. 542 } 543 544 /** 545 * Set background color of the cell. 546 * 547 * @param mixed $color either a string (like 'blue'), or an integer (range is [8...63]) 548 */ 549 public function set_bg_color($color) { 550 $this->properties['bg_color'] = $this->parse_color($color); 551 } 552 553 /** 554 * Set the cell fill pattern. 555 * 556 * @deprecated use set_bg_color() instead. 557 * @param integer 558 */ 559 public function set_pattern($pattern=1) { 560 if ($pattern > 0) { 561 if (!isset($this->properties['bg_color'])) { 562 $this->properties['bg_color'] = $this->parse_color('black'); 563 } 564 } else { 565 unset($this->properties['bg_color']); 566 } 567 568 } 569 570 /** 571 * Set text wrap of the format 572 */ 573 public function set_text_wrap() { 574 $this->properties['wrap'] = true; 575 } 576 577 /** 578 * Set the cell alignment of the format. 579 * 580 * @param string $location alignment for the cell ('left', 'right', 'justify', etc...) 581 */ 582 public function set_align($location) { 583 if (in_array($location, array('left', 'centre', 'center', 'right', 'fill', 'merge', 'justify', 'equal_space'))) { 584 $this->set_h_align($location); 585 586 } else if (in_array($location, array('top', 'vcentre', 'vcenter', 'bottom', 'vjustify', 'vequal_space'))) { 587 $this->set_v_align($location); 588 } 589 } 590 591 /** 592 * Set the cell horizontal alignment of the format. 593 * 594 * @param string $location alignment for the cell ('left', 'right', 'justify', etc...) 595 */ 596 public function set_h_align($location) { 597 switch ($location) { 598 case 'left': 599 $this->properties['align'] = 'start'; 600 break; 601 case 'center': 602 case 'centre': 603 $this->properties['align'] = 'center'; 604 break; 605 case 'right': 606 $this->properties['align'] = 'end'; 607 break; 608 } 609 } 610 611 /** 612 * Set the cell vertical alignment of the format. 613 * 614 * @param string $location alignment for the cell ('top', 'bottom', 'center', 'justify') 615 */ 616 public function set_v_align($location) { 617 switch ($location) { 618 case 'top': 619 $this->properties['v_align'] = 'top'; 620 break; 621 case 'vcentre': 622 case 'vcenter': 623 case 'centre': 624 case 'center': 625 $this->properties['v_align'] = 'middle'; 626 break; 627 default: 628 $this->properties['v_align'] = 'bottom'; 629 } 630 } 631 632 /** 633 * Set the top border of the format. 634 * 635 * @param integer $style style for the cell. 1 => thin, 2 => thick 636 */ 637 public function set_top($style) { 638 if ($style == 1) { 639 $style = 0.2; 640 } else if ($style == 2) { 641 $style = 0.5; 642 } else { 643 return; 644 } 645 $this->properties['border_top'] = $style; 646 } 647 648 /** 649 * Set the bottom border of the format. 650 * 651 * @param integer $style style for the cell. 1 => thin, 2 => thick 652 */ 653 public function set_bottom($style) { 654 if ($style == 1) { 655 $style = 0.2; 656 } else if ($style == 2) { 657 $style = 0.5; 658 } else { 659 return; 660 } 661 $this->properties['border_bottom'] = $style; 662 } 663 664 /** 665 * Set the left border of the format. 666 * 667 * @param integer $style style for the cell. 1 => thin, 2 => thick 668 */ 669 public function set_left($style) { 670 if ($style == 1) { 671 $style = 0.2; 672 } else if ($style == 2) { 673 $style = 0.5; 674 } else { 675 return; 676 } 677 $this->properties['border_left'] = $style; 678 } 679 680 /** 681 * Set the right border of the format. 682 * 683 * @param integer $style style for the cell. 1 => thin, 2 => thick 684 */ 685 public function set_right($style) { 686 if ($style == 1) { 687 $style = 0.2; 688 } else if ($style == 2) { 689 $style = 0.5; 690 } else { 691 return; 692 } 693 $this->properties['border_right'] = $style; 694 } 695 696 /** 697 * Set cells borders to the same style 698 * @param integer $style style to apply for all cell borders. 1 => thin, 2 => thick. 699 */ 700 public function set_border($style) { 701 $this->set_top($style); 702 $this->set_bottom($style); 703 $this->set_left($style); 704 $this->set_right($style); 705 } 706 707 /** 708 * Set the numerical format of the format. 709 * It can be date, time, currency, etc... 710 * 711 * @param mixed $num_format The numeric format 712 */ 713 public function set_num_format($num_format) { 714 715 $numbers = array(); 716 717 $numbers[1] = '0'; 718 $numbers[2] = '0.00'; 719 $numbers[3] = '#,##0'; 720 $numbers[4] = '#,##0.00'; 721 $numbers[11] = '0.00E+00'; 722 $numbers[12] = '# ?/?'; 723 $numbers[13] = '# ??/??'; 724 $numbers[14] = 'mm-dd-yy'; 725 $numbers[15] = 'd-mmm-yy'; 726 $numbers[16] = 'd-mmm'; 727 $numbers[17] = 'mmm-yy'; 728 $numbers[22] = 'm/d/yy h:mm'; 729 $numbers[49] = '@'; 730 731 if ($num_format !== 0 and in_array($num_format, $numbers)) { 732 $flipped = array_flip($numbers); 733 $this->properties['num_format'] = $flipped[$num_format]; 734 } 735 if (!isset($numbers[$num_format])) { 736 return; 737 } 738 739 $this->properties['num_format'] = $num_format; 740 } 741 742 /** 743 * Standardise colour name. 744 * 745 * @param mixed $color name of the color (i.e.: 'blue', 'red', etc..), or an integer (range is [8...63]). 746 * @return string the RGB color value 747 */ 748 protected function parse_color($color) { 749 if (strpos($color, '#') === 0) { 750 // No conversion should be needed. 751 return $color; 752 } 753 754 if ($color > 7 and $color < 53) { 755 $numbers = array( 756 8 => 'black', 757 12 => 'blue', 758 16 => 'brown', 759 15 => 'cyan', 760 23 => 'gray', 761 17 => 'green', 762 11 => 'lime', 763 14 => 'magenta', 764 18 => 'navy', 765 53 => 'orange', 766 33 => 'pink', 767 20 => 'purple', 768 10 => 'red', 769 22 => 'silver', 770 9 => 'white', 771 13 => 'yellow', 772 ); 773 if (isset($numbers[$color])) { 774 $color = $numbers[$color]; 775 } else { 776 $color = 'black'; 777 } 778 } 779 780 $colors = array( 781 'aqua' => '00FFFF', 782 'black' => '000000', 783 'blue' => '0000FF', 784 'brown' => 'A52A2A', 785 'cyan' => '00FFFF', 786 'fuchsia' => 'FF00FF', 787 'gray' => '808080', 788 'grey' => '808080', 789 'green' => '00FF00', 790 'lime' => '00FF00', 791 'magenta' => 'FF00FF', 792 'maroon' => '800000', 793 'navy' => '000080', 794 'orange' => 'FFA500', 795 'olive' => '808000', 796 'pink' => 'FAAFBE', 797 'purple' => '800080', 798 'red' => 'FF0000', 799 'silver' => 'C0C0C0', 800 'teal' => '008080', 801 'white' => 'FFFFFF', 802 'yellow' => 'FFFF00', 803 ); 804 805 if (isset($colors[$color])) { 806 return('#'.$colors[$color]); 807 } 808 809 return('#'.$colors['black']); 810 } 811 } 812 813 814 /** 815 * ODS file writer. 816 * 817 * @package core 818 * @copyright 2013 Petr Skoda {@link http://skodak.org} 819 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 820 */ 821 class MoodleODSWriter { 822 protected $worksheets; 823 824 public function __construct(array $worksheets) { 825 $this->worksheets = $worksheets; 826 } 827 828 public function get_file_content() { 829 global $CFG; 830 831 require_once($CFG->libdir.'/filelib.php'); 832 833 do { 834 $dir = 'ods/'.time().'_'.rand(0, 10000); 835 } while (file_exists($CFG->tempdir.'/'.$dir)); 836 837 make_temp_directory($dir); 838 make_temp_directory($dir.'/META-INF'); 839 $dir = "$CFG->tempdir/$dir"; 840 $files = array(); 841 842 $handle = fopen("$dir/mimetype", 'w'); 843 fwrite($handle, $this->get_ods_mimetype()); 844 $files[] = "$dir/mimetype"; 845 846 $handle = fopen("$dir/content.xml", 'w'); 847 fwrite($handle, $this->get_ods_content($this->worksheets)); 848 $files[] = "$dir/content.xml"; 849 850 $handle = fopen("$dir/meta.xml", 'w'); 851 fwrite($handle, $this->get_ods_meta()); 852 $files[] = "$dir/meta.xml"; 853 854 $handle = fopen("$dir/styles.xml", 'w'); 855 fwrite($handle, $this->get_ods_styles()); 856 $files[] = "$dir/styles.xml"; 857 858 $handle = fopen("$dir/settings.xml", 'w'); 859 fwrite($handle, $this->get_ods_settings()); 860 $files[] = "$dir/settings.xml"; 861 862 $handle = fopen("$dir/META-INF/manifest.xml", 'w'); 863 fwrite($handle, $this->get_ods_manifest()); 864 $files[] = "$dir/META-INF"; 865 866 $filename = "$dir/result.ods"; 867 zip_files($files, $filename); 868 869 $handle = fopen($filename, 'rb'); 870 $contents = fread($handle, filesize($filename)); 871 fclose($handle); 872 873 remove_dir($dir); // Cleanup the temp directory. 874 875 return $contents; 876 } 877 878 protected function get_ods_content() { 879 880 // Find out the size of worksheets and used styles. 881 $formats = array(); 882 $formatstyles = ''; 883 $rowstyles = ''; 884 $colstyles = ''; 885 886 foreach($this->worksheets as $wsnum=>$ws) { 887 $this->worksheets[$wsnum]->maxr = 0; 888 $this->worksheets[$wsnum]->maxc = 0; 889 foreach($ws->data as $rnum=>$row) { 890 if ($rnum > $this->worksheets[$wsnum]->maxr) { 891 $this->worksheets[$wsnum]->maxr = $rnum; 892 } 893 foreach($row as $cnum=>$cell) { 894 if ($cnum > $this->worksheets[$wsnum]->maxc) { 895 $this->worksheets[$wsnum]->maxc = $cnum; 896 } 897 if (!empty($cell->format)) { 898 if (!array_key_exists($cell->format->id, $formats)) { 899 $formats[$cell->format->id] = $cell->format; 900 } 901 } 902 } 903 } 904 905 foreach($ws->rows as $rnum=>$row) { 906 if (!empty($row->format)) { 907 if (!array_key_exists($row->format->id, $formats)) { 908 $formats[$row->format->id] = $row->format; 909 } 910 } 911 if ($rnum > $this->worksheets[$wsnum]->maxr) { 912 $this->worksheets[$wsnum]->maxr = $rnum; 913 } 914 // Define all column styles. 915 if (!empty($ws->rows[$rnum])) { 916 $rowstyles .= '<style:style style:name="ws'.$wsnum.'ro'.$rnum.'" style:family="table-row">'; 917 if (isset($row->height)) { 918 $rowstyles .= '<style:table-row-properties style:row-height="'.$row->height.'pt"/>'; 919 } 920 $rowstyles .= '</style:style>'; 921 } 922 } 923 924 foreach($ws->columns as $cnum=>$col) { 925 if (!empty($col->format)) { 926 if (!array_key_exists($col->format->id, $formats)) { 927 $formats[$col->format->id] = $col->format; 928 } 929 } 930 if ($cnum > $this->worksheets[$wsnum]->maxc) { 931 $this->worksheets[$wsnum]->maxc = $cnum; 932 } 933 // Define all column styles. 934 if (!empty($ws->columns[$cnum])) { 935 $colstyles .= '<style:style style:name="ws'.$wsnum.'co'.$cnum.'" style:family="table-column">'; 936 if (isset($col->width)) { 937 $colstyles .= '<style:table-column-properties style:column-width="'.$col->width.'pt"/>'; 938 } 939 $colstyles .= '</style:style>'; 940 } 941 } 942 } 943 944 foreach($formats as $format) { 945 $textprop = ''; 946 $cellprop = ''; 947 $parprop = ''; 948 $dataformat = ''; 949 foreach($format->properties as $pname=>$pvalue) { 950 switch ($pname) { 951 case 'size': 952 if (!empty($pvalue)) { 953 $textprop .= ' fo:font-size="'.$pvalue.'pt"'; 954 } 955 break; 956 case 'bold': 957 if (!empty($pvalue)) { 958 $textprop .= ' fo:font-weight="bold"'; 959 } 960 break; 961 case 'italic': 962 if (!empty($pvalue)) { 963 $textprop .= ' fo:font-style="italic"'; 964 } 965 break; 966 case 'underline': 967 if (!empty($pvalue)) { 968 $textprop .= ' style:text-underline-color="font-color" style:text-underline-style="solid" style:text-underline-width="auto"'; 969 if ($pvalue == 2) { 970 $textprop .= ' style:text-underline-type="double"'; 971 } 972 } 973 break; 974 case 'strikeout': 975 if (!empty($pvalue)) { 976 $textprop .= ' style:text-line-through-style="solid"'; 977 } 978 break; 979 case 'color': 980 if ($pvalue !== false) { 981 $textprop .= ' fo:color="'.$pvalue.'"'; 982 } 983 break; 984 case 'bg_color': 985 if ($pvalue !== false) { 986 $cellprop .= ' fo:background-color="'.$pvalue.'"'; 987 } 988 break; 989 case 'align': 990 $parprop .= ' fo:text-align="'.$pvalue.'"'; 991 break; 992 case 'v_align': 993 $cellprop .= ' style:vertical-align="'.$pvalue.'"'; 994 break; 995 case 'wrap': 996 if ($pvalue) { 997 $cellprop .= ' fo:wrap-option="wrap"'; 998 } 999 break; 1000 case 'border_top': 1001 $cellprop .= ' fo:border-top="'.$pvalue.'pt solid #000000"'; 1002 break; 1003 case 'border_left': 1004 $cellprop .= ' fo:border-left="'.$pvalue.'pt solid #000000"'; 1005 break; 1006 case 'border_bottom': 1007 $cellprop .= ' fo:border-bottom="'.$pvalue.'pt solid #000000"'; 1008 break; 1009 case 'border_right': 1010 $cellprop .= ' fo:border-right="'.$pvalue.'pt solid #000000"'; 1011 break; 1012 case 'num_format': 1013 $dataformat = ' style:data-style-name="NUM'.$pvalue.'"'; 1014 break; 1015 } 1016 } 1017 if (!empty($textprop)) { 1018 $textprop = ' 1019 <style:text-properties'.$textprop.'/>'; 1020 } 1021 1022 if (!empty($cellprop)) { 1023 $cellprop = ' 1024 <style:table-cell-properties'.$cellprop.'/>'; 1025 } 1026 1027 if (!empty($parprop)) { 1028 $parprop = ' 1029 <style:paragraph-properties'.$parprop.'/>'; 1030 } 1031 1032 $formatstyles .= ' 1033 <style:style style:name="format'.$format->id.'" style:family="table-cell"'.$dataformat.'>'.$textprop.$cellprop.$parprop.' 1034 </style:style>'; 1035 } 1036 1037 // The text styles may be breaking older ODF validators. 1038 $scriptstyles =' 1039 <style:style style:name="T1" style:family="text"> 1040 <style:text-properties style:text-position="33% 58%"/> 1041 </style:style> 1042 <style:style style:name="T2" style:family="text"> 1043 <style:text-properties style:text-position="-33% 58%"/> 1044 </style:style> 1045 '; 1046 // Header. 1047 $buffer = 1048 '<?xml version="1.0" encoding="UTF-8"?> 1049 <office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 1050 xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 1051 xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 1052 xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 1053 xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 1054 xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 1055 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" 1056 xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 1057 xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 1058 xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" 1059 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 1060 xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 1061 xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 1062 xmlns:math="http://www.w3.org/1998/Math/MathML" 1063 xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 1064 xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 1065 xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" 1066 xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" 1067 xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 1068 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 1069 xmlns:rpt="http://openoffice.org/2005/report" 1070 xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 1071 xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" 1072 xmlns:tableooo="http://openoffice.org/2009/table" 1073 xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 1074 xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 1075 xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" 1076 xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"> 1077 <office:scripts/> 1078 <office:font-face-decls> 1079 <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" 1080 style:font-pitch="variable"/> 1081 <style:font-face style:name="Arial Unicode MS" svg:font-family="'Arial Unicode MS'" 1082 style:font-family-generic="system" style:font-pitch="variable"/> 1083 <style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" 1084 style:font-pitch="variable"/> 1085 </office:font-face-decls> 1086 <office:automatic-styles>'; 1087 $buffer .= $this->get_num_styles(); 1088 $buffer .= ' 1089 <style:style style:name="ta1" style:family="table" style:master-page-name="Standard1"> 1090 <style:table-properties table:display="true"/> 1091 </style:style>'; 1092 1093 $buffer .= $formatstyles; 1094 $buffer .= $rowstyles; 1095 $buffer .= $colstyles; 1096 $buffer .= $scriptstyles; 1097 1098 $buffer .= ' 1099 </office:automatic-styles> 1100 <office:body> 1101 <office:spreadsheet> 1102 '; 1103 1104 foreach($this->worksheets as $wsnum=>$ws) { 1105 1106 // Worksheet header. 1107 $buffer .= '<table:table table:name="' . htmlspecialchars($ws->name, ENT_QUOTES, 'utf-8') . '" table:style-name="ta1">'."\n"; 1108 1109 // Define column properties. 1110 $level = 0; 1111 for($c=0; $c<=$ws->maxc; $c++) { 1112 if (array_key_exists($c, $ws->columns)) { 1113 $column = $ws->columns[$c]; 1114 if ($column->level > $level) { 1115 while ($column->level > $level) { 1116 $buffer .= '<table:table-column-group>'; 1117 $level++; 1118 } 1119 } else if ($column->level < $level) { 1120 while ($column->level < $level) { 1121 $buffer .= '</table:table-column-group>'; 1122 $level--; 1123 } 1124 } 1125 $extra = ''; 1126 if (!empty($column->format)) { 1127 $extra .= ' table:default-cell-style-name="format'.$column->format->id.'"'; 1128 } 1129 if ($column->hidden) { 1130 $extra .= ' table:visibility="collapse"'; 1131 } 1132 $buffer .= '<table:table-column table:style-name="ws'.$wsnum.'co'.$c.'"'.$extra.'/>'."\n"; 1133 } else { 1134 while ($level > 0) { 1135 $buffer .= '</table:table-column-group>'; 1136 $level--; 1137 } 1138 $buffer .= '<table:table-column/>'."\n"; 1139 } 1140 } 1141 while ($level > 0) { 1142 $buffer .= '</table:table-column-group>'; 1143 $level--; 1144 } 1145 1146 // Print all rows. 1147 $level = 0; 1148 for($r=0; $r<=$ws->maxr; $r++) { 1149 if (array_key_exists($r, $ws->rows)) { 1150 $row = $ws->rows[$r]; 1151 if ($row->level > $level) { 1152 while ($row->level > $level) { 1153 $buffer .= '<table:table-row-group>'; 1154 $level++; 1155 } 1156 } else if ($row->level < $level) { 1157 while ($row->level < $level) { 1158 $buffer .= '</table:table-row-group>'; 1159 $level--; 1160 } 1161 } 1162 $extra = ''; 1163 if (!empty($row->format)) { 1164 $extra .= ' table:default-cell-style-name="format'.$row->format->id.'"'; 1165 } 1166 if ($row->hidden) { 1167 $extra .= ' table:visibility="collapse"'; 1168 } 1169 $buffer .= '<table:table-row table:style-name="ws'.$wsnum.'ro'.$r.'"'.$extra.'>'."\n"; 1170 } else { 1171 while ($level > 0) { 1172 $buffer .= '</table:table-row-group>'; 1173 $level--; 1174 } 1175 $buffer .= '<table:table-row>'."\n"; 1176 } 1177 for($c=0; $c<=$ws->maxc; $c++) { 1178 if (isset($ws->data[$r][$c])) { 1179 $cell = $ws->data[$r][$c]; 1180 $extra = ''; 1181 if (!empty($cell->format)) { 1182 $extra .= ' table:style-name="format'.$cell->format->id.'"'; 1183 } 1184 if (!empty($cell->merge)) { 1185 $extra .= ' table:number-columns-spanned="'.$cell->merge['columns'].'" table:number-rows-spanned="'.$cell->merge['rows'].'"'; 1186 } 1187 $pretext = '<text:p>'; 1188 $posttext = '</text:p>'; 1189 if (!empty($cell->format->properties['sub_script'])) { 1190 $pretext = $pretext.'<text:span text:style-name="T2">'; 1191 $posttext = '</text:span>'.$posttext; 1192 } else if (!empty($cell->format->properties['super_script'])) { 1193 $pretext = $pretext.'<text:span text:style-name="T1">'; 1194 $posttext = '</text:span>'.$posttext; 1195 } 1196 1197 if (isset($cell->formula)) { 1198 $buffer .= '<table:table-cell table:formula="of:'.$cell->formula.'"'.$extra.'></table:table-cell>'."\n"; 1199 } else if ($cell->type == 'date') { 1200 $buffer .= '<table:table-cell office:value-type="date" office:date-value="' . strftime('%Y-%m-%dT%H:%M:%S', $cell->value) . '"'.$extra.'>' 1201 . $pretext . strftime('%Y-%m-%dT%H:%M:%S', $cell->value) . $posttext 1202 . '</table:table-cell>'."\n"; 1203 } else if ($cell->type == 'float') { 1204 $buffer .= '<table:table-cell office:value-type="float" office:value="' . htmlspecialchars($cell->value, ENT_QUOTES, 'utf-8') . '"'.$extra.'>' 1205 . $pretext . htmlspecialchars($cell->value, ENT_QUOTES, 'utf-8') . $posttext 1206 . '</table:table-cell>'."\n"; 1207 } else if ($cell->type == 'string') { 1208 $buffer .= '<table:table-cell office:value-type="string"'.$extra.'>' 1209 . $pretext . htmlspecialchars($cell->value, ENT_QUOTES, 'utf-8') . $posttext 1210 . '</table:table-cell>'."\n"; 1211 } else { 1212 $buffer .= '<table:table-cell office:value-type="string"'.$extra.'>' 1213 . $pretext . '!!Error - unknown type!!' . $posttext 1214 . '</table:table-cell>'."\n"; 1215 } 1216 } else { 1217 $buffer .= '<table:table-cell/>'."\n"; 1218 } 1219 } 1220 $buffer .= '</table:table-row>'."\n"; 1221 } 1222 while ($level > 0) { 1223 $buffer .= '</table:table-row-group>'; 1224 $level--; 1225 } 1226 $buffer .= '</table:table>'."\n"; 1227 1228 } 1229 1230 // Footer. 1231 $buffer .= ' 1232 </office:spreadsheet> 1233 </office:body> 1234 </office:document-content>'; 1235 1236 return $buffer; 1237 } 1238 1239 public function get_ods_mimetype() { 1240 return 'application/vnd.oasis.opendocument.spreadsheet'; 1241 } 1242 1243 protected function get_ods_settings() { 1244 $buffer = 1245 '<?xml version="1.0" encoding="UTF-8"?> 1246 <office:document-settings xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 1247 xmlns:xlink="http://www.w3.org/1999/xlink" 1248 xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 1249 xmlns:ooo="http://openoffice.org/2004/office" office:version="1.2"> 1250 <office:settings> 1251 <config:config-item-set config:name="ooo:view-settings"> 1252 <config:config-item config:name="VisibleAreaTop" config:type="int">0</config:config-item> 1253 <config:config-item config:name="VisibleAreaLeft" config:type="int">0</config:config-item> 1254 <config:config-item-map-indexed config:name="Views"> 1255 <config:config-item-map-entry> 1256 <config:config-item config:name="ViewId" config:type="string">view1</config:config-item> 1257 <config:config-item-map-named config:name="Tables"> 1258 '; 1259 foreach ($this->worksheets as $ws) { 1260 $buffer .= ' <config:config-item-map-entry config:name="'.htmlspecialchars($ws->name, ENT_QUOTES, 'utf-8').'">'."\n"; 1261 $buffer .= ' <config:config-item config:name="ShowGrid" config:type="boolean">'.($ws->showgrid ? 'true' : 'false').'</config:config-item>'."\n"; 1262 $buffer .= ' </config:config-item-map-entry>."\n"'; 1263 } 1264 $buffer .= 1265 ' </config:config-item-map-named> 1266 </config:config-item-map-entry> 1267 </config:config-item-map-indexed> 1268 </config:config-item-set> 1269 <config:config-item-set config:name="ooo:configuration-settings"> 1270 <config:config-item config:name="ShowGrid" config:type="boolean">true</config:config-item> 1271 </config:config-item-set> 1272 </office:settings> 1273 </office:document-settings>'; 1274 1275 return $buffer; 1276 } 1277 protected function get_ods_meta() { 1278 global $CFG, $USER; 1279 1280 return 1281 '<?xml version="1.0" encoding="UTF-8"?> 1282 <office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 1283 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" 1284 xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 1285 xmlns:ooo="http://openoffice.org/2004/office" xmlns:grddl="http://www.w3.org/2003/g/data-view#" 1286 office:version="1.2"> 1287 <office:meta> 1288 <meta:generator>Moodle '.$CFG->release.'</meta:generator> 1289 <meta:initial-creator>'.fullname($USER, true).'</meta:initial-creator> 1290 <meta:creation-date>'.strftime('%Y-%m-%dT%H:%M:%S').'</meta:creation-date> 1291 <meta:document-statistic meta:table-count="1" meta:cell-count="0" meta:object-count="0"/> 1292 </office:meta> 1293 </office:document-meta>'; 1294 } 1295 1296 protected function get_ods_styles() { 1297 return 1298 '<?xml version="1.0" encoding="UTF-8"?> 1299 <office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 1300 xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 1301 xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 1302 xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 1303 xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 1304 xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 1305 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" 1306 xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 1307 xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 1308 xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" 1309 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 1310 xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 1311 xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 1312 xmlns:math="http://www.w3.org/1998/Math/MathML" 1313 xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 1314 xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 1315 xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" 1316 xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" 1317 xmlns:rpt="http://openoffice.org/2005/report" 1318 xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 1319 xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" 1320 xmlns:tableooo="http://openoffice.org/2009/table" 1321 xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 1322 xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"> 1323 <office:font-face-decls> 1324 <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" 1325 style:font-pitch="variable"/> 1326 <style:font-face style:name="Arial Unicode MS" svg:font-family="'Arial Unicode MS'" 1327 style:font-family-generic="system" style:font-pitch="variable"/> 1328 <style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system" 1329 style:font-pitch="variable"/> 1330 </office:font-face-decls> 1331 <office:styles> 1332 <style:default-style style:family="table-cell"> 1333 <style:paragraph-properties style:tab-stop-distance="1.25cm"/> 1334 </style:default-style> 1335 <number:number-style style:name="N0"> 1336 <number:number number:min-integer-digits="1"/> 1337 </number:number-style> 1338 <style:style style:name="Default" style:family="table-cell"> 1339 <style:text-properties style:font-name-asian="Arial Unicode MS" style:font-name-complex="Arial Unicode MS"/> 1340 </style:style> 1341 <style:style style:name="Result" style:family="table-cell" style:parent-style-name="Default"> 1342 <style:text-properties fo:font-style="italic" style:text-underline-style="solid" 1343 style:text-underline-width="auto" style:text-underline-color="font-color" 1344 fo:font-weight="bold"/> 1345 </style:style> 1346 <style:style style:name="Result2" style:family="table-cell" style:parent-style-name="Result" 1347 style:data-style-name="N104"/> 1348 <style:style style:name="Heading" style:family="table-cell" style:parent-style-name="Default"> 1349 <style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/> 1350 <style:paragraph-properties fo:text-align="center"/> 1351 <style:text-properties fo:font-size="16pt" fo:font-style="italic" fo:font-weight="bold"/> 1352 </style:style> 1353 <style:style style:name="Heading1" style:family="table-cell" style:parent-style-name="Heading"> 1354 <style:table-cell-properties style:rotation-angle="90"/> 1355 </style:style> 1356 </office:styles> 1357 <office:automatic-styles> 1358 <style:page-layout style:name="Mpm1"> 1359 <style:page-layout-properties style:writing-mode="lr-tb"/> 1360 <style:header-style> 1361 <style:header-footer-properties fo:min-height="0.75cm" fo:margin-left="0cm" fo:margin-right="0cm" 1362 fo:margin-bottom="0.25cm"/> 1363 </style:header-style> 1364 <style:footer-style> 1365 <style:header-footer-properties fo:min-height="0.75cm" fo:margin-left="0cm" fo:margin-right="0cm" 1366 fo:margin-top="0.25cm"/> 1367 </style:footer-style> 1368 </style:page-layout> 1369 <style:page-layout style:name="Mpm2"> 1370 <style:page-layout-properties style:writing-mode="lr-tb"/> 1371 <style:header-style> 1372 <style:header-footer-properties fo:min-height="0.75cm" fo:margin-left="0cm" fo:margin-right="0cm" 1373 fo:margin-bottom="0.25cm" fo:border="2.49pt solid #000000" 1374 fo:padding="0.018cm" fo:background-color="#c0c0c0"> 1375 <style:background-image/> 1376 </style:header-footer-properties> 1377 </style:header-style> 1378 <style:footer-style> 1379 <style:header-footer-properties fo:min-height="0.75cm" fo:margin-left="0cm" fo:margin-right="0cm" 1380 fo:margin-top="0.25cm" fo:border="2.49pt solid #000000" 1381 fo:padding="0.018cm" fo:background-color="#c0c0c0"> 1382 <style:background-image/> 1383 </style:header-footer-properties> 1384 </style:footer-style> 1385 </style:page-layout> 1386 </office:automatic-styles> 1387 <office:master-styles> 1388 <style:master-page style:name="Default" style:page-layout-name="Mpm1"> 1389 <style:header> 1390 <text:p> 1391 <text:sheet-name>???</text:sheet-name> 1392 </text:p> 1393 </style:header> 1394 <style:header-left style:display="false"/> 1395 <style:footer> 1396 <text:p>Page 1397 <text:page-number>1</text:page-number> 1398 </text:p> 1399 </style:footer> 1400 <style:footer-left style:display="false"/> 1401 </style:master-page> 1402 <style:master-page style:name="Report" style:page-layout-name="Mpm2"> 1403 <style:header> 1404 <style:region-left> 1405 <text:p> 1406 <text:sheet-name>???</text:sheet-name> 1407 (<text:title>???</text:title>) 1408 </text:p> 1409 </style:region-left> 1410 <style:region-right> 1411 <text:p><text:date style:data-style-name="N2" text:date-value="2013-01-05">00.00.0000</text:date>, 1412 <text:time>00:00:00</text:time> 1413 </text:p> 1414 </style:region-right> 1415 </style:header> 1416 <style:header-left style:display="false"/> 1417 <style:footer> 1418 <text:p>Page 1419 <text:page-number>1</text:page-number> 1420 / 1421 <text:page-count>99</text:page-count> 1422 </text:p> 1423 </style:footer> 1424 <style:footer-left style:display="false"/> 1425 </style:master-page> 1426 </office:master-styles> 1427 </office:document-styles>'; 1428 } 1429 1430 protected function get_ods_manifest() { 1431 return 1432 '<?xml version="1.0" encoding="UTF-8"?> 1433 <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2"> 1434 <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/> 1435 <manifest:file-entry manifest:full-path="meta.xml" manifest:media-type="text/xml"/> 1436 <manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/> 1437 <manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/> 1438 <manifest:file-entry manifest:full-path="settings.xml" manifest:media-type="text/xml"/> 1439 </manifest:manifest>'; 1440 } 1441 1442 protected function get_num_styles() { 1443 return ' 1444 <number:number-style style:name="NUM1"> 1445 <number:number number:decimal-places="0" number:min-integer-digits="1"/> 1446 </number:number-style> 1447 <number:number-style style:name="NUM2"> 1448 <number:number number:decimal-places="2" number:min-integer-digits="1"/> 1449 </number:number-style> 1450 <number:number-style style:name="NUM3"> 1451 <number:number number:decimal-places="0" number:min-integer-digits="1" number:grouping="true"/> 1452 </number:number-style> 1453 <number:number-style style:name="NUM4"> 1454 <number:number number:decimal-places="2" number:min-integer-digits="1" number:grouping="true"/> 1455 </number:number-style> 1456 <number:number-style style:name="NUM11"> 1457 <number:scientific-number number:decimal-places="2" number:min-integer-digits="1" 1458 number:min-exponent-digits="2"/> 1459 </number:number-style> 1460 <number:number-style style:name="NUM12"> 1461 <number:fraction number:min-integer-digits="0" number:min-numerator-digits="1" 1462 number:min-denominator-digits="1"/> 1463 </number:number-style> 1464 <number:number-style style:name="NUM13"> 1465 <number:fraction number:min-integer-digits="0" number:min-numerator-digits="2" 1466 number:min-denominator-digits="2"/> 1467 </number:number-style> 1468 <number:date-style style:name="NUM14" number:automatic-order="true"> 1469 <number:month number:style="long"/> 1470 <number:text>/</number:text> 1471 <number:day number:style="long"/> 1472 <number:text>/</number:text> 1473 <number:year/> 1474 </number:date-style> 1475 <number:date-style style:name="NUM15"> 1476 <number:day/> 1477 <number:text>.</number:text> 1478 <number:month number:textual="true"/> 1479 <number:text>.</number:text> 1480 <number:year number:style="long"/> 1481 </number:date-style> 1482 <number:date-style style:name="NUM16" number:automatic-order="true"> 1483 <number:month number:textual="true"/> 1484 <number:text></number:text> 1485 <number:day number:style="long"/> 1486 </number:date-style> 1487 <number:date-style style:name="NUM17"> 1488 <number:month number:style="long"/> 1489 <number:text>-</number:text> 1490 <number:day number:style="long"/> 1491 </number:date-style> 1492 <number:date-style style:name="NUM22" number:automatic-order="true" 1493 number:format-source="language"> 1494 <number:month/> 1495 <number:text>/</number:text> 1496 <number:day/> 1497 <number:text>/</number:text> 1498 <number:year/> 1499 <number:text></number:text> 1500 <number:hours number:style="long"/> 1501 <number:text>:</number:text> 1502 <number:minutes number:style="long"/> 1503 <number:text></number:text> 1504 <number:am-pm/> 1505 </number:date-style> 1506 <number:text-style style:name="NUM49"> 1507 <number:text-content/> 1508 </number:text-style> 1509 '; 1510 } 1511 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |