Commit dc7502df authored by berliner's avatar berliner Committed by dravenk
Browse files

Issue #3086234 by berliner: PhpSpreadsheet support (PHPOffice/PHPExcel deprecated)

parent 7f425ac1
Loading
Loading
Loading
Loading
+15 −27
Original line number Diff line number Diff line
The PHPExcel module allows developers to export/import data to/from real Excel files.



# DEPENDENCIES

This module depends on the Libraries API module (http://drupal.org/project/libraries).

In order for this module to work, you must download the PHPExcel library (version 1.7 - http://phpexcel.codeplex.com/).

  ## IMPORTANT NOTE

Code downloaded from Github (the new home of the PHPExcel library) will not contain a proper version number in the changelog.txt file (http://drupal.org/node/1908282). The Libraries API module requires this information, though. If you download the code from Github, open the changelog.txt file and change the ##VERSION## string to the proper version tag (e.g. 1.7.8).


In order for this module to work, you must install the PhpSpreadsheet library (version 1.7 or higher - https://github.com/PHPOffice/PhpSpreadsheet).

# INSTALLATION

The PHPExcel library can be extracted in any libraries folder you want (sites/*/libraries). You should have sites/*/libraries/PHPExcel/Classes/PHPExcel.php.



# IMPORTANT: UPGRADE FROM 2.x TO 3.x
The PhpSpreadsheet library should be installed using composer:

The phpexcel.api.inc file was still available in 2.x for backward compatibility reasons, *but has completely been removed in 3.x*. Code must now include phpexcel.inc !
  composer require phpoffice/phpspreadsheets

Also, *the include path for the PHPExcel library changes*! Make sure to move your library files (see Installation above). This may seem odd, but the previous way to store the library was not "right", in that you could not simply extract the downloaded archive to your libraries folder. Now you can.
 No newline at end of file
After that you should have vendor/phpoffice/phpspreadsheet/src/Bootstrap.php.
+16 −18
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
/**
 * @defgroup phpexcel_api PHPExcel API
 * @{
 * PHPExcel (the library) is a powerful PHP library to export and import data
 * PhpSpreadsheet (the library) is a powerful PHP library to export and import data
 * to and from Excel file. It is very flexible, and well built. The PHPExcel
 * Drupal module, on the other hand, provides a "wrapper", a simpler API that
 * behaves in a "Drupal" way. This module simplifies the export or import of
@@ -125,10 +125,9 @@
 *   writable.
 * - PHPEXCEL_ERROR_LIBRARY_NOT_FOUND: Error. Returned when the library could
 *   not be loaded. Usually this means the library is not in the correct
 *   location, or not extracted correctly. Remember that the changelog.txt file
 *   that comes with the source code must be present in the library directory.
 *   location, or not extracted correctly.
 * - PHPEXCEL_ERROR_FILE_NOT_WRITTEN: Error. Even though the path is writable,
 *   something prevented PHPExcel from actually saving the file.
 *   something prevented PhpSpreadsheet from actually saving the file.
 * - PHPEXCEL_CACHING_METHOD_UNAVAILABLE: Error. This is a configuration error,
 *   and happens when the site administrator uses an unavailable caching method,
 *   like Memcached, when there's no Memcached server running.
@@ -214,7 +213,7 @@
 * );
 * @endcode
 *
 * It is possible to specify method calls to the PHPExcel reader before
 * It is possible to specify method calls to the PhpSpreadsheet reader before
 * processing the file data. This is done via the fourth parameter, which is
 * an array, keyed by method name, and whose value is the parameters. For
 * instance, if you only want to load specific worksheets to save memory:
@@ -242,13 +241,13 @@
/**
 * @defgroup phpexcel_perf PHPExcel performance settings
 * @{
 * PHPExcel (the library) allows developers to have fine-grained control over
 * PhpSpreadsheet (the library) allows developers to have fine-grained control over
 * the way cell data is cached. Large Excel files can quickly take up a lot of
 * memory (about 1Kb per cell), and PHP processes could die running out of
 * available memory.
 *
 * PHPExcel is usable with APC, Memcached, SQLite or static file storage, to
 * optimize memory usage. PHPExcel can also gzip cell data, resulting in less
 * PhpSpreadsheet is usable with APC, Memcached, SQLite or static file storage, to
 * optimize memory usage. PhpSpreadsheet can also gzip cell data, resulting in less
 * memory usage, but at the cost of speed.
 *
 * Because this should not be controlled by any modules, but depends on each
@@ -271,17 +270,17 @@
 *   usage.
 * - Static files (stored in php://tmp). Slowest, but doesn't increase memory
 *   usage. In this case, it is still possible to set a maximum limit, up until
 *   which PHPExcel will still use in-memory caching. Defaults to 1Mb. After
 *   which PhpSpreadsheet will still use in-memory caching. Defaults to 1Mb. After
 *   reaching that limit, data is stored in static files.
 * @}
 */

/**
 * @defgroup phpexcel_cookbook PHPExcel cookbook
 * @defgroup phpexcel_cookbook PhpSpreadsheet cookbook
 * @{
 * This section provides several real-life examples of using the PHPExcel module
 * This section provides several real-life examples of using the PhpSpreadsheet module
 * with your own modules and sites. For the basics, see
 * @link phpexcel_api the PHPExcel API topic @endlink.
 * @link phpexcel_api the PhpSpreadsheet API topic @endlink.
 *
 * @section toc Table of contents
 *
@@ -311,7 +310,7 @@
 * @code
 * module_load_include('inc', 'phpexcel');
 *
 * // Prepare the file path. The PHPExcel library doesn't handle PHP stream
 * // Prepare the file path. The PhpSpreadsheet library doesn't handle PHP stream
 * // wrappers, so we need the real path.
 * $wrapper = file_stream_wrapper_get_instance_by_uri('temporary://');
 * // Generate a file name. If it's unique, it's less likely to conflict with an
@@ -473,10 +472,10 @@
 *
 * @section batch_import Import data in a batch
 *
 * When dealing with very large PHPExcel files, we sometimes want to import data
 * When dealing with very large PhpSpreadsheet files, we sometimes want to import data
 * in a batch instead of everything at once in order to save memory. We can
 * achieve this using a custom PHPExcel_Reader_IReadFilter class. A filter can
 * be used by PHPExcel to only read certain rows, which saves memory.
 * be used by PhpSpreadsheet to only read certain rows, which saves memory.
 *
 * @see batch
 *
@@ -497,7 +496,7 @@
 *   // ChunkReaderFilter class.
 *   $library = libraries_load('PHPExcel');
 *   if (empty($library['loaded'])) {
 *     drupal_set_message(t("Couldn't load the PHPExcel library."), 'error');
 *     drupal_set_message(t("Couldn't load the PhpSpreadsheet library."), 'error');
 *     $context['sandbox']['finished'] = 1;
 *     $context['success'] = FALSE;
 *     return;
@@ -647,7 +646,7 @@
 *    - "post cell": The $data parameter contains the call value that was
 *      rendered. This value cannot be altered anymore.
 * @param PHPExcel|PHPExcel_Worksheet $phpexcel
 *    The current object used. Can either be a PHPExcel object when working
 *    The current object used. Can either be a PhpSpreadsheet object when working
 *    with the excel file in general or a PHPExcel_Worksheet object when
 *    iterating through the worksheets. Depends on the value of $op:
 *    - "headers" or "data": The $phpexcel parameter will contain the PHPExcel
@@ -754,4 +753,3 @@ function hook_phpexcel_import($op, &$data, $phpexcel, $options, $column = NULL,
/**
 * @} End of "addtogroup hooks".
 */
+41 −50
Original line number Diff line number Diff line
@@ -79,10 +79,8 @@ not set to TRUE. Excel export aborted.");
    return PHPEXCEL_ERROR_PATH_NOT_WRITABLE;
  }

  $library = libraries_load('PHPExcel');

  if (empty($library['loaded'])) {
    \Drupal::logger('phpecel')->error("Couldn't find the PHPExcel library. Excel export aborted.");
  if (!class_exists('\PhpOffice\PhpSpreadsheet\IOFactory')) {
    \Drupal::logger('phpecel')->error("Couldn't find the PhpSpreadsheet library. Excel export aborted.");

    return PHPEXCEL_ERROR_LIBRARY_NOT_FOUND;
  }
@@ -90,27 +88,25 @@ not set to TRUE. Excel export aborted.");
  $path = phpexcel_munge_filename($path);

  // Determine caching method.
  list($cache_method, $cache_settings) = _phpexcel_get_cache_settings();
  $cache_method = _phpexcel_get_cache_settings();

  // Is it available ? If not, return an error.
  if (empty($cache_method)) {
    return PHPEXCEL_CACHING_METHOD_UNAVAILABLE;
  // Enable if exist
  if (!empty($cache_method)) {
  \PhpOffice\PhpSpreadsheet\Settings::setCache($cache_method);
  }

  PHPExcel_Settings::setCacheStorageMethod($cache_method, $cache_settings);

  // First, see if the file already exists
  if (file_exists($path)) {
    $xls = PHPExcel_IOFactory::load($path);
    $xls = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
  }
  elseif (!empty($options['template'])) {
    // Must we render from a template file ?
    $xls_reader = PHPExcel_IOFactory::createReaderForFile($options['template']);
    $xls_reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($options['template']);

    $xls = $xls_reader->load($options['template']);
  }
  else {
    $xls = new PHPExcel();
    $xls = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  }

  _phpexcel_set_properties($xls->getProperties(), $options);
@@ -129,7 +125,7 @@ not set to TRUE. Excel export aborted.");
        $sheet = $xls->setActiveSheetIndex($sheet_name);
        $style = array(
          'alignment' => array(
            'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
            'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
          )
        );
        $sheet->getStyle($merge_cells)->applyFromArray($style);
@@ -138,20 +134,20 @@ not set to TRUE. Excel export aborted.");
    }
  }

  $format = isset($options['format']) ? drupal_strtolower($options['format']) : @end(explode('.', $path));
  $format = isset($options['format']) ? mb_strtolower($options['format']) : @end(explode('.', $path));

  switch ($format) {
    case 'xlsx':
      $writer = new PHPExcel_Writer_Excel2007($xls);
      $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($xls);
      break;
    case 'csv':
      $writer = new PHPExcel_Writer_CSV($xls);
      $writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($xls);
      break;
    case 'ods':
      $writer = new PHPExcel_Writer_OpenDocument($xls);
      $writer = new \PhpOffice\PhpSpreadsheet\Writer\Ods($xls);
      break;
    default:
      $writer = new PHPExcel_Writer_Excel5($xls);
      $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($xls);
  }

  $writer->save($path);
@@ -202,7 +198,7 @@ function _phpexcel_set_properties($properties, $options) {
    $properties->setCreator($options['creator']);
  }
  else {
    $properties->setCreator("PHPExcel");
    $properties->setCreator("\PhpOffice\PhpSpreadsheet\Spreadsheet");
  }

  if (isset($options['title'])) {
@@ -245,8 +241,8 @@ function _phpexcel_set_headers($xls, &$headers, $options) {
        $sheet = $xls->setActiveSheetIndex($sheet_id);
      }
      else {
        // PHPExcel always creates one sheet.
        $sheet = $xls->getSheet();
        // PhpSpreadsheet always creates one sheet.
        $sheet = $xls->getSheet(0);
      }

      $sheet->setTitle($sheet_name);
@@ -259,7 +255,7 @@ function _phpexcel_set_headers($xls, &$headers, $options) {

      phpexcel_invoke('export', 'pre cell', $value, $sheet, $options, $i, 1);

      $sheet->setCellValueByColumnAndRow($i, 1, $value);
      $sheet->setCellValueByColumnAndRow($i + 1, 1, $value);

      phpexcel_invoke('export', 'post cell', $value, $sheet, $options, $i, 1);
    }
@@ -298,8 +294,8 @@ function _phpexcel_set_columns($xls, &$data, $headers = NULL, $options = array()
          $sheet = $xls->setActiveSheetIndex($sheet_id);
        }
        else {
          // PHPExcel always creates one sheet.
          $sheet = $xls->getSheet();
          // PhpSpreadsheet always creates one sheet.
          $sheet = $xls->getSheet(0);
        }

        $sheet->setTitle($sheet_name);
@@ -321,10 +317,10 @@ function _phpexcel_set_columns($xls, &$data, $headers = NULL, $options = array()
        $value = isset($sheet_data[$i][$j]) ? $sheet_data[$i][$j] : '';

        // We must offset the row count (by 2 if the first row is used by the
        // headers, because PHPExcel starts the count at 1, not 0).
        // headers, because PhpSpreadsheet starts the count at 1, not 0).
        phpexcel_invoke('export', 'pre cell', $value, $sheet, $options, $j, $i + $offset);

        $sheet->setCellValueByColumnAndRow($j, $i + $offset, $value);
        $sheet->setCellValueByColumnAndRow($j + 1, $i + $offset, $value);

        phpexcel_invoke('export', 'post cell', $value, $sheet, $options, $j, $i + $offset);
      }
@@ -368,20 +364,15 @@ function _phpexcel_set_columns($xls, &$data, $headers = NULL, $options = array()
 */
function phpexcel_import($path, $keyed_by_headers = TRUE, $keyed_by_worksheet = FALSE, $custom_calls = array()) {
  if (is_readable($path)) {
    $library = libraries_load('PHPExcel');

    if (!empty($library['loaded'])) {
    if (class_exists('\PhpOffice\PhpSpreadsheet\IOFactory')) {
      // Determine caching method.
      list($cache_method, $cache_settings) = _phpexcel_get_cache_settings();

      // Is it available ? If not, return an error.
      if (empty($cache_method)) {
        return PHPEXCEL_CACHING_METHOD_UNAVAILABLE;
      $cache_method = _phpexcel_get_cache_settings();
      // Enable if exist
      if (!empty($cache_method)) {
        \PhpOffice\PhpSpreadsheet\Settings::setCache($cache_method);
      }

      PHPExcel_Settings::setCacheStorageMethod($cache_method, $cache_settings);

      $xls_reader = PHPExcel_IOFactory::createReaderForFile($path);
      $xls_reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile($path);

      $custom_calls = array(
        'setReadDataOnly' => array(TRUE),
@@ -471,7 +462,7 @@ function phpexcel_import($path, $keyed_by_headers = TRUE, $keyed_by_worksheet =
            else {
              $col_index = $k;
              if ($cells->getIterateOnlyExistingCells()) {
                $col_index = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1;
                $col_index = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($cell->getColumn()) - 1;
              }

              phpexcel_invoke(
@@ -515,7 +506,7 @@ function phpexcel_import($path, $keyed_by_headers = TRUE, $keyed_by_worksheet =
      return $data;
    }
    else {
      \Drupal::logger('phpexcel')->error("Couldn't find the PHPExcel library. Excel import 
      \Drupal::logger('phpexcel')->error("Couldn't find the PhpSpreadsheet library. Excel import
aborted.");

      return PHPEXCEL_ERROR_LIBRARY_NOT_FOUND;
@@ -572,33 +563,33 @@ function phpexcel_munge_filename($path) {
 *    The first key is the caching method, the second the settings.
 */
function _phpexcel_get_cache_settings() {
  $cache_settings = array();
  return NULL;
  $phpexcel_config = \Drupal::config('phpexcel.settings');
  switch ($phpexcel_config->get('cache_mechanism')) {
    case 'cache_in_memory_serialized':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_in_memory_serialized;
      break;

    case 'cache_in_memory_gzip':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_in_memory_gzip;
      break;

    case 'cache_to_phpTemp':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_to_phpTemp;
      $cache_settings = array(
        'memoryCacheSize' => $phpexcel_config->get('phptemp_limit') . 'MB'
      );
      break;

    case 'cache_to_apc':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_to_apc;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_to_apc;
      $cache_settings = array(
        'cacheTime' => $phpexcel_config->get('apc_cachetime')
      );
      break;

    case 'cache_to_memcache':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_to_memcache;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_to_memcache;
      $cache_settings = array(
        'memcacheServer' => $phpexcel_config->get('memcache_host'),
        'memcachePort' => $phpexcel_config->get('_memcache_port'),
@@ -607,13 +598,13 @@ function _phpexcel_get_cache_settings() {
      break;

    case 'cache_to_sqlite3':
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_to_sqlite3;
      break;

    default:
      $cache_method = PHPExcel_CachedObjectStorageFactory::cache_in_memory;
      $cache_method = \PhpOffice\PhpSpreadsheet\Collection\CellsFactory::cache_in_memory;
      break;
  }

  return array($cache_method, $cache_settings);
  return $cache_method;
}
+1 −1
Original line number Diff line number Diff line
name: PHPExcel
description: 'Provides a simple API for using the PHPExcel library'
description: 'Provides a simple API for using the PhpSpreadsheet library'
type: module
core: 8.x

+1 −1
Original line number Diff line number Diff line
phpexcel.admin:
  title: 'PHPExcel cache settings'
  description: 'Manage the PHPExcel library caching settings.'
  description: 'Manage the PhpSpreadsheet library caching settings.'
  route_name: phpexcel.admin
  parent: system.admin_config_development
  weight: 10
Loading