sozday-sovremennyy-veb-sayt/excel-editor.html

318 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru" data-theme="auto">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Excel Редактор | Сопоставление данных</title>
<link rel="icon" href="design-system/brand/kt-ai-logo.png">
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
<link rel="stylesheet" href="design-system/kt-ai-components.css">
<link rel="stylesheet" href="design-system/kt-ai-page.css">
<style>
.kt-ai-btn { text-decoration: none; }
.upload-zone {
border: 2px dashed var(--kt-ai-border);
border-radius: var(--kt-ai-radius-xl);
padding: var(--kt-ai-space-8);
text-align: center;
cursor: pointer;
transition: all 0.2s;
background: var(--kt-ai-bg-soft);
}
.upload-zone:hover {
border-color: var(--kt-ai-primary);
background: var(--kt-ai-primary-bg);
}
.upload-zone.has-file {
border-color: var(--kt-ai-success);
background: var(--kt-ai-success-bg);
}
.file-info {
margin-top: var(--kt-ai-space-3);
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
}
.mapping-row {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: var(--kt-ai-space-3);
align-items: center;
padding: var(--kt-ai-space-3);
border-radius: var(--kt-ai-radius-lg);
background: var(--kt-ai-bg-soft);
margin-bottom: var(--kt-ai-space-2);
}
.mapping-row.matched {
background: var(--kt-ai-success-bg);
}
.mapping-row.no-match {
background: var(--kt-ai-warning-bg);
}
.column-badge {
padding: var(--kt-ai-space-1) var(--kt-ai-space-2);
border-radius: var(--kt-ai-radius-md);
background: var(--kt-ai-card-bg);
border: 1px solid var(--kt-ai-border);
font-size: var(--kt-ai-text-xs);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.preview-table {
width: 100%;
border-collapse: collapse;
font-size: var(--kt-ai-text-sm);
}
.preview-table th,
.preview-table td {
padding: var(--kt-ai-space-2) var(--kt-ai-space-3);
border: 1px solid var(--kt-ai-border);
text-align: left;
}
.preview-table th {
background: var(--kt-ai-bg-soft);
font-weight: var(--kt-ai-weight-semibold);
position: sticky;
top: 0;
}
.preview-table tr:nth-child(even) {
background: var(--kt-ai-bg-soft);
}
.preview-table tr:hover {
background: var(--kt-ai-primary-bg);
}
.table-container {
max-height: 400px;
overflow: auto;
border: 1px solid var(--kt-ai-border);
border-radius: var(--kt-ai-radius-lg);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--kt-ai-space-4);
margin: var(--kt-ai-space-4) 0;
}
.stat-card {
padding: var(--kt-ai-space-4);
border-radius: var(--kt-ai-radius-lg);
background: var(--kt-ai-card-bg);
border: 1px solid var(--kt-ai-border);
}
.stat-value {
font-size: var(--kt-ai-text-2xl);
font-weight: var(--kt-ai-weight-bold);
color: var(--kt-ai-fg);
}
.stat-label {
font-size: var(--kt-ai-text-xs);
color: var(--kt-ai-fg-muted);
margin-top: var(--kt-ai-space-1);
}
.step-indicator {
display: flex;
gap: var(--kt-ai-space-2);
margin-bottom: var(--kt-ai-space-6);
}
.step {
flex: 1;
padding: var(--kt-ai-space-3);
border-radius: var(--kt-ai-radius-lg);
background: var(--kt-ai-bg-soft);
border: 2px solid var(--kt-ai-border);
text-align: center;
font-size: var(--kt-ai-text-sm);
font-weight: var(--kt-ai-weight-semibold);
}
.step.active {
border-color: var(--kt-ai-primary);
background: var(--kt-ai-primary-bg);
color: var(--kt-ai-primary-fg);
}
.step.completed {
border-color: var(--kt-ai-success);
background: var(--kt-ai-success-bg);
}
.hidden { display: none; }
</style>
</head>
<body>
<header class="kt-ai-pagehead">
<div class="kt-ai-wrap kt-ai-pagehead-in">
<div style="display: flex; align-items: center; gap: var(--kt-ai-space-3);">
<img src="design-system/brand/kt-ai-logo.png" alt="" height="24">
<strong>Excel Редактор</strong>
</div>
<span class="kt-ai-spacer"></span>
<a class="kt-ai-btn" data-variant="ghost" href="index.html">← Назад</a>
</div>
</header>
<main>
<section class="kt-ai-hero" data-align="center">
<div class="kt-ai-wrap">
<h1>Сопоставление Excel файлов</h1>
<p class="kt-ai-hero-sub">Заполните пустые столбцы шаблона данными из основного файла по номеру телефона или лицевому счету</p>
</div>
</section>
<div class="kt-ai-wrap">
<div class="step-indicator">
<div class="step active" id="step1">1. Загрузка файлов</div>
<div class="step" id="step2">2. Настройка полей</div>
<div class="step" id="step3">3. Результат</div>
</div>
<!-- STEP 1: UPLOAD -->
<div id="upload-section">
<div class="kt-ai-section">
<div class="kt-ai-wrap">
<div class="kt-ai-section-head">
<h2>Загрузите файлы</h2>
<p>Основной файл содержит данные для заполнения, шаблон — файл для заполнения</p>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--kt-ai-space-6); margin-top: var(--kt-ai-space-6);">
<div>
<h3 style="margin-bottom: var(--kt-ai-space-3);">Основной файл</h3>
<div class="upload-zone" id="main-upload" onclick="document.getElementById('main-file').click()">
<svg class="kt-icon kt-icon-lg" style="color: var(--kt-ai-primary);" aria-hidden="true"><use href="#file"></use></svg>
<p style="margin-top: var(--kt-ai-space-3); font-weight: var(--kt-ai-weight-medium);">Основной файл с данными</p>
<p style="font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); margin-top: var(--kt-ai-space-1);">.xlsx, .xls, .csv</p>
<div class="file-info" id="main-file-info"></div>
</div>
<input type="file" id="main-file" accept=".xlsx,.xls,.csv" style="display: none;" onchange="handleFileSelect(event, 'main')">
</div>
<div>
<h3 style="margin-bottom: var(--kt-ai-space-3);">Файл-шаблон</h3>
<div class="upload-zone" id="template-upload" onclick="document.getElementById('template-file').click()">
<svg class="kt-icon kt-icon-lg" style="color: var(--kt-ai-primary);" aria-hidden="true"><use href="#file"></use></svg>
<p style="margin-top: var(--kt-ai-space-3); font-weight: var(--kt-ai-weight-medium);">Шаблон для заполнения</p>
<p style="font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg-muted); margin-top: var(--kt-ai-space-1);">.xlsx, .xls, .csv</p>
<div class="file-info" id="template-file-info"></div>
</div>
<input type="file" id="template-file" accept=".xlsx,.xls,.csv" style="display: none;" onchange="handleFileSelect(event, 'template')">
</div>
</div>
<div style="margin-top: var(--kt-ai-space-6); text-align: center;">
<button class="kt-ai-btn" data-variant="primary" data-size="lg" id="btn-mapping" onclick="goToMapping()" disabled>
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#arrowRight"></use></svg>
Продолжить
</button>
</div>
</div>
</div>
</div>
<!-- STEP 2: MAPPING -->
<div id="mapping-section" class="hidden">
<div class="kt-ai-section">
<div class="kt-ai-wrap">
<div class="kt-ai-section-head">
<h2>Настройте поля для сопоставления</h2>
<p>Укажите, какие поля использовать для поиска соответствий</p>
</div>
<div class="kt-ai-card" style="padding: var(--kt-ai-space-5); margin-top: var(--kt-ai-space-4);">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-4);">
<div class="kt-ai-field">
<label>Поле из основного файла</label>
<select class="kt-ai-select" id="main-key-field" onchange="processMapping()"></select>
</div>
<div class="kt-ai-field">
<label>Поле из шаблона</label>
<select class="kt-ai-select" id="template-key-field" onchange="processMapping()"></select>
</div>
</div>
<div style="margin-bottom: var(--kt-ai-space-4);">
<label style="font-weight: var(--kt-ai-weight-semibold); display: block; margin-bottom: var(--kt-ai-space-2);">Поля для заполнения:</label>
<div id="fields-to-fill"></div>
</div>
<div id="mapping-stats" class="stats-grid"></div>
</div>
<div class="kt-ai-card" style="padding: var(--kt-ai-space-5); margin-top: var(--kt-ai-space-4);">
<h3 style="margin-bottom: var(--kt-ai-space-4);">Предпросмотр сопоставления</h3>
<div class="table-container">
<table class="preview-table" id="mapping-preview"></table>
</div>
</div>
<div style="margin-top: var(--kt-ai-space-6); display: flex; gap: var(--kt-ai-space-3);">
<button class="kt-ai-btn" data-variant="ghost" onclick="goBackToUpload()">Назад</button>
<button class="kt-ai-btn" data-variant="primary" data-size="lg" id="btn-process" onclick="processFiles()" disabled>
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#rocket"></use></svg>
Заполнить и скачать результат
</button>
</div>
</div>
</div>
</div>
<!-- STEP 3: RESULT -->
<div id="result-section" class="hidden">
<div class="kt-ai-section">
<div class="kt-ai-wrap">
<div class="kt-ai-section-head">
<h2>Готово!</h2>
<p>Файл успешно обработан</p>
</div>
<div class="kt-ai-card" style="padding: var(--kt-ai-space-6); text-align: center;">
<svg class="kt-icon kt-icon-lg" style="color: var(--kt-ai-success);" aria-hidden="true"><use href="#check"></use></svg>
<h3 style="margin: var(--kt-ai-space-4) 0;">Файл готов к скачиванию</h3>
<p style="color: var(--kt-ai-fg-muted); margin-bottom: var(--kt-ai-space-4);">Все пустые столбцы заполнены данными из основного файла</p>
<div style="display: flex; gap: var(--kt-ai-space-3); justify-content: center; margin-top: var(--kt-ai-space-4);">
<a class="kt-ai-btn" data-variant="primary" data-size="lg" id="download-link" href="#">
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#download"></use></svg>
Скачать Excel
</a>
<button class="kt-ai-btn" data-variant="ghost" onclick="location.reload()">
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#refresh"></use></svg>
Обработать ещё
</button>
</div>
</div>
<div class="stats-grid" id="result-stats"></div>
</div>
</div>
</div>
</div>
</main>
<footer class="kt-ai-wrap kt-ai-pagefoot">
<span>© 2026 Excel Редактор</span>
<span class="kt-ai-spacer"></span>
<span>Сопоставление данных по ключевым полям</span>
</footer>
<script src="https://cdn.sheetjs.com/xlsx-0.20.1/package/dist/xlsx.full.min.js"></script>
<script>
// Проверка загрузки библиотеки
window.addEventListener('DOMContentLoaded', function() {
console.log('DOM загружен');
if (window.XLSX) {
console.log('SheetJS версии:', XLSX.version);
} else {
console.error('SheetJS НЕ загружен!');
document.getElementById('upload-section').innerHTML =
'<div class="kt-ai-card" style="padding: var(--kt-ai-space-5); text-align: center; background: var(--kt-ai-danger-bg);">' +
'<h3>Ошибка загрузки библиотеки</h3>' +
'<p>Не удалось загрузить библиотеку для работы с Excel.</p>' +
'<p>Проверьте подключение к интернету или обновите страницу.</p>' +
'</div>';
}
});
</script>
<script src="excel-editor.js"></script>
</body>
</html>