87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
/**
|
||
* 文件下载
|
||
* *将实时创建<a>标签并在下载完成后自动移除
|
||
* @param url 文件地址
|
||
* @param name 文件名
|
||
*/
|
||
export function downloadFile(url: string, name?: string): void {
|
||
if (!url) return;
|
||
const element = document.createElement('a');
|
||
element.href = url;
|
||
if (name) {
|
||
element.download = name;
|
||
}
|
||
element.click();
|
||
element.remove();
|
||
}
|
||
|
||
/**
|
||
* 文件选择
|
||
* @param accept 支持的文件类型
|
||
* @param limit 文件大小限制(byte)
|
||
* @returns 选中的文件域
|
||
*/
|
||
export async function selectFile(accept?: string, limit?: number): Promise<File | void> {
|
||
const element = document.createElement('input');
|
||
element.type = 'file';
|
||
element.accept = accept ?? '';
|
||
try {
|
||
return await new Promise<File | void>((resolve, reject) => {
|
||
element.onchange = () => {
|
||
const file = element.files?.[0];
|
||
if (!file?.size) return resolve();
|
||
if (limit && limit < file.size) return reject(`文件大小不能超过${~~(limit / 1000)}KB`);
|
||
const extension = file.name.split('.').pop()!.toLowerCase();
|
||
if (accept && !accept.toLowerCase().includes(extension)) return reject(`仅支持${accept}文件`);
|
||
resolve(file);
|
||
};
|
||
element.oncancel = () => resolve();
|
||
element.click();
|
||
});
|
||
} finally {
|
||
element.onchange = null;
|
||
element.oncancel = null;
|
||
element.remove();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Base64图片转二进制
|
||
* @param base64:Base64 图片数据
|
||
* @returns 二进制数据
|
||
*/
|
||
export function base64ToBlob(base64: string): Blob | undefined {
|
||
const [prefix, data] = base64?.split('base64,', 2) ?? [];
|
||
const type = prefix?.match(/:(.*?);/)?.[1];
|
||
const str = atob(data ?? '');
|
||
if (!type || !str?.length) return;
|
||
let n = str.length;
|
||
const buffer = new Uint8Array(n);
|
||
while (n--) {
|
||
buffer[n] = str.charCodeAt(n);
|
||
}
|
||
return new Blob([buffer], { type });
|
||
}
|
||
|
||
/**
|
||
* 文本转二进制
|
||
* @param text 文本字符
|
||
* @returns 二进制数据
|
||
*/
|
||
export function textToBlob(text: string): Blob | undefined {
|
||
if (!text.length) return;
|
||
return new Blob([text], { type: 'text/plain' });
|
||
}
|
||
|
||
/**
|
||
* 文本文件解码
|
||
* @param file 文件域
|
||
* @returns 文本字符串
|
||
*/
|
||
export async function decodeTextFile(file: File): Promise<string | undefined> {
|
||
if (!file.size) return;
|
||
const decoder = new TextDecoder();
|
||
const buffer = await file.arrayBuffer();
|
||
return decoder.decode(buffer);
|
||
}
|