一、需求:用户想导出备份
简记往来上线后,有用户反馈:"我想把礼金记录导出到Excel,方便备份和二次分析。"
数据导出是一个重要的功能------它让用户感觉"数据是自己的",而不是被工具锁住的。
二、数据查询与组装
导出功能的第一步:查询数据并组装成CSV格式。
javascript
async function exportRecords(bookId) {
// 1. 查询账本的所有记录
const records = await db.records.find({ bookId }).toArray()
// 2. 查询所有联系人
const contacts = await db.contacts.find({ bookId }).toArray()
const contactMap = {}
contacts.forEach(c => { contactMap[c.id] = c.name })
// 3. 组装数据
const rows = records.map(r => ({
date: r.date,
type: r.type === 'receive' ? '收礼' : '送礼',
name: contactMap[r.contactId] || '未知',
amount: r.amount,
note: r.note || '',
createdAt: r.createdAt
}))
return rows
}
三、CSV格式生成
CSV的生成需要注意几个问题:
- 中文乱码:需要添加BOM(Byte Order Mark)
- 字段中包含逗号:需要用双引号包裹
- 字段中包含换行:需要用双引号包裹
javascript
function generateCSV(rows) {
// 1. 定义表头
const headers = ['日期', '类型', '姓名', '金额', '备注', '创建时间']
// 2. 构建CSV内容
let csv = headers.join(',') + '\n'
for (const row of rows) {
const fields = [
row.date,
row.type,
`"${row.name}"`, // 姓名可能包含逗号,用引号包裹
row.amount,
`"${row.note}"`, // 备注可能包含逗号或换行
row.createdAt
]
csv += fields.join(',') + '\n'
}
// 3. 添加BOM(解决中文乱码)
return '\uFEFF' + csv
}
四、浏览器下载触发
在微信小程序中,CSV文件通过以下方式下载:
javascript
// 1. 生成CSV内容
const csv = generateCSV(rows)
// 2. 保存到本地文件
const fs = wx.getFileSystemManager()
const filePath = `${wx.env.USER_DATA_PATH}/礼金记录_${Date.now()}.csv`
fs.writeFileSync(filePath, csv, 'utf-8')
// 3. 触发分享/保存
wx.shareFileMessage({
filePath: filePath,
fileName: `礼金记录_${Date.now()}.csv`,
success: () => {
wx.showToast({ title: '导出成功', icon: 'success' })
},
fail: () => {
wx.showToast({ title: '导出失败', icon: 'none' })
}
})
五、完整代码
javascript
async function exportBookData(bookId) {
try {
// 1. 查询数据
const records = await db.records.find({ bookId }).toArray()
const contacts = await db.contacts.find({ bookId }).toArray()
const contactMap = {}
contacts.forEach(c => { contactMap[c.id] = c.name })
// 2. 组装行数据
const rows = records.map(r => ({
date: r.date,
type: r.type === 'receive' ? '收礼' : '送礼',
name: contactMap[r.contactId] || '未知',
amount: r.amount,
note: r.note || '',
createdAt: r.createdAt
}))
// 3. 生成CSV
const headers = ['日期', '类型', '姓名', '金额', '备注', '创建时间']
let csv = headers.join(',') + '\n'
for (const row of rows) {
csv += [
row.date,
row.type,
`"${row.name}"`,
row.amount,
`"${row.note}"`,
row.createdAt
].join(',') + '\n'
}
csv = '\uFEFF' + csv // 添加BOM
// 4. 保存并分享
const fs = wx.getFileSystemManager()
const filePath = `${wx.env.USER_DATA_PATH}/礼金记录_${Date.now()}.csv`
fs.writeFileSync(filePath, csv, 'utf-8')
wx.shareFileMessage({
filePath: filePath,
fileName: `礼金记录_${Date.now()}.csv`,
success: () => wx.showToast({ title: '导出成功', icon: 'success' }),
fail: () => wx.showToast({ title: '导出失败', icon: 'none' })
})
} catch (err) {
console.error('导出失败', err)
wx.showToast({ title: '导出失败', icon: 'none' })
}
}
六、总结
数据导出功能的关键点:
- BOM处理:解决中文乱码问题
- 字段转义:逗号和换行需要用双引号包裹
- 用户体验:导出完成后给用户明确反馈
数据导出让用户感觉"数据是自己的",而不是被工具锁住的。这是建立用户信任的重要一环。