Заметки кодящего дизайнера

Как создать CSV-таблицу

Понадобилось мне как-то выгружать набор данных с веб-страницы в формате .csv.

И сделать мне это надо было без участия бэка.

Сперва я добавил на страницу две кнопки #download-list для загрузки файла и #copy-list для копирования в буфер.

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

// Функция для создания CSV-содержимого из таблицы
const generateCSVContent = () => {
    const list = document.getElementById('items-list');
    const items = list.getElementsByTagName('li');

    // Готовим данные CSV
    let csvContent = "id;name;year\n";
    for (let i = 0; i < items.length; i++) {
        const id = items[i].querySelector('.id').textContent;
        const name = items[i].querySelector('.name').textContent;
        const year = items[i].querySelector('.year').textContent;
        csvContent += id + ";" + name + ";" + year + "\n";
    }
    
    return csvContent;
}

// Обработчик для кнопки скачивания CSV
document.getElementById('download-list').addEventListener('click', () => {
    const csvContent = "data:text/csv;charset=utf-8," + generateCSVContent();

    // Создание ссылки для загрузки
    const encodedUri = encodeURI(csvContent);
    const link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "data_list.csv");
    document.body.appendChild(link); // Требуется для FF

    // Имитация клика по ссылке
    link.click();

    // Удаление ссылки после загрузки
    document.body.removeChild(link);
});

// Обработчик для кнопки копирования CSV в буфер обмена
document.getElementById('copy-list').addEventListener('click', () => {
    const csvContent = generateCSVContent();

    // Копирование содержимого в буфер обмена
    navigator.clipboard.writeText(csvContent).then(() => {
        alert("CSV скопирован в буфер обмена!");
    }).catch((error) => {
        console.error("Ошибка при копировании в буфер обмена: ", error);
    });
});