0
点赞
收藏
分享

微信扫一扫

前端实现csv文件的解析预览、上传、下载


最近遇到了一些关于​​csv​​​文件的上传、下载、解析预览、删除的需求。因为之前没有做过,尤其是关于​​csv​​的解析并预览,于是记录一下。

上传

关于上传,绝大部分的选择都是通过第三方的​​OSS​​​进行存储,比如阿里云的。
这个其实没什么难度,有文档可以看。对于前端来说,上传到OSS和上传给自己的后端,在过程上没什么区别,只是上传​​​OSS​​多了一些配置项的参数。

首先下载​​oss​​​的​​npm​​​包
​​​npm install ali-oss --save​

顶部进行引入
​​​import OSS from 'ali-oss';​

上传的核心代码:

const uploadFile = async (files,) => {
const fileMaxSize = 1024 * 10;
const fileType = ['csv', 'txt'];
const { originFile: { size, name } } = files[0];
const nameType = name.split('.')[1];
if (size / 1024 > fileMaxSize) {
Message('error', '文件过大!');
return;
};
if (!fileType.includes(nameType)) {
Message('error', '只支持csv和txt格式文件!');
return;
}
const ossConfig = {
region: 'oss-cn-xxxxxxx',
accessKeyId: 'xxxxxxx',
accessKeySecret: 'xxxxxxxxxx',
bucket: 'xxxxx',
};
const client = new OSS(ossConfig);
const { name: res_name, url } = await client.put(
`xxxxxx/test/${v4()}.${nameType}`,
files[0].originFile,
)
};

其实需要的参数就是​​ossConfig​​​这个对象,用来实例化引入的​​OSS​​。

  • ​region​​​,这个填写的是你买的​​oss​​​资源的地区,比如​​oss-cn-beijing​​, 就是买的中国北京地区的资源
  • ​accessKeyId​​​、​​accessKeySecret​​,这两个是用来鉴权需要的密钥,我是像运维要的,估计是在阿里云后台里生成的
  • ​bucket​​,这个是你放到的根文件夹名字,一般就是你申请资源时的主体

然后实例化出来的​​client​​​就可以直接用了,一般都是用​​put​​​方法,直接进行覆盖。传入的第一个参数是你要放到​​OSS​​​的路径,比如​​creator/test/xxxx.csv​​​,我这个名字为了避免重复,是用了一个​​uuid​​​的,需要的可以自己下一下,还是比较好用的,理论上不会重复的一段字符串。
​​​npm install uuid --save​​​​import { v4 } from 'uuid'​

然后你就可以在返回值里拿到一系列的返回值了。

前端实现文件上传到​​OSS​​,总体比较简单,配置一下参数之后,就跟正常的上传二进制文件一样了。

下载

下载也相对来说简单一下,先说下载,最后说预览解析。

前端实现文件的下载,其实方法比较单一,基本都是通过动态创建​​a​​标签模拟点击来实现的。

const downloadFile = async (name,) => {
console.log(name, url);
const result = await fetch(url);
const file = await result.blob();
let a = document.createElement('a');
let _url = window.URL.createObjectURL(file);
let filename = name;
a.href = _url;
a.download = filename;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(_url);
document.body.removeChild(a);
}

因为文件是上传到了​​OSS​​,所以前端进行下载操作的前提是,先拿到这个文件的二进制流。

先通过原生的​​fetch​​​方法请求存在​​OSS​​​的这个文件。然后通过查看原型链,可以找到这个​​blob​​方法,将返回值转为我们需要的二进制流。

接下来的一系列操作就是通用的前端实现文件下载的代码:

  • 动态创建​​a​​标签
  • 通过​​window​​​提供的​​createObjectURL​​​将二进制流文件转为当前域名下的一段​​url​
  • 然后将这个​​url​​​赋值给​​a​​​标签的​​href​​属性
  • 给这个要下载的文件起一个名字赋值给​​a​​​标签的​​download​​属性
  • 将​​a​​标签隐藏,放入当前文档流中(可选)
  • 模拟​​click​​事件点击
  • 销毁​​url​​​、销毁​​a​​标签

总结下来,前端实现下载文件,其实在业务场景中很常见,实现方式也比较单一,先获取到要下载的文件二进制流、通过​​a​​标签实现下载。

解析预览

首先,我们需要知道,​​csv​​文件的特性,才可以进行解析。

​csv​​​的内容其实就是形如下方的这个格式。
​​​username, password, nickname, age,,,​​​​creator, 123456, creator, 12,,,​​​​xiaozhang, 123456, xiaozhang, 12,,,​​ 所以,根据​​csv​​文件的特点,我们就可以进行解析和展示的,展示形式一般都是表格​​table​​。

默认情况下,我们认为​​csv​​的第一行数据是表头,所以,我们预期是将上面这段内容转为:

[
{
username: 'creator',
password: '123456',
nickname: 'creator',
age: '12',
},
{
username: 'xiaozhang',
password: '123456',
nickname: 'xiaozhang',
age: '12',
}
]

进行数据转为的代码封装为一个函数。

const formatCSV = (str) => {
let result = [];
let jsonObj = str.split(/((\r\n)|[\r\n])+/gi);
let arrHeader = [];
for (let i in jsonObj) {
if (typeof jsonObj[i] === 'string' && jsonObj[i].length > 0) {
let row = `${jsonObj[i]}`;
if (row.trim().length > 0) {
const kv = jsonObj[i].split(',');
if (i === 0) {
arrHeader = kv;
} else {
const obj = {};
for (let index = 0; index < arrHeader.length; index ++) {
const name = String(arrHeader[index]);
if (!obj[name]) {
try {
if (kv[index]) {
obj[name] = String(kv[index]);
} else {
obj[name] = '';
}
} catch (err) {
obj[name] = '';
}
}
}
result.push(obj);
}
}
}
}
}

const previewFile = async (url) => {
const result = await fetch(url);
console.log(result);
const file = await result.blob();

const reader = new FileReader();
reader.onload = () => {
const text = reader.result;
const resultData = formatCSV(text);
setPreviewData(resultData)
setPreview(true);
};

reader.readAsText(file);
};

然后我们就可以拿到我们想要的格式的数据了。
关于表格的展示,因为我用的是​​​react​​​ + ​​antdeisgn​​​。
所以拼接出​​​Table​​​组件需要的​​data​​​和​​column​​​即可。
​​​data​​​不需要额外处理,经过我们​​formatCSV​​​返回的结果,就是我们需要的​​data​​。

​column​

let column = [];
for (let i in data[0]) {
column.push({
title: i,
dataIndex: i,
})
}

<Table columns={tableColumn} data={tableData} />

ok,经过这一系列操作,就完成了我们既定的需求,关于​​csv​​文件的上传、下载、解析预览。

总结

最近工作中做了一些没接触过的需求,总结后给大家分享一下。在此之前我甚至不知道什么是​​csv​​​的文件,只知道类似于​​excel​​的表格。做了这个需求知道,我知道了前端上传文件到OSS、前端下载OSS的文件、csv文件的本质格式、前端解析csv文件并预览展示。 经验就是在一个个未接触过的需求中增长的。


公众号: Code程序人生
B站账号: LuckyRay123
个人博客: http://rayblog.ltd/
欢迎关注我的各类账号, 持续更新优质前端内容


举报

相关推荐

0 条评论