C#结合JavaScript实现多文件上传

目录

需求

引入

关键代码

操作界面

​JavaScript包程序

服务端 ashx 程序

服务端上传后处理程序

小结


需求

在许多应用场景里,多文件上传是一项比较实用的功能。实际应用中,多文件上传可以考虑如下需求:

1、对上传文件的类型、大小有一个基本的控制。

2、上传文件时有一个进度显示,包括当前文件和整体进度。

3、上传后,在服务端后续事件进行一些处理。

引入

首先请在WEB应用程序根目录下创建COMMON目录,并引入 JavaScript 程序包,该程序包已经打包,下载地址为:https://download.csdn.net/download/michaelline/88615565。

下载成功后解压到COMMON目录即可,请引入如下图中的 JS 文件:

另外,我们还需要在 app_data目录下创建 ajaxUploadFiles 子目录,以备上传创建文件使用。

关键代码

操作界面

界面上放置标准的 input file 控件,并将其服务器化,即 runat="server"。点击选择文件,选中所有目标文件后,自动实现文件上传功能。

示例界面如下:

示例UI代码如下:

<input  class="file" type="file" id="ajaxMfile" runat="server" 
                                    onbeginupload="ajax_uploadFiles_beginUpload" onprogressupload="ajax_uploadFiles_progressUpload" onendupload="ajax_uploadFiles_endUpload" 
                                    multiple="multiple" allowtype="pptx|docx|mp3|txt|std" allowsize="500m|100m" fileindex="0" name="fileupload"
                                    serverbuttonid="ajaxEndBtn" serverfilelistid="ajaxReturnFileName"
                                    progresspanelid="ajaxMfileProgressPanel"
                                    onchange="ajax_uploadFiles(this);return false" />
                            <asp:TextBox runat="server" Width="100%" ID="ajaxReturnFileName" style="display:none" ></asp:TextBox>
                                        <br />
                            <asp:button ID="ajaxEndBtn" text="后台处理" runat="server" style="display:none" onclick="ajaxEndBtn_Click"  />
                                        <br />
                                        <br />
                                        <table style="display:none; color:White" id="ajaxMfileProgressPanel">
                                            <tr>
                                                <td >
                                                    当前文件:</td>
                                                <td style="position:relative; padding:0px">
                                                    <asp:Label Font-Size="9pt" style="z-index:1;position:absolute;left:0px;top:-9px;" Width="300px" runat="server" ID="ajax_uploadFiles_curfilename"/>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="position:relative; padding:0px;width:120px">
                                                    当前文件进度<asp:Label style="z-index:1;position:absolute;left:85px;top:-9px;" runat="server" Font-Size="9pt" ID="ajax_uploadFiles_upprogress"></asp:Label>
                                                </td>
                                                <td style="position:relative; padding:10px">
                                                    <img id="ajax_uploadFiles_curprogress" style="z-index:1;position:absolute;left:0px;top:4px;width:0px;height:12px" alt="" src="/common/Jquery/images/win7progress.jpg" />
                                                    <div id="ajax_uploadFiles_curbg" style="z-index:0;position:absolute;left:0px;top:4px;width:300px;height:12px;background-color:Gray"></div>
                                                </td>

                                            </tr>
                                            <tr>
                                                <td style="position:relative; padding:0px">
                                                    上传总量进度<asp:Label style="z-index:1;position:absolute;left:85px;top:-9px;" runat="server" Font-Size="9pt" ID="ajax_uploadFiles_cprogress"></asp:Label></td>
                                                <td style="position:relative; padding:10px">
                                                    <img id="ajax_uploadFiles_totalprogress" style="z-index:1;position:absolute;left:0px;top:4px;width:0px;height:12px" alt="" src="/common/Jquery/images/win7progress2.jpg" />
                                                    <div id="ajax_uploadFiles_totalbg" style="z-index:0; position:absolute;left:0px;top:4px;width:300px;height:12px;background-color:Gray"></div>
                                                </td>
                                            </tr>
                                            
                                        </table>
                                        <table style="color:White; width:100%">
                                           <tr>
                                                <td style="position:relative">
                                                    <asp:Label runat="server" Font-Size="11pt" ID="ajax_uploadFiles_serverProcessTip"></asp:Label>
                                                </td>
                                            </tr>
                                        </table>

input file 控件的一些设置如下:

(1)onbeginupload="ajax_uploadFiles_beginUpload"   js方法,开始上传前事件,默认值

(2)onprogressupload="ajax_uploadFiles_progressUpload"   js方法,上传中事件,默认值

(3)onendupload="ajax_uploadFiles_endUpload"    js方法,选择完文件上传事件,默认值
(4)multiple="multiple"         控件属性,允许多文件选中上传

(5)allowtype="pptx|docx|mp3|txt|std"    自定义属性,允许上传的文件类型,以 | 分隔

(6)allowsize="500m|100m"    自定义属性,允许上传的文件最大尺寸,可以以 | 分隔,并一一对应,如果不对应,则根据 allowtype 的设置从左至右进行匹配

        如举例中的设置则表示为,pptx 允许最大 500M , docx 最大 100M,后面未设置则均为100M

(7) serverbuttonid="ajaxEndBtn"   自定义属性,执行的服务器按钮ID,默认值 

(8)serverfilelistid="ajaxReturnFileName"  自定义属性,服务器端返回的文件ID列表,默认值

(9)οnchange="ajax_uploadFiles(this);return false"  自定义属性,js方法,选择文件后自动执行上传功能,默认值

根据示例代码的设置,以上部分除了 allowtype和 allowsize 均可以不用改变设置。

上传中的效果如下图:

 

JavaScript包程序

本包程序实现了前面设置的界面元素方法、事件、属性的实现及对文件上传的客户端控制,示例代码如下:

 //批量上传文件的内置默认辅助方法,表示每上传一个文件之前发生的事件,
         //事件的fileObj参数代表 file对象(上传控件),由主方法自动传入,开发者可以重新指定自定义方法
         function ajax_uploadFiles_beginUpload(fileObj) {
            var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
            if (fIndex == 0) {
                document.getElementById('ajax_uploadFiles_serverProcessTip').innerHTML = '';
                document.getElementById("ajax_uploadFiles_upprogress").innerHTML = "";
                document.getElementById("ajax_uploadFiles_cprogress").innerHTML = "";
                document.getElementById("ajax_uploadFiles_totalprogress").style.width = "0px";
                document.getElementById(fileObj.getAttribute("serverfilelistid")).value = "";
            }
            document.getElementById("ajax_uploadFiles_curfilename").innerHTML = fileObj.files[fIndex].name;
        }
        //批量上传文件的内置默认辅助方法,表示当前正在上传文件时发生的事件(主要用于显示上传进度),
        //事件的fileObj参数代表 file对象(上传控件), loaded:已经上传的文件总字节, total:正在上传的文件总字数,
        // percent:不超过100的整数,表示为百分比。这些参数由主方法自动传入,开发者可以重新指定自定义方法
        function ajax_uploadFiles_progressUpload(fileObj, loaded, total, percent) {
            document.getElementById("ajax_uploadFiles_upprogress").innerHTML = ("" + percent + "%");
            var curb = parseInt(document.getElementById("ajax_uploadFiles_curbg").style.width, 10);
            document.getElementById("ajax_uploadFiles_curprogress").style.width = Math.floor(curb * loaded / total) + "px";
        }
        //批量上传文件的内置默认辅助方法,表示当前文件上传完成时发生的事件(主要用于处理文件上传后的跟踪处理,并且返回服务器上保存的文件列到一个文本框中,以|分隔),
        //事件的fileObj参数代表 file对象(上传控件), type:上传状态返回,包括success成功,error失败, 
        //data:文件的数据,暂时未使用, desfile:要保存在服务器上的文件名
        // 这些参数由主方法自动传入,开发者可以重新指定自定义方法
        function ajax_uploadFiles_endUpload(fileObj, type, data, desfile) {
            var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
            var filecount = fileObj.files.length;
            document.getElementById(fileObj.getAttribute("serverfilelistid")).value += desfile + "|";
            var totalb = parseInt(document.getElementById("ajax_uploadFiles_totalbg").style.width, 10);
            document.getElementById("ajax_uploadFiles_totalprogress").style.width = Math.floor(totalb * (fIndex + 1) / filecount) + "px";
            document.getElementById("ajax_uploadFiles_cprogress").innerHTML = ("" + Math.floor(100 * (fIndex + 1) / filecount) + "%");
            if (fIndex < filecount - 1) {
                fIndex++;
                fileObj.setAttribute("fileindex", fIndex);
                ajax_uploadFiles(fileObj);
                return;
            }
            fileObj.setAttribute("fileindex", 0);

            if (type == "success") {
                            document.getElementById('ajaxMfile').style.display='none';
                document.getElementById('ajax_uploadFiles_serverProcessTip').innerHTML = '上传完成!正在进行后台处理...';
                document.getElementById(fileObj.getAttribute("serverbuttonid")).click();
            } else if (type == "error") {
                alert("error");
            }
        }
        //生成一个guid
        function newguid() {
            function S4() {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            }
            return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
        }
        //批量上传文件的主方法,fileObj参数代表 file对象(上传控件)
        function ajax_uploadFiles(fileObj) {
            var formData = new FormData();
            var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
            var filecount = fileObj.files.length;
            if (filecount == 0) {
                alert('请先浏览选择文件...');
                return;
            }
            var uploadSessionId = newguid();
            var upfile = fileObj.files[fIndex].name;
            var dotpos = upfile.lastIndexOf('.');
            var desfile = "";
            var exname = "";
            if (dotpos > 0) {
                exname = upfile.substring(dotpos + 1, upfile.length);
                desfile = uploadSessionId + upfile.substring(0, dotpos) + '.' + exname;
            } else {
                desfile = uploadSessionId + upfile;
            }
            //        alert(Math.round(upsize / 1024));
            if (fIndex == 0) {
                var allowtype = fileObj.getAttribute("allowtype");
                var allowsize = fileObj.getAttribute("allowsize");
                var at = allowtype.split('|');
                var as = allowsize.split('|');
                for (var j = 0; j < filecount; j++) {
                    var validfile = fileObj.files[j].name;
                    var upsize = fileObj.files[j].size;
                    var validdotpos = validfile.lastIndexOf('.');
                    var validexname = "";
                    if (validdotpos > 0) {
                        validexname = validfile.substring(validdotpos + 1, validfile.length);
                    }
                    var i = 0;
                    if (allowtype != "") {
                        var find = false;
                        for (i = 0; i < at.length; i++) {
                            if (at[i].toLowerCase() == validexname.toLowerCase()) {
                                find = true;
                                break;
                            }
                        }
                        if (find == false) {
                            alert("文件" + validfile + "上传的类型不符合要求!仅允许上传扩展名为:" + allowtype.split("|").join("、") + "的文件。");
                            fileObj.style.display = '';
                            document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
                            var t = fileObj;
                            t.outerHTML = t.outerHTML;
                            return;
                        }
                    }
                    if (allowsize != "") {
                        if (at.length <= as.length) {
                        } else {
                            i = 0;
                        }
                        as[i] = as[i].toLowerCase();
                        var csize = parseInt(as[i]);
                        var tsize = upsize;
                        if (as[i].lastIndexOf('k') != -1) {
                            csize = csize * 1024;
                            tsize = Math.round(upsize / 1024) + "KB";
                        } else if (as[i].lastIndexOf('m') != -1) {
                            csize = csize * 1024 * 1024;
                            tsize = Math.round(upsize / 1024 / 1024) + "MB";
                        } else if (as[i].lastIndexOf('g') != -1) {
                            csize = csize * 1024 * 1024 * 1024;
                            tsize = Math.round(upsize / 1024 / 1024 / 1024) + "GB";
                        } else if (as[i].lastIndexOf('t') != -1) {
                            csize = csize * 1024 * 1024 * 1024 * 1024;
                            tsize = Math.round(upsize / 1024 / 1024 / 1024 / 1024) + "TB";
                        }
                        if (upsize > csize) {
                            alert("上传文件" + validfile + "的大小近" + tsize + ",系统规定大小不能超过" + as[i].toUpperCase() + ",请重新选择。");
                            fileObj.style.display = '';
                            document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
                            var t = fileObj;
                            t.outerHTML = t.outerHTML;
                            return;

                        }
                    }
                } //j
            } // findex
            //        document.getElementById(callObjId).disabled = 'disabled';

            //        if (beginFuncName != null) {
            //            beginFuncName(fIndex, filecount,upfile);
            //        }
            fileObj.style.display = 'none';
            document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = '';
            var findfunc = fileObj.getAttribute("onbeginupload");
            if (eval(findfunc)) {
                var execfunc = eval(findfunc);
                //            alert(findfunc);
                execfunc(fileObj);
            }

            formData.append("file", fileObj.files[fIndex]); //append()里面的第一个参数file对应permission/upload里面的参数file
            var processUploadUrl = window.location.protocol + "//" + window.location.host + "//common//uploadfile.ashx?guid=" + uploadSessionId;
            $.ajax({
                type: "post",
                async: true,  //这里要设置异步上传,才能成功调用myXhr.upload.addEventListener('progress',function(e){}),progress的回掉函数
                Accept: 'text/html;charset=UTF-8',
                data: formData,
                contentType: "multipart/form-data",
                url: processUploadUrl,
                processData: false, // 告诉jQuery不要去处理发送的数据
                contentType: false, // 告诉jQuery不要去设置Content-Type请求头
                xhr: function () {
                    myXhr = $.ajaxSettings.xhr();
                    if (myXhr.upload) { // check if upload property exists
                        myXhr.upload.addEventListener('progress', function (e) {
                            var loaded = e.loaded;                  //已经上传大小情况 
                            var total = e.total;                      //附件总大小 
                            var percent = Math.floor(100 * loaded / total);     //已经上传的百分比  
                            //                        if (progressFuncName != null) {
                            //                            progressFuncName(loaded, total, percent);
                            //                        }
                            var findfunc = fileObj.getAttribute("onprogressupload");
                            if (eval(findfunc)) {
                                var execfunc = eval(findfunc);
                                //            alert(findfunc);
                                execfunc(fileObj, loaded, total, percent);
                            }
                            //                            $("#processBar").css("width", percent);
                        }, false); // for handling the progress of the upload
                    }
                    return myXhr;
                },
                success: function (data) {
                    if (fIndex == fileObj.files.length - 1) {
                        fileObj.style.display = '';
                        document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
                        var t = fileObj;
                        t.outerHTML = t.outerHTML;
                    }
                    //                if (endFuncName != null) {
                    //                    endFuncName("success", data, desfile, fIndex,filecount);
                    //                }
                    var findfunc = fileObj.getAttribute("onendupload");
                    if (eval(findfunc)) {
                        var execfunc = eval(findfunc);
                        //            alert(findfunc);
                        execfunc(fileObj, "success", data, desfile);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert(errorThrown);
                    if (endFuncName != null) {
                        endFuncName(fileObj, "error", null, '');
                    }
                }
            });
        } 

服务端 ashx 程序

ashx,一般处理程序(HttpHandler)是·NET众多web组件的一种。一个 httpHandler 接受并处理一个http请求,类似 Java 中的 servlet 。

本程序实现服务器端上传文件的接收和另存操作,在这里我们存为uploadfile.ashx,代码如下:

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.IO;

public class Handler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        if (context.Request.Files.Count > 0)
        {
            //HttpContext.Current.Request.FilePath;
            string strPath = System.Web.HttpContext.Current.Server.MapPath("~/app_data/ajaxUploadFiles/");
            string strName = context.Request.Files[0].FileName;
            string ext=Path.GetExtension(strName);
            string filename =HttpContext.Current.Request.QueryString["guid"].ToString()+Path.GetFileNameWithoutExtension(strName);
            if(ext!=""){
                filename = filename  + ext;
            }
            context.Request.Files[0].SaveAs(System.IO.Path.Combine(strPath, filename));
        }
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

服务端上传后处理程序

在多个文件上传到服务器后,我们需要对文件进行后期处理,在前端我们设置了ID为 “ajaxEndBtn”的服务器按钮,进行模拟调用其 click 事件。

服务器端按钮处理事件示例代码如下:

   void ajaxEndBtn_Click(object sender, EventArgs e)
    {
        //得到保存后的文件名列表
        string[] upfiles = ajaxReturnFileName.Text.Split('|');
        //给予用户基本的提示
        ajax_uploadFiles_serverProcessTip.Text = "本次上传分析:共计上传" + (upfiles.Length - 1).ToString() + "个文件。";
        //遍历上传文件列表,进行后期处理
        foreach (string filename in upfiles)
        {
            if (filename.Trim() == "") continue;
            string upfilename = Request.PhysicalApplicationPath + "app_data\\ajaxUploadFiles\\" + filename;
            string exname = System.IO.Path.GetExtension(upfilename);

            //执行业务处理程序


        }

 

小结

以上提供的代码仅供参考,默认的设置仅可能提供最基础的实现,比如 ashx 程序还需要进行安全控制;进度图片和UI可以重新设计;实际的业务可以根据需求对控件的属性、事件进行重写。

以上就是自己的一些分享,时间仓促,不妥之处还请大家批评指正!

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

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

相关文章

风险评估是什么,为什么被称为保护网络安全的重要一环!

随着互联网的普及和信息技术的快速发展&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;网络在为我们带来便利的同时&#xff0c;也存在着各种安全风险。因此&#xff0c;进行网络风险评估是保护网络安全的重要一环。而为什么说风险评估是保护网络…

2.2 C语言之常量

2.2 C语言之常量 一、常量 一、常量 类似于1234的整数常量属于int类型。 printf("%d\n", 1234);long类型的常量以l或L结尾 printf("%d\n", 123456789l);printf("%d\n", 123456789L);如果一个整数太大&#xff0c;以至于无法用int类型表示时&…

LINUX-ROS集成安装MQTT库步骤注意事项

环境信息 roottitan-ubuntu1:/home/mogo/data/jp/paho.mqtt.cpp# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS Release: 18.04 Codename: bionic 步骤 安装doxygen sudo apt install doxygen 构…

Tomcat从认识安装到详细使用

文章目录 一.什么是Tomact?二.Tomcat的安装1.下载安装包2.一键下载3.打开Tomcat进行测试4.解决Tomcat中文服务器乱码 三.Tomcat基本使用1.启动与关闭Tomcat2.Tomcat部署项目与浏览器访问项目 四.Tomcat操作中的常见问题1.启动Tomcat后&#xff0c;启动窗口一闪而过&#xff1f…

Day15——File类与IO流

1.java.io.File类的使用 1.1 File类的理解 File 类及本章下的各种流&#xff0c;都定义在 java.io 包下。一个 File 对象代表硬盘或网络中可能存在的一个文件或者文件目录&#xff08;俗称文件夹&#xff09;&#xff0c;与平台无关。&#xff08;体会万事万物皆对象&#xf…

金山终端安全系统V9.0 update_software_info_v2.php处SQL注入漏洞分析

文章目录 金山终端安全系统V9.0 update_software_info_v2.php处SQL注入漏洞分析前言一、漏洞描述二、影响版本三、POC四、漏洞原理分析参考链接&#xff1a; 金山终端安全系统V9.0 update_software_info_v2.php处SQL注入漏洞分析 前言 免责声明&#xff1a;请勿利用文章内的相…

idea 本身快捷键ctrl+d复制 无法像eclipse快捷键ctrl+alt+上下键,自动换行格式问题解决

问题 例如我使用ctrld 想复制如下内容 复制效果如下&#xff0c;没有自动换行&#xff0c;还需要自己在进行调整 解决 让如下快捷键第一个删除 修改成如下&#xff0c;将第二个添加ctrld 提示&#xff1a;对应想要修改的item&#xff0c;直接右键&#xff0c;remove是删…

Nginx反向代理跳过国内备案(以宝塔面板为例)

需要两台服务器&#xff0c;一台已备案或者免备案&#xff0c;一台国内主力服务器放你的项目。 先把域名解析到A服务器 然后在A服务器里配置 server {listen 80;server_name 你的域名;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_…

(3)kylin系统部署weblogic项目

一、jdk迁移 1、拷贝成功后要配置环境变量 vi /etc/profile 将jdk的目录添加进去 2、将jdk安装目录拷贝后权限会发生变化&#xff0c; 要对jdk下bin目录中的所有文件修改权限&#xff1a; chmod x ./* 回车即可 ----------------------------- 环境变量 export …

ES6原生音乐播放器(有接口)

视频展示 ES6音乐播放器 项目介绍 GutHub地址&#xff1a;GitHub - baozixiangqianchong/ES6_MusicPlayer: 音乐播放器 ES6_MusicPlayer 是基于JavaScriptES6Ajax等通过原生构建的项目。能够充分锻炼JS能力。 本项目有主页、详情页、歌单页面三部分组成 ├── assets&…

多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现RIME-…

编程学新要求:OS发布之前,都应该在各种虚拟机上测试

这几天在VirtualBox上安装ArchLinux&#xff0c;掌握了方法之后&#xff0c;非常顺利。进入桌面之后&#xff0c;又出问题了&#xff0c;如下图&#xff1a; 底部的那个工具条&#xff0c;空空如也。原因是显示错误。这怎么用&#xff1f; 所以编程学干脆提出一个新要求&#x…

leetcode 股票DP系列 总结篇

121. 买卖股票的最佳时机 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。 只能进行一次交易 很简单&#xff0c;只需边遍历边记录最小值即可。 class Solution { public:int maxProfit(vector<int>& prices) {int res …

【JavaWeb笔记】单选框,结合Servlet

各个部分的作用 jsp部分 form action"..."&#xff1a;表单标签&#xff0c;供用户提交数据。内部的submit点击之后相当于是点action的URL input type"radio"&#xff1a;输入类型为单选框。把name设置为一样的&#xff0c;这样效果上就是单选&#xff…

C++ 对象数组

对象数组用于创建同一个类的多个对象。声明对象数组的方法与声明标准类陷阱数组相同。以Stock类为例&#xff1a; class Stock { private:std::string company;int shares;double share_val;double total_val;void set_tot(){return total_val shares * share_val;} public:S…

基于Java SSM框架实现电影售票系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现电影售票系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#…

SU渲染受到电脑性能影响大吗?如何提高渲染速度

一般3d设计师们在进行设计工作前都需要提供一台高配电脑&#xff0c;那么你这知道su渲染对电脑要求高吗&#xff1f;电脑带不动su怎么解决&#xff1f;su对电脑什么配件要求高&#xff1f;今天这篇文章就详细为大家带来电脑硬件对su建模渲染的影响&#xff0c;以及su渲染慢怎么…

Flask应用基础入门总结

【1】使用migrate方式进行数据库连接 使用migrate方式进行数据库连接需要在终端分别运行三行代码&#xff1a; #init&#xff08;运行一次即可&#xff09;&#xff08;此db为自己设置的连接数据库的对象,可以修改&#xff09; flask db init #&#xff08;将orm模型生成迁移…

qt creator配置opencv库 (MSVC版本)

目录 1. MSVC版本 1.1 使用cmake编译opencv 1.2 再使用visual studio 2019生成opencv的lib,dll 1.3 配置opencv的系统环境变量 1.4 新建qt项目 1. MSVC版本 1.1 使用cmake编译opencv 1.2 再使用visual studio 2019生成opencv的lib,dll 1.3 配置opencv的系统环境变量 D:…