/**
* 将字符串、画布元素、图像元素、`Blob` 或 `File`、`ArrayBuffer` 或类型化数组、对象(转为 JSON 字符串)等下载为文件。
* @category misc
* @alias misc_download
* @param {Element | File | Blob | ArrayBuffer | URL | string} content - 下载内容/下载链接。
* @param {string} [filename=document.title] - 文件名,默认使用页面标题。
* @param {boolean} [isURL=false] - 传入的字符串是否为下载链接。(否则将作为文本内容下载)默认为 `false`。
* @author xkloveme <xkloveme@gmail.com>
*/
export default function downloadContent (content, filename = document.title, isURL = false) {
if (content === void 0 || content === null) {
throw new TypeError('无下载内容!');
}
const anchor = document.createElement('a');
// 将数值类型与布尔类型转为字符串
if (typeof content === 'number' || typeof content === 'bigint' || typeof content === 'boolean') {
return downloadContent(String(content), filename, isURL);
}
if (typeof content === 'string') {
if (isURL) {
anchor.href = content;
} else {
// 下载为文本内容
return downloadContent(new Blob([content]), filename, isURL);
}
} else if (content instanceof HTMLCanvasElement) {
anchor.href = content.toDataURL('image/png');
} else if (content instanceof HTMLImageElement || content instanceof HTMLMediaElement || content instanceof HTMLSourceElement || content instanceof HTMLTrackElement || content instanceof HTMLEmbedElement) {
anchor.href = content.src;
} else if (content instanceof HTMLObjectElement) {
anchor.href = content.data;
} else if (content instanceof Blob) {
anchor.href = URL.createObjectURL(content);
} else if (content instanceof ArrayBuffer) {
return downloadContent(new Blob([content]), filename, isURL);
} else if (content instanceof URL) {
anchor.href = content.href;
} else if (ArrayBuffer.isView(content)) {
return downloadContent(content.buffer, filename, isURL);
} else if (typeof content === 'object') {
try {
// 尝试转为 JSON 字符串
return downloadContent(new Blob([JSON.stringify(content)]), filename, isURL);
} catch (error) {
throw new TypeError('对象可能包含循环引用。');
}
} else {
throw new TypeError('无法处理的类型');
}
// 设置文件名
anchor.download = filename;
// 触发下载
anchor.click();
// 清理:撤销创建的对象 URL
if (content instanceof Blob) {
URL.revokeObjectURL(anchor.href);
}
}