• .Net+Vue3实现数据简易导入功能


    在开发的过程中,上传文件或者导入数据是一件很常见的事情,导入数据可以有两种方式:

    1. 前端上传文件到后台,后台读取文件内容,进行验证再进行存储
    2. 前端读取数据,进行数据验证,然后发送数据到后台进行存储

    这两种方式需要根据不同的业务才进行采用

    这次用.Net6.0+Vue3来实现一个数据导入的功能

    接下来分别用代码来实现这两种方式

    1. 前端上传文件到后台进行数据存储

    1.1编写文件上传接口

    复制代码
            [DisableRequestSizeLimit]
            [HttpPost]
            public IActionResult Upload()
            {
                var files = Request.Form.Files;
                long size = files.Sum(f => f.Length);
    
                string contentRootPath = AppContext.BaseDirectory;
                List<string> filenames = new List<string>();
                foreach (IFormFile formFile in files)
                {
                    if (formFile.Length > 0)
                    {
                        string fileExt = Path.GetExtension(formFile.FileName);
                        long fileSize = formFile.Length;
                        string newFileName = System.Guid.NewGuid().ToString() + fileExt;
                        var filePath = contentRootPath + "/fileUpload/";
                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        using (var stream = new FileStream(filePath + newFileName, FileMode.Create))
                        {
                            formFile.CopyTo(stream);
                        }
                        filenames.Add(newFileName);
                    }
                }
                return Ok(filenames);
            }
    复制代码

    这里只是上传文件分了两步走,第一步把文件上传到服务器,第二步调用接口把返回的文件路径发送给后台进行数据保存

    1.2存储上传文件路径,读取数据并进行存储

    复制代码
      /// 
            /// 上传文件数据
            /// 
            /// 
            /// 
            [HttpPut]
            public IActionResult Put(DataInput uploadStuInfoInput)
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    
                var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fileUpload", uploadStuInfoInput.filePath);
                if (!System.IO.File.Exists(filePath))
                {
                    return BadRequest("导入失败,文件不存在!");
                }
                var row = MiniExcelLibs.MiniExcel.Query(filePath).ToList();
                companies.AddRange(row.Select(x => new Company { Name = x.名称, Address = x.地址 }));
                return Ok("导入成功!");
            }
    复制代码

    1.3前端Vue建立创建列表数据页面,包含表格功能及分页功能

    复制代码
    
          for="item in state.colunm" :prop="item.key" :key="item.key" :label="item.lable">
          
        
     
    if='state.tableData.total > 0'>               :page-sizes="[10, 50, 200, 1000]" layout="total, sizes, prev, pager, next, jumper" @size-change="getData"         @current-change="getData" :total="state.tableData.total" />    
    复制代码

    1.4调用接口获取表格数据方法

    复制代码
     const getData = () => {
          axios.get('/Company', { params: state.searchInput }).then(function (response) {
            state.tableData = response.data;
          })
        }
    复制代码

    1.5后台开发数据返回接口

    复制代码
            [HttpGet]
            public dynamic Get([FromQuery] SelectInput selectInput)
            {
                return new
                {
                    total = companies.Count(),
                    data = companies.Skip((selectInput.pageIndex - 1) * selectInput.pageSize).Take(selectInput.pageSize).ToList()
                };
            }
    复制代码

    1.6主页面创建上传文件组件并进行引用

    import FileUpload from '@/components/FileUpload.vue'; 

    并绑定子页面回调方法fileUploadchildClick

      

    1.7FleUpload页面主要上传文件到服务器,并回调父页面存储接口

    复制代码
     
        
          
            :on-success='fileUploadEnd' :action='fileUploadUrl()'>
            
            
    将文件拖到此处,或点击上传
           
    请选择({{  accept  }})文件
         
         
                      导入           取消              
       
     
    复制代码

    1.8这里的titleaccept参数由父页面传值过来,可以进行组件复用

    选择文件成功回调方法

    复制代码
     const fileUploadEnd = (response, file) => {
          state.fileresponse = file.name;
          state.formData.filePath = response[0];
          if (state.fileList.length > 0) {
            state.fileList.splice(0, 1);
          }
        }
    复制代码

    1.9提交保存时回调父页面存储数据方法

    复制代码
    const submit = () => {
          if (state.formData.filePath == '') {
            ElMessage.error('请选择上传的文件')
            return;
          }
          context.emit('childClick', state.formData)
        }
    复制代码

    1.10父页面方法调用接口进行数据存储,存储成功后关闭子页面

     

    复制代码
     const fileUploadchildClick = (e) => {
          axios.put('/Company', {
            filePath: e.filePath,
          }).then(function (response) {
            if (response.status == 200) {
              ElMessage.success(response.data);
              fileUpload.value.cancel();
              getData();
            } else {
              ElMessage.error(response.data)
            }
          })
        }
    复制代码

     

    1.11后台数据存储接口

    复制代码
     /// 
            /// 上传文件数据
            /// 
            /// 
            /// 
            [HttpPut]
            public IActionResult Put(DataInput uploadStuInfoInput)
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    
                var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fileUpload", uploadStuInfoInput.filePath);
                if (!System.IO.File.Exists(filePath))
                {
                    return BadRequest("导入失败,文件不存在!");
                }
                var row = MiniExcelLibs.MiniExcel.Query(filePath).ToList();
                companies.AddRange(row.Select(x => new Company { Name = x.名称, Address = x.地址 }));
                return Ok("导入成功!");
         }
    复制代码

    2前端读取数据,发送读取数据到后台进行数据存储

    2.1创建上传数据组件并引用

    import DataUpload from '@/components/DataUpload.vue';

    并绑定子页面回调方法dataUploadchildClick

    2.2DataUpload页面主要读取选择文件数据,并进行展示

     

    复制代码
    
        
          
          
    将文件拖到此处,或点击上传
       
       
                  确认导入          
              for="item in state.colunm" :prop="item.key" :key="item.key" :label="item.lable">              
    if='state.tableData.total > 0'>               :page-sizes="[10, 50, 200, 1000]" layout="total, sizes, prev, pager, next, jumper" @size-change="getData"         @current-change="getData" :total="state.tableData.total" />    
     
    复制代码

     

    2.3文件上传成功方法,保存数据到临时变量进行分页处理

    复制代码
    const uploadChange = async (file) => {
          let dataBinary = await readFile(file.raw)
          let workBook = XLSX.read(dataBinary, { type: 'binary', cellDates: true })
          let workSheet = workBook.Sheets[workBook.SheetNames[0]]
          let data: any = XLSX.utils.sheet_to_json(workSheet)
    
          let tHeader = state.colunm.map(obj => obj.lable)
          let filterVal = state.colunm.map(obj => obj.key)
          tHeader.map(val => filterVal.map(obj => val[obj]))
          const tempData: any = [];
          data.forEach((value) => {
            const ob = {};
            tHeader.forEach((item, index) => {
              ob[filterVal[index]] = value[item].toString();
            })
            tempData.push(ob);
          })
          state.tempTableData = tempData;
          getData();
        }
    复制代码

    2.4数据绑定到表格上,这里需要通过当前选择页码及页面显示数量处理需要绑定到表格上的数据

    复制代码
    const getData = () => {
          const tempData: any = [];
          state.tempTableData.forEach((value, index) => {
            if (index >= ((state.searchInput.PageIndex - 1) * state.searchInput.PageSize) && index < ((state.searchInput.PageIndex) * state.searchInput.PageSize)) {
              tempData.push(value);
            }
          });
          state.tableData.data = tempData;
          state.tableData.total = state.tempTableData.length;
        }
    复制代码

    2.5点击确认导入按钮回调父页面方法进行数据保存

    const submit = () => {
          context.emit('childClick', state.tempTableData)
        }

    2.6父页面方法调用接口进行数据存储,存储成功后关闭子页面

    复制代码
    const dataUploadchildClick = (data) => {
          axios.post('/Company', data)
            .then(function (response) {
              if (response.status == 200) {
                ElMessage.success(response.data);
                dataUpload.value.cancel();
                getData();
              } else {
                ElMessage.error(response.data)
              }
            })
        }
    复制代码

    2.7后台数据存储接口

     

    复制代码
      /// 上传数据
            /// 
            /// 
            /// 
            [HttpPost]
            public IActionResult Post(List  companiesInput)
            {
                companies.AddRange(companiesInput);
                return Ok("保存成功!");
    
            }
    复制代码

     

    最后关于这个数据导入的功能就完成了,代码中有很多得伪代码,而且很多功能还待完善,后续再进行补充

    附上git地址:https://gitee.com/wyf854861085/file-upload.git

    Git演示图:

     

  • 相关阅读:
    成功解决ModuleNotFoundError: No module named ‘sklearn.ensemble.weight_boosting‘
    【卫朋】硬件创业:营销与开发同行
    机器学习笔记 YOLOv9模型相关论文简读
    lightdb Oracle模式下to_char支持格式‘HH24MiSS‘
    Webinspect
    睿趣科技:现在开抖音小店到底要多少钱
    对软件重构的认识
    zabbix基于Zabbix-in-telegram实现图片告警(centos7)
    分享一个追剧神器(不是看剧),可以追电视剧、动漫和电影
    运维Shell脚本小试牛刀(十二):awk编程尝鲜
  • 原文地址:https://www.cnblogs.com/wuyongfu/p/16651107.html