Выделяем ноды и экспортируем в ворд!

Аватар пользователя kyky kyky 29 марта 2008 в 10:37

Недавно спрашивал на форуме, как реализовать подобное, но ответа не получил и решил задачу самостоятельно.
Собственно, задача в том, чтобы получить список нод в виде (можно с расширенными фильтрами), выбрать те ноды, что нас интересуют и получить вордовский файл, содержащий полные ноды или табличное представление полей. Вот какой рецепт могу предложить.

для реализации задачи потребуется модули:

  • views
  • views_bonus
  • views_bulk_operations

есть вид, пусть даже с расширенными фильтрами, который нам даёт какой-то набор нод.
Модуль views_bulk_operations дорисовывает к каждой ноде чекбокс и предлагает на выбор несколько стандартных операций (удалить, на главную, убрать с главной и тд.)

в наборе модулей views_bonus есть модуль views_export, который делает экспорт вида в doc или CSV формат
он позволяет добавлять к любому виду аргументы doc или csv, что приводит к выбросу информации в указанный файл.

если к виду добавить сначала аргумент NID (номер ноды), а затем аргумент DOC, то получим выброс ноды в doc-файл, например:

www.site.com/vid_name/4+2+5+8/doc

то получим ноды 4, 2, 5 и 8 в ворде

теперь зделаем так, чтобы выбрасывались любые ноды, какие пожелаем. Для этого нужна своя операция для views_bulk_operations. Этот модуль зависит от модуля actions, поскольку дёргает операции через него, однако есть одна тонкость - операция удаления переопределена и зашита в views_bulk_operations. Нужно заменить её код:

открываем views_bulk_operations.module;
ищем function views_bulk_operations_delete_nodes($nodes);
меняем функцию на:

function views_bulk_operations_delete_nodes($nodes) {
  $url = '{вид_который_даёт_doc}/';
  $temp = '';

  foreach ($nodes as $nid) {
    $temp = $nid;
    settype($temp, "string");
    $url = $url.$temp.'+';
  }
  $url = substr($url, 0, strlen($url)-1);
  $url = $url.'/doc';
  drupal_goto($url);
}

потом настраиваем тот вид, который даёт вордовский файл, что выводится и как.

можете посмотреть файлы в аттаче: там скрины и запакованный вордовкий файл, в котором, правда выводилось всего 2 поля. Вы можете поставить хоть какое представление.
Кстати, перед выбросом нод в ворд следует всё перевести из UTF в 1251:

открываем views_bonus_export.module,
переписываем функцию

function theme_views_bonus_export_doc($view, $nodes) {
  if (!user_access('export views')) {
    return;
  }

  drupal_set_header('Content-Type: application/msword');
  drupal_set_header('Content-Disposition: attachment; filename="view-'. $view->name .'.doc"');
  $table = theme('views_view_table', $view, $nodes, null);
  $table = preg_replace('/<\/?(a|span) ?.*?>/', '', $table); // strip 'a' and 'span' tags
  $table = utf2win1251($table);
  print $table;
  module_invoke_all('exit');
  exit;
}

(добавилась 1 строка)

где нибудь повыше пишем

function utf2win1251($content)
{
                $newcontent = "";

                for ($i = 0; $i < strlen($content); $i++)
                {
                        $c1 = substr($content, $i, 1);
                        $byte1 = ord($c1);
                        if ($byte1>>5 == 6)
                        {
                                $i++;
                                $c2 = substr($content, $i, 1);
                                $byte2 = ord($c2);
                                $byte1 &= 31;
                                $byte2 &= 63;
                                $byte2 |= (($byte1 & 3) << 6);
                                $byte1 >>= 2;
                                $word = ($byte1<<8) + $byte2;

                                if ($word == 1025) $newcontent .= chr(168);
                                else if ($word == 1105) $newcontent .= chr(184);
                                else if ($word >= 0x0410 && $word <= 0x044F) $newcontent .= chr($word-848);
                                else
                                {
                                        $a = dechex($byte1);
                                        $a = str_pad($a, 2, "0", STR_PAD_LEFT);
                                        $b = dechex($byte2);
                                        $b = str_pad($b, 2, "0", STR_PAD_LEFT);
                                        $newcontent .= "?".$a.$b.";";
                                }
                        }
                        else
                                $newcontent .= $c1;
                }

        return $newcontent;
}

(это я уже стырил с Хабра)

ну вот и всё!



ВложениеРазмер
Файл view-test.rar1.92 КБ

Комментарии

Аватар пользователя Valeratal Valeratal 30 марта 2008 в 23:11

Спасибо, интересно
А вот, можно ли сделать так, чтобы просто внизу материала была ссылка - открыть ворде (без групповых операций) ?

А что взято с хабра?

Аватар пользователя neochief neochief 30 марта 2008 в 23:21

Оффтоп: Автор, я восхищаюсь способностью вашей аватары вызывать у меня каждый раз новые будоражащие чувства Smile Вот вроде бы мог бы уже привыкнуть, а н-нет.

Аватар пользователя kyky kyky 31 марта 2008 в 5:05

2 Valeratal:
Это сделать можно, причем несколькими способами:
а) найти в модуле views_export.module функцию экспорта и переписать её в шаблон материала (это трудновато будет);
б) гораздо проще в ноде добавлять ссылку www.site.ru/vid/NID/doc, где vid - имя вида для экспорта (показывает полные ноды), NID - id той ноды, которую вы хотите выбросить в ворд

с Хабра я взял функцию перевода контента и UTF в win1251. Без неё в ворде вместо букв мы увидим чешую.

Аватар пользователя Valeratal Valeratal 31 марта 2008 в 10:02

Спасибо, буду пробовать
Еще бы понять как ссылку на экспорт вставить в зону links

Аватар пользователя kyky kyky 31 марта 2008 в 13:08

2 Valeratal:
тут конечно не обойдётся без ПХП, номер текущей ноды получим через $id = $node->nid, а где выводить саму ссылку - это вам виднее. Но можно дописать этот код в шаблон темы.

2 Slavyansk.net.ru:
Полезно, конечно, но это не то. Здесь основная фишка в том, что можно произвольно выбирать материалы для экспорта

Аватар пользователя F10 F10 8 октября 2008 в 17:37

Так же охота сделать Export CSV
Вот функция:

function theme_views_bonus_export_csv($view, $nodes) {
  if (!user_access('export views')) {
    return;
  }
  $fields = _views_get_fields();
  drupal_set_header('Content-Type: text/x-comma-separated-values');
  drupal_set_header('Content-Disposition: attachment; filename="view-'. $view->name .'.csv"');
 
  // headings row
  $headings = array();
  foreach ($view->field as $field) {
    if ($fields[$field['id']]['visible'] !== false) {
      $headings[] = $field['label'] ? $field['label'] : $fields[$field['fullname']]['name'];
    }
  }
  $comma = t(',');
  print implode($comma, $headings) ."\r\n";
 
  // one row for each node
  foreach ($nodes as $node) {
    $values = array();
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $value = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
        $values[] = '"' . str_replace('"', '""', decode_entities(strip_tags($value))) . '"';
      }
    }
    print implode($comma, $values) ."\r\n";
  }
  module_invoke_all('exit');
  exit;
}

Заработает ли:

 $table = utf2win1251($table);

там
И куда её вставить?

Аватар пользователя yasik yasik 15 декабря 2008 в 3:39

а как переделать функцию

function views_bulk_operations_delete_nodes($nodes) {
  $url = '{вид_который_даёт_doc}/';
  $temp = '';
 
  foreach ($nodes as $nid) {
    $temp = $nid;
    settype($temp, "string");
    $url = $url.$temp.'+';
  }
  $url = substr($url, 0, strlen($url)-1);
  $url = $url.'/doc';
  drupal_goto($url);
}

если несколько видов проблема в строке $url = '{вид_который_даёт_doc}/'; жестко привязана к одному виду пробывал написать так
$url = $view->url.'/'; не помогло может я просто не правильно вызываю переменную

Аватар пользователя ryumkin ryumkin 10 июля 2009 в 13:23

А кто знает как работает в drupal 6.x экспорт? Включил модуль и не знаю чего делать, в документации пусто. Пробовал сайт/вьюха/ноды/csv ничего не происходит.

Аватар пользователя yasik yasik 9 сентября 2009 в 20:18

Понадобилось при экспорте сделать заголовок в doc файле, нужно чтоб этот заголовок соответствовал тексту который перед views выводится — переменная $view->page_header.
Открываем views_bonus_export.module, и добавляем в строку функцию

<?phpfunction theme_views_bonus_export_doc($view, $nodes) {
  if (!user_access('export views')) {
    return;
  }
  drupal_set_header('Content-Type: application/msword');
  drupal_set_header('Content-Disposition: attachment; filename="view-'. $view->name .'.doc"');
  $table = theme('views_view_table', $view, $nodes, null);
  $table = preg_replace('/<\/?(a|span) ?.*?>/', '', $table); // strip 'a' and 'span' tags
  print $view->page_header;
  print $table;
  module_invoke_all('exit');
  exit;
}?>

Все классно работает если это текст, а если в $view->page_header PHP текст получается с перемененными
вот такой:
global $user;
print $user->name;
?>

он это так текстом в doc и вставляет
конечно если все это вызвать во views_bonus_export.module то тоже все работает, но это получается для всех вьюсов.

+ дополнительные правки кода модуля которые вылезут боком при update
как сделать все таки по аккуратней?

Аватар пользователя presich presich 4 августа 2010 в 16:34

Народ, встречал кто-либо готовое решение проблемы фильтрации, выбора и експорта нод в CSV/XML для Drupal 6?

Или всё-равно пока нужно влезать в код Views Export?

Аватар пользователя ii ii 17 ноября 2010 в 4:13

может ли возникнуть проблема с большим количеством экспортируемых материалов, связанная именно с кол-вом передаваемых в пути параметров?