JS 上传CSV转JSON | JSON数据转CSV下载 | 数组转CSV

⏹转换方法来源:

https://www.30secondsofcode.org/js/s/csv-to-json
https://www.30secondsofcode.org/js/s/array-to-csv

⏹上传CSV转JSON

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSV转换JSON</title>
</head>
<body>
    <label for="ipt">读取本地的csv</label><br>
    <!-- accept属性限制只能上传csv文件 -->
    <input id="ipt" type="file" accept=".csv" />
</body>
<script src="../jquery.min.js"></script>
<script>

    // 转换CSV为JSON数据
    const CSVToJSON = (data, csvTitleKbn, delimiter = ',') => {

        const titles = data.slice(0, data.indexOf('\n')).split(delimiter);
        const hanleData = data.slice(data.indexOf('\n') + 1).split('\n');

        const json = hanleData.map(v => {

            const values = v.split(delimiter);
            return csvTitleKbn.reduce(
                (obj, title, index) => ((obj[title] = values[index]), obj),
                {}
            );
        });

        return json;
    };

    // 文件上传后触发change事件
    $(ipt).change((event) => {
        
        // 获取出上传的文件
        const {
            target: {
                files
            },
            target
        } = event;
        const file = files[0];

        // 文件类型校验
        if(!file?.name.includes(".csv")) {
            // 清空文件上传框
            target.outerHTML = target.outerHTML;
            alert("请选择csv文件上传!");
            return;
        }

        // 构建文件读取对象
        const reader  = new FileReader();
        // 将上传的文件读取为文本
        reader.readAsText(file);
        // 当文件完全读取完成之后触发load事件,从响应事件中解构出读取的文本
        reader.addEventListener('load', ({target: {result: csvText}}) => {

            // CSV标题汉字所对应的区分名
            const csvTitleKbn = ["id", "name"];

            // 将CSV文本转换为JSON数据
            const jsonFromCsvFile = CSVToJSON(csvText, csvTitleKbn);
            console.log(jsonFromCsvFile);
        });
    })
</script>
</html>

⏹JSON数据转CSV下载

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON转换CSV</title>
</head>
<body>
    <button id="btn">点击下载CSV文件</button>
</body>
<script src="../jquery.min.js"></script>
<script>

    // 转换Json到CSV数据
    const JSONtoCSV = (arr, columns, csvTitleNames, delimiter = ',') => {

        // 转换为csv数据List
        const csvdataList = [
            columns.join(delimiter),
            ...arr.map(obj =>
                columns.reduce(
                    (acc, key) =>
                    `${acc}${!acc.length ? '' : delimiter}"${!obj[key] ? '' : obj[key]}"`,
                    ''
                )
            ),
        ];

        // 将标题替换为汉字
        csvdataList[0] = csvTitleNames;

        // 转换为csv字符串
        return csvdataList.join('\n');
    }

    // 下载CSV文件
    function downloadCSVFile(fileName, csvFileContent) {

        // 防止中文乱码的unicode
        const unicodeMark = "\ufeff";
        const blob = new Blob(
            // 必须添加此unicode,否则CSV中的中文会乱码
            [unicodeMark + csvFileContent], 
            {type: 'text/csv'}
        );

        // 创建一个隐藏的用来下载文件的a标签
        const aElement = document.createElement('a');
        aElement.download = fileName;
        aElement.style.display = 'none';

        // 将文件放入内存中
        const src = URL.createObjectURL(blob);
        aElement.href = src;
        document.body.appendChild(aElement);

        // 模拟点击下载事件,进行下载
        aElement.click();

        // 点击之后,移除我们定义的隐藏a标签
        document.body.removeChild(aElement);

        // 移除文件对象
        URL.revokeObjectURL(src);
    }

    // 模拟从后端获取的数据
    const dataFromAPI = [
        { id: 1, name: '贾飞天' }, 
        { id: 3, name: '高橋', address: '地球' }, 
        { id: 6 },
        { name: '李四' }
    ]
    // CSV标题
    const csvTitleKbn = ['id', 'name'];
    const csvTitleName = ['ID', '姓名'];

    $(btn).click(() => {

        // 将json数据转换为CSV格式
        const csvFileContent = JSONtoCSV(dataFromAPI, csvTitleKbn, csvTitleName);

        const fileName = `自定义csv${new Date().getTime()}.csv`;

        // 下载CSV
        downloadCSVFile(fileName, csvFileContent);
    });
</script>
</html>

⏹数组转CSV

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数组转CSV</title>
</head>
<body>
    
</body>
<script>
    // 转换数组到CSV
    const arrayToCSV = (arr, delimiter = ',') => {

        const csvData = arr.map(v => {
            return v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter)
        }).join('\n');

        return csvData;
    }

    // 模拟从后端获取到的数据
    const dataFromAPI = [
        ['a', '"b" great', '测试数据'],
        ['c', 3.1415]
    ];

    // 将数组转换为csv
    const csvData = arrayToCSV(dataFromAPI);
    console.log(csvData);
</script>
</html>

版权声明:本文为feyehong原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。