ASP.NET Core MVC上传、导入、导出知多少
前言
本君已成夜猫子,本节我们来讲讲ASP.NET Core MVC中的上传,这两天在研究批量导入功能,本节顺便简单搞搞导入、导出,等博主弄妥当了再来和大家一并分享。
.NET Core MVC上传
首先我们来看看官网的上传的例子,再然后进行拓展训练,官网的表单是这样的。
<form method="post" enctype="multipart/form-data" asp-controller="UploadFiles" asp-action="Index"> <p class="form-group"> <p class="col-md-10"> <p>Upload one or more files using this form:</p> <input type="file" name="files" multiple /> </p> </p> <p class="form-group"> <p class="col-md-10"> <input type="submit" value="上传" /> </p> </p> </form>
在ASP.NET Core MVC中接收上传的文件需要用 IFormFile 来接收,该接口定义如下:
public interface IFormFile { string ContentType { get; } string ContentDisposition { get; } IHeaderDictionary Headers { get; } long Length { get; } string Name { get; } string FileName { get; } Stream OpenReadStream(); void CopyTo(Stream target); Task CopyToAsync(Stream target, CancellationToken cancellationToken = null); }
后台控制器关于上传的Action方法进行如下定义:
[HttpPost("UploadFiles")] public async Task<IActionResult> Post(List<IFormFile> files) { long size = files.Sum(f => f.Length); // full path to file in temp location var filePath = Path.GetTempFileName(); foreach (var formFile in files) { if (formFile.Length > 0) { using (var stream = new FileStream(filePath, FileMode.Create)) { await formFile.CopyToAsync(stream); } } } return Ok(new { count = files.Count, size, filePath }); }
为了很清楚地上传文件所在目录,我们将官网例子进行一下改造。
public IActionResult UploadFiles(List<IFormFile> files) { long size = 0; foreach (var file in files) { //var fileName = file.FileName; var fileName = ContentDispositionHeaderValue .Parse(file.ContentDisposition) .FileName .Trim('"'); fileName = hostingEnv.WebRootPath + $@"\{fileName}"; size += file.Length; using (FileStream fs = System.IO.File.Create(fileName)) { file.CopyTo(fs); fs.Flush(); } } ViewBag.Message = $"{files.Count}个文件 /{size}字节上传成功!"; return View(); }
如上通过注入 private IHostingEnvironment hostingEnv; 来获取网站根目录路径。在前台表单中请求action方法用渲染的方式,如下:
<form method="post" enctype="multipart/form-data" asp-controller="Upload" asp-action="UploadFiles"> </form>
当然别忘记添加TagHelper:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
成功上传我们显示上传字节大小,如下:
上传的文件在网站根目录下我们能够看到,如下:
上述我们只是牛刀小试通过表单提交,接下来我们进行拓展通过Ajax来提交。我们将表单类型submit修改为button,如下:
<p class="row"> <p class="form-group"> <p class="col-md-10"> <p>使用表单上传多个文件</p> <input type="file" id="files" name="files" multiple /> @ViewBag.Message </p> </p> </p> <p class="row"> <p class="form-group"> <p class="col-md-10"> <input type="button" id="upload" class="btn btn-success" style="cursor:pointer;width:100px;" value="上传" /> </p> </p> </p>
我们通过FormData对象来获取文件从而进行Ajax提交,如下:
$(function () { $("#upload").click(function (evt) { var fileUpload = $("#files").get(0); var files = fileUpload.files; var data = new FormData(); for (var i = 0; i < files.length ; i++) { data.append(files[i].name, files[i]); } $.ajax({ type: "POST", url: "/Upload/UploadFiles", contentType: false, processData: false, data: data, success: function (message) { alert(message); }, error: function () { alert("上传文件出现错误!"); } }); }); });
此时后台则需要进行略微修改,我们不再需要IFormFile接口来获取文件,通过请求中的表单获取,如下:
public IActionResult UploadFiles() { long size = 0; var files = Request.Form.Files; foreach (var file in files) { //var fileName = file.FileName; var fileName = ContentDispositionHeaderValue .Parse(file.ContentDisposition) .FileName .Trim('"'); fileName = hostingEnv.WebRootPath + $@"\{fileName}"; size += file.Length; using (FileStream fs = System.IO.File.Create(fileName)) { file.CopyTo(fs); fs.Flush(); } } ViewBag.Message = $"{files.Count}个文件 /{size}字节上传成功!"; return View(); }
到这里关于ASP.NET Core MVC中的上传就告一段落,还是比较简单但是算是比较常见的需求。
导入、导出Excel
项目中需要用到批量导入和导出于是进行了一点研究,.net core刚出世时还未有对于.net core中Excel的导出,但是见过园中有热心园友分享并制作了.net core中导出Excel,但是博主发现在2月19号有老外已针对.net core的Excel导出和导入目前版本为1.3基于EPPlus,功能和EPPlus差不多,不过是移植到了.net core中,下面我们一起来看看。首先我们下载EPPlus.Core程序包,如下:
我们直接上导出代码:
[HttpGet] [Route("Export")] public string Export() { string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = @"Jeffcky.xlsx"; string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, sFileName); FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); if (file.Exists) { file.Delete(); file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); } using (ExcelPackage package = new ExcelPackage(file)) { // add a new worksheet ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Jeffcky"); //sheet header worksheet.Cells[1, 1].Value = "ID"; worksheet.Cells[1, 2].Value = "Name"; worksheet.Cells[1, 3].Value = "Age"; //Add values worksheet.Cells["A2"].Value = 1000; worksheet.Cells["B2"].Value = "Jeffcky1"; worksheet.Cells["C2"].Value = 18; worksheet.Cells["A3"].Value = 1001; worksheet.Cells["B3"].Value = "Jeffcky2"; worksheet.Cells["C3"].Value = 19; package.Save(); //Save the workbook. } return URL; }
这里我们进行统一封装下来进行导出只需要设置导出属性和列表数据即可,如下:
public IActionResult Export() { var properties = new PropertyByName<Person>[] { new PropertyByName<Person>("Id",d=>d.Id), new PropertyByName<Person>("Name",d=>d.Name), new PropertyByName<Person>("Age",d=>d.Age) }; var list = new List<Person>() { new Person() {Id=1,Name="Jeffcky1",Age=18 }, new Person() {Id=2,Name="Jeffcky2",Age=19 }, new Person() {Id=3,Name="Jeffcky3",Age=20 }, new Person() {Id=4,Name="Jeffcky4",Age=21 }, new Person() {Id=5,Name="Jeffcky5",Age=22 } }; var bytes = _ExportManager.ExportToXlsx<Person>(properties, list); return new FileContentResult(bytes, MimeTypes.TextXlsx); }
说完导出我们再来看导入,我们来读取刚刚导入的数据返回到页面上:
public string Import() { string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = @"Jeffcky.xlsx"; FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); try { using (ExcelPackage package = new ExcelPackage(file)) { StringBuilder sb = new StringBuilder(); ExcelWorksheet worksheet = package.Workbook.Worksheets[1]; int rowCount = worksheet.Dimension.Rows; int ColCount = worksheet.Dimension.Columns; bool bHeaderRow = true; for (int row = 1; row <= rowCount; row++) { for (int col = 1; col <= ColCount; col++) { if (bHeaderRow) { sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t"); } else { sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t"); } } sb.Append(Environment.NewLine); } return sb.ToString(); } } catch (Exception ex) { return "Some error occured while importing." + ex.Message; } }
此时我们再来对导入进行统一封装下,如下:
[HttpGet] [Route("Import")] public void Import() { string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = @"Jeffcky.xlsx"; FileStream fs = new FileStream(Path.Combine(sWebRootFolder, sFileName), FileMode.Open, FileAccess.Read, FileShare.Read); var list = _ImportManager.ImportPersonFromXlsx(fs); }
导入大概就介绍完毕了,要我说真正的难点不在于利用EPPlus导入和导出,难点在于批量导入,批量进行导入后对数据格式的检验,如果给定一个导入模板,然后再导入批量数据怎么确保用户给的数据格式完全是正确的以及数据没有重复的校验,这两天基本上是完成了批量的导入,大概分为:数据必填项的校验、数据格式的校验、数据库是否存在数据的校验、数据导入部分导入失败返回格式的用户体验。当利用NPOI、EPPlus来导入和导出这样的功能再简单不过了,但是如果遇到了不同的场景怎么让用户体验更好的使用这是一个问题,如果数据导入失败我们怎么去提示用户呢,还有如果Excel中有下拉框和合并的单元格数据我们怎么去获取这又是一个问题,可能很多简历上写着会利用NPOI和EPPlus的导入和导出,其实没什么看头,二者不过是一个工具罢了,如何利用工具去应用到复杂的场景并举例那才算是高级的东西。
总结
本节我们稍微介绍了.net core中的下载、导入和导出,如果有可能的话后续会给出关于EPPlus中高级的知识,比如如上提出的获取合并列数据还有获取图片等等,我们下节再会,哦,关于SQL Server有时间会定期进行更新,see u。
Atas ialah kandungan terperinci ASP.NET Core MVC上传、导入、导出知多少. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Kaedah penggunaan simbol dalam bahasa C meliputi aritmetik, tugasan, syarat, logik, pengendali bit, dan lain-lain. Operator aritmetik digunakan untuk operasi matematik asas, pengendali tugasan digunakan untuk penugasan dan penambahan, penolakan, pendaraban dan tugasan pembahagian, pengendali keadaan digunakan untuk operasi yang digunakan untuk operasi yang digunakan untuk Operasi Bit untuk Penunjuk null, penanda akhir fail, dan nilai bukan angka.

Perbezaan antara multithreading dan asynchronous adalah bahawa multithreading melaksanakan pelbagai benang pada masa yang sama, sementara secara tidak sengaja melakukan operasi tanpa menyekat benang semasa. Multithreading digunakan untuk tugas-tugas yang berintensifkan, sementara asynchronously digunakan untuk interaksi pengguna. Kelebihan multi-threading adalah untuk meningkatkan prestasi pengkomputeran, sementara kelebihan asynchronous adalah untuk tidak menghalang benang UI. Memilih multithreading atau asynchronous bergantung kepada sifat tugas: tugas-tugas intensif pengiraan menggunakan multithreading, tugas yang berinteraksi dengan sumber luaran dan perlu menyimpan respons UI menggunakan asynchronous.

Dalam C, jenis char digunakan dalam rentetan: 1. Simpan satu watak; 2. Gunakan array untuk mewakili rentetan dan berakhir dengan terminator null; 3. Beroperasi melalui fungsi operasi rentetan; 4. Baca atau output rentetan dari papan kekunci.

Arus char menyimpan urutan watak dalam bahasa C dan diisytiharkan sebagai array_name char [saiz]. Unsur akses diluluskan melalui pengendali subskrip, dan elemen berakhir dengan terminator null '\ 0', yang mewakili titik akhir rentetan. Bahasa C menyediakan pelbagai fungsi manipulasi rentetan, seperti strlen (), strcpy (), strcat () dan strcmp ().

Dalam bahasa C, watak -watak khas diproses melalui urutan melarikan diri, seperti: \ n mewakili rehat garis. \ t bermaksud watak tab. Gunakan urutan melarikan diri atau pemalar watak untuk mewakili watak khas, seperti char c = '\ n'. Perhatikan bahawa backslash perlu melarikan diri dua kali. Platform dan penyusun yang berbeza mungkin mempunyai urutan melarikan diri yang berbeza, sila rujuk dokumentasi.

Dalam bahasa C, penukaran jenis char boleh ditukar secara langsung kepada jenis lain dengan: Casting: Menggunakan aksara pemutus. Penukaran Jenis Automatik: Apabila satu jenis data dapat menampung jenis nilai lain, pengkompil secara automatik menukarkannya.

Dalam bahasa C, perbezaan utama antara char dan wchar_t adalah pengekodan aksara: char menggunakan ASCII atau memanjangkan ASCII, WCHAR_T menggunakan unicode; Char mengambil 1-2 bait, wchar_t mengambil 2-4 bait; Char sesuai untuk teks bahasa Inggeris, WCHAR_T sesuai untuk teks berbilang bahasa; CHAR disokong secara meluas, WCHAR_T bergantung kepada sama ada penyusun dan sistem operasi menyokong Unicode; Char adalah terhad dalam pelbagai watak, WCHAR_T mempunyai pelbagai watak yang lebih besar, dan fungsi khas digunakan untuk operasi aritmetik.

Tiada fungsi jumlah terbina dalam dalam bahasa C, jadi ia perlu ditulis sendiri. Jumlah boleh dicapai dengan melintasi unsur -unsur array dan terkumpul: Versi gelung: SUM dikira menggunakan panjang gelung dan panjang. Versi Pointer: Gunakan petunjuk untuk menunjuk kepada unsur-unsur array, dan penjumlahan yang cekap dicapai melalui penunjuk diri sendiri. Secara dinamik memperuntukkan versi Array: Perlawanan secara dinamik dan uruskan memori sendiri, memastikan memori yang diperuntukkan dibebaskan untuk mengelakkan kebocoran ingatan.
