Преобразование JSON в Excel (XLSX) в Angular

Введение
Как разработчик, вы часто решаете прикладные задачи, где веб‑приложению нужно не только отображать данные, но и экспонировать их в других форматах: PDF, XML, DOCX или Excel. Экспорт в Excel удобен для отчётов, обмена с бизнес‑пользователями и интеграции с существующими процессами.
В этой инструкции подробно описано, как настроить библиотеку xlsx в Angular, написать сервис для экспорта JSON в XLSX и интегрировать его в компонент. Также приведены советы по форматированию, ограничениям и тестированию.
Важно: под «JSON» здесь подразумевается массив объектов с простыми полями (строки, числа, булевы). Сложные вложенные структуры и даты требуют дополнительной обработки.
Что такое библиотека xlsx
Xlsx — это порт библиотеки SheetJS для JavaScript/TypeScript. Она умеет:
- конвертировать JSON в рабочие листы (sheet) и рабочие книги (workbook),
- читать и записывать .xlsx и другие Excel‑совместимые форматы,
- добавлять несколько листов, управлять стилями и форматом ячеек (ограниченно),
- преобразовывать Excel обратно в JSON.
Краткое определение: xlsx — клиентская/серверная библиотека для чтения и записи таблиц Excel в JavaScript/TypeScript.
Требования и подготовка окружения
- Node.js и npm установлены (LTS‑версия рекомендуется).
- Angular CLI установлен: npm install -g @angular/cli
- Создать проект: ng new your-angular-app-name
- Перейти в папку проекта: cd your-angular-app-name
- Запуск dev‑сервера: ng serve –open
Установите библиотеку:
npm install xlsx –save
(При необходимости добавьте типы: npm install –save-dev @types/xlsx, но современные версии часто включают типы.)
Создание сервиса экспорта в Excel
Создайте сервис командой:
ng generate service excel
В результате появится файл src/app/excel.service.ts. Ниже — рекомендуемая реализация сервиса с понятными комментариями.
import { Injectable } from '@angular/core';
import * as XLSX from 'xlsx';
const EXCEL_EXTENSION = '.xlsx'; // расширение для файлов Excel
@Injectable({ providedIn: 'root' })
export class ExcelService {
constructor() { }
/**
* Экспорт массива объектов в XLSX файл.
* element — массив объектов (JSON).
* fileName — имя файла без расширения.
*/
public exportToExcel(element: any[], fileName: string): void {
// Преобразуем JSON в рабочий лист
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(element);
// Создаём новую рабочую книгу
const workbook: XLSX.WorkBook = XLSX.utils.book_new();
// Добавляем лист с именем Sheet1
XLSX.utils.book_append_sheet(workbook, ws, 'Sheet1');
// Сохраняем файл локально
XLSX.writeFile(workbook, fileName + EXCEL_EXTENSION);
}
}Пояснения:
- XLSX.utils.json_to_sheet автоматически генерирует заголовки столбцов из ключей объектов.
- Для более сложного управления колонками используйте XLSX.utils.sheet_add_aoa или конструируйте массив списков значений.
Интеграция сервиса в компонент
Импортируйте и используйте сервис в компоненте, где загружается JSON из API. Пример упрощённого компонента:
import { Component } from '@angular/core';
import { ExcelService } from './excel.service';
@Component({
selector: 'app-root',
template: `
`
})
export class AppComponent {
apiJsonResponseData: any[] = []; // заполните данными из API
constructor(private excelService: ExcelService) { }
exportExcel(): void {
const fileToExport = this.apiJsonResponseData.map((items: any) => {
return {
'User Id': items?.userId,
'Id': items?.id,
'Title': items?.title,
'Body': items?.body
};
});
this.excelService.exportToExcel(fileToExport, 'yourExcelFile-' + new Date().getTime());
}
}Замечания:
- Используйте безопасный доступ items?.field, если данные могут быть неполными.
- Добавление временной метки в имя файла помогает избегать перезаписи.
При клике по кнопке браузер скачает файл .xlsx. Пример результата:
Частые проблемы и как их решать
- Даты: JSON‑строки с датами будут экспортированы как текст. Для корректного формата дат нужно конвертировать строки в Date и выставить формат ячейки.
- Вложенные объекты: json_to_sheet не разворачивает вложенные структуры автоматически. Решение — преобразовать объект в плоский вид или сериализовать вложенные поля в JSON‑строку.
- Большие объёмы данных: при экспорте сотен тысяч строк в браузере могут возникать проблемы по памяти. Для больших объёмов рассматривайте серверный экспорт или генерацию потоковых файлов.
- Стиль и ширина колонок: базовая библиотека ограничена в стилях; для продвинутой верстки используйте дополнительные библиотеки/плагины или серверную генерацию.
Полезные приёмы и шаблоны
- Преобразование вложенных полей в плоскую структуру:
function flatten(obj: any, prefix = ''): any {
const res: any = {};
for (const key of Object.keys(obj)) {
const val = obj[key];
const newKey = prefix ? `${prefix}.${key}` : key;
if (val && typeof val === 'object' && !Array.isArray(val) && !(val instanceof Date)) {
Object.assign(res, flatten(val, newKey));
} else {
res[newKey] = val;
}
}
return res;
}- Форматирование дат перед экспортом:
const normalized = items.map(i => ({
...i,
dateField: i.dateField ? new Date(i.dateField).toLocaleString('ru-RU') : ''
}));- Шаблон колонок с контролем порядка:
const headers = ['User Id', 'Id', 'Title', 'Body'];
const rows = data.map(d => headers.map(h => d[h] ?? ''));
const ws = XLSX.utils.aoa_to_sheet([headers, ...rows]);Альтернативные подходы
- Server‑side генерация (Node.js, Python, .NET): безопаснее для больших данных и позволяет детально управлять стилями и шаблонами.
- CSV вместо XLSX: подходит, если не нужны формулы/форматирование и важна скорость/простота.
- Использование специализированных сервисов отчётности (например, Power BI, Tableau) при сложной визуализации и агрегации.
Ментальные модели и эвристики
- «Экспорт — это представление»: подумайте, как пользователи будут работать с файлом в Excel, и подготовьте данные соответственно (порядок колонок, понятные заголовки).
- «Предобработка > постобработка»: легче нормализовать данные до экспорта, чем править Excel вручную.
- «Безопасность и GDPR»: никогда не включайте в экспорт чувствительные данные без проверки прав доступа.
Чек‑лист перед выпуском функции экспорта
- Тестированы края: пустые массивы, null‑значения, вложенные объекты
- Имена колонок понятны и локализованы
- Размер файлов в допустимых пределах
- Обработаны даты и числовые форматы
- Пользователь получает понятное имя файла
- Добавлены автотесты на ключевые сценарии
Критерии приёмки
- Функция экспортирует корректный .xlsx файл при заданном массиве JSON.
- Количество строк и колонок в файле совпадает с ожидаемым результатом.
- Поля с датами и числами форматируются согласно заданным правилам.
- Негативные кейсы (пустой массив, неопределённые поля) обрабатываются спокойно и не ломают загрузку.
Тестовые сценарии (приёмочные кейсы)
- Экспорт простого массива из 3 объектов с полями id, name, createdAt. Ожидаемый результат: 3 строки + заголовок.
- Экспорт массива с вложенным объектом profile. Ожидаемый результат: профиль представлен в одной или нескольких колонках согласно flatten‑логике.
- Пустой массив. Ожидаемый результат: файл с заголовками только или уведомление «Нет данных для экспорта».
- Экспорт с большим объёмом (10k+ строк). Ожидаемый результат: файл выгружается без существенного падения UX (или предлагается серверный экспорт).
Пример runbook при ошибке экспорта в проде
- Проверить логи клиента (console) и сервера (API) на предмет ошибок данных.
- Проверить структуру JSON: ожидаемые ключи и типы.
- Попробовать экспорт меньшего среза данных.
- Временно переключить на серверную генерацию, если проблема связана с объёмом.
- Сообщить пользователям статус и предложение временных решений.
Решение для локализации и UX
- Локализуйте заголовки колонок (например, «User Id» → «ID пользователя»).
- Формат дат адаптируйте под локаль клиента (toLocaleString(‘ru‑RU’)).
- В интерфейсе добавьте подсказку: «Файл содержит X строк, Y колонок» перед экспортом.
Решение для производительности
- Пагинация: экспортируйте данные по частям и объединяйте на сервере.
- Web Worker: переносите тяжёлые операции преобразования в воркер, чтобы не блокировать UI.
- Серверная генерация: для больших отчётов предпочтительна генерация на сервере и отдача готового файла.
Пример простой decision flow (Mermaid)
flowchart TD
A[Пользователь нажимает 'Экспорт'] --> B{Данных < 10k строк?}
B -- Да --> C[Генерируем в браузере через xlsx]
B -- Нет --> D[Запрос на сервер для генерации файла]
C --> E[Скачать файл]
D --> EЗаключение
Библиотека xlsx даёт быстрый и гибкий путь для преобразования JSON в Excel в Angular‑приложении. Для большинства сценариев клиентского экспорта она достаточна. При работе с большими объёмами и сложным форматированием рассмотрите серверные решения или гибридный подход.
Ключевые рекомендации:
- Подготовьте данные (флаттенинг, нормализация дат).
- Тестируйте на граничных случаях.
- Локализуйте заголовки и форматы.
- Для масштабируемости используйте серверную генерацию или Web Worker.
Важно: перед экспортом проверьте, что в выгружаемых данных нет чувствительной информации и что экспорт соответствует политике безопасности данных вашей организации.
Похожие материалы
Как устроить идеальную вечеринку для просмотра ТВ
Как распаковать несколько RAR‑файлов сразу
Приватный просмотр в Linux: как и зачем
Windows 11 не видит iPod — способы исправить
PS5: как настроить игровые пресеты