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
This commit is contained in:
2026-05-15 19:06:28 +09:00
parent 16e78a7a74
commit beee0eac64

View File

@@ -458,12 +458,29 @@ function esc(s) {
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════
// ─── Photo ───────────────────────────────────────────── // ─── 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); const flag = flags.find(f => f.id === flagId);
if (!flag || !file) return; if (!flag || !file) return;
const reader = new FileReader(); flag.photoData = await compressImage(file);
reader.onload = (e) => { flag.photoData = e.target.result; renderList(); }; renderList();
reader.readAsDataURL(file);
} }
function removePhoto(flagId) { function removePhoto(flagId) {
@@ -692,10 +709,16 @@ document.getElementById('export-btn').addEventListener('click', () => {
Photo: f.photoData ?? '', Photo: f.photoData ?? '',
})); }));
const wb = XLSX.utils.book_new(); 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 }]; 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.utils.book_append_sheet(wb, ws, 'Flags');
try {
XLSX.writeFile(wb, 'flag_export.xlsx'); 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; }
}
}); });
// ═══════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════