首页 > 其他分享 >前端导入导出文件(前后端不分离)

前端导入导出文件(前后端不分离)

时间:2024-08-07 17:57:43浏览次数:7  
标签:文件 数据 前端 导出 导入 error var data 数据库

    有时候在对硬件传送过来的数据进行处理后,需要将这些数据显示在折线图上,从而来观察这些数据是怎样变化的,这个好办,但有时候又要求需要将折线图上面显示的数据全部导出到一个文件中,并且有时候又要求在文件中改变数据后,再将文件中的数据重新导入到折线图中,哪有该如何写呢?

  我的思路如下:

1.首先,我们需要实现将折线图上显示的数据导出到文件中,常见的文件格式可以选择为CSV(逗号分隔值),因为它易于读取和处理。(首先需要一个导出文件的按钮)

下面以电池实时电量变化和电池实时温度变化这两个数据为例

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>变化分析图</title>
    <!-- 引入 echarts.js -->
    <script src="echarts.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<button onclick="exportDataToFile()">导出数据到文件</button>
<input type="file" id="fileInput" accept=".json" onchange="importDataFromFile(event)">
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例---------------有多个数据---即多条线,并且还有导入导出
    //文件为csv
    var myChart = echarts.init(document.getElementById('main'));
    // 初始化图表的配置项
    var option = {
        title: {
            text: '数据分析图'
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross'
            }
        },
        legend: {
            data:['电池电量', '电池温度']
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: []
        },
        yAxis: {
            type: 'value'
        },
        tooltip: {
            trigger: 'axis', // 设置触发类型为坐标轴触发
            axisPointer: {
                type: 'cross' // 十字准星指示器,显示在坐标轴上
            }
        },
        series: [
            {
                name: '电池电量',
                type: 'line',
                data: []
            },
            {
                name: '电池温度',
                type: 'line',
                data: []
            }
        ]
    };
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
    // 获取数据并更新图表
    function fetchData() {
        fetch('http://localhost:8080/mysql/getAllHistory1')  // 修改为你的后端接口地址
            .then(response => response.json())
            .then(data => {
                var timeData = [];
                var c1Data = [];
                var tem1Data = [];
                data.forEach(item => {
                    /*   var now=new Date();
                       var currentTime = [now.getHours(), now.getMinutes(), now.getSeconds()].map(num => num < 10 ? '0' + num : num).join(':');*/
                    timeData.push(item.time);  // 时间
                    c1Data.push(item.c);  //
                    tem1Data.push(item.tem);  //
                });
                // 更新图表数据
                myChart.setOption({
                    xAxis: {
                        data: timeData
                    },
                    series: [
                        {
                            name: '电量',
                            data: c1Data
                        },
                        {
                            name: '温度',
                            data: tem1Data
                        }

                    ]
                });
            })
            .catch(error => console.error('Error fetching data:', error));
    }
    // 初次加载数据
    fetchData();
    // 定期获取数据
    setInterval(fetchData, 5000);  // 每隔5秒钟获取一次数据
    //导出图表数据到文件
    function exportDataToFile() {
        fetch("http://localhost:8080/mysql/getAllHistory1")
            .then(response => response.json())
            .then(data => {
                // 将数据转换为 JSON 格式字符串
                var jsonData = JSON.stringify(data, null, 2);
                // 创建一个 Blob 对象
                var blob = new Blob([jsonData], { type: 'application/json' });
                // 创建一个下载链接
                var url = URL.createObjectURL(blob);
                // 创建一个下载链接的 <a> 元素
                var a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.download = 'queue_data.json'; // 下载的文件名
                // 添加到 DOM 并触发点击下载
                document.body.appendChild(a);
                a.click();
                // 下载之后就清理
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
            })
            .catch(error => console.error('Error exporting data:', error));
    }

其中这段代码里面有些是固定代码,当你需要显示其他数据时,可以将这些固定代码直接抄过去,只需要改变后端请求路径: fetch("http://localhost:8080/mysql/getAllHistory1")----这里具体问题具体分析,根据自己的请求路径来写。

2.后端代码

我使用的是前后端不分离的情况,可能有所不同,接下来分享我的代码:

(1)controller层代码

package com.demo.controller;
import com.demo.pojo.Data1;
import com.demo.service.Data1Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@CrossOrigin(origins = "http://localhost:63342")
@RequestMapping("/mysql")
public class Data1Controller {
    @Autowired
    private Data1Service data1Service;
    @GetMapping("/getAllHistory1")
    public List<Data1> getAllHistory() {
        List<Data1> allHistory = data1Service.getAllHistory();
        Data1 data1 = allHistory.get(0);
        return data1Service.getAllHistory();
    }
}

(2)mapper层代码

@Mapper
public interface Data1Mapper extends BaseMapper<Data1> {
    @Insert("insert into " +
            "data1(id,c,tem,time) " +
            "values " +
            "(#{id},#{c},#{tem}, #{time})")
    int insert(Data1 data1);//插入语句--这里在将数据存入数据库时需要用到,通常只需要改变字段和实体类名字(数据库名字)

    @Select("select * from data1")
    List<Data1> getAll();

}

(3)service层代码

public interface Data1Service extends IService<Data1> {
    List<Data1> getAllHistory();//获取所有数据
}

  通常只需要改变实体类名字就可以搬运了

(4)service实现类代码

@Service
public class Data1ServiceImpl extends ServiceImpl<Data1Mapper, Data1>
    implements Data1Service {
    @Autowired
    private Data1Mapper data1Mapper;

    @Autowired
    public Data1ServiceImpl(Data1Mapper data1Mapper) {
        this.data1Mapper = data1Mapper
        ;
    }

    @Override
    public List<Data1> getAllHistory() {
        QueryWrapper wrapper=new QueryWrapper<>();
        List<Data1> data1s = data1Mapper.selectList(null);
        return data1s;
    }
}

注意:这里只需要导出到文件

2.如果还需要将文件中的数据改变之后,再将文件中的数据导入到折线图中,则需要在几个地方进行改变:

我的代码都是从数据库中获取数据,然后渲染到折线图中,所以,当在文件中改变数据时需要先在数据库中更新数据,然后前端发送请求给后端数据库,再重新获取数据渲染在页面上,具体代码如下:(即先点击导入文件按钮,点击事件发送之后,将文件内容转换为对象数组发送请求给后端,后端进行数据库更新,更新完之后,前端再重新获取数据渲染在折线图上)

//导入图表数据
    function importDataFromFile(event) {
        var file = event.target.files[0];
        if (!file) {
            console.error("没有选择文件");
            return;
        }
        //利用reader读取文件里面的数据
        var reader = new FileReader();
        reader.onload = function (e) {
            var contents = e.target.result;
            try {
                var importedDataArray = JSON.parse(contents); // 解析整个文件为一个数组
                importedDataArray.forEach(importedData => {
                    // 确保每个 importedData 是一个对象
                    if (typeof importedData !== 'object' || Array.isArray(importedData)) {
                        throw new Error('File content is not valid JSON object');
                    }
                    // 发送数据到后端的逻辑
                    fetch("http://localhost:8080/Mysql/UpdateMessage1", {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        mode: 'cors',
                        body: JSON.stringify(importedData)
                    })
                        .then(data => {
                            console.log('Success:', data);
                            // 更新图表数据(如果需要)
                            updateChartWithData(importedData);
                        })
                        .catch(error => {
                            console.error('There has been a problem with your fetch operation:', error);
                        });
                });
            } catch (error) {
                console.error('Error parsing JSON:', error);
                console.log(contents);
            }
        };
        reader.readAsText(file);
    }

</script>
</body>
</html>

后端代码-----更新数据库

(1)controller层代码

 // 更新某条记录-----跟导入数据有关
//当在文件中改变的是某一个数据时,可以根据唯一的字段进行更新
    @PostMapping("/UpdateMessage1")
    //其中需要写实体类----在service中这个方法
    public void updateLine(@RequestBody Data1 data1) {
        data1Service.updateLine(data1);
    }
   //更新整个数据库---当数据库中的数据全部清空时--利用图表将数据导入到文件中,然后再导入到图表中
//注意,一定要在导入之前将数据库中的数据清空,即当导出文件时,数据库中的数据存在文件中,当在文件中修改数据时,修改之后保存文件,再导入到图中时,首先得把数据库中的数据清空再来导入,否则会报错
    @PostMapping("/UpdateMessage3")
    public void insert(@RequestBody data1 data1) {
        data1Mapper.insert(data1);
    }

注意:更新整个数据库用到的是插入语句,在导入文件前清空数据库是为了在利用insert语句更新数据库时,不会有重复的数据出现,即不会在现有的数据库中接着插入语句,就是本来数据库中有10个记录,当我修改其中的某几个记录后,在导入文件之前清空数据库,利用insert语句之后,还是10个记录,如果不清空的话,那么一共会有20个记录。

(2)service层代码:

 //更新数据库中某条记录
    void updateLine(data1 dat1);

(3)service实现类代码:

 @Override
    public void updateLine(Data1 data1) {
       data1Mapper.updateById(data1); // 使用updateById更新数据
   }

以上代码经供参考,如发现有错的的地方,欢迎指出

标签:文件,数据,前端,导出,导入,error,var,data,数据库
From: https://blog.csdn.net/m0_74809043/article/details/140958579

相关文章

  • 前端国际化自动工具 - 国际化文案配置系统
    背景笔者之前所在的公司主要做东南亚和欧洲一些国家的业务,做的是Web后台管理系统,项目被不同国家(有的项目多达七八个国家)的客户使用,所以前端项目需要支持多语言展示,也就是适配国际化。日常编码中,系统需要接入前端web国际化插件,vue项目使用的是vue-i18n,而react项目......
  • XD6500S— LoRa SIP模块芯片 集成了射频前端和LoRa射频收发器SX1262 应用温湿度传感器
    XD6500S是一系列LoRaSIP模块,集成了射频前端和LoRa射频收发器SX1262系列,支持LoRa和FSK调制。收发器SX1262系列,支持LoRa和FSK调制。LoRa技术是一种扩频协议,针对LPWAN应用的低数据速率、超远距离和超低功耗通信进行了优化。通信进行了优化。XD6500S的主动接收电流消耗为4.2mA,电池寿......
  • 企业业务前端监控实践
    监控的背景和意义在现代前端开发中,接入监控系统是一个很重要的环节,它可以帮助开发者、产品、运营了解应用的性能表现,用户的实际体验以及潜在的错误和问题,从而进一步优化用户体验,帮助产品升级迭代。背景•应用复杂性增加:随着单页应用(SPA)和渐进式网页应用(PWA)的流行,前端应用变得......
  • 将普通 python 文件导入另一个文件时出现 AttributeError
    我是新手。我正在尝试将简单的python文件导入到我的主文件中。相同的代码在我的mac上工作,但在我的电脑上不起作用。我不断收到此错误消息。“AttributeError:模块‘logo’没有属性‘hammer_logo’”第一个文件拍卖.py代码importlogoprint(logo.hammer_logo)第......
  • 帝国cms数据库表和前端不一致怎么办
    解决帝国CMS数据库表和前端不一致问题,可以采取以下步骤:1.检查模板文件数据库中的字段名称是否与模板文件中的字段名称匹配?字段的值是否正确传递到模板文件?模板文件是否正确调用字段的值?2.检查缓存设置确保帝国CMS设置为不使用缓存,或者将缓存设置为定期更新。清除......
  • 如何快速成为高薪的前端开发选手
    在如今的互联网时代,前端开发已经成为一个炙手可热的职业。如何在激烈的竞争中脱颖而出,成为高薪的前端开发选手?今天,我想和大家分享一个秘密武器——MemFireCloud,一款专为懒人开发者准备的一站式开发应用神器。通过它,你可以快速提升开发效率,轻松接私活,赚取高薪。一站式开发......
  • Altium Designer怎么导入面板设置文件(.TLT文件)
    AltiumDesigner怎么导入面板文件(.TLT文件)文章目录`AltiumDesigner怎么导入面板文件(.TLT文件)``如果对你有帮助,就点赞收藏把!(。・ω・。)ノ♡`最近换新电脑,要将AltiumDesigner移植过去同时要将AltiumDesigner的设置移植过去(比pads强)但是上次移植设置还是在上次忘记怎么......
  • ArcPro (3.2+) Python 脚本工具中从 .atbx Toolbox 相对导入本地模块
    我设置了一个库和关联的ArcGISToolbox,以便:/root├──Toolbox.atbx├──mylib│└──my_function.py├──my_tools│└──my_gp_script.py我将代码存储库的开发克隆保存在公司共享服务器上的一个位置,并在GitHub上托管一份副本。当我进行更新时,我会......
  • 【项目实战】在前端开发中,集成了两款富文本编辑器(如 Quill Editor和 Froala Editor)可
    在前端开发中,集成富文本编辑器(如Quill和Froala)可以让用户在网页上编辑和格式化文本,就像使用桌面文字处理器一样。Quill和Froala都是非常流行的富文本编辑器,各有其特点和优势。下面分别介绍一下这两款编辑器以及如何在项目中集成它们。一、QuillEditor介绍Quill......
  • HTML前端面试基础(一)
    HTML面试题可以涵盖多个方面,包括HTML基础、HTML5新特性、标签语义化、元素分类、属性理解等。以下是一些常见的HTML面试题及其简要答案:1.HTML基础问题:请解释一下HTML文档的基本结构。答案:HTML文档的基本结构包括<!DOCTYPEhtml>声明、<html>根元素、<head>头部元素(包含文......