xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Программный экспорт товаров в CSV

Опубликовано в

Пример экспорта товаров Drupal Commerce в CSV файл:

define('MODULENAME_CSV_DELIMITER', ';');
 
/**
 * Export form.
 */
function modulename_export_form($form, &$form_state) {
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Run export'),
  );
 
  if (!empty($_SESSION['export_file_ready'])) {
    drupal_add_js('
      jQuery(function() {
        var link = document.createElement("a");
        link.download = "products-export.csv";
        link.href = "' . file_create_url('public://products-export.csv') . '";
        link.click();
      });
    ', 'inline');
    unset($_SESSION['export_file_ready']);
  }
 
  return $form;
}
 
/**
 * Export form submit callback.
 */
function modulename_export_form_submit($form, &$form_state) {
  // Create CSV file with header
  $csv_handle = fopen('temporary://products-export.csv', 'w');
  fputcsv($csv_handle, modulename_get_csv_header_col_names(), MODULENAME_CSV_DELIMITER);
 
  // Create batch operations
  $product_display_nids = modulename_get_product_display_nids();
  $batch_operations = array();
  foreach ($product_display_nids as $product_display_nid) {
    $batch_operations[] = array('modulename_export_node', array($product_display_nid));
  }
 
  // Batch init
  $batch = array(
    'operations' => $batch_operations,
    'finished' => 'modulename_export_batch_finished',
  );
  batch_set($batch);
}
 
/**
 * Batch worker callback.
 */
function modulename_export_node($product_display_nid, &$context) {
  $csv_handle = fopen('temporary://products-export.csv', 'a');
 
  $product_display_wrapper = entity_metadata_wrapper('node', $product_display_nid);
  $product_wrapper = $product_display_wrapper->field_product;
 
  $row = array_fill_keys(modulename_get_csv_header_col_names(), '');
 
  $row['nid']      = $product_display_nid;
  $row['title']    = $product_display_wrapper->title->value();
  $row['body']     = $product_display_wrapper->body->value->value();
  $row['status']   = $product_display_wrapper->status->value();
  $row['category'] = $product_display_wrapper->field_product_category->name->value();
  $row['sku']      = $product_wrapper->sku->value();
  $row['price']    = commerce_currency_amount_to_decimal($product_wrapper->commerce_price->amount->value(), $product_wrapper->commerce_price->currency_code->value());
 
  fputcsv($csv_handle, $row, MODULENAME_CSV_DELIMITER);
  fclose($csv_handle);
}
 
/**
 * Batch finish callback.
 */
function modulename_export_batch_finished($success, $results, $operations) {
  file_unmanaged_move('temporary://products-export.csv', 'public://products-export.csv', FILE_EXISTS_REPLACE);
  $_SESSION['export_file_ready'] = TRUE;
}
 
/**
 * Return all product display nids.
 */
function modulename_get_product_display_nids() {
  return db_select('node', 'node')
    ->fields('node', array('nid'))
    ->condition('node.type', 'product_display')
    ->execute()
    ->fetchCol();
}
 
/**
 * Return CSV header col names.
 */
function modulename_get_csv_header_col_names() {
  return array(
    'nid',
    'title',
    'body',
    'status',
    'category',
    'sku',
    'price',
  );
}
Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

Если переписать батч на экспорт пачки товаров за одну итерацию, то можно хорошо повысить скорость выгрузки товара. Особенно актуально если товара много.

Мне кажется, что это неправильный подход. Правильный - поставить views data export, настроить и, если нужно, дергать программно.

Во views data export вы не сможете заложить необходиму логику экспорта

Например? Учитывая то, что это вьюха, которая экзекьютится в батче, то с помощью хендлеров и хуков можно сделать всё очень кастомизированно, если необходимо.

хендлеры, хуки, .... Это все усложняет задачу, а не упрощает (плюсом будете еще иметь проблемы с производительностью). Если простая выгрузка, то проще views data export, если есть логика, которая может в будущем усложнятся - лучше сразу заложить программную генерацию.

Я бы сказал, что наоборот. Вместо какого-то кастомного решения, с вручную написанной обработкой полей, используются вьюхи, вылизанные кучей разработчиков.
Они отлично переносится через фичи, обладают огромной гибкостью сами по себе (поля, разные варианты вывода, т.п.), а также существует куча модулей, расширяющих их функциональность.
Views data export же позволяет этот вывод перенаправлять в файл (причем поддерживает несколько форматов), генерировать данные как напрямую, так и через батч - и так далее.
--
Использовать вьюхи - это друпал вэй. Вы же, когда хотите вывести табличку с данными, не создаете отдельный меню коллбек, в котором вызываете theme('table')? Намного легче и правильнее создать вьюху типа "page" да и накидать, что нужно.

Друпал вэй - это использовать голову, а не вьюхи. Views в данной задачи не нужен совершенно.

Евгений, больше похоже, что вы еще не сталкивались с кастомным выводом сложных данных в csv файл. Далеко не всю логику можно реализовать с помощью готовых модулей. И иногда быстрее сделать свой небольшой модуль, чем настраивать какого то монстра под узкую задачу. Но это придет) У вас еще все впереди, развивайтесь и изучайте альтернативные методы решения задач.

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании