96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
/**
|
|
* utils.js — Вспомогательные утилиты
|
|
* Чтение Excel, работа с CSV, скачивание файлов
|
|
*/
|
|
|
|
/**
|
|
* Прочитать Excel-файл и вернуть массив листов
|
|
* @param {File} file - файл .xlsx/.xls
|
|
* @returns {Promise<Array<{name: string, data: string[][]}>>}
|
|
*/
|
|
export async function readExcel(file) {
|
|
const arr = await file.arrayBuffer();
|
|
const wb = XLSX.read(arr, { type: 'array', codepage: 1251 });
|
|
return wb.SheetNames.map(name => ({
|
|
name,
|
|
data: XLSX.utils.sheet_to_json(wb.Sheets[name], { header: 1, defval: '' })
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Проверить допустимость расширения файла
|
|
* @param {File} file
|
|
* @returns {boolean}
|
|
*/
|
|
export function validateFile(file) {
|
|
const allowed = ['.xlsx', '.xls'];
|
|
const ext = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
|
|
if (!allowed.includes(ext)) {
|
|
alert(`❌ Недопустимый тип файла: ${ext}. Разрешены: .xlsx, .xls`);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Преобразовать массив объектов в CSV-строку
|
|
* @param {Object[]} data
|
|
* @param {string[]} headers
|
|
* @returns {string}
|
|
*/
|
|
export function arrayToCsv(data, headers) {
|
|
const rows = data.map(r =>
|
|
headers.map(h => `"${String(r[h] ?? '').replace(/"/g, '""')}"`).join(',')
|
|
);
|
|
return '\uFEFF' + headers.join(',') + '\n' + rows.join('\n');
|
|
}
|
|
|
|
/**
|
|
* Скачать строку/Blob как файл
|
|
* @param {string|Blob} content
|
|
* @param {string} filename
|
|
*/
|
|
export function downloadFile(content, filename) {
|
|
const blob = new Blob([content], { type: 'application/octet-stream' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
}
|
|
|
|
/**
|
|
* Скачать Excel-файл (XLSX) из массива данных
|
|
* @param {Object[]} data - массив строк
|
|
* @param {string} filename
|
|
*/
|
|
export function downloadExcel(data, filename) {
|
|
const wb = XLSX.utils.book_new();
|
|
const ws = XLSX.utils.json_to_sheet(data);
|
|
// Авто-ширина колонок
|
|
const colWidths = Object.keys(data[0] || {}).map(key => {
|
|
const maxLen = data.reduce((max, row) => {
|
|
const val = String(row[key] ?? '');
|
|
return Math.max(max, val.length);
|
|
}, key.length);
|
|
return { wch: Math.min(maxLen + 2, 40) };
|
|
});
|
|
ws['!cols'] = colWidths;
|
|
XLSX.utils.book_append_sheet(wb, ws, 'Сверка');
|
|
const wbOut = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
|
|
downloadFile(wbOut, filename);
|
|
}
|
|
|
|
/**
|
|
* Форматировать число в рубли (с пробелами как разделителями разрядов)
|
|
* @param {number} num
|
|
* @returns {string}
|
|
*/
|
|
export function formatMoney(num) {
|
|
if (num === null || num === undefined || isNaN(num)) return '—';
|
|
return num.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
|
|
}
|