diff --git a/trunk/gosa-core/include/utils/excel/class.writeexcel_olewriter.inc.php b/trunk/gosa-core/include/utils/excel/class.writeexcel_olewriter.inc.php
--- /dev/null
@@ -0,0 +1,353 @@
+<?php
+
+/*
+ * Copyleft 2002 Johann Hanne
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This is the Spreadsheet::WriteExcel Perl package ported to PHP
+ * Spreadsheet::WriteExcel was written by John McNamara, jmcnamara@cpan.org
+ */
+
+class writeexcel_olewriter {
+ var $_OLEfilename;
+ var $_OLEtmpfilename; /* ABR */
+ var $_filehandle;
+ var $_fileclosed;
+ var $_internal_fh;
+ var $_biff_only;
+ var $_size_allowed;
+ var $_biffsize;
+ var $_booksize;
+ var $_big_blocks;
+ var $_list_blocks;
+ var $_root_start;
+ var $_block_count;
+
+ /*
+ * Constructor
+ */
+ function writeexcel_olewriter($filename) {
+
+ $this->_OLEfilename = $filename;
+ $this->_filehandle = false;
+ $this->_fileclosed = 0;
+ $this->_internal_fh = 0;
+ $this->_biff_only = 0;
+ $this->_size_allowed = 0;
+ $this->_biffsize = 0;
+ $this->_booksize = 0;
+ $this->_big_blocks = 0;
+ $this->_list_blocks = 0;
+ $this->_root_start = 0;
+ $this->_block_count = 4;
+
+ $this->_initialize();
+ }
+
+ /*
+ * Check for a valid filename and store the filehandle.
+ */
+ function _initialize() {
+ $OLEfile = $this->_OLEfilename;
+
+ /* Check for a filename. Workbook.pm will catch this first. */
+ if ($OLEfile == '') {
+ trigger_error("Filename required", E_USER_ERROR);
+ }
+
+ /*
+ * If the filename is a resource it is assumed that it is a valid
+ * filehandle, if not we create a filehandle.
+ */
+ if (is_resource($OLEfile)) {
+ $fh = $OLEfile;
+ } else {
+ // Create a new file, open for writing
+ $fh = fopen($OLEfile, "wb");
+ // The workbook class also checks this but something may have
+ // happened since then.
+ if (!$fh) {
+ trigger_error("Cannot open $OLEfile! It may be in use or ".
+ "protected.", E_USER_ERROR);
+ }
+
+ $this->_internal_fh = 1;
+ }
+
+ // Store filehandle
+ $this->_filehandle = $fh;
+ }
+
+ /*
+ * Set the size of the data to be written to the OLE stream
+ *
+ * $big_blocks = (109 depot block x (128 -1 marker word)
+ * - (1 x end words)) = 13842
+ * $maxsize = $big_blocks * 512 bytes = 7087104
+ */
+ function set_size($size) {
+ $maxsize = 7087104;
+
+ if ($size > $maxsize) {
+ trigger_error("Maximum file size, $maxsize, exceeded. To create ".
+ "files bigger than this limit please use the ".
+ "workbookbig class.", E_USER_ERROR);
+ return ($this->_size_allowed = 0);
+ }
+
+ $this->_biffsize = $size;
+
+ // Set the min file size to 4k to avoid having to use small blocks
+ if ($size > 4096) {
+ $this->_booksize = $size;
+ } else {
+ $this->_booksize = 4096;
+ }
+
+ return ($this->_size_allowed = 1);
+ }
+
+ /*
+ * Calculate various sizes needed for the OLE stream
+ */
+ function _calculate_sizes() {
+ $datasize = $this->_booksize;
+
+ if ($datasize % 512 == 0) {
+ $this->_big_blocks = $datasize/512;
+ } else {
+ $this->_big_blocks = floor($datasize/512)+1;
+ }
+ // There are 127 list blocks and 1 marker blocks for each big block
+ // depot + 1 end of chain block
+ $this->_list_blocks = floor(($this->_big_blocks)/127)+1;
+ $this->_root_start = $this->_big_blocks;
+
+ //print $this->_biffsize. "\n";
+ //print $this->_big_blocks. "\n";
+ //print $this->_list_blocks. "\n";
+ }
+
+ /*
+ * Write root entry, big block list and close the filehandle.
+ * This method must be called so that the file contents are
+ * actually written.
+ */
+ function close() {
+
+ if (!$this->_size_allowed) {
+ return;
+ }
+
+ if (!$this->_biff_only) {
+ $this->_write_padding();
+ $this->_write_property_storage();
+ $this->_write_big_block_depot();
+ }
+
+ // Close the filehandle if it was created internally.
+ if ($this->_internal_fh) {
+ fclose($this->_filehandle);
+ }
+/* ABR */
+ if ($this->_OLEtmpfilename != '') {
+ $fh = fopen($this->_OLEtmpfilename, "rb");
+ if ($fh == false) {
+ trigger_error("Cannot read temporary file!", E_USER_ERROR);
+ }
+ fpassthru($fh);
+ fclose($fh);
+ unlink($this->_OLEtmpfilename);
+ };
+
+ $this->_fileclosed = 1;
+ }
+
+ /*
+ * Write BIFF data to OLE file.
+ */
+ function write($data) {
+ fputs($this->_filehandle, $data);
+ }
+
+ /*
+ * Write OLE header block.
+ */
+ function write_header() {
+ if ($this->_biff_only) {
+ return;
+ }
+
+ $this->_calculate_sizes();
+
+ $root_start = $this->_root_start;
+ $num_lists = $this->_list_blocks;
+
+ $id = pack("C8", 0xD0, 0xCF, 0x11, 0xE0,
+ 0xA1, 0xB1, 0x1A, 0xE1);
+ $unknown1 = pack("VVVV", 0x00, 0x00, 0x00, 0x00);
+ $unknown2 = pack("vv", 0x3E, 0x03);
+ $unknown3 = pack("v", -2);
+ $unknown4 = pack("v", 0x09);
+ $unknown5 = pack("VVV", 0x06, 0x00, 0x00);
+ $num_bbd_blocks = pack("V", $num_lists);
+ $root_startblock = pack("V", $root_start);
+ $unknown6 = pack("VV", 0x00, 0x1000);
+ $sbd_startblock = pack("V", -2);
+ $unknown7 = pack("VVV", 0x00, -2 ,0x00);
+ $unused = pack("V", -1);
+
+ fputs($this->_filehandle, $id);
+ fputs($this->_filehandle, $unknown1);
+ fputs($this->_filehandle, $unknown2);
+ fputs($this->_filehandle, $unknown3);
+ fputs($this->_filehandle, $unknown4);
+ fputs($this->_filehandle, $unknown5);
+ fputs($this->_filehandle, $num_bbd_blocks);
+ fputs($this->_filehandle, $root_startblock);
+ fputs($this->_filehandle, $unknown6);
+ fputs($this->_filehandle, $sbd_startblock);
+ fputs($this->_filehandle, $unknown7);
+
+ for ($c=1;$c<=$num_lists;$c++) {
+ $root_start++;
+ fputs($this->_filehandle, pack("V", $root_start));
+ }
+
+ for ($c=$num_lists;$c<=108;$c++) {
+ fputs($this->_filehandle, $unused);
+ }
+ }
+
+ /*
+ * Write big block depot.
+ */
+ function _write_big_block_depot() {
+ $num_blocks = $this->_big_blocks;
+ $num_lists = $this->_list_blocks;
+ $total_blocks = $num_lists * 128;
+ $used_blocks = $num_blocks + $num_lists + 2;
+
+ $marker = pack("V", -3);
+ $end_of_chain = pack("V", -2);
+ $unused = pack("V", -1);
+
+ for ($i=1;$i<=($num_blocks-1);$i++) {
+ fputs($this->_filehandle, pack("V", $i));
+ }
+
+ fputs($this->_filehandle, $end_of_chain);
+ fputs($this->_filehandle, $end_of_chain);
+
+ for ($c=1;$c<=$num_lists;$c++) {
+ fputs($this->_filehandle, $marker);
+ }
+
+ for ($c=$used_blocks;$c<=$total_blocks;$c++) {
+ fputs($this->_filehandle, $unused);
+ }
+ }
+
+ /*
+ * Write property storage. TODO: add summary sheets
+ */
+ function _write_property_storage() {
+ $rootsize = -2;
+ $booksize = $this->_booksize;
+
+ // name type dir start size
+ $this->_write_pps('Root Entry', 0x05, 1, -2, 0x00);
+ $this->_write_pps('Book', 0x02, -1, 0x00, $booksize);
+ $this->_write_pps('', 0x00, -1, 0x00, 0x0000);
+ $this->_write_pps('', 0x00, -1, 0x00, 0x0000);
+ }
+
+ /*
+ * Write property sheet in property storage
+ */
+ function _write_pps($name, $type, $dir, $start, $size) {
+ $names = array();
+ $length = 0;
+
+ if ($name != '') {
+ $name = $name . "\0";
+ // Simulate a Unicode string
+ $chars=preg_split("''", $name, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($chars as $char) {
+ array_push($names, ord($char));
+ }
+ $length = strlen($name) * 2;
+ }
+
+ $rawname = call_user_func_array('pack', array_merge(array("v*"), $names));
+ $zero = pack("C", 0);
+
+ $pps_sizeofname = pack("v", $length); //0x40
+ $pps_type = pack("v", $type); //0x42
+ $pps_prev = pack("V", -1); //0x44
+ $pps_next = pack("V", -1); //0x48
+ $pps_dir = pack("V", $dir); //0x4c
+
+ $unknown1 = pack("V", 0);
+
+ $pps_ts1s = pack("V", 0); //0x64
+ $pps_ts1d = pack("V", 0); //0x68
+ $pps_ts2s = pack("V", 0); //0x6c
+ $pps_ts2d = pack("V", 0); //0x70
+ $pps_sb = pack("V", $start); //0x74
+ $pps_size = pack("V", $size); //0x78
+
+ fputs($this->_filehandle, $rawname);
+ fputs($this->_filehandle, str_repeat($zero, (64-$length)));
+ fputs($this->_filehandle, $pps_sizeofname);
+ fputs($this->_filehandle, $pps_type);
+ fputs($this->_filehandle, $pps_prev);
+ fputs($this->_filehandle, $pps_next);
+ fputs($this->_filehandle, $pps_dir);
+ fputs($this->_filehandle, str_repeat($unknown1, 5));
+ fputs($this->_filehandle, $pps_ts1s);
+ fputs($this->_filehandle, $pps_ts1d);
+ fputs($this->_filehandle, $pps_ts2d);
+ fputs($this->_filehandle, $pps_ts2d);
+ fputs($this->_filehandle, $pps_sb);
+ fputs($this->_filehandle, $pps_size);
+ fputs($this->_filehandle, $unknown1);
+ }
+
+ /*
+ * Pad the end of the file
+ */
+ function _write_padding() {
+ $biffsize = $this->_biffsize;
+
+ if ($biffsize < 4096) {
+ $min_size = 4096;
+ } else {
+ $min_size = 512;
+ }
+
+ if ($biffsize % $min_size != 0) {
+ $padding = $min_size - ($biffsize % $min_size);
+ fputs($this->_filehandle, str_repeat("\0", $padding));
+ }
+ }
+
+}
+
+?>