From beee0eac64e15fc20fc53c78165ee1abe56ed767 Mon Sep 17 00:00:00 2001 From: user01 Date: Fri, 15 May 2026 19:06:28 +0900 Subject: [PATCH] Compress photos on upload to fit Excel 32,767-char cell limit - Add compressImage(): resize to max 400px width, JPEG quality 0.5 - Replace FileReader with canvas-based compression in handlePhotoUpload - Add try-catch in export with alert on overflow --- index.html | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 28ee219..e716782 100644 --- a/index.html +++ b/index.html @@ -458,12 +458,29 @@ function esc(s) { // ═══════════════════════════════════════════════════════════ // ─── Photo ───────────────────────────────────────────── // ═══════════════════════════════════════════════════════════ -function handlePhotoUpload(flagId, file) { +function compressImage(file, maxW = 400, quality = 0.5) { + return new Promise((resolve) => { + const img = new Image(); + const url = URL.createObjectURL(file); + img.onload = () => { + URL.revokeObjectURL(url); + let w = img.width, h = img.height; + if (w > maxW) { h = h * maxW / w; w = maxW; } + const c = document.createElement('canvas'); + c.width = w; c.height = h; + const ctx = c.getContext('2d'); + ctx.drawImage(img, 0, 0, w, h); + resolve(c.toDataURL('image/jpeg', quality)); + }; + img.src = url; + }); +} + +async function handlePhotoUpload(flagId, file) { const flag = flags.find(f => f.id === flagId); if (!flag || !file) return; - const reader = new FileReader(); - reader.onload = (e) => { flag.photoData = e.target.result; renderList(); }; - reader.readAsDataURL(file); + flag.photoData = await compressImage(file); + renderList(); } function removePhoto(flagId) { @@ -692,10 +709,16 @@ document.getElementById('export-btn').addEventListener('click', () => { Photo: f.photoData ?? '', })); const wb = XLSX.utils.book_new(); - const ws = XLSX.utils.json_to_sheet(rows); + const ws = XLSX.utils.json_to_sheet(rows, { cellDates: true }); ws['!cols'] = [{ wch: 12 }, { wch: 20 }, { wch: 10 }, { wch: 12 }, { wch: 12 }, { wch: 60 }, { wch: 30 }]; XLSX.utils.book_append_sheet(wb, ws, 'Flags'); - XLSX.writeFile(wb, 'flag_export.xlsx'); + try { + XLSX.writeFile(wb, 'flag_export.xlsx'); + } catch (e) { + if (e.message?.includes('32767')) { + alert('Photo data is too large. Try uploading smaller photos.'); + } else { throw e; } + } }); // ═══════════════════════════════════════════════════════════