dolibarr  13.0.2
export_excel2007.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2012 Marcos GarcĂ­a <marcosgdf@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 require_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
26 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
27 
28 use PhpOffice\PhpSpreadsheet\Spreadsheet;
29 use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
30 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
31 
36 {
40  public $id;
41 
45  public $label;
46 
47  public $extension;
48 
53  public $version = 'dolibarr';
54 
55  public $label_lib;
56 
57  public $version_lib;
58 
59  public $workbook; // Handle file
60 
61  public $worksheet; // Handle sheet
62 
63  public $styleArray;
64 
65  public $row;
66 
67  public $col;
68 
69  public $file; // To save filename
70 
71 
77  public function __construct($db)
78  {
79  global $conf, $langs;
80  $this->db = $db;
81 
82  $this->id = 'excel2007'; // Same value then xxx in file name export_xxx.modules.php
83  $this->label = 'Excel 2007'; // Label of driver
84  $this->desc = $langs->trans('Excel2007FormatDesc');
85  $this->extension = 'xlsx'; // Extension for generated file by this driver
86  $this->picto = 'mime/xls'; // Picto
87  $this->version = '1.30'; // Driver version
88  $this->phpmin = array(5, 6); // Minimum version of PHP required by module
89 
90  $this->disabled = 0;
91 
92  if (empty($this->disabled))
93  {
94  require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
95  $this->label_lib = 'PhpSpreadSheet';
96  $this->version_lib = '1.6.0'; // No way to get info from library
97  }
98 
99  $this->row = 0;
100  }
101 
107  public function getDriverId()
108  {
109  return $this->id;
110  }
111 
117  public function getDriverLabel()
118  {
119  return $this->label;
120  }
121 
127  public function getDriverDesc()
128  {
129  return $this->desc;
130  }
131 
137  public function getDriverExtension()
138  {
139  return $this->extension;
140  }
141 
147  public function getDriverVersion()
148  {
149  return $this->version;
150  }
151 
157  public function getLibLabel()
158  {
159  return $this->label_lib;
160  }
161 
167  public function getLibVersion()
168  {
169  return $this->version_lib;
170  }
171 
172 
173  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
181  public function open_file($file, $outputlangs)
182  {
183  // phpcs:enable
184  global $user, $conf, $langs;
185 
186  if (!empty($conf->global->MAIN_USE_PHP_WRITEEXCEL))
187  {
188  $outputlangs->charset_output = 'ISO-8859-1'; // Because Excel 5 format is ISO
189  }
190 
191  dol_syslog(get_class($this)."::open_file file=".$file);
192  $this->file = $file;
193 
194  $ret = 1;
195 
196  $outputlangs->load("exports");
197 
198  require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/autoloader.php';
199  require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
200  require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
201 
202  if ($this->id == 'excel2007')
203  {
204  if (!class_exists('ZipArchive')) // For Excel2007, PHPSpreadSheet may need ZipArchive
205  {
206  $langs->load("errors");
207  $this->error = $langs->trans('ErrorPHPNeedModule', 'zip');
208  return -1;
209  }
210  }
211 
212  $this->workbook = new Spreadsheet();
213  $this->workbook->getProperties()->setCreator($user->getFullName($outputlangs).' - '.DOL_APPLICATION_TITLE.' '.DOL_VERSION);
214  //$this->workbook->getProperties()->setLastModifiedBy('Dolibarr '.DOL_VERSION);
215  $this->workbook->getProperties()->setTitle(basename($file));
216  $this->workbook->getProperties()->setSubject(basename($file));
217  $this->workbook->getProperties()->setDescription(DOL_APPLICATION_TITLE.' '.DOL_VERSION);
218 
219  $this->workbook->setActiveSheetIndex(0);
220  $this->workbook->getActiveSheet()->setTitle($outputlangs->trans("Sheet"));
221  $this->workbook->getActiveSheet()->getDefaultRowDimension()->setRowHeight(16);
222 
223  return $ret;
224  }
225 
226  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
233  public function write_header($outputlangs)
234  {
235  // phpcs:enable
236  //$outputlangs->charset_output='ISO-8859-1'; // Because Excel 5 format is ISO
237 
238  return 0;
239  }
240 
241 
242  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
252  public function write_title($array_export_fields_label, $array_selected_sorted, $outputlangs, $array_types)
253  {
254  // phpcs:enable
255  global $conf;
256 
257  // Create a format for the column headings
258  $this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
259  $this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT);
260 
261  $this->col = 1;
262  if (!empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) {
263  $this->col = 0;
264  }
265  foreach ($array_selected_sorted as $code => $value)
266  {
267  $alias = $array_export_fields_label[$code];
268  //print "dd".$alias;
269  if (empty($alias)) dol_print_error('', 'Bad value for field with code='.$code.'. Try to redefine export.');
270  if (!empty($conf->global->MAIN_USE_PHP_WRITEEXCEL))
271  {
272  $this->worksheet->write($this->row, $this->col, $outputlangs->transnoentities($alias), $formatheader);
273  } else {
274  $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($this->col, $this->row + 1, $outputlangs->transnoentities($alias));
275  if (!empty($array_types[$code]) && in_array($array_types[$code], array('Date', 'Numeric', 'TextAuto'))) // Set autowidth for some types
276  {
277  $this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($this->col + 1))->setAutoSize(true);
278  }
279  }
280  $this->col++;
281  }
282  $this->row++;
283  return 0;
284  }
285 
286  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
296  public function write_record($array_selected_sorted, $objp, $outputlangs, $array_types)
297  {
298  // phpcs:enable
299  global $conf;
300 
301  // Define first row
302  $this->col = 1;
303  if (!empty($conf->global->MAIN_USE_PHP_WRITEEXCEL)) {
304  $this->col = 0;
305  }
306 
307  $reg = array();
308 
309  foreach ($array_selected_sorted as $code => $value)
310  {
311  if (strpos($code, ' as ') == 0) $alias = str_replace(array('.', '-', '(', ')'), '_', $code);
312  else $alias = substr($code, strpos($code, ' as ') + 4);
313  if (empty($alias)) dol_print_error('', 'Bad value for field with code='.$code.'. Try to redefine export.');
314  $newvalue = $objp->$alias;
315 
316  $newvalue = $this->excel_clean($newvalue);
317  $typefield = isset($array_types[$code]) ? $array_types[$code] : '';
318 
319  if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7))
320  {
321  $array = unserialize($typefield);
322  $array = $array['options'];
323  $newvalue = $array[$newvalue];
324  }
325 
326  // Traduction newvalue
327  if (preg_match('/^\((.*)\)$/i', $newvalue, $reg))
328  {
329  $newvalue = $outputlangs->transnoentities($reg[1]);
330  } else {
331  $newvalue = $outputlangs->convToOutputCharset($newvalue);
332  }
333 
334  if (preg_match('/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/i', $newvalue))
335  {
336  $newvalue = dol_stringtotime($newvalue);
337  $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($this->col, $this->row + 1, \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($newvalue));
338  $coord = $this->workbook->getActiveSheet()->getCellByColumnAndRow($this->col, $this->row + 1)->getCoordinate();
339  $this->workbook->getActiveSheet()->getStyle($coord)->getNumberFormat()->setFormatCode('yyyy-mm-dd');
340  } elseif (preg_match('/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/i', $newvalue))
341  {
342  $newvalue = dol_stringtotime($newvalue);
343  $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($this->col, $this->row + 1, \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($newvalue));
344  $coord = $this->workbook->getActiveSheet()->getCellByColumnAndRow($this->col, $this->row + 1)->getCoordinate();
345  $this->workbook->getActiveSheet()->getStyle($coord)->getNumberFormat()->setFormatCode('yyyy-mm-dd h:mm:ss');
346  } else {
347  if ($typefield == 'Text' || $typefield == 'TextAuto')
348  {
349  $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($this->col, $this->row + 1, (string) $newvalue);
350  $coord = $this->workbook->getActiveSheet()->getCellByColumnAndRow($this->col, $this->row + 1)->getCoordinate();
351  $this->workbook->getActiveSheet()->getStyle($coord)->getNumberFormat()->setFormatCode('@');
352  $this->workbook->getActiveSheet()->getStyle($coord)->getAlignment()->setHorizontal(PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT);
353  } else {
354  $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($this->col, $this->row + 1, $newvalue);
355  }
356  }
357  $this->col++;
358  }
359  $this->row++;
360  return 0;
361  }
362 
363 
364  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
371  public function write_footer($outputlangs)
372  {
373  // phpcs:enable
374  return 0;
375  }
376 
377 
378  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
384  public function close_file()
385  {
386  // phpcs:enable
387  global $conf;
388 
389  $objWriter = new Xlsx($this->workbook);
390  $objWriter->save($this->file);
391  $this->workbook->disconnectWorksheets();
392  unset($this->workbook);
393 
394  return 1;
395  }
396 
397 
398  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
405  public function excel_clean($newvalue)
406  {
407  // phpcs:enable
408  // Rule Dolibarr: No HTML
409  $newvalue = dol_string_nohtmltag($newvalue);
410 
411  return $newvalue;
412  }
413 
414 
421  public function column2Letter($c)
422  {
423 
424  $c = intval($c);
425  if ($c <= 0) return '';
426 
427  while ($c != 0) {
428  $p = ($c - 1) % 26;
429  $c = intval(($c - $p) / 26);
430  $letter = chr(65 + $p).$letter;
431  }
432 
433  return $letter;
434  }
435 
444  public function setCellValue($val, $startCell, $endCell = '')
445  {
446  try {
447  $this->workbook->getActiveSheet()->setCellValue($startCell, $val);
448 
449  if (!empty($endCell)) {
450  $cellRange = $startCell.':'.$endCell;
451  $this->workbook->getActiveSheet()->mergeCells($startCell.':'.$endCell);
452  }
453  else $cellRange = $startCell;
454  if (!empty($this->styleArray)) $this->workbook->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->styleArray);
455  }
456  catch (Exception $e) {
457  $this->error = $e->getMessage();
458  return -1;
459  }
460  return 1;
461  }
462 
470  public function setBorderStyle($thickness, $color)
471  {
472  $this->styleArray['borders'] = array(
473  'outline' => array(
474  'borderStyle' => $thickness,
475  'color' => array('argb' => $color)
476  )
477  );
478  return 1;
479  }
480 
488  public function setFontStyle($bold, $color)
489  {
490  $this->styleArray['font'] = array(
491  'color' => array('argb' => $color),
492  'bold' => $bold
493  );
494  return 1;
495  }
496 
503  public function setAlignmentStyle($horizontal)
504  {
505  $this->styleArray['alignment'] = array('horizontal' => $horizontal);
506  return 1;
507  }
508 
513  public function resetStyle()
514  {
515  $this->styleArray = array();
516  return 1;
517  }
518 
527  public function setBlock($startCell, $TDatas = array(), $boldTitle = false)
528  {
529  try {
530  if (!empty($TDatas)) {
531  $startCell = $this->workbook->getActiveSheet()->getCell($startCell);
532  $startColumn = Coordinate::columnIndexFromString($startCell->getColumn());
533  $startRow = $startCell->getRow();
534  foreach ($TDatas as $column => $TRows) {
535  if ($boldTitle) $this->setFontStyle(true, $this->styleArray['font']['color']['argb']);
536  $cell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn, $startRow);
537  $this->setCellValue($column, $cell->getCoordinate());
538  $rowPos = $startRow;
539  if ($boldTitle) $this->setFontStyle(false, $this->styleArray['font']['color']['argb']);
540  foreach ($TRows as $row) {
541  $rowPos++;
542  $cell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn, $rowPos);
543  $this->setCellValue($row, $cell->getCoordinate());
544  }
545  $startColumn++;
546  }
547  }
548  }
549  catch (Exception $e) {
550  $this->error = $e->getMessage();
551  return -1;
552  }
553  return 1;
554  }
555 
564  public function setBlock2Columns($startCell, $TDatas = array(), $boldTitle = false)
565  {
566  try {
567  if (!empty($TDatas)) {
568  $startCell = $this->workbook->getActiveSheet()->getCell($startCell);
569  $startColumn = Coordinate::columnIndexFromString($startCell->getColumn());
570  $startRow = $startCell->getRow();
571  foreach ($TDatas as $title => $val) {
572  $cell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn, $startRow);
573  if ($boldTitle) $this->setFontStyle(true, $this->styleArray['font']['color']['argb']);
574  $this->setCellValue($title, $cell->getCoordinate());
575  if ($boldTitle) $this->setFontStyle(false, $this->styleArray['font']['color']['argb']);
576  $cell2 = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn + 1, $startRow);
577  $this->setCellValue($val, $cell2->getCoordinate());
578  $startRow++;
579  }
580  }
581  }
582  catch (Exception $e) {
583  $this->error = $e->getMessage();
584  return -1;
585  }
586  return 1;
587  }
588 
596  public function enableAutosize($firstColumn, $lastColumn)
597  {
598  foreach (range($firstColumn, $lastColumn) as $columnID) {
599  $this->workbook->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
600  }
601  return 1;
602  }
603 
613  public function setMergeCellValueByLength($val, $startCell, $length, $offset = 0)
614  {
615  try {
616  $startCell = $this->workbook->getActiveSheet()->getCell($startCell);
617  $startColumn = Coordinate::columnIndexFromString($startCell->getColumn());
618  if (!empty($offset)) $startColumn += $offset;
619 
620  $startRow = $startCell->getRow();
621  $startCell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn, $startRow);
622  $startCoordinate = $startCell->getCoordinate();
623  $this->setCellValue($val, $startCell->getCoordinate());
624 
625  $endCell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($startColumn + ($length - 1), $startRow);
626  $endCoordinate = $endCell->getCoordinate();
627  $this->workbook->getActiveSheet()->mergeCells($startCoordinate.':'.$endCoordinate);
628  }
629  catch (Exception $e) {
630  $this->error = $e->getMessage();
631  return -1;
632  }
633  return $endCoordinate;
634  }
635 }
getDriverExtension()
getDriverExtension
Parent class for export modules.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto= 'UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
write_record($array_selected_sorted, $objp, $outputlangs, $array_types)
Output record line into file.
excel_clean($newvalue)
Clean a cell to respect rules of Excel file cells.
getDriverVersion()
getDriverVersion
getDriverDesc()
getDriverDesc
enableAutosize($firstColumn, $lastColumn)
Enable auto sizing for column range.
open_file($file, $outputlangs)
Open output file.
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition: date.lib.php:319
getLibVersion()
getLibVersion
setBorderStyle($thickness, $color)
Set border style.
setCellValue($val, $startCell, $endCell= '')
Set cell value and automatically merge if we give an endcell.
$conf db
API class for accounts.
Definition: inc.php:54
setBlock2Columns($startCell, $TDatas=array(), $boldTitle=false)
Make a 2xN Tab in Sheet.
setMergeCellValueByLength($val, $startCell, $length, $offset=0)
Set a value cell and merging it by giving a starting cell and a length.
Class to build export files with Excel format.
write_header($outputlangs)
Write header.
close_file()
Close Excel file.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
setFontStyle($bold, $color)
Set font style.
column2Letter($c)
Convert a column to letter (1-&gt;A, 0-&gt;B, 27-&gt;AA, ...)
setAlignmentStyle($horizontal)
Set alignment style (horizontal, left, right, ...)
write_title($array_export_fields_label, $array_selected_sorted, $outputlangs, $array_types)
Output title line into file.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
write_footer($outputlangs)
Write footer.
setBlock($startCell, $TDatas=array(), $boldTitle=false)
Make a NxN Block in sheet.
__construct($db)
Constructor.
getDriverLabel()
getDriverLabel