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

41 篇文章 2 订阅
13 篇文章 0 订阅

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

上传

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

首先下载ossnpm
npm install ali-oss --save

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

上传的核心代码:

  const uploadFile = async (files, fileLists) => {
        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, 就是买的中国北京地区的资源
  • accessKeyIdaccessKeySecret,这两个是用来鉴权需要的密钥,我是像运维要的,估计是在阿里云后台里生成的
  • bucket,这个是你放到的根文件夹名字,一般就是你申请资源时的主体

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

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

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

下载

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

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

const downloadFile = async (name, url) => {
        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组件需要的datacolumn即可。
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文件并预览展示。 经验就是在一个个未接触过的需求中增长的。

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

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CreatorRay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值