1<?php
2/**
3* Exports results in Microsoft Excel format.  By default the Writer sends
4* HTTP headers and the file contents via HTTP.  For testing purposes a
5* file name can be  to the constructor which will cause the ExcelWriter to
6* output to a file.
7*/
8class ExcelWriter extends Writer
9{
10    private $workbook;
11    private $currentSheet;
12    private $separator;
13    private $hasOutputHeader;
14    private $rowCounter;
15    private $forceDownload = true;
16
17    /**
18     * The presence of a filename will cause the writer to output to
19     * a file rather than send.
20     *
21     * @return ExcelWriter
22     */
23    public function __construct()
24    {
25        require_once(APPPATH.'/third_party/xlsx_writer/xlsxwriter.class.php');
26        $this->separator = '~|';
27        $this->hasOutputHeader = false;
28        $this->rowCounter = 0;
29    }
30
31    public function init(SurveyObj $survey, $sLanguageCode, FormattingOptions $oOptions)
32    {
33        parent::init($survey, $sLanguageCode, $oOptions);
34
35        $this->workbook = new XLSXWriter();
36        $this->workbook->setTempDir(Yii::app()->getConfig('tempdir'));
37        $worksheetName = $survey->languageSettings['surveyls_title'];
38        $worksheetName = mb_substr(str_replace(array('*', ':', '/', '\\', '?', '[', ']'), array(' '), $worksheetName), 0, 31, 'utf-8'); // Remove invalid characters
39        if ($worksheetName == '') {
40            $worksheetName = 'survey_'.$survey->id;
41        }
42        $this->currentSheet = $worksheetName;
43        $this->forceDownload = !($oOptions->output == 'file');
44    }
45
46    protected function outputRecord($headers, $values, FormattingOptions $oOptions)
47    {
48        if (!$this->hasOutputHeader) {
49            $this->workbook->writeSheetRow($this->currentSheet, $headers);
50            $this->hasOutputHeader = true;
51        }
52        $this->workbook->writeSheetRow($this->currentSheet, $values);
53    }
54
55    public function close()
56    {
57        $this->workbook->writeToFile($this->filename);
58        if ($this->forceDownload) {
59            header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
60            header("Content-Disposition: attachment; filename=\"{$this->webfilename}.xlsx\"");
61            header('Content-Length: '.filesize($this->filename));
62            readfile($this->filename);
63        }
64        return $this->workbook;
65    }
66}