JavaScript 导出csv文件页面卡死时的处理方式

JavaScript 导出csv文件页面卡死时的处理方式_第1张图片

文章概叙

当我在使用xlsx包导出csv文件时候,数据过大导致页面卡死,因此才使用blob的方式来导出csv文件,如果没有出现这个问题,建议还是使用xlsx包

XLSX包

npm的地址,对于前后端开发的同学来说,文档难度不大,大概看下就可以快速上手,且当前开发的最高版本为0.18.5,项目使用也很稳定

https://www.npmjs.com/package/xlsx

为什么使用blob生成文件

当数据量大于某个值的时候(需要看你当时的内存,有时候可能一两个g都没问题,有时候可能100m都炸),会导致页面的卡死,基本是因为使用xlsx的时候,生成每一个sheet的时候,传入的数据形式类似下面

let array1 = new Array(10).fill({
        name: 'mk',
        age: "18"
        });

数据大概如下,就是一个长度为10的数组对象。
JavaScript 导出csv文件页面卡死时的处理方式_第2张图片
当数据量不会太大的时候,内存并不会溢出,也就是说页面并不会卡死,数据量较少时候放在前端,是一个很明智的选择。但当你把导出excel的功能放在前端的时候,你就必须考虑一个内存会爆的情况。这时候可以尝试使用blob的形式导出csv文件。我想你也不会想我花两三个小时的时间解释Blob的作用,直接上代码吧。

使用Blob创建文件

    const downloadFunction = (dataArray) => {
        document.getElementById('download').onclick = function () {
          
            var csvRows = dataArray;
            var csvString = csvRows.join("\r\n");
            var csvData = new Blob([csvString], { type: 'text/csv' });var a = document.createElement('a');
            a.href = URL.createObjectURL(csvData);
            a.target = '_blank';
            a.download = 'export.csv';
            document.body.appendChild(a);
            a.click();
        }
    }

上述的代码没有啥理解的难度,主要是生成一个下载名为export.csv的文件,对传进去的数据的处理逻辑也只是将数组转化为string,并且添加空格作为切割,以及将其转化为blob,并导出去。

代码使用以及测试

先来一波最简单的压力测试,让大家大概地了解下用法。

   const downloadFunction = (dataArray) => {
        document.getElementById('download').onclick = function () {var csvRows = dataArray;
            var csvString = csvRows.join("\r\n");
            var csvData = new Blob([csvString], { type: 'text/csv' });var a = document.createElement('a');
            a.href = URL.createObjectURL(csvData);
            a.target = '_blank';
            a.download = 'export.csv';
            document.body.appendChild(a);
            a.click();
        }
    }
    let column = ["name", "age"];const data = ["mk", "18"];let array = new Array(100000).fill(data);
    downloadFunction([column, ...array]);

请添加图片描述

生成了一个最简单的excel,生成了一个csv文件,大概内容如下

对于csv文件,百度的解释是这样的

逗号分隔值(Comma-Separated
Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。

因此,对于数据中的逗号,需要做一些处理,比如下面这种情况。

这儿对数据的格式做了处理,比如,将其添加了一个逗号,这样子,会出现下面的这种情况,数据“mk, a coder” 被csv文件切割成了"mk", "a coder"这两个不同的格子里面。
请添加图片描述

所以,对逗号的处理,需要添加下面的这种操作,这儿修改下,只生成两个数组

let array = new Array(2)
    .fill(data.map(string => string === null ? '' : `\"${string}\"`));
 console.log(array);

请添加图片描述

ok,逗号的问题,暂时解决了。接下来要处理的,是数字的问题,大家应该都有发现,我这儿用的数字是18,但是如果是用户的编号,类似00001这样子的话,生成的csv文件,会出问题。如下:
请添加图片描述

所以,需要再加一个数字的处理,具体逻辑就是加一个"\t",具体可以百度下是什么意思,我就不喜欢做保姆了。

let array = new Array(2)
    .fill(
        data
            // 对数字格式的字符串做处理
            .map(string => { if (!!parseInt(string)) { return `\t${string}` } })
            // 对逗号做处理
            .map(string => string === null ? '' : `\"${string}\"`)
    );

接下来还有一个问题,当我们将数据修改为如下的格式的时候。

    let column = ["name", "age", "description", "remark"];const data = ["mk, a coder",
     "000018",
      '{"desc1":"desc1","desc2":"desc2"}',
       'the remarks is: {"remark1":"remark2","reamrk3":"remark4"}'
       ];

可以看到新的数据,他们多增加了一个双引号,这就导致了我们生成的csv文件中,在有逗号的地方,会分割开,生成一个新的格子。让我们打印出来文字看看。

JavaScript 导出csv文件页面卡死时的处理方式_第3张图片

可以看到最后是由于页面中的",被csv文件认为是需要做切割的地方,因此,对于逗号的处理,我们要修改下操作​​

let array = new Array(2)
        .fill(
            data
                // 对数字格式的字符串做处理
                .map(string => !!parseInt(string) ? `\t${string}` : string)
                // 对逗号以及json做处理
                .map(string => string === null ? '' : "\"" + string.replaceAll("\"", "\"\"") + "\"")
        );

打印出来的文字如下
请添加图片描述

​生成的文件如下:

请添加图片描述

完美,游戏结束,最后的代码如下:

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head><body>
    <button id="download">下载</button>
</body>
<script>const downloadFunction = (dataArray) => {
        document.getElementById('download').onclick = function () {var csvRows = dataArray;
            var csvString = csvRows.join("\r\n");
            var csvData = new Blob([csvString], { type: 'text/csv' });var a = document.createElement('a');
            a.href = URL.createObjectURL(csvData);
            a.target = '_blank';
            a.download = 'export.csv';
            document.body.appendChild(a);
            a.click();
        }
    }
​
​
    let column = ["name", "age", "description", "remark"];const data = ["mk, a coder", "000018", '{"desc1":"desc1","desc2":"desc2"}', 'the remarks is: {"remark1":"remark2","reamrk3":"remark4"}'];let array = new Array(2)
        .fill(
            data
                // 对数字格式的字符串做处理
                .map(string => !!parseInt(string) ? `\t${string}` : string)
                // 对逗号以及json做处理
                .map(string => string === null ? '' : "\"" + string.replaceAll("\"", "\"\"") + "\"")
        );
    console.log(array);
    downloadFunction([column, ...array]);
</script></html>

当然,我的建议是能使用xlsx就使用xlsx

你可能感兴趣的:(javascript,arcgis,开发语言)