1: <?php
2: /**
3: * PHPExcel
4: *
5: * Copyright (c) 2006 - 2014 PHPExcel
6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2.1 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, write to the Free Software
19: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20: *
21: * @category PHPExcel
22: * @package PHPExcel_Writer_CSV
23: * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24: * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25: * @version 1.8.0, 2014-03-02
26: */
27:
28:
29: /**
30: * PHPExcel_Writer_CSV
31: *
32: * @category PHPExcel
33: * @package PHPExcel_Writer_CSV
34: * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
35: */
36: class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter {
37: /**
38: * PHPExcel object
39: *
40: * @var PHPExcel
41: */
42: private $_phpExcel;
43:
44: /**
45: * Delimiter
46: *
47: * @var string
48: */
49: private $_delimiter = ',';
50:
51: /**
52: * Enclosure
53: *
54: * @var string
55: */
56: private $_enclosure = '"';
57:
58: /**
59: * Line ending
60: *
61: * @var string
62: */
63: private $_lineEnding = PHP_EOL;
64:
65: /**
66: * Sheet index to write
67: *
68: * @var int
69: */
70: private $_sheetIndex = 0;
71:
72: /**
73: * Whether to write a BOM (for UTF8).
74: *
75: * @var boolean
76: */
77: private $_useBOM = false;
78:
79: /**
80: * Whether to write a fully Excel compatible CSV file.
81: *
82: * @var boolean
83: */
84: private $_excelCompatibility = false;
85:
86: /**
87: * Create a new PHPExcel_Writer_CSV
88: *
89: * @param PHPExcel $phpExcel PHPExcel object
90: */
91: public function __construct(PHPExcel $phpExcel) {
92: $this->_phpExcel = $phpExcel;
93: }
94:
95: /**
96: * Save PHPExcel to file
97: *
98: * @param string $pFilename
99: * @throws PHPExcel_Writer_Exception
100: */
101: public function save($pFilename = null) {
102: // Fetch sheet
103: $sheet = $this->_phpExcel->getSheet($this->_sheetIndex);
104:
105: $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();
106: PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);
107: $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();
108: PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);
109:
110: // Open file
111: $fileHandle = fopen($pFilename, 'wb+');
112: if ($fileHandle === false) {
113: throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing.");
114: }
115:
116: if ($this->_excelCompatibility) {
117: fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header
118: $this->setEnclosure('"'); // Set enclosure to "
119: $this->setDelimiter(";"); // Set delimiter to a semi-colon
120: $this->setLineEnding("\r\n");
121: fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding);
122: } elseif ($this->_useBOM) {
123: // Write the UTF-8 BOM code if required
124: fwrite($fileHandle, "\xEF\xBB\xBF");
125: }
126:
127: // Identify the range that we need to extract from the worksheet
128: $maxCol = $sheet->getHighestDataColumn();
129: $maxRow = $sheet->getHighestDataRow();
130:
131: // Write rows to file
132: for($row = 1; $row <= $maxRow; ++$row) {
133: // Convert the row to an array...
134: $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas);
135: // ... and write to the file
136: $this->_writeLine($fileHandle, $cellsArray[0]);
137: }
138:
139: // Close file
140: fclose($fileHandle);
141:
142: PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);
143: PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);
144: }
145:
146: /**
147: * Get delimiter
148: *
149: * @return string
150: */
151: public function getDelimiter() {
152: return $this->_delimiter;
153: }
154:
155: /**
156: * Set delimiter
157: *
158: * @param string $pValue Delimiter, defaults to ,
159: * @return PHPExcel_Writer_CSV
160: */
161: public function setDelimiter($pValue = ',') {
162: $this->_delimiter = $pValue;
163: return $this;
164: }
165:
166: /**
167: * Get enclosure
168: *
169: * @return string
170: */
171: public function getEnclosure() {
172: return $this->_enclosure;
173: }
174:
175: /**
176: * Set enclosure
177: *
178: * @param string $pValue Enclosure, defaults to "
179: * @return PHPExcel_Writer_CSV
180: */
181: public function setEnclosure($pValue = '"') {
182: if ($pValue == '') {
183: $pValue = null;
184: }
185: $this->_enclosure = $pValue;
186: return $this;
187: }
188:
189: /**
190: * Get line ending
191: *
192: * @return string
193: */
194: public function getLineEnding() {
195: return $this->_lineEnding;
196: }
197:
198: /**
199: * Set line ending
200: *
201: * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL)
202: * @return PHPExcel_Writer_CSV
203: */
204: public function setLineEnding($pValue = PHP_EOL) {
205: $this->_lineEnding = $pValue;
206: return $this;
207: }
208:
209: /**
210: * Get whether BOM should be used
211: *
212: * @return boolean
213: */
214: public function getUseBOM() {
215: return $this->_useBOM;
216: }
217:
218: /**
219: * Set whether BOM should be used
220: *
221: * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false
222: * @return PHPExcel_Writer_CSV
223: */
224: public function setUseBOM($pValue = false) {
225: $this->_useBOM = $pValue;
226: return $this;
227: }
228:
229: /**
230: * Get whether the file should be saved with full Excel Compatibility
231: *
232: * @return boolean
233: */
234: public function getExcelCompatibility() {
235: return $this->_excelCompatibility;
236: }
237:
238: /**
239: * Set whether the file should be saved with full Excel Compatibility
240: *
241: * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file
242: * Note that this overrides other settings such as useBOM, enclosure and delimiter
243: * @return PHPExcel_Writer_CSV
244: */
245: public function setExcelCompatibility($pValue = false) {
246: $this->_excelCompatibility = $pValue;
247: return $this;
248: }
249:
250: /**
251: * Get sheet index
252: *
253: * @return int
254: */
255: public function getSheetIndex() {
256: return $this->_sheetIndex;
257: }
258:
259: /**
260: * Set sheet index
261: *
262: * @param int $pValue Sheet index
263: * @return PHPExcel_Writer_CSV
264: */
265: public function setSheetIndex($pValue = 0) {
266: $this->_sheetIndex = $pValue;
267: return $this;
268: }
269:
270: /**
271: * Write line to CSV file
272: *
273: * @param mixed $pFileHandle PHP filehandle
274: * @param array $pValues Array containing values in a row
275: * @throws PHPExcel_Writer_Exception
276: */
277: private function _writeLine($pFileHandle = null, $pValues = null) {
278: if (is_array($pValues)) {
279: // No leading delimiter
280: $writeDelimiter = false;
281:
282: // Build the line
283: $line = '';
284:
285: foreach ($pValues as $element) {
286: // Escape enclosures
287: $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element);
288:
289: // Add delimiter
290: if ($writeDelimiter) {
291: $line .= $this->_delimiter;
292: } else {
293: $writeDelimiter = true;
294: }
295:
296: // Add enclosed string
297: $line .= $this->_enclosure . $element . $this->_enclosure;
298: }
299:
300: // Add line ending
301: $line .= $this->_lineEnding;
302:
303: // Write to file
304: fwrite($pFileHandle, $line);
305: } else {
306: throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer.");
307: }
308: }
309:
310: }
311: