«

Js怎么根据文件夹目录获取Json数据输出demo

时间:2024-7-22 09:27     作者:韩俊     分类: Javascript


今天小编给大家分享一下Js怎么根据文件夹目录获取Json数据输出demo的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

1.搭建初始样式(html,css)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            h3 {
                text-align: center;
            }
            #file_input {
                display: none;
            }
            .userBtn {
                padding: 6px 25px;
                background: #00bfff;
                border-radius: 4px;
                color: white;
                cursor: pointer;
                border: none;
            }
            .userBtn:active {
                background-color: #00bfff90;
            }
            .userBtn[disabled] {
                background: #00bfff60;
                cursor: not-allowed;
            }
            #dataShowArea {
                width: 100%;
                height: 600px;
                border: 1px solid #000;
                box-sizing: border-box;
                margin-top: 20px;
                overflow: hidden;
                padding: 20px;
                padding-top: 10px;
                background: #0cff0014;
                border-radius: 6px;
                display: flex;
                flex-wrap: wrap;
                flex-direction: column;
            }
            #dataShowArea #realityArea {
                width: 100%;
                flex: 1;
                overflow: overlay;
                box-sizing: border-box;
                margin: 0px;
                color: #3300ed;
                /* border: 1px solid #3300ed; */
                border-radius: 6px;
            }
            #dataShowArea #realityArea::-webkit-scrollbar {
                display: none;
            }
            #dataShowArea .hintUser{
                width: 100%;
                color: #3300ed;
                text-align: center;
                font-style: italic;
                margin-bottom: 10px;
            }
            .userBtnArea{
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-around;
            }
        </style>
    </head>
    <body>
        <h3>文件夹路径生成json文件</h3>
        <div class="userBtnArea">
            <button id="coverInput" class="userBtn" onclick="coverInputClick()">选择文件夹</button>
            <button id="saveJson" class="userBtn" onclick="saveJsonFile()" disabled>输出JSON文件</button>
        </div>
        <!-- 选取单个文件夹 -->
        <input type="file" id="file_input" webkitdirectory directory onchange="outputFile(this.files)" />
        <!-- 存放加载文件的数据的区域 -->
        <div id="dataShowArea">
            <div class="hintUser">数据预览</div>
            <pre id="realityArea" class="hljs"></pre>
        </div>
        <script>
            //全局的文件 json 数据
            let filesData = '';
            let obj = document.getElementById('realityArea');
            let saveJsonBtn = document.getElementById('saveJson');
        </script>
    </body>
</html>

2.文件夹目录转换成JSON数据

//File 文件格式需要转成 Object => 将字段提出方便装换
const fileField = [
    'lastModified',
    'lastModifiedDate',
    'name',
    'size',
    'type',
    'webkitRelativePath',
];
//文件 目录数据生成
async function handleFiles(files) {
    if (files.length > 0) {
        let catalogue = {
            // childer:{}
        };
        for (fileItem of files) {
            //获取要插入的对象 => File类型不能直接插入,会报错 => File类型不归属于Object类型
            let fileData = {};
            fileField.forEach((item) => {
                fileData[item] = eval(`fileItem.${item}.toString()`);
            });
            //文件的name值为  xx.文件属性  会在执行插入语句时报错,只拿文件名,不拿文件属性
            fileData.noTypeName = fileData.name.split('.')[0];
            let fileData_ = JSON.stringify(fileData);
            //获取树的每个字段
            let catalogueField = fileItem.webkitRelativePath.split('/');
            //要执行的js语句拼接
            let objStr = catalogueField.reduce((pre, cur, index, arr) => {
                /**
                 * pre:上一次调用返回的值,或者提供的初始值
                 * cur:数组中当前处理的元素
                 * index:数组中当前处理的元素的下标
                 * arr:调用reduce函数的数组
                 * */
                if (index >= arr.length - 1) {
                    !eval(pre) && eval(`${pre}={isLeaf:true}`);
                    pre = `${pre}['${fileData.noTypeName}']`;
                } else {
                    index == 0 ? (pre = `${pre}['${cur}']`) : (pre = `${pre}.Folder['${cur}']`);
                    !eval(pre) && eval(`${pre}={isLeaf:false,type:'folder',Folder:{}}`);
                }
                return pre;
            }, 'catalogue');
            eval(`${objStr}={isLeaf:true,...${fileData_}}`);
        }
        return catalogue;
    }
}

3.JSON数据输出成JSON文件

//写成json文件输出
function saveToJson(data) {
    if (!data) {
        console.error('json文件的数据对象不存在');
        return;
    }
    var content = JSON.stringify(data, null, ' ');
    // 转成blob数据对象
    var blob = new Blob([content], {
        type: 'text/plain;charset=utf-8',
    });
    //第二步 => 文件数据 转为可以 下载 的地址路径 改路径指向文件数据
    let url = window.URL.createObjectURL(blob);
    //动态创建a标签 => 模拟触发a标签的下载 => 用于将生成的json数据下载到本地
    let link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', 'model.json');
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    //URL.createObjectURL函数创建的数据不会再内存删除 得手动删除或者浏览器转态退出
    window.URL.revokeObjectURL(url);
}

4.完整代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            h3 {
                text-align: center;
            }
            #file_input {
                display: none;
            }
            .userBtn {
                padding: 6px 25px;
                background: #00bfff;
                border-radius: 4px;
                color: white;
                cursor: pointer;
                border: none;
            }
            .userBtn:active {
                background-color: #00bfff90;
            }
            .userBtn[disabled] {
                background: #00bfff60;
                cursor: not-allowed;
            }
            #dataShowArea {
                width: 100%;
                height: 600px;
                border: 1px solid #000;
                box-sizing: border-box;
                margin-top: 20px;
                overflow: hidden;
                padding: 20px;
                padding-top: 10px;
                background: #0cff0014;
                border-radius: 6px;
                display: flex;
                flex-wrap: wrap;
                flex-direction: column;
            }
            #dataShowArea #realityArea {
                width: 100%;
                flex: 1;
                overflow: overlay;
                box-sizing: border-box;
                margin: 0px;
                color: #3300ed;
                /* border: 1px solid #3300ed; */
                border-radius: 6px;
            }
            #dataShowArea #realityArea::-webkit-scrollbar {
                display: none;
            }
            #dataShowArea .hintUser{
                width: 100%;
                color: #3300ed;
                text-align: center;
                font-style: italic;
                margin-bottom: 10px;
            }
            .userBtnArea{
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-around;
            }
        </style>
    </head>
    <body>
        <h3>文件夹路径生成json文件</h3>
        <div class="userBtnArea">
            <button id="coverInput" class="userBtn" onclick="coverInputClick()">选择文件夹</button>
            <button id="saveJson" class="userBtn" onclick="saveJsonFile()" disabled>输出JSON文件</button>
        </div>
        <!-- 选取单个文件 -->
        <!-- <input type="file" id="file" onchange="handleFiles(this.files)" /> -->
        <!-- 选取多个文件 -->
        <!-- <input type="file" id="file_input" multiple="multiple" onchange="handleFiles(this.files)" /> -->
        <!-- 选取单个文件夹 -->
        <input type="file" id="file_input" webkitdirectory directory onchange="outputFile(this.files)" />
        <!-- 存放加载文件的数据的区域 -->
        <div id="dataShowArea">
            <div class="hintUser">数据预览</div>
            <pre id="realityArea" class="hljs"></pre>
        </div>
        <script>
            //全局的文件 json 数据
            let filesData = '';
            let obj = document.getElementById('realityArea');
            let saveJsonBtn = document.getElementById('saveJson');
            //按钮点击触发input标签的点击
            function coverInputClick() {
                document.getElementById('file_input').click();
            }
            //报错json文件
            function saveJsonFile(data) {
                saveToJson(filesData);
            }
            //File 文件格式需要转成 Object => 将字段提出方便装换
            const fileField = [
                'lastModified',
                'lastModifiedDate',
                'name',
                'size',
                'type',
                'webkitRelativePath',
            ];
            //文件 目录数据生成
            async function handleFiles(files) {
                if (files.length > 0) {
                    let catalogue = {
                        // childer:{}
                    };
                    for (fileItem of files) {
                        //获取要插入的对象 => File类型不能直接插入,会报错 => File类型不归属于Object类型
                        let fileData = {};
                        fileField.forEach((item) => {
                            fileData[item] = eval(`fileItem.${item}.toString()`);
                        });
                        //文件的name值为  xx.文件属性  会在执行插入语句时报错,只拿文件名,不拿文件属性
                        fileData.noTypeName = fileData.name.split('.')[0];
                        let fileData_ = JSON.stringify(fileData);
                        //获取树的每个字段
                        let catalogueField = fileItem.webkitRelativePath.split('/');
                        //要执行的js语句拼接
                        let objStr = catalogueField.reduce((pre, cur, index, arr) => {
                            /**
                             * pre:上一次调用返回的值,或者提供的初始值
                             * cur:数组中当前处理的元素
                             * index:数组中当前处理的元素的下标
                             * arr:调用reduce函数的数组
                             * */
                            if (index >= arr.length - 1) {
                                !eval(pre) && (eval(`${pre}={isLeaf:true}`))
                                pre = `${pre}['${fileData.noTypeName}']`;
                            } else {
                                index == 0 ? pre = `${pre}['${cur}']` : pre = `${pre}.Folder['${cur}']`;
                                !eval(pre) && (eval(`${pre}={isLeaf:false,type:'folder',Folder:{}}`))
                            }
                            // !eval(pre) && (eval(`${pre}={isLeaf:false}`))
                            return pre;
                        }, 'catalogue');
                        eval(`${objStr}={isLeaf:true,...${fileData_}}`);
                    };
                    return catalogue;
                }
            }
            //写成json文件输出
            function saveToJson(data) {
                if (!data) {
                    console.error("json文件的数据对象不存在");
                    return;
                }
                /**
                 * JSON.stringify(value[, replacer [, space]])
                 * 
                 * value:将要序列化成 一个 JSON 字符串的值。
                 * 
                 * replacer
                 * 如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;
                 * 如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;
                 * 如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
                 * 
                 * space
                 * 指定缩进用的空白字符串,用于美化输出(pretty-print);
                 * 如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;
                 * 如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;
                 * 如果该参数没有提供(或者为 null),将没有空格。
                 * */
                var content = JSON.stringify(data, null, ' ');
                // 转成blob数据对象
                var blob = new Blob([content], {
                    type: "text/plain;charset=utf-8"
                });
                //第二步 => 文件数据 转为可以 下载 的地址路径 改路径指向文件数据
                /**
                 * objectURL = URL.createObjectURL(object);
                 * 
                 * object:用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。
                 * 返回值:一个DOMString包含了一个对象 URL,该 URL 可用于指定源 object的内容。
                 * 
                 * 在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,
                 * 即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。
                 * 
                 * 
                 * 与FileReader.readAsDataURL(file)区别
                 * 主要区别
                 * 通过FileReader.readAsDataURL(file)可以获取一段data:base64的字符串
                 * 通过URL.createObjectURL(blob)可以获取当前文件的一个内存URL
                 * 
                 * 执行时机
                 * createObjectURL是同步执行(立即的)
                 * FileReader.readAsDataURL是异步执行(过一段时间)
                 * 
                 * 内存使用
                 * createObjectURL返回一段带hash的url,并且一直存储在内存中,直到document触发了unload事件(例如:document close)或者执行revokeObjectURL来释放。
                 * FileReader.readAsDataURL则返回包含很多字符的base64,并会比blob url消耗更多内存,但是在不用的时候会自动从内存中清除(通过垃圾回收机制)
                 * 
                 * 优劣对比
                 * 使用createObjectURL可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存
                 * 如果不太在意设备性能问题,并想获取图片的base64,则推荐使用FileReader.readAsDataURL
                 * */
                let url = window.URL.createObjectURL(blob);
                //这里你会看到类似的地址:blob:http://localhost:8080/d2dbbe3f-7466-415b-a2d0-387cff290acb
                console.log(url);
                //动态创建a标签 => 模拟触发a标签的下载 => 用于将生成的json数据下载到本地
                let link = document.createElement('a');
                link.style.display = "none";
                link.href = url;
                link.setAttribute('download', 'model.json');
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                window.URL.revokeObjectURL(url);
            }
            /* 文件输出 */
            function outputFile(files) {
                filesData = '';
                btnDisabled(saveJsonBtn);
                handleFiles(files).then(res => {
                    filesData = res;
                    btnCanClick(saveJsonBtn)
                    obj.innerText = JSON.stringify(res, null, 2);
                }).catch(err => {
                    console.error(err)
                })
            }
            /* 按钮可选 */
            function btnCanClick(btnObj) {
                btnObj.removeAttribute('disabled');
            }
            /* 按钮不可选 */
            function btnDisabled(btnObj) {
                btnObj.setAttribute('disabled', 'disabled');
            }
        </script>
    </body>
</html>

预览

标签: javascript

热门推荐