Экспорт данных в формате CSV или в любом другом формате на сайт с CMS Joomla 4



Введение в экспорт данных для Joomla 4

Это решение создано на основе компонента, в котором необходимо экспортировать данные из множества различных списков. Для выполнения этой задачи каждому экспорту необходима кнопка панели инструментов для запуска экспорта и контроллер для создания и экспорта данных. Для облегчения экспорта необходим один файл JavaScript.

Можно использовать ряд различных подходов к экспорту данных в CMS Joomla 4. В Joomla есть примеры, в которых используется специальная форма для загрузки, отдельная от стандартной формы администрирования списка. Список видов экспорта данных содержит почти 30 фильтров, поэтому лучше всего использовать форму администратора с установленными фильтрами.

HTML-код кнопки панели инструментов Joomla 4 экспорта

В следующем примере кода есть две кнопки экспорта, одна для csv, а другая для html (и даже не спрашивайте, почему!). Это отрывок кода из файла src/View/Viewname/HtmlView.php:

	protected function addToolbar()
	{
		// Получить экземпляр объекта панели инструментов
		$toolbar = Toolbar::getInstance('toolbar');
		...
		$downloads = $toolbar->dropdownButton('download-group')
		->text('Download') // but use Text::_('COM_MYCOMPONENT_VIEWNAME_DOWNLOAD')
		->toggleSplit(false)
		->icon('fa fa-file-download')
		->buttonClass('btn btn-action')
		->listCheck(false);

		$dlchild = $downloads->getChildToolbar();

		$dlchild->standardButton('download-csv')
		->icon('fa fa-file-download')
		->text('CSV Data') // but use Text::_('COM_MYCOMPONENT_VIEWNAME_DOWNLOAD_CSV_DATA')
		->task('camps.download_csv')
		->listCheck(false);

		$dlchild->standardButton('download-html')
		->icon('fa fa-file-download')
		->text('HTML')
		->task('camps.download_html')
		->listCheck(false);
		...
	}

Поразмыслив, возможно, было бы лучше использовать слово Export вместо Download везде. Но, сделанного не воротишь, а переписывать - лень! Итого: имеем ещё одну кнопку в панели управления Joomla 4:

имеем ещё одну кнопку в панели управления Joomla 4

Файл JavaScript экспорта данных для Joomla 4

Оказывается, удобно хранить код экспорта JavaScript в одном файле, загружаемом только в тех представлениях списков, которые имеют функцию экспорта. Исходный источник обрабатывает более десятка экспортных файлов. Только два из них проиллюстрированы ниже. Первая часть перехватывает событие отправки в форме администратора и при необходимости вызывает функцию экспорта. В противном случае он просто передает вызов стандартному обработчику отправки.

Joomla.submitbutton = task => {
	if (
			... more tasks
			task === 'camps.download_csv' || 
			task === 'camps.download_html' ||
			... more tasks
		) {
		downloadcommon(task);
		return;
	}

	Joomla.submitform(task);
};

async function downloadcommon(task) {
	// task - это скрытое поле в нижней части формы
	let task_id = document.getElementById("task");
	task_id.value = task;
	const adminform = document.getElementById('adminForm');
	// Связать объект FormData и элемент формы
	const data = new FormData( adminform );
	const url = 'index.php?option=com_mycomponent';
	const options = {
		method: 'POST',
		body: data
	}
	let response = await fetch(url, options);
	if (!response.ok) {
		throw new Error (Joomla.Text._('COM_MYCOMPONENT_JS_ERROR_STATUS') + `${response.status}`);
	}
	const disposition = response.headers.get('content-disposition');
	let filename = '';
	let ext = '';
	if (disposition && disposition.indexOf('attachment') !== -1) {
		var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
		var matches = filenameRegex.exec(disposition);
		if (matches != null && matches[1]) { 
			filename = matches[1].replace(/['"]/g, '');
			ext = filename.substr(filename.lastIndexOf('.'));
		}
	}
	let result = await response.blob();
	// Создать элемент ссылки, спрятать его, направить на большой двоичный объект, а затем программно выволнить 'click'
	let a = document.createElement("a");
	a.style = "display: none";
	document.body.appendChild(a);
	// Создать DOMString, представляющий большой двоичный объект, и направить на него элемент link
	let myurl = window.URL.createObjectURL(result);
	a.href = myurl;
	// использовать имя файла, отправленное сервером, чтобы сохранить файл
	a.download = filename;
	// программно нажать на ссылку, чтобы запустить загрузку
	a.click();
	// освободить ссылку на файл, отменив URL-адрес объекта
	window.URL.revokeObjectURL(myurl);
	// удалить ссылку, созданную для загрузки
	a.remove();
	// и сбросить задачу формы, иначе ...
	task_id.value = '';
}

HTML-файл контроллера экспорта данных для Joomla 4

Отправка формы обрабатывается на сервере контроллером. Его задача состоит в том, чтобы проверить маркер формы, а затем выбрать данные в виде списка строк. Заголовки HTTP необходимы для того, чтобы сообщить браузеру, что происходит. Это также хорошее место для установки разумного имени файла. Для уникальности можно использовать дату или дату и время. Это кусок кода в файле src/Controller/MyviewController.php.

	public function download_csv () {
		Session::checkToken( 'post' ) or die( 'Invalid Token' );
		$app = Factory::getApplication();

		... Сделать все необходимое, чтобы получить строки данных

		$filename = 'Some-useful-prefix-';
		$date = date('Y-m-d');

		$app->setHeader('Content-Type', 'text/csv; charset=utf-8', true);
		$app->setHeader('Content-disposition', 'attachment; filename="' . $filename . '-' . $date . '.csv"', true);
		$app->setHeader('Cache-Control', 'no-cache', true);
		$app->sendHeaders();

		... отправить строки

		$app->close();
	}

Результат экспорта данных для Joomla 4

В итоге имеет такой вывод:

 Joomla 4 - результат экспорта данных

Перевод с английского официальной документации Joomla 4:
https://docs.joomla.org/Joomla_4_Tips_and_Tricks:_Export_Data

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню