摘要
Day 21 我們完成了圖表統計(長條/圓餅/趨勢)。今天把重點放回「資料主權」:把瀏覽器裡的紀錄 匯出到電腦。
- JSON 匯出:原樣保存,方便再次匯入或做進階處理。
- CSV 匯出:用 Excel / Google 試算表就能開啟,快速做樞紐分析或圖表。
讓資料不只待在瀏覽器裡,也能被你帶走、備份、分析。
<a download>
→ 觸發點擊 → 回收 URL。假設已具備:
<!-- [Day22-NEW] 匯出功能 -->
<div id="exportSection" style="margin-top:.75rem;">
<button id="btnExportJSON" type="button">匯出 JSON</button>
<button id="btnExportCSV" type="button">匯出 CSV</button>
<p id="exportFeedback" class="muted" aria-live="polite" style="margin:.25rem 0 0;"></p>
</div>
// [Day22-NEW] 匯出節點
const btnExportJSON = document.getElementById('btnExportJSON');
const btnExportCSV = document.getElementById('btnExportCSV');
const exportFeedback = document.getElementById('exportFeedback');
// [Day22-NEW] 下載工具:把字串/Uint8Array 變成檔案下載
function triggerDownload(filename, mime, data) {
const blob = new Blob([data], { type: mime });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
// 釋放 URL
setTimeout(() => URL.revokeObjectURL(url), 1000);
}
// [Day22-NEW] 組 CSV:確保跳脫與 BOM
function toCSVRow(cells) {
return cells.map(v => {
const s = String(v ?? '');
// 若包含逗號、雙引號或換行,需用雙引號包起來,且把內部 " 轉成 ""
return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
}).join(',');
}
function buildCSV(records) {
const header = ['createdAt(ISO)','createdAt(Local)','task','reasonCode','reason','quote'];
const rows = records.map(r => {
const dt = new Date(r.createdAt || Date.now());
return toCSVRow([
dt.toISOString(),
dt.toLocaleString(),
r.task || '',
r.reasonCode || '',
r.reason || '',
r.quote || ''
]);
});
return [toCSVRow(header), ...rows].join('\n');
}
// [Day22-NEW] 匯出 JSON
btnExportJSON?.addEventListener('click', () => {
const list = readRecords();
if (!Array.isArray(list) || list.length === 0) {
exportFeedback.textContent = '目前沒有可匯出的紀錄。';
return;
}
const pretty = JSON.stringify(list, null, 2);
triggerDownload('procrastinator-records.json', 'application/json;charset=utf-8', pretty);
exportFeedback.textContent = `已匯出 ${list.length} 筆紀錄(JSON)。`;
});
// [Day22-NEW] 匯出 CSV(含 UTF-8 BOM,避免 Excel 亂碼)
btnExportCSV?.addEventListener('click', () => {
const list = readRecords();
if (!Array.isArray(list) || list.length === 0) {
exportFeedback.textContent = '目前沒有可匯出的紀錄。';
return;
}
const csv = buildCSV(list);
const BOM = '\uFEFF'; // UTF-8 Byte Order Mark
triggerDownload('procrastinator-records.csv', 'text/csv;charset=utf-8', BOM + csv);
exportFeedback.textContent = `已匯出 ${list.length} 筆紀錄(CSV)。`;
});
想加碼?你也可以用同樣方式,額外提供
readMoodLog() 的 JSON 匯出(例如 mood-log.json),但本篇主線聚焦在「任務紀錄」。
欄位錯亂、換行被切開
確認 toCSVRow() 有把含「逗號、雙引號、換行」的欄位用 " 包住,內部 " 變 ""。
點按沒有下載