LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

告别 JSON 格式烦恼!用 EasyUI 做了个超实用的格式化实用小工具

admin
2026年4月15日 17:3 本文热度 112
作为开发者,日常和 JSON 打交道的场景实在太多了 —— 接口调试、数据解析、日志查看…… 但每次面对一堆挤成一团的 JSON 字符串,或者手写的 JSON 格式不规范导致解析报错,都忍不住想吐槽。市面上虽然有不少在线 JSON 工具,但要么广告满天飞,要么功能太复杂,要么需要频繁切换网页,用起来总觉得不太顺手。


于是干脆自己动手,基于 EasyUI 开发了一款轻量又好用的 JSON 格式化工具之所以选择 EasyUI,前面已有写过两篇关于EasyUI的,轻车熟路更高效;更关键的是它浏览器适配性广,兼容各类使用环境,再加上组件化设计贴合工具开发需求,布局组件速建左右分栏的输入输出界面,树形组件直观展示 JSON 层级,按钮、标签页等让操作更流畅,无需重复造轮子。
这个工具的核心诉求很简单:解决日常开发中的实际痛点。比如支持一键格式化,让杂乱的 JSON 瞬间变得层次清晰;也能反向压缩,满足接口传输时的精简需求;内置的 JSON 验证功能,能快速定位格式错误,不用再对着控制台报错逐行排查;还加了树形视图切换,复杂 JSON 的层级关系一目了然,比纯文本查看方便多了。
没有多余的功能,也没有广告干扰,打开就能用,本地运行不占资源。对我而言,它不仅是提高效率的小工具,更是贴合自己使用习惯的 “定制款”—— 比如复制功能优化了兼容性,状态提示能实时反馈操作结果,清空、验证等功能按钮都放在最顺手的位置。
其实开发这个小工具的初衷,就是想把日常重复的操作简化,少踩一些 JSON 格式的坑。有时候好用的工具不一定多复杂,能精准解决问题,用得顺手,就是最好的设计
截图
树形视图
压缩
校验


下载地址:https://pan.baidu.com/s/1cKR0nxAgymm5_OYzmibn-w?pwd=mta7

源码下载:

<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>JSON格式化工具 - EasyUI版</title>

    <link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">

    <link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/icon.css">

    <script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.min.js"></script>

    <script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>

    <style>

        body {

            margin: 0;

            padding: 0;

            font-family: "Microsoft YaHei";

            background: #f2f2f2;

        }

        .container {

            padding: 10px;

        }

        .toolbar {

            padding: 10px;

            background: #fafafa;

            border-bottom: 1px solid #ddd;

        }

        .status-bar {

            padding: 5px 10px;

            background: #f5f5f5;

            color: #666;

           

            border-top: 1px solid #ddd;

        }

        .code-block {

            font-family: Consolas, Monaco, monospace;

            font-size: 16px;

            line-height: 1.5;

            border: 1px solid #ddd;

            background: #fff;

            padding: 10px;

            white-space: pre; /* 确保格式保留 */

        }

        .json-key { color: #881391; }

        .json-string { color: #c41a16; }

        .json-number { color: #1c00cf; }

        .json-boolean { color: #0d22aa; }

        .json-null { color: #777; }

        /* 树形视图样式优化 */

        .easyui-tree {

            font-family: Consolas, Monaco, monospace;

            font-size: 13px;

            line-height: 1.5;

        }

        .tree-node {

            padding: 2px 0;

        }

    </style>

</head>

<body class="easyui-layout">

    <div data-options="region:'north', split:false" style="height:60px;background:#2d3d50;color:#fff;padding:10px 15px;">

        <h2 style="margin:0;"><i class="icon-script"></i> JSON格式化工具</h2>

    </div>

     

    <div data-options="region:'center'" style="padding:10px;">

        <div class="easyui-panel" title="JSON处理" style="width:100%;height:100%;padding:5px;">

            <div class="toolbar">

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-ok" onclick="formatJson()">格式化</a>

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-reload" onclick="compressJson()">压缩</a>

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-search" onclick="validateJson()">验证</a>

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-clear" onclick="clearAll()">清空</a>

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cut" onclick="copyToClipboard()">复制</a>

                <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-tip" onclick="toggleTreeView()">树视图</a>

            </div>

             

            <div class="easyui-layout" style="width:100%;height:90%;">

                <div data-options="region:'west', split:true" style="width:50%;padding:5px;">

                    <div class="easyui-panel" title="输入" style="width:100%;height:100%;">

                        <textarea id="jsonInput" style="width:100%;height:95%;border:0;padding:10px;resize:none;"></textarea>

                    </div>

                </div>

                <div data-options="region:'center'" style="padding:5px;">

                    <div class="easyui-tabs" style="width:100%;height:100%;">

                        <div title="格式化输出" style="padding:5px;">

                            <pre id="jsonOutput" class="code-block"></pre>

                        </div>

                        <div title="树形视图" style="padding:5px;">

                            <ul id="jsonTree" class="easyui-tree"></ul>

                        </div>

                    </div>

                </div>

            </div>

             

            <div class="status-bar">

                <span id="status">就绪</span>

            </div>

        </div>

    </div>

 

    <script>

        // 存储原始格式化字符串(用于复制功能)

        let rawFormattedJson = '';

 

        // 格式化JSON并添加颜色

        function formatJson() {

            try {

                const input = $('#jsonInput').val();

                if (!input.trim()) {

                    $.messager.alert('提示', '请输入JSON内容', 'info');

                    return;

                }

                 

                const obj = JSON.parse(input);

                const formatted = JSON.stringify(obj, null, 4);

                rawFormattedJson = formatted; // 保存原始格式化字符串

                const highlighted = syntaxHighlight(formatted);

                 

                $('#jsonOutput').html(highlighted);

                $('#status').text('格式化成功');

                 

                // 构建树形视图

                buildTreeView(obj);

                 

                // 切换到格式化输出标签页

                $('.easyui-tabs').tabs('select', 0);

                 

            } catch (e) {

                $.messager.alert('错误', '无效的JSON格式: ' + e.message, 'error');

                $('#status').text('格式化失败: ' + e.message);

                rawFormattedJson = '';

            }

        }

         

        // JSON语法高亮

        function syntaxHighlight(json) {

            json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');

            return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {

                let cls = 'json-number';

                if (/^"/.test(match)) {

                    cls = /:$/.test(match) ? 'json-key' : 'json-string';

                } else if (/true|false/.test(match)) {

                    cls = 'json-boolean';

                } else if (/null/.test(match)) {

                    cls = 'json-null';

                }

                return '<span class="' + cls + '">' + match + '</span>';

            });

        }

         

        // 压缩JSON

        function compressJson() {

            try {

                const input = $('#jsonInput').val();

                if (!input.trim()) {

                    $.messager.alert('提示', '请输入JSON内容', 'info');

                    return;

                }

                 

                const obj = JSON.parse(input);

                const compressed = JSON.stringify(obj);

                rawFormattedJson = compressed;

                const highlighted = syntaxHighlight(compressed);

                 

                $('#jsonOutput').html(highlighted);

                $('#status').text('压缩成功');

                 

                // 切换到格式化输出标签页

                $('.easyui-tabs').tabs('select', 0);

                 

            } catch (e) {

                $.messager.alert('错误', '无效的JSON格式: ' + e.message, 'error');

                $('#status').text('压缩失败: ' + e.message);

                rawFormattedJson = '';

            }

        }

         

        // 切换树视图

        function toggleTreeView() {

            const inputVal = $('#jsonInput').val().trim();

            if (!inputVal) {

                $.messager.alert('提示', '请先输入JSON内容', 'info');

                return;

            }

             

            try {

                const obj = JSON.parse(inputVal);

                // 强制重新构建树形视图,确保数据最新

                buildTreeView(obj);

                $('.easyui-tabs').tabs('select', 1);

                 

                // 切换后尝试展开根节点

                setTimeout(() => {

                    const roots = $('#jsonTree').tree('getRoots');

                    if (roots.length > 0) {

                        $('#jsonTree').tree('expand', roots[0].target);

                    }

                }, 100); // 短暂延迟,确保DOM已更新

            } catch (e) {

                $.messager.alert('提示', '请输入有效的JSON格式', 'info');

            }

        }

         

        // 清空内容

        function clearAll() {

            $('#jsonInput').val('');

            $('#jsonOutput').html('');

            $('#jsonTree').tree('loadData', []);

            $('#status').text('已清空');

            rawFormattedJson = '';

        }

         

        // 验证JSON

        function validateJson() {

            try {

                const input = $('#jsonInput').val();

                if (!input.trim()) {

                    $.messager.alert('提示', '请输入JSON内容', 'info');

                    return;

                }

                 

                JSON.parse(input);

                $.messager.alert('成功', 'JSON格式有效', 'info');

                $('#status').text('验证通过');

                 

            } catch (e) {

                $.messager.alert('错误', '无效的JSON格式: ' + e.message, 'error');

                $('#status').text('验证失败: ' + e.message);

            }

        }

         

        // 复制到剪贴板(优化版)

        function copyToClipboard() {

            if (rawFormattedJson.trim()) {

                copyTextToClipboard(rawFormattedJson);

                return;

            }

             

            const output = $('#jsonOutput').text();

            if (!output.trim()) {

                $.messager.alert('提示', '没有可复制的内容', 'info');

                return;

            }

             

            copyTextToClipboard(output);

        }

         

        // 通用复制方法

        function copyTextToClipboard(text) {

            const textarea = document.createElement('textarea');

            textarea.style.position = 'fixed';

            textarea.style.top = '-999px';

            textarea.style.left = '-999px';

            textarea.value = text;

             

            document.body.appendChild(textarea);

            textarea.select();

            textarea.setSelectionRange(0, text.length); // 兼容移动设备

             

            try {

                const successful = document.execCommand('copy');

                if (successful) {

                    $.messager.alert('成功', '已复制到剪贴板', 'info');

                    $('#status').text('内容已复制');

                } else {

                    throw new Error('复制失败');

                }

            } catch (e) {

                $.messager.alert('错误', '复制失败,请手动复制', 'error');

                $('#status').text('复制失败');

            } finally {

                document.body.removeChild(textarea);

            }

        }

         

        // 构建树形视图

        function buildTreeView(obj) {

            try {

                const treeNode = convertToTreeData(obj); // 单个根节点对象

                // console.log('树形视图数据:', treeNode); // 确认数据结构

                 

                $('#jsonTree').tree({

                    data: [treeNode], // 关键:将单个节点包装成数组

                    animate: true,

                    lines: true,

                    // 确保节点文本中的HTML标签正确渲染(不被转义)

                    formatter: function(node) {

                        return node.text;

                    },

                    // 简化点击逻辑,直接切换展开/折叠状态

                    onClick: function(node) {

                        $(this).tree('toggle', node.target);

                    }

                });

 

                // 自动展开根节点(确保初始化后可见)

                setTimeout(() => {

                    const roots = $('#jsonTree').tree('getRoots');

                    if (roots.length > 0) {

                        $('#jsonTree').tree('expand', roots[0].target);

                    }

                }, 100); // 延迟确保DOM已更新

            } catch (e) {

                console.error('构建树形视图失败:', e);

                $.messager.alert('错误', '树形视图加载失败: ' + e.message, 'error');

            }

        }

 

         

        // 转换为树形数据(优化版:按值类型显示不同颜色)

        function convertToTreeData(obj, name = 'root') {

            // 处理基本类型值

            if (obj === null || typeof obj !== 'object') {

                let valueClass = 'json-number';

                let displayValue = obj;

                 

                if (typeof obj === 'string') {

                    valueClass = 'json-string';

                    displayValue = `"${obj.replace(/"/g, '\\"')}"`; // 转义双引号,避免HTML解析问题

                } else if (typeof obj === 'boolean') {

                    valueClass = 'json-boolean';

                } else if (obj === null) {

                    valueClass = 'json-null';

                    displayValue = 'null';

                }

                 

                return {

                    text: `<span class="json-key">${name}:</span> <span class="${valueClass}">${displayValue}</span>`,

                    iconCls: 'icon-ok',

                    state: 'open' // 基本类型无子节点,始终展开

                };

            }

             

            // 处理数组

            if (Array.isArray(obj)) {

                const children = obj.map((item, index) => convertToTreeData(item, `[${index}]`));

                return {

                    text: `<span class="json-key">${name}</span> <span class="json-number">(${obj.length}项)</span>`,

                    iconCls: 'icon-list',

                    children: children,

                    state: children.length > 0 ? 'closed' : 'open' // 有子节点默认折叠

                };

            }

             

            // 处理对象

            const keys = Object.keys(obj);

            const children = keys.map(key => convertToTreeData(obj[key], key));

            return {

                text: `<span class="json-key">${name}</span> <span class="json-number">(${keys.length}个属性)</span>`,

                iconCls: 'icon-folder',

                children: children,

                state: children.length > 0 ? 'closed' : 'open' // 有子节点默认折叠

            };

        }

    </script>

</body>

</html>

阅读原文:https://mp.weixin.qq.com/s/aUvt6i7NLNpvWXsecu26aA


该文章在 2026/4/15 17:58:38 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-9  粤公网安备44030602007207号