fix: 修复导出下载链路(Electron 保存对话框 + 原生文件写入 + revoke 竞态)
This commit is contained in:
@@ -1,16 +1,24 @@
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
|
||||
function csvCell(v: string | number | null | undefined): string {
|
||||
const s = v == null ? '' : String(v)
|
||||
return '"' + s.replace(/"/g, '""') + '"'
|
||||
}
|
||||
|
||||
// 导出 UTF-8 BOM 的 CSV,Excel 可直接打开中文不乱码
|
||||
export function downloadCsv(filename: string, rows: (string | number | null | undefined)[][]): void {
|
||||
// 导出 UTF-8 BOM 的 CSV,Excel 可直接打开中文不乱码;返回落盘位置(原生平台)
|
||||
export async function downloadCsv(filename: string, rows: (string | number | null | undefined)[][]): Promise<string> {
|
||||
const content = rows.map(r => r.map(csvCell).join(',')).join('\r\n')
|
||||
const blob = new Blob(['\ufeff' + content], { type: 'text/csv;charset=utf-8' })
|
||||
const text = '\ufeff' + content
|
||||
if (Capacitor.isNativePlatform()) {
|
||||
const { downloadText } = await import('./download')
|
||||
return downloadText(filename, text)
|
||||
}
|
||||
const blob = new Blob([text], { type: 'text/csv;charset=utf-8' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
window.setTimeout(() => URL.revokeObjectURL(url), 10000)
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -1,9 +1,38 @@
|
||||
export function downloadText(filename: string, text: string): void {
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
|
||||
// 导出文本文件:返回落盘位置(原生平台返回文件 URI;浏览器返回空串)
|
||||
// 原生环境写入公共文档目录,失败时回退应用缓存目录
|
||||
export async function downloadText(filename: string, text: string): Promise<string> {
|
||||
if (Capacitor.isNativePlatform()) {
|
||||
const { Filesystem, Directory, Encoding } = await import('@capacitor/filesystem')
|
||||
try {
|
||||
const r = await Filesystem.writeFile({
|
||||
path: filename,
|
||||
data: text,
|
||||
directory: Directory.Documents,
|
||||
encoding: Encoding.UTF8,
|
||||
recursive: true
|
||||
})
|
||||
return r.uri
|
||||
} catch {
|
||||
const r = await Filesystem.writeFile({
|
||||
path: filename,
|
||||
data: text,
|
||||
directory: Directory.Cache,
|
||||
encoding: Encoding.UTF8,
|
||||
recursive: true
|
||||
})
|
||||
return r.uri
|
||||
}
|
||||
}
|
||||
|
||||
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
// 延迟释放,避免立即 revoke 导致下载被取消
|
||||
window.setTimeout(() => URL.revokeObjectURL(url), 10000)
|
||||
return ''
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user