SpringBoot+Vue3实现数据可视化大屏

前端工程的地址:UserManagerFront: 数据可视化前端 (gitee.com)

效果展示,可以展现出来了,样式可能还有一些丑。

后端代码

后端主要是拿到数据并对数据进行处理,按照前端需要的格式进行返回即可。
import com.njitzx.entity.Student;
import com.njitzx.entity.vo.*;
import com.njitzx.mapper.StudentMapper;
import com.njitzx.mapper.TeacherMapper;
import com.njitzx.serivce.StudentService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
  
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.LinkedHashMap;
@Service
@RequiredArgsConstructor
public class StudentServiceImpl implements StudentService {

    private final StudentMapper studentMapper;

    private final TeacherMapper teacherMapper;

    @Override
    public CollegeVO getCollege() {
        List<Student> students = studentMapper.getAll();

        // 分组并计算每个学院的学生数量
        Map<String, Long> collect = students.stream() //收集成map集合
                .collect(Collectors.groupingBy(Student::getCollege, Collectors.counting()));

        // 根据值进行排序(降序),然后将结果收集到一个新的LinkedHashMap中
        Map<String, Long> sortedCollect = collect.entrySet().stream()
                .sorted(Entry.<String, Long>comparingByValue().reversed())
                .collect(Collectors.toMap(
                        Entry::getKey,
                        Entry::getValue,
                        (e1, e2) -> e1,
                        LinkedHashMap::new
                ));

        // 将排序后的键和值拼接成字符串
        String college = String.join(",", sortedCollect.keySet());
      
        String countList = sortedCollect.values().stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        return CollegeVO.builder().nameList(college).numberList(countList).build();
    }

    @Override
    public List<GenderVO> getSex() {
        List<Student> students = studentMapper.getAll();
        Map<String, Long> collect = students.stream()
                .collect(Collectors.groupingBy(Student::getGender, Collectors.counting()));

        List<GenderVO> genderVOList = collect.entrySet().stream()
                .map(entry -> {
                    GenderVO vo = new GenderVO();
                    vo.setName(entry.getKey());
                    vo.setValue(entry.getValue());
                    return vo;
                })
                .collect(Collectors.toList());
        return  genderVOList;
    }

    @Override
    public List<ProvinceVO> getProvince() {
        List<Student> students = studentMapper.getAll();
        Map<String, Long> collect = students.stream()
                .collect(Collectors.groupingBy(Student::getProvinces, Collectors.counting()));
        List<ProvinceVO> genderVOList = collect.entrySet().stream()
                .map(entry -> {
                    ProvinceVO vo = new ProvinceVO();
                    vo.setName(entry.getKey());
                    vo.setValue(entry.getValue());
                    return vo;
                })
                .collect(Collectors.toList());

        return  genderVOList;
    }
    @Override
    public NumberVO getnumbwer() {
        Long l = studentMapper.selectCount();
        Long r = teacherMapper.selectCount();
        return  NumberVO.builder().numberStudent(l).numberTeacher(r).build();
    }

    @Override
    public HobbyVO getHobby() {
        List<Student> students = studentMapper.getAll();

        // 分组并计算每个学院的学生数量
        Map<String, Long> collect = students.stream()
                .collect(Collectors.groupingBy(Student::getHobby, Collectors.counting()));

        // 将排序后的键和值拼接成字符串
        String name = String.join(",", collect.keySet());
        String count = collect.values().stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        return HobbyVO.builder().name(name).count(count).build();
    }
}

前端

主要是学习前端如何编写的。

vue3编写echarts代码

1.创建一个盒子<div class="panel bar" ref="chart1"> //通过ref 拿到这个盒子
2 导入echarts import * as echarts from 'echarts';

3const chart1 = ref(null);  创建dom对象

4.创建option配置

5 初始化  let instance = echarts.init(chart1.value);
  
6挂载配置到instance上面 instance.setOption(chartOptions);

  也可以通过document来获取对象,进行初始化和挂载。
    let initMap = echarts.init(document.querySelector('#hobbyRef'))
    initMap.setOption(option)
柱状图的配置
```javascript const chartOptions = { //设置距离边框的样式 grid: { left: '0%', right: '0%', top: "20%", bottom: '4%', containLabel: true }, // 设置标题 title: { // 标题 text: '学院人数排名前五', //居中位置 left: 'center', //设置标题的样式 textStyle: { color: '#2f89cf', // 设置标题颜色为红色 fontSize: 18, // 设置字体大小 fontWeight: 'bold' // 设置字体粗细 } }, color: ['#2f89cf'], tooltip: { trigger: 'axis', //坐标轴点上去触发 axisPointer: {type: 'shadow'} }, xAxis: { type: 'category', data: collegeNameList.value, axisTick: { alignWithLabel: true }, //修改 axisLabel: { color: "rgba(255,255,255,.6)", fontSize: 12, // 调大字体大小 interval: 0, // 强制显示所有标签 rotate: 30, // 旋转标签以避免重叠 formatter: function (value) { // 如果名称超过10个字符,显示省略号 return value.length > 10 ? value.slice(0, 10) + '...' : value; } }, axisLine: { show: false, // 如果想要设置单独的线条样式 lineStyle: { color: "rgba(255,255,255,.1)", width: 1, type: "solid" } } }, yAxis: { type: 'value', axisLabel: { color: "rgba(255,255,255,.6)", fontSize: "12" }, // y轴线条样式 axisLine: { lineStyle: { color: "rgba(255,255,255,.1)", // width: 1, // type: "solid" } }, // y 轴分隔线样式 splitLine: { lineStyle: { color: "rgba(255,255,255,.1)" } } }, //配置数据的 series: [{ name: '学生数量', type: 'bar', barWidth: '35%', data: collegeNumberList.value, itemStyle: { barBorderRadius: 5 } }] }; ```

<h4 id="hA9LP">中国地图</h4>
``javascript
import china from '@/json/china.json'  //导入地图的json数据


const mockData = ref([])

//从后端拿到地图的数据 [{'nane':'北京市','value':500}]
const getmokcData = async () => {
  const res = await getStudentProvince();
  mockData.value = res.data.data
  await nextTick(() => {
    getEcharts3();
  });
}

 let initMap = echarts.init(document.querySelector('#mapDom')); //初始化
  //注册中国地图
 echarts.registerMap('china', china);

//拿到前五的数据
  let topFiveData = mockData.value.sort((a, b) => b.value - a.value).slice(0, 5);
  // 将筛选后的数据转换为 ECharts 需要的格式
  let data = topFiveData.map(i => {
    let cityPosition = getCityPositionByName(i.name);
    return {
      name: i.name,
      value: cityPosition ? [...cityPosition.value.map(Number), i.value] : [0, 0, i.value]
    };
  });
// 创建一个方便查找的字典对象
  let mockDataMap = mockData.value.reduce((acc, item) => {
    acc[item.name] = item.value;
    return acc;
  }, {});

  let options = {
    title: {
      text: '学生家乡分布',
      left: 'center',
      textStyle: {
        color: '#fa4c27',
        fontSize: 18,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: (params) => {
        // 从 mockDataMap 中获取对应省份的数据值
        let count = mockDataMap[params.name] || 0; // 确保显示为0而不是NaN
        return `${params.name}<br/>${count} (学生总数)`;
      }
    },
    //又下角的工具
    toolbox: {
      show: true,
      orient: 'vertical',
      left: 'right',
      top: 'center',
      feature: {
        dataView: {readOnly: false, title: '数据视图'},
        restore: {title: '还原'},
        saveAsImage: {title: '保存为图片', pixelRatio: 2}
      }
    },
    visualMap: {
      min: 0,
      max: Math.max(...topFiveData.map(d => d.value)),
      text: ['High', 'Low'],
      realtime: false,
      calculable: true,
      inRange: {
        color: ['#e0f7fa', '#80deea', '#0288d1']
      }
    },
    //地图坐标
    geo: {
      map: 'china',
      roam: false,
      // zoom: 1, // 调整这个值来放大地图
      label: {
        show: false
      },
      emphasis: {
        label: {
          show: false
        }
      }
    },
    series: [
      {
        name: '中国',
        type: 'map',
        map: 'china',
        label: {
          show: false
        },
        data: mockData.value,
      },
      {
        type: 'scatter',
        coordinateSystem: 'geo',
        symbol: 'pin',
        symbolSize: [50, 50],
        label: {
          show: true,
          color: '#fff',
          formatter(value) {
            return value.name + value.data.value[2]; // 显示人数
          },
          fontSize: 10
        },
        itemStyle: {
          color: '#e30707' // 标记颜色
        },
        data: data,
      }
    ]
  };

  initMap.setOption(options);
背景样式
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

li {
  list-style: none;
}

@font-face {
  font-family: electronicFont;
  src: url("@/assets/font/DS-DIGIT.TTF");
}

.header {
  position: relative;
  height: 1.25rem;
  background: url('@/assets/images/head_bg.png') no-repeat top center;
  background-color: #0b1341;
  background-size: 100% 100%;
  h1 {
    font-size: 0.475rem;
    color: #fff;
    text-align: center;
    line-height: 1rem;
  }
  .showTime {
    position: absolute;
    top: 0;
    right: 0.375rem;
    line-height: 0.9375rem;
    font-size: 0.25rem;
    color: rgba(255, 255, 255, 0.7);
  }
}


.mainbox {
  font-family: Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
  /*  背景图定位 / 背景图尺寸  cover 完全铺满容器  contain 完整显示在容器内 */
  background: url('@/assets/images/bg.jpg') no-repeat #000;
  background-size: cover;
  /* 行高是字体1.15倍 */
  line-height: 1.15;
}


.mainbox {
  min-width: 1024px;
  max-width: 1920px;
  padding: 0.125rem 0.125rem 0;
  display: flex;

  .column {
    flex: 3;

    &:nth-child(2) {
      flex: 5;
      margin: 0 0.125rem 0.1875rem;
      overflow: hidden;
    }
  }
}

.panel {
  position: relative;
  height: 3.875rem;
  border: 1px solid rgba(25, 186, 139, 0.17);
  background: rgba(255, 255, 255, 0.04) url('@/assets/images/line.png');
  padding: 0 0.1875rem 0.5rem;
  margin-bottom: 0.1875rem;

  &::before {
    position: absolute;
    top: 0;
    left: 0;
    content: "";
    width: 10px;
    height: 10px;
    border-top: 2px solid #02a6b5;
    border-left: 2px solid #02a6b5;
  }

  &::after {
    position: absolute;
    top: 0;
    right: 0;
    content: "";
    width: 10px;
    height: 10px;
    border-top: 2px solid #02a6b5;
    border-right: 2px solid #02a6b5;
  }

  .panel-footer {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
   //z-index: 0;
    &::before {
      position: absolute;
      bottom: 0;
      left: 0;
      content: "";
      width: 10px;
      height: 10px;
      border-bottom: 2px solid #02a6b5;
      border-left: 2px solid #02a6b5;
    }

    &::after {
      position: absolute;
      bottom: 0;
      right: 0;
      content: "";
      width: 10px;
      height: 10px;
      border-bottom: 2px solid #02a6b5;
      border-right: 2px solid #02a6b5;
    }
  }
  //.panel-footer::before, .panel-footer::after {
  //  z-index: 0; /* 确保伪元素在 panel-footer 下层 */
  //}
  h2 {
    //z-index: 1; /* 确保 panel 在最上层 */
    height: 0.6rem;
    line-height: 0.6rem;
    text-align: center;
    color: #fff;
    font-size: 0.25rem;
    font-weight: 400;

    a {
      margin: 0 0.1875rem;
      color: #fff;
      text-decoration: underline;
    }
  }

  .chart {
    height: 3rem;
  }
}

.no {
  background: rgba(101, 132, 226, 0.1);
  padding: 0.1875rem;

  .no-hd {
    position: relative;
    border: 1px solid rgba(25, 186, 139, 0.17);

    &::before {
      content: "";
      position: absolute;
      width: 30px;
      height: 10px;
      border-top: 2px solid #02a6b5;
      border-left: 2px solid #02a6b5;
      top: 0;
      left: 0;
    }

    &::after {
      content: "";
      position: absolute;
      width: 30px;
      height: 10px;
      border-bottom: 2px solid #02a6b5;
      border-right: 2px solid #02a6b5;
      right: 0;
      bottom: 0;
    }

    ul {
      display: flex;

      li {
        position: relative;
        flex: 1;
        text-align: center;
        height: 1rem;
        line-height: 1rem;
        font-size: 0.875rem;
        color: #ffeb7b;
        padding: 0.05rem 0;
        font-family: electronicFont;
        font-weight: bold;

        &:first-child::after {
          content: "";
          position: absolute;
          height: 50%;
          width: 1px;
          background: rgba(255, 255, 255, 0.2);
          right: 0;
          top: 25%;
        }
      }
    }
  }

  .no-bd ul {
    display: flex;

    li {
      flex: 1;
      height: 0.5rem;
      line-height: 0.5rem;
      text-align: center;
      font-size: 0.225rem;
      color: rgba(255, 255, 255, 0.7);
      padding-top: 0.125rem;
    }
  }
}

.map {
  position: relative;
  height: 10.125rem;

  .chart {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 5;
    height: 10.125rem;
    width: 100%;
  }

  .map1,
  .map2,
  .map3 {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 6.475rem;
    height: 6.475rem;
    background: url('@/assets/images/map.png') no-repeat;
    background-size: 100% 100%;
    opacity: 0.3;
  }

  .map2 {
    width: 8.0375rem;
    height: 8.0375rem;
    background-image: url('@/assets/images/lbx.png');
    opacity: 0.6;
    animation: rotate 15s linear infinite;
    z-index: 2;
  }

  .map3 {
    width: 7.075rem;
    height: 7.075rem;
    background-image: url('@/assets/images/jt.png');
    animation: rotate1 10s linear infinite;
  }

  @keyframes rotate {
    from {
      transform: translate(-50%, -50%) rotate(0deg);
    }
    to {
      transform: translate(-50%, -50%) rotate(360deg);
    }
  }
  @keyframes rotate1 {
    from {
      transform: translate(-50%, -50%) rotate(0deg);
    }
    to {
      transform: translate(-50%, -50%) rotate(-360deg);
    }
  }
}

@media screen and (max-width: 1024px) {
  html {
    font-size: 42px !important;
  }
}

@media screen and (min-width: 1920px) {
  html {
    font-size: 80px !important;
  }
}

template

整体结构是 flex布局 3 5 3 布局样式。

<template>
  
  <div class="header">
    <h1>工程数据分析</h1>
    <div class="showTime"></div>
  </div>

  
  <!-- 页面主体  一个大的盒子  划分 -->
  <div class="mainbox">
    <div class="column">
      <div class="panel bar" ref="chart1">
        <div class="chart"></div>
        <!--        <h2 style="color: red">学院人数排名前五</h2>-->
        <div class="panel-footer"></div>
      </div>
      <div class="panel line" ref="chart2">
        <div class="chart"></div>
        <h2>标题</h2>
        <div class="panel-footer"></div>
      </div>
      <div class="panel pie">
        <h2></h2>
        <div class="panel-footer"></div>
      </div>
    </div>


    <div class="column">
      <div class="no">
        <div class="no-hd">
          <ul>
            <li>{{ stNumber.numberTeacher }}</li>
            <li>{{ stNumber.numberStudent }}</li>
          </ul>
        </div>
        <div class="no-bd">
          <ul>
            <li>学生人数</li>
            <li>老师人数</li>
          </ul>
        </div>
      </div>
      <!-- 地图模块 -->
      <div class="map">
        <!-- 放到map中间 -->
        <div class="chart" id="mapDom"></div>
        <div class="map1"></div>
        <div class="map2"></div>
        <div class="map3"></div>
      </div>
    </div>


    <div class="column">
      <div class="panel bar" >
        <h2></h2>
        <div class="chart" id="hobbyRef"></div>
        <div class="panel-footer"></div>
      </div>
      <div class="panel line">
        <h2></h2>

        <div class="panel-footer"></div>
      </div>
      <div class="panel pie">
        <h2></h2>
        <div class="panel-footer"></div>
      </div>

    </div>
  </div>
</template>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/916102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

<项目代码>YOLOv8 手机识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

算法定制LiteAIServer摄像机实时接入分析平台烟火识别检测算法

在公共安全领域&#xff0c;火灾的及时发现与处理是保障人民群众生命财产安全的重要手段。传统的烟火检测手段受限于人工巡查的局限&#xff0c;难以做到全天候、无遗漏的监控。然而&#xff0c;随着人工智能技术的飞速发展&#xff0c;LiteAIServer摄像机实时接入分析平台烟火…

JMeter与大模型融合应用之JMeter日志分析服务化实战应用

JMeter与大模型融合应用之JMeter日志分析服务化 引言 在当今的互联网时代,网站和应用程序的性能直接影响到用户的体验和业务的成功。为了保证系统的稳定性和高效性,性能测试成为了软件开发过程中的一个重要环节。在这其中,Apache JMeter作为一款开源的性能测试工具,凭借其…

【Pikachu】任意文件上传实战

将过去和羁绊全部丢弃&#xff0c;不要吝惜那为了梦想流下的泪水。 1.不安全的文件上传漏洞概述 不安全的文件上传漏洞概述 文件上传功能在web应用系统很常见&#xff0c;比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后&#xff0c;后台会对上传的…

STM32 ADC --- 单通道采样

STM32 ADC — 单通道采样 文章目录 STM32 ADC --- 单通道采样cubeMX配置代码修改&#xff1a;应用 使用cubeMX生成HAL工程 需求&#xff1a;有多个通道需要进行ADC采样&#xff0c;实现每次采样只采样一个通道&#xff0c;且可以随时采样不同通道的功能。 cubeMX配置 这里我们…

influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI

安装 Install InfluxDB | InfluxDB OSS v2 Documentation Debian和Ubuntu用户可以用apt-get包管理来安装最新版本的InfluxDB。 对于Ubuntu用户&#xff0c;可以用下面的命令添加InfluxDB的仓库&#xff0c;添加之后即可apt-get 安装influxdb2 wget -q https://repos.influx…

【轻量化】YOLOv10 更换骨干网络之 MobileNetv4 | 模块化加法!非 timm 包!

之前咱们在这个文章中讲了timm包的加法,不少同学反馈要模块化的加法,那么这篇就讲解下模块化的加法,值得注意的是,这样改加载不了mobilebnetv4官方开源的权重了~ 论文地址:https://arxiv.org/pdf/2404.10518 代码地址:https://github.com/tensorflow/models/blob/master…

电气自动控制电路图图例

单相照明双路互备自投供电电路 双路三相电源自投电路 茶炉水加热自动控制电路 简单的温度控制器电路 简易晶闸管温度自动控制电路 用双向晶闸管控制温度电路 XCT-101动圈式温度调节仪控温电路 电接点压力式温度表控温电路 TDA-8601型温度指示调节仪控温电路 XMT-DA数字…

D3 可以加载的数据格式有哪些?(12种)

D3.js 支持多种数据格式&#xff0c;这些格式涵盖了从简单的表格数据到复杂的地理数据。以下是一些常见的数据格式及其加载方法&#xff1a; D3.js 数据加载方法 d3.blob(input, init) 用途: 加载二进制数据&#xff0c;返回一个 Blob 对象。参数: input: 数据源 URL。init: …

Pinpoint(APM)进阶--Pinot指标采集(System Metric/Inspector)

接上文 Pinpoint使用Pinot进行指标数据存储&#xff0c;Pinot流摄入需要Kafka 本文详解Kafka和Pinot的安装部署&#xff0c;以及Pinpoint的指标采集 Pinot 简介 Apache Pinot是一个实时分布式OLAP数据存储&#xff0c;专为低延迟、高吞吐量分析而构建&#xff0c;非常适合面…

mmsegmentation: 安装 并使用自定义数据集进行训练 ·2

我用的是CHASE_DB1.py 数据集下载链接 https://staffnet.kingston.ac.uk/~ku15565/CHASE_DB1/assets/CHASEDB1.zip 这个用来转换mmseg所需要的格式 python tools/dataset_converters/chase_db1.py /path/to/CHASEDB1.zip其他数据集请看链接&#xff1a;https://mmsegmenta…

通义千问API调用测试 (colab-python,vue)

文章目录 代码&#xff08;来自官网&#xff09;colab中用python测试Qwen2.5在官网上查看并确定过期时间这里看到我的免费额度到25年5月在同一个页面&#xff0c;点击API示例 前端调用直接在前端调用的优缺点以vue为例&#xff08;代码是基于官网node.js的代码转换而来&#xf…

【c++笔试强训】(第九篇)

目录 链表相加&#xff08;⼆&#xff09;&#xff08;链表⾼精度加法&#xff09; 题目解析 讲解算法原理 编写代码 ⼤数乘法&#xff08;⾼精度乘法&#xff09; 题目解析 讲解算法原理 辨析代码 链表相加&#xff08;⼆&#xff09;&#xff08;链表⾼精度加法&#…

C#高级:使用Invoke关键字通过 Type 类型调用指定的方法

demo如下&#xff1a; using System.Reflection; using System;public class Program {public class Calculator{public int Add(int a, int b){return a b;}}public class Student{public string Name { get; set; }}public class Example{// 泛型方法public string Generi…

B-树特点以及插入、删除数据过程

B树&#xff08;B-Tree&#xff09;是一种自平衡的多路查找树&#xff0c;它广泛应用于数据库索引和文件系统中&#xff0c;尤其适用于外部存储设备&#xff08;如磁盘&#xff09;。B树的设计使得它能够高效地存储大量数据并支持高效的插入、删除和查询操作。以下是B树的主要特…

自定义反序列化过程

需求&#xff1a;student对象中name属性&#xff0c;序列化时将该属性映射为stuname&#xff0c;反序列化时将 Json中的NAME键值对映射到name属性中 AllArgsConstructorNoArgsConstructorGetterSetterstatic class Student {JsonProperty("stuname")private List<…

解读 ConcurrentHashMap 源码:探索高并发场景下的卓越性能

ConcurrentHashMap 了&#xff0c;作为线程安全的 HashMap &#xff0c;它的使用频率也是很高。那么它的存储结构和实现原理是怎么样的呢&#xff1f;HashMap 源码&#xff1a;揭开哈希表背后的秘密 1、ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储…

为什么配置TIM11作为系统时基的时候会出现__NVIC_PRIO_BITS

回想起当初学freertos的时候&#xff0c;某个中断优先级以下的任务是不能被freertos管理的&#xff08;好像是全是抢占优先级&#xff0c;0子优先级的设置&#xff09;。当初还不是非常了解。只知道管理不了 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {RCC_ClkI…

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)

数字IC实践项目&#xff08;10&#xff09;—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证&#xff08;付费项目&#xff09; 前言项目框图1&#xff09;DDR4 Verification IP2&#xff09;DDR4 JEDEC Model & Tb 项目文件1&#xff09;DDR4 Veri…

python解析网页上的json数据落地到EXCEL

安装必要的库 import requests import pandas as pd import os import sys import io import urllib3 import json测试数据 网页上的数据结构如下 {"success": true,"code": "CIFM_0000","encode": null,"message": &quo…