1. a标签直接下载
H5利用<a>标签的href属性直接进行下载, 后端接口只需要返回一个下载地址(URL)即可,不能跨域下载
// 如果不加download 则会将txt , pdf, 图片 等直接打开预览,而不是下载
// href 如果不是完整的url,只是一个路径,如/xxx/xxx/test.csv 则会在前面自动拼接域名
<a href="下载地址" download>
// 如果后面加了文件名,则下载的时候,会将文件名改为download的属性值,
// 注意:若后端设置了响应头 Content-Disposition字段中设置了 filename,
// 则download="文件名"不会起效果
<a href="下载地址" download='文件名'>
如果后端返回了一个文件地址,下载txt的时候,需要配置跨域
export function getFileAndDownload(fileName: string, url: string) {
var x = new XMLHttpRequest();
x.open('GET', url, true);
x.responseType = 'blob';
x.onload = function (e) {
var blob = x.response;
var a = document.createElement('a');
a.style.display = 'none';
a.download = fileName;
a.href = URL.createObjectURL(blob);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
x.send();
}
2. blob数据下载
利用服务端返回的blob数据,来进行转换下载。将服务端的blob数据存储到本地,主要还是用到a链接
完整代码: 兼容问题暂未考虑
const downloadFile = (blobData: Blob, fileName: string) => {
const blob = new Blob([blobData]); // 创建blob对象
const ElementA = document.createElement('a');
// ElementA.style.display = 'none'
ElementA.href = URL.createObjectURL(blob);
ElementA.download = fileName;
document.body.appendChild(ElementA);
ElementA.click();
document.body.removeChild(ElementA); // 移除a
URL.revokeObjectURL(ElementA.href) // 释放url内存
}
3. 下载大文件
注意: 如果下载特别大的文件,则上面的就不行了,可能会造成网页崩溃,这里就需要用到下载的库。 FileSaver github.com/eligrey/Fil…, 轻松实现下载文件500M
4. blob与base64数据相互转换
有的图片可以使用base64来进行展示,直接将base64地址放到img的src 中就可以展示出来
base64转换blob数据
function dataURLToBlob(dataURL: string) {
const parts = dataURL.split(/[:;,]/);
const mime = parts[1];
const decoder = parts[2] === 'base64' ? atob : decodeURIComponent;
const binary = decoder(parts.pop());
const array = binary.split('').map((item, i) => binary.charCodeAt(i));
return new BlobConstructor([new Uint8Array(array)], { type: mime });
}
blob数据转换base64
function blobToDaTaURL(blobData: string) {
const blob = blobData;
const reader = new FileReader()
reader.readAsDataURL(blob) // 开始读取指定blob中的内容
reader.onload = (e) => {
// 读取完成后的result属性中将包含一个data: URL格式的Base64字符串
以表示所读取文件的内容。
const base64String = e.target.result;
// 如果是图片,则可以直接写到src展示出来
}
}
下载为csv文件
1.可以直接使用下载的一个库 react-csv
// 导入 react-csv
import { CSVLink } from 'react-csv';
const csvRef = useRef(null);
const handleClick = () => {
csvRef.current.link.click();
};
<Button onClick={handleClick} />
<CSVLink filename={`${filename}.csv`} data={dataSource} ref={csvRef} />
- 自己处理数据进行下载
// 将要下载的数据转换为这种格式 ,\n 代表换行, 逗号代表空
const csvArray = '标题一, 标题二, \n x1,x2,x3,x4,x5,x6,x7 \n a1,a2,a3,a4,,,a6';
// 转为blob下载
const blob = new Blob([`\uFEFF${csvArray}`], {
type: 'text/csv; charset=utf-8',
});
downloadCsv(blob, '测试');
// 下载
const downloadCsv = (blob: Blob, name: string = 'data') => {
const fileName = `${name}`;
const data = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', fileName);
link.click();
};
- 上传解析csv 文件
const uploadData = (file: File) => {
if (!/\.csv$/.test(file.name)) {
message.error('请选择csv文件上传');
return;
}
const reader = new FileReader();
reader.onload = async () => {
const content = reader.result as string;
const rows = content.split('\n');
if (rows.length < 2) {
return;
}
const res: UploadFileType[] = [];
rows.splice(0, 1);
// 手动处理上传的数据
let count = 0;
rows.forEach((row) => {
if (row) {
if (row.startsWith(',,,,')) {
let str = row.slice(4);
if (str.includes('(') || str.includes('[')) {
str = str.replace(',', '*');
}
const arr = str.split(',');
let label = arr[0];
if (label.startsWith('"')) {
label = label.slice(1, label.length - 1);
}
label = label.replace('*', ', ');
const tmp = res[res.length - 1];
tmp.bins.push({
iv: parseFloat(arr[5]),
positive_count: arr[1],
total_count: arr[2],
negative_count: parseInt(arr[2], 10) - parseInt(arr[1], 10),
woe: parseFloat(arr[6]),
index: (count += 1),
});
} else {
const cols = row.split(',');
res.push({
iv: parseFloat(cols[2]),
type: cols[1],
bin_count: parseInt(cols[3], 10),
bins: [],
});
count = 0;
}
}
});
};
reader.readAsText(file);
// eslint-disable-next-line consistent-return
return false;
};
<Upload action="" beforeUpload={uploadData} showUploadList={false}>
<Button>上传文件</Button>
</Upload>