diff --git a/apps/web-antd/src/utils/file/base64Conver.ts b/apps/web-antd/src/utils/file/base64Conver.ts new file mode 100644 index 000000000..3a487c3b6 --- /dev/null +++ b/apps/web-antd/src/utils/file/base64Conver.ts @@ -0,0 +1,46 @@ +/** + * @description: base64 to blob + */ +export function dataURLtoBlob(base64Buf: string): Blob { + const arr = base64Buf.split(','); + const typeItem = arr[0]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const mime = typeItem!.match(/:(.*?);/)![1]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const bstr = window.atob(arr[1]!); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + u8arr[n] = bstr.codePointAt(n)!; + } + return new Blob([u8arr], { type: mime }); +} + +/** + * img url to base64 + * @param url + */ +export function urlToBase64(url: string, mineType?: string): Promise { + return new Promise((resolve, reject) => { + let canvas = document.createElement('CANVAS') as HTMLCanvasElement | null; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const ctx = canvas!.getContext('2d'); + + const img = new Image(); + img.crossOrigin = ''; + img.addEventListener('load', () => { + if (!canvas || !ctx) { + // eslint-disable-next-line prefer-promise-reject-errors + return reject(); + } + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img, 0, 0); + const dataURL = canvas.toDataURL(mineType || 'image/png'); + canvas = null; + resolve(dataURL); + }); + img.src = url; + }); +} diff --git a/apps/web-antd/src/utils/file/download.ts b/apps/web-antd/src/utils/file/download.ts new file mode 100644 index 000000000..5686fc424 --- /dev/null +++ b/apps/web-antd/src/utils/file/download.ts @@ -0,0 +1,124 @@ +import { dataURLtoBlob, urlToBase64 } from './base64Conver'; + +/** + * Download online pictures + * @param url + * @param filename + * @param mime + * @param bom + */ +export function downloadByOnlineUrl( + url: string, + filename: string, + mime?: string, + bom?: BlobPart, +) { + urlToBase64(url).then((base64) => { + downloadByBase64(base64, filename, mime, bom); + }); +} + +/** + * Download pictures based on base64 + * @param buf + * @param filename + * @param mime + * @param bom + */ +export function downloadByBase64( + buf: string, + filename: string, + mime?: string, + bom?: BlobPart, +) { + const base64Buf = dataURLtoBlob(buf); + downloadByData(base64Buf, filename, mime, bom); +} + +/** + * Download according to the background interface file stream + * @param {*} data + * @param {*} filename + * @param {*} mime + * @param {*} bom + */ +export function downloadByData( + data: BlobPart, + filename: string, + mime?: string, + bom?: BlobPart, +) { + const blobData = bom === undefined ? [data] : [bom, data]; + const blob = new Blob(blobData, { type: mime || 'application/octet-stream' }); + + const blobURL = window.URL.createObjectURL(blob); + const tempLink = document.createElement('a'); + tempLink.style.display = 'none'; + tempLink.href = blobURL; + tempLink.setAttribute('download', filename); + if (tempLink.download === undefined) + tempLink.setAttribute('target', '_blank'); + + document.body.append(tempLink); + tempLink.click(); + tempLink.remove(); + window.URL.revokeObjectURL(blobURL); +} + +/** + * Download file according to file address + * @param {*} sUrl + */ +export function downloadByUrl({ + url, + target = '_blank', + fileName, +}: { + fileName?: string; + target?: '_blank' | '_self'; + url: string; +}): boolean { + const isChrome = window.navigator.userAgent.toLowerCase().includes('chrome'); + const isSafari = window.navigator.userAgent.toLowerCase().includes('safari'); + + if (/iP/.test(window.navigator.userAgent)) { + console.error('Your browser does not support download!'); + return false; + } + if (isChrome || isSafari) { + const link = document.createElement('a'); + link.href = url; + link.target = target; + + if (link.download !== undefined) + link.download = fileName || url.slice(url.lastIndexOf('/') + 1); + + if (document.createEvent) { + const e = document.createEvent('MouseEvents'); + e.initEvent('click', true, true); + link.dispatchEvent(e); + return true; + } + } + if (!url.includes('?')) url += '?download'; + + openWindow(url, { target }); + return true; +} + +export function openWindow( + url: string, + opt?: { + noopener?: boolean; + noreferrer?: boolean; + target?: '_blank' | '_self' | string; + }, +) { + const { noopener = true, noreferrer = true, target = '__blank' } = opt || {}; + const feature: string[] = []; + + noopener && feature.push('noopener=yes'); + noreferrer && feature.push('noreferrer=yes'); + + window.open(url, target, feature.join(',')); +}