| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Excel File Reader - Show All Text</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .file-input-wrapper { |
| position: relative; |
| overflow: hidden; |
| display: inline-block; |
| } |
| .file-input-wrapper input[type=file] { |
| font-size: 100px; |
| position: absolute; |
| left: 0; |
| top: 0; |
| opacity: 0; |
| cursor: pointer; |
| } |
| .excel-grid-container { |
| position: relative; |
| overflow: auto; |
| border: 1px solid #e2e8f0; |
| border-radius: 0.5rem; |
| max-height: none !important; |
| } |
| .excel-sheet { |
| position: relative; |
| min-width: 100%; |
| } |
| .excel-cell { |
| position: absolute; |
| box-sizing: border-box; |
| border: 1px solid #e2e8f0; |
| padding: 4px 8px; |
| font-size: 14px; |
| overflow: visible; |
| white-space: normal; |
| word-wrap: break-word; |
| background-color: white; |
| min-height: 30px; |
| } |
| .excel-header { |
| background-color: #f8fafc; |
| font-weight: 600; |
| } |
| .excel-col-header { |
| position: absolute; |
| top: 0; |
| z-index: 10; |
| background-color: #f8fafc; |
| font-weight: 600; |
| text-align: center; |
| border: 1px solid #e2e8f0; |
| } |
| .excel-row-header { |
| position: sticky; |
| left: 0; |
| z-index: 10; |
| background-color: #f8fafc; |
| font-weight: 600; |
| text-align: center; |
| border: 1px solid #e2e8f0; |
| } |
| .excel-corner { |
| position: sticky; |
| top: 0; |
| left: 0; |
| z-index: 20; |
| background-color: #f8fafc; |
| border: 1px solid #e2e8f0; |
| } |
| .merged-cell { |
| background-color: #f0f9ff; |
| } |
| .text-bold { |
| font-weight: bold; |
| } |
| .text-italic { |
| font-style: italic; |
| } |
| .text-underline { |
| text-decoration: underline; |
| } |
| .text-center { |
| text-align: center; |
| } |
| .text-right { |
| text-align: right; |
| } |
| .text-left { |
| text-align: left; |
| } |
| .bg-yellow { |
| background-color: #fef9c3; |
| } |
| .bg-green { |
| background-color: #dcfce7; |
| } |
| .bg-red { |
| background-color: #fee2e2; |
| } |
| .bg-blue { |
| background-color: #dbeafe; |
| } |
| .pulse { |
| animation: pulse 2s infinite; |
| } |
| @keyframes pulse { |
| 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); } |
| 70% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); } |
| 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); } |
| } |
| .sheet-tab { |
| transition: all 0.2s ease; |
| } |
| .sheet-tab:hover { |
| transform: translateY(-2px); |
| } |
| .sheet-tab.active { |
| border-bottom: 3px solid #3b82f6; |
| font-weight: 600; |
| } |
| |
| .auto-height { |
| height: auto !important; |
| min-height: 30px; |
| } |
| .text-preserve { |
| white-space: pre-wrap !important; |
| overflow: visible !important; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 min-h-screen"> |
| <div class="container mx-auto px-4 py-8"> |
| <div class="max-w-6xl mx-auto"> |
| |
| <div class="text-center mb-10"> |
| <h1 class="text-4xl font-bold text-blue-600 mb-2">Excel File Reader</h1> |
| <p class="text-gray-600">View your Excel files with all text preserved</p> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8 transition-all duration-300 hover:shadow-lg"> |
| <div class="p-6"> |
| <div class="flex flex-col items-center justify-center py-12 px-4 border-2 border-dashed border-gray-300 rounded-lg bg-gray-50"> |
| <div class="file-input-wrapper"> |
| <button id="uploadBtn" class="flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 pulse"> |
| <i class="fas fa-file-excel mr-2"></i> |
| Choose Excel File |
| </button> |
| <input id="fileInput" type="file" accept=".xlsx, .xls" class="hidden"> |
| </div> |
| <p class="mt-4 text-gray-500">or drag and drop your file here</p> |
| <p class="text-sm text-gray-400 mt-2">Supports .xlsx and .xls files</p> |
| </div> |
| <div id="fileInfo" class="mt-4 hidden"> |
| <div class="flex items-center justify-between bg-blue-50 p-3 rounded-lg"> |
| <div class="flex items-center"> |
| <i class="fas fa-file-excel text-blue-600 text-xl mr-3"></i> |
| <div> |
| <p id="fileName" class="font-medium text-gray-800"></p> |
| <p id="fileSize" class="text-sm text-gray-500"></p> |
| </div> |
| </div> |
| <button id="clearBtn" class="text-red-500 hover:text-red-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="sheetsNav" class="hidden mb-6"> |
| <div class="flex space-x-1 overflow-x-auto pb-2"> |
| |
| </div> |
| </div> |
|
|
| |
| <div id="dataPreview" class="hidden"> |
| <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8"> |
| <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center"> |
| <h3 class="text-lg font-medium text-gray-900">Sheet Preview</h3> |
| <div class="flex space-x-2"> |
| <button id="downloadJsonBtn" class="flex items-center px-3 py-1.5 bg-green-100 text-green-800 rounded-md text-sm hover:bg-green-200"> |
| <i class="fas fa-file-code mr-1"></i> JSON |
| </button> |
| <button id="downloadCsvBtn" class="flex items-center px-3 py-1.5 bg-blue-100 text-blue-800 rounded-md text-sm hover:bg-blue-200"> |
| <i class="fas fa-file-csv mr-1"></i> CSV |
| </button> |
| <button id="toggleAutoHeight" class="flex items-center px-3 py-1.5 bg-purple-100 text-purple-800 rounded-md text-sm hover:bg-purple-200"> |
| <i class="fas fa-arrows-alt-v mr-1"></i> Auto Height |
| </button> |
| </div> |
| </div> |
| <div class="p-6"> |
| <div class="excel-grid-container" style="max-height: 70vh;"> |
| <div id="excelContainer"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="statsSection" class="hidden"> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8"> |
| <div class="bg-white rounded-xl shadow-md p-6"> |
| <div class="flex items-center"> |
| <div class="p-3 rounded-full bg-blue-100 text-blue-600 mr-4"> |
| <i class="fas fa-table text-lg"></i> |
| </div> |
| <div> |
| <p class="text-sm text-gray-500">Sheets</p> |
| <p id="sheetsCount" class="text-2xl font-semibold">0</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-xl shadow-md p-6"> |
| <div class="flex items-center"> |
| <div class="p-3 rounded-full bg-green-100 text-green-600 mr-4"> |
| <i class="fas fa-columns text-lg"></i> |
| </div> |
| <div> |
| <p class="text-sm text-gray-500">Columns</p> |
| <p id="columnsCount" class="text-2xl font-semibold">0</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-white rounded-xl shadow-md p-6"> |
| <div class="flex items-center"> |
| <div class="p-3 rounded-full bg-purple-100 text-purple-600 mr-4"> |
| <i class="fas fa-list text-lg"></i> |
| </div> |
| <div> |
| <p class="text-sm text-gray-500">Rows</p> |
| <p id="rowsCount" class="text-2xl font-semibold">0</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| const fileInput = document.getElementById('fileInput'); |
| const uploadBtn = document.getElementById('uploadBtn'); |
| const fileInfo = document.getElementById('fileInfo'); |
| const fileName = document.getElementById('fileName'); |
| const fileSize = document.getElementById('fileSize'); |
| const clearBtn = document.getElementById('clearBtn'); |
| const sheetsNav = document.getElementById('sheetsNav'); |
| const dataPreview = document.getElementById('dataPreview'); |
| const excelContainer = document.getElementById('excelContainer'); |
| const downloadJsonBtn = document.getElementById('downloadJsonBtn'); |
| const downloadCsvBtn = document.getElementById('downloadCsvBtn'); |
| const toggleAutoHeight = document.getElementById('toggleAutoHeight'); |
| const statsSection = document.getElementById('statsSection'); |
| const sheetsCount = document.getElementById('sheetsCount'); |
| const columnsCount = document.getElementById('columnsCount'); |
| const rowsCount = document.getElementById('rowsCount'); |
| let workbook = null; |
| let currentSheet = null; |
| let jsonData = null; |
| let autoHeightEnabled = false; |
| const cellWidth = 120; |
| const defaultCellHeight = 30; |
| const headerSize = 25; |
| |
| uploadBtn.addEventListener('click', function() { |
| fileInput.click(); |
| }); |
| fileInput.addEventListener('change', function(e) { |
| if (e.target.files.length) { |
| const file = e.target.files[0]; |
| processFile(file); |
| } |
| }); |
| |
| const dropArea = document.querySelector('.bg-gray-50'); |
| |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| dropArea.addEventListener(eventName, preventDefaults, false); |
| }); |
| function preventDefaults(e) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
| ['dragenter', 'dragover'].forEach(eventName => { |
| dropArea.addEventListener(eventName, highlight, false); |
| }); |
| ['dragleave', 'drop'].forEach(eventName => { |
| dropArea.addEventListener(eventName, unhighlight, false); |
| }); |
| function highlight() { |
| dropArea.classList.add('bg-blue-50', 'border-blue-300'); |
| } |
| function unhighlight() { |
| dropArea.classList.remove('bg-blue-50', 'border-blue-300'); |
| } |
| dropArea.addEventListener('drop', function(e) { |
| const dt = e.dataTransfer; |
| const file = dt.files[0]; |
| |
| if (file && (file.name.endsWith('.xlsx') || file.name.endsWith('.xls'))) { |
| fileInput.files = dt.files; |
| processFile(file); |
| } else { |
| alert('Please upload an Excel file (.xlsx or .xls)'); |
| } |
| }); |
| |
| clearBtn.addEventListener('click', function() { |
| resetUI(); |
| }); |
| |
| toggleAutoHeight.addEventListener('click', function() { |
| autoHeightEnabled = !autoHeightEnabled; |
| if (autoHeightEnabled) { |
| this.classList.add('bg-purple-200'); |
| this.classList.remove('bg-purple-100'); |
| document.querySelectorAll('.excel-cell').forEach(cell => { |
| cell.classList.add('auto-height'); |
| cell.style.height = 'auto'; |
| }); |
| } else { |
| this.classList.remove('bg-purple-200'); |
| this.classList.add('bg-purple-100'); |
| document.querySelectorAll('.excel-cell').forEach(cell => { |
| cell.classList.remove('auto-height'); |
| cell.style.height = defaultCellHeight + 'px'; |
| }); |
| } |
| |
| if (workbook && currentSheet) { |
| loadSheet(currentSheet); |
| } |
| }); |
| |
| function processFile(file) { |
| fileName.textContent = file.name; |
| fileSize.textContent = formatFileSize(file.size); |
| fileInfo.classList.remove('hidden'); |
| uploadBtn.classList.remove('pulse'); |
| const reader = new FileReader(); |
| reader.onload = function(e) { |
| const data = new Uint8Array(e.target.result); |
| workbook = XLSX.read(data, { type: 'array', cellStyles: true, cellText: true }); |
| |
| |
| sheetsCount.textContent = workbook.SheetNames.length; |
| |
| |
| renderSheetsNav(workbook.SheetNames); |
| |
| |
| loadSheet(workbook.SheetNames[0]); |
| |
| |
| dataPreview.classList.remove('hidden'); |
| statsSection.classList.remove('hidden'); |
| }; |
| reader.readAsArrayBuffer(file); |
| } |
| |
| function formatFileSize(bytes) { |
| if (bytes === 0) return '0 Bytes'; |
| const k = 1024; |
| const sizes = ['Bytes', 'KB', 'MB', 'GB']; |
| const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; |
| } |
| |
| function renderSheetsNav(sheetNames) { |
| sheetsNav.classList.remove('hidden'); |
| const sheetsContainer = sheetsNav.querySelector('.flex'); |
| sheetsContainer.innerHTML = ''; |
| |
| sheetNames.forEach((name, index) => { |
| const tab = document.createElement('button'); |
| tab.className = `sheet-tab px-4 py-2 text-sm font-medium text-gray-600 hover:text-blue-600 ${index === 0 ? 'active' : ''}`; |
| tab.textContent = name; |
| tab.dataset.sheetName = name; |
| tab.addEventListener('click', function() { |
| document.querySelectorAll('.sheet-tab').forEach(t => t.classList.remove('active')); |
| this.classList.add('active'); |
| loadSheet(this.dataset.sheetName); |
| }); |
| sheetsContainer.appendChild(tab); |
| }); |
| } |
| |
| function loadSheet(sheetName) { |
| currentSheet = sheetName; |
| const worksheet = workbook.Sheets[sheetName]; |
| |
| |
| const range = worksheet['!ref'] ? XLSX.utils.decode_range(worksheet['!ref']) : {s: {c:0, r:0}, e: {c:0, r:0}}; |
| |
| |
| columnsCount.textContent = range.e.c - range.s.c + 1; |
| rowsCount.textContent = range.e.r - range.s.r + 1; |
| |
| |
| renderExcelSheet(worksheet, range); |
| } |
| |
| function renderExcelSheet(worksheet, range) { |
| excelContainer.innerHTML = ''; |
| |
| |
| const sheetContainer = document.createElement('div'); |
| sheetContainer.className = 'excel-sheet'; |
| |
| |
| const width = (range.e.c - range.s.c + 1) * cellWidth + headerSize; |
| const height = (range.e.r - range.s.r + 1) * defaultCellHeight + headerSize; |
| |
| sheetContainer.style.width = `${width}px`; |
| sheetContainer.style.height = `${height}px`; |
| |
| |
| const cornerHeader = document.createElement('div'); |
| cornerHeader.className = 'excel-corner'; |
| cornerHeader.style.width = `${headerSize}px`; |
| cornerHeader.style.height = `${headerSize}px`; |
| cornerHeader.style.top = '0'; |
| cornerHeader.style.left = '0'; |
| sheetContainer.appendChild(cornerHeader); |
| |
| |
| for (let C = range.s.c; C <= range.e.c; ++C) { |
| const colHeader = document.createElement('div'); |
| colHeader.className = 'excel-col-header'; |
| colHeader.style.width = `${cellWidth}px`; |
| colHeader.style.height = `${headerSize}px`; |
| colHeader.style.left = `${headerSize + (C - range.s.c) * cellWidth}px`; |
| colHeader.style.top = '0'; |
| colHeader.textContent = XLSX.utils.encode_col(C); |
| sheetContainer.appendChild(colHeader); |
| } |
| |
| |
| for (let R = range.s.r; R <= range.e.r; ++R) { |
| const rowHeader = document.createElement('div'); |
| rowHeader.className = 'excel-row-header'; |
| rowHeader.style.width = `${headerSize}px`; |
| rowHeader.style.height = `${defaultCellHeight}px`; |
| rowHeader.style.left = '0'; |
| rowHeader.style.top = `${headerSize + (R - range.s.r) * defaultCellHeight}px`; |
| rowHeader.textContent = (R + 1).toString(); |
| sheetContainer.appendChild(rowHeader); |
| } |
| |
| |
| for (let R = range.s.r; R <= range.e.r; ++R) { |
| for (let C = range.s.c; C <= range.e.c; ++C) { |
| const cell_address = {c: C, r: R}; |
| const cell_ref = XLSX.utils.encode_cell(cell_address); |
| |
| |
| const cell = document.createElement('div'); |
| cell.className = 'excel-cell text-preserve'; |
| cell.style.width = `${cellWidth}px`; |
| cell.style.left = `${headerSize + (C - range.s.c) * cellWidth}px`; |
| cell.style.top = `${headerSize + (R - range.s.r) * defaultCellHeight}px`; |
| |
| |
| if (worksheet[cell_ref]) { |
| const excelCell = worksheet[cell_ref]; |
| |
| |
| if (excelCell.w) { |
| |
| cell.innerHTML = excelCell.w.replace(/\n/g, '<br>'); |
| } else if (excelCell.v !== undefined && excelCell.v !== null) { |
| |
| if (typeof excelCell.v === 'string') { |
| cell.innerHTML = excelCell.v.replace(/\n/g, '<br>'); |
| } else { |
| cell.textContent = excelCell.v.toString(); |
| } |
| } |
| |
| |
| applyCellStyles(cell, excelCell); |
| |
| |
| if (worksheet['!merges']) { |
| const merge = worksheet['!merges'].find(m => { |
| return R >= m.s.r && R <= m.e.r && |
| C >= m.s.c && C <= m.e.c; |
| }); |
| |
| if (merge) { |
| cell.classList.add('merged-cell'); |
| cell.style.width = `${(merge.e.c - merge.s.c + 1) * cellWidth}px`; |
| |
| |
| if (autoHeightEnabled) { |
| cell.style.height = 'auto'; |
| cell.classList.add('auto-height'); |
| } else { |
| cell.style.height = `${(merge.e.r - merge.s.r + 1) * defaultCellHeight}px`; |
| } |
| |
| |
| if (!cell.style.textAlign) { |
| cell.style.textAlign = 'center'; |
| cell.style.display = 'flex'; |
| cell.style.alignItems = 'center'; |
| cell.style.justifyContent = 'center'; |
| } |
| } |
| } |
| |
| |
| if (autoHeightEnabled && !cell.classList.contains('merged-cell')) { |
| cell.style.height = 'auto'; |
| cell.classList.add('auto-height'); |
| } else if (!cell.classList.contains('merged-cell')) { |
| cell.style.height = defaultCellHeight + 'px'; |
| } |
| } else { |
| |
| cell.style.height = defaultCellHeight + 'px'; |
| if (autoHeightEnabled) { |
| cell.style.height = 'auto'; |
| cell.classList.add('auto-height'); |
| } |
| } |
| |
| sheetContainer.appendChild(cell); |
| } |
| } |
| |
| excelContainer.appendChild(sheetContainer); |
| |
| |
| if (autoHeightEnabled) { |
| adjustCellHeights(); |
| } |
| } |
| |
| function adjustCellHeights() { |
| document.querySelectorAll('.excel-cell').forEach(cell => { |
| |
| const clone = document.createElement('div'); |
| clone.style.position = 'absolute'; |
| clone.style.visibility = 'hidden'; |
| clone.style.width = cell.offsetWidth + 'px'; |
| clone.style.padding = window.getComputedStyle(cell).padding; |
| clone.style.whiteSpace = 'pre-wrap'; |
| clone.style.wordWrap = 'break-word'; |
| clone.innerHTML = cell.innerHTML; |
| |
| document.body.appendChild(clone); |
| const height = clone.offsetHeight + 8; |
| document.body.removeChild(clone); |
| |
| |
| cell.style.height = Math.max(height, defaultCellHeight) + 'px'; |
| }); |
| } |
| |
| function applyCellStyles(cell, excelCell) { |
| if (!excelCell.s) return; |
| |
| const style = excelCell.s; |
| let cellStyle = ''; |
| |
| |
| if (style.font) { |
| const font = style.font; |
| |
| if (font.bold) cell.classList.add('text-bold'); |
| if (font.italic) cell.classList.add('text-italic'); |
| if (font.underline) cell.classList.add('text-underline'); |
| |
| |
| if (font.name) { |
| cellStyle += `font-family: ${font.name}, sans-serif;`; |
| } |
| |
| |
| if (font.color && font.color.rgb) { |
| cellStyle += `color: #${font.color.rgb.slice(2)};`; |
| } |
| |
| |
| if (font.sz) { |
| cellStyle += `font-size: ${font.sz}pt;`; |
| } |
| } |
| |
| |
| if (style.alignment) { |
| const align = style.alignment.horizontal; |
| if (align === 'center') { |
| cell.classList.add('text-center'); |
| } else if (align === 'right') { |
| cell.classList.add('text-right'); |
| } else if (align === 'left') { |
| cell.classList.add('text-left'); |
| } |
| |
| |
| if (style.alignment.vertical) { |
| const vertical = style.alignment.vertical; |
| if (vertical === 'top') { |
| cellStyle += 'vertical-align: top;'; |
| } else if (vertical === 'center') { |
| cellStyle += 'vertical-align: middle;'; |
| } else if (vertical === 'bottom') { |
| cellStyle += 'vertical-align: bottom;'; |
| } |
| |
| |
| cellStyle += 'display: flex; align-items: center;'; |
| } |
| |
| |
| cellStyle += 'white-space: pre-wrap; word-wrap: break-word; overflow: visible;'; |
| |
| |
| if (style.alignment.indent) { |
| cellStyle += `padding-left: ${style.alignment.indent * 10}px;`; |
| } |
| } |
| |
| |
| if (style.fill && style.fill.fgColor && style.fill.fgColor.rgb) { |
| const bgColor = `#${style.fill.fgColor.rgb.slice(2)}`; |
| cellStyle += `background-color: ${bgColor};`; |
| } else if (style.fill && style.fill.patternType === 'solid' && style.fill.bgColor && style.fill.bgColor.rgb) { |
| const bgColor = `#${style.fill.bgColor.rgb.slice(2)}`; |
| cellStyle += `background-color: ${bgColor};`; |
| } |
| |
| |
| if (style.border) { |
| const border = style.border; |
| |
| if (border.top && border.top.style) { |
| const color = border.top.color?.rgb ? `#${border.top.color.rgb.slice(2)}` : '#94a3b8'; |
| const width = border.top.style === 'thin' ? '1px' : |
| border.top.style === 'medium' ? '2px' : |
| border.top.style === 'thick' ? '3px' : '1px'; |
| cellStyle += `border-top: ${width} solid ${color};`; |
| } |
| if (border.bottom && border.bottom.style) { |
| const color = border.bottom.color?.rgb ? `#${border.bottom.color.rgb.slice(2)}` : '#94a3b8'; |
| const width = border.bottom.style === 'thin' ? '1px' : |
| border.bottom.style === 'medium' ? '2px' : |
| border.bottom.style === 'thick' ? '3px' : '1px'; |
| cellStyle += `border-bottom: ${width} solid ${color};`; |
| } |
| if (border.left && border.left.style) { |
| const color = border.left.color?.rgb ? `#${border.left.color.rgb.slice(2)}` : '#94a3b8'; |
| const width = border.left.style === 'thin' ? '1px' : |
| border.left.style === 'medium' ? '2px' : |
| border.left.style === 'thick' ? '3px' : '1px'; |
| cellStyle += `border-left: ${width} solid ${color};`; |
| } |
| if (border.right && border.right.style) { |
| const color = border.right.color?.rgb ? `#${border.right.color.rgb.slice(2)}` : '#94a3b8'; |
| const width = border.right.style === 'thin' ? '1px' : |
| border.right.style === 'medium' ? '2px' : |
| border.right.style === 'thick' ? '3px' : '1px'; |
| cellStyle += `border-right: ${width} solid ${color};`; |
| } |
| } |
| |
| |
| if (excelCell.z) { |
| |
| |
| } |
| |
| |
| if (cellStyle) { |
| cell.style.cssText += cellStyle; |
| } |
| |
| |
| cell.style.padding = '4px 8px'; |
| } |
| |
| downloadJsonBtn.addEventListener('click', function() { |
| if (!workbook || !currentSheet) return; |
| |
| const worksheet = workbook.Sheets[currentSheet]; |
| const json = XLSX.utils.sheet_to_json(worksheet); |
| |
| const blob = new Blob([JSON.stringify(json, null, 2)], { type: 'application/json' }); |
| const url = URL.createObjectURL(blob); |
| |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `${currentSheet}.json`; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| }); |
| |
| downloadCsvBtn.addEventListener('click', function() { |
| if (!workbook || !currentSheet) return; |
| |
| const worksheet = workbook.Sheets[currentSheet]; |
| const csv = XLSX.utils.sheet_to_csv(worksheet); |
| |
| const blob = new Blob([csv], { type: 'text/csv' }); |
| const url = URL.createObjectURL(blob); |
| |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `${currentSheet}.csv`; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| }); |
| |
| function resetUI() { |
| fileInput.value = ''; |
| fileInfo.classList.add('hidden'); |
| sheetsNav.classList.add('hidden'); |
| dataPreview.classList.add('hidden'); |
| statsSection.classList.add('hidden'); |
| uploadBtn.classList.add('pulse'); |
| workbook = null; |
| currentSheet = null; |
| jsonData = null; |
| excelContainer.innerHTML = ''; |
| autoHeightEnabled = false; |
| toggleAutoHeight.classList.remove('bg-purple-200'); |
| toggleAutoHeight.classList.add('bg-purple-100'); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=KEXEL/excel-file-reader" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |
|
|