From 8d84056cc193f3c519c34998908ce81f27880219 Mon Sep 17 00:00:00 2001 From: host Date: Thu, 30 Jul 2026 17:14:05 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils.js | 95 -------------------------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 utils.js diff --git a/utils.js b/utils.js deleted file mode 100644 index 23fb721..0000000 --- a/utils.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * utils.js — Вспомогательные утилиты - * Чтение Excel, работа с CSV, скачивание файлов - */ - -/** - * Прочитать Excel-файл и вернуть массив листов - * @param {File} file - файл .xlsx/.xls - * @returns {Promise>} - */ -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 }); -}