在 ASP.NET Core 6.0 Web API 中将 Excel 文件数据上传并保存到数据库中

本文示例代码: https://download.csdn.net/download/hefeng_aspnet/90174856

本文将探讨使用 ASP.NET Core Web API 上传 Excel 文件并将其数据保存到数据库的分步过程。我们将利用NPOI库和 Entity Framework Core 来实现此功能。

安装所需的库

首先,我们必须从 NuGet 包管理器安装 NPOI 库:

接下来,我们还将安装 Entity Framework Core。我们将使用 Entity Framework Core Sqlite 来简化该过程。我们还可以使用其他提供程序,例如 SqlServer 或 PostgreSQL。

如果您使用的是 .NET 6.0,请确保选择 Entity Framework 的 6.xx (6.0.20) 版本。

创建实体模型

我们将使用实体模型来表示我们想要存储在数据库中的数据结构。

namespace UploadExcel.WebApi;

public class Product

{

public Guid Id { get; set; }

public string Name { get; set; }

public int Quantity { get; set; }

public decimal Price { get; set; }

public bool IsActive { get; set; }

public DateTime ExpiryDate { get; set; }

}

Product类具有最常用的数据类型的属性(string,int,decimal,bool,DateTime)。

创建数据上下文

另外,我们创建一个继承自 Entity Framework Core 的 DbContext 类的数据库上下文。此上下文将处理与数据库的通信。

using Microsoft.EntityFrameworkCore;

namespace UploadExcel.WebApi;

public class DataContext : DbContext

{

public DataContext(DbContextOptions<DataContext> opt) : base(opt)

{

}

public DbSet<Product> Products { get; set; }

}

创建请求模型

接下来,我们创建一个表示 Excel 文件数据结构的请求模型。此类共享 Product 类的所有属性,但 Id 属性除外,该属性将自动生成。

namespace UploadExcel.WebApi;

public class ProductRequest

{

public string Name { get; set; }

public int Quantity { get; set; }

public decimal Price { get; set; }

public bool IsActive { get; set; }

public DateTime ExpiryDate { get; set; }

}

ExcelHelper 类

ExcelHelper类是一个自定义类,它提供了一个辅助方法来从 Excel 文件读取数据并将其转换为对象列表。

using NPOI.SS.UserModel;

using NPOI.XSSF.UserModel;

namespace UploadExcel.WebApi;

public static class ExcelHelper

{

public static List<T> Import<T>(string filePath) where T : new()

{

XSSFWorkbook workbook;

using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))

{

workbook = new XSSFWorkbook(stream);

}

var sheet = workbook.GetSheetAt(0);

var rowHeader = sheet.GetRow(0);

var colIndexList = new Dictionary<string, int>();

foreach (var cell in rowHeader.Cells)

{

var colName = cell.StringCellValue;

colIndexList.Add(colName, cell.ColumnIndex);

}

var listResult = new List<T>();

var currentRow = 1;

while (currentRow <= sheet.LastRowNum)

{

var row = sheet.GetRow(currentRow);

if (row == null) break;

var obj = new T();

foreach (var property in typeof(T).GetProperties())

{

if (!colIndexList.ContainsKey(property.Name))

throw new Exception($"Column {property.Name} not found.");

var colIndex = colIndexList[property.Name];

var cell = row.GetCell(colIndex);

if (cell == null)

{

property.SetValue(obj, null);

}

else if (property.PropertyType == typeof(string))

{

cell.SetCellType(CellType.String);

property.SetValue(obj, cell.StringCellValue);

}

else if (property.PropertyType == typeof(int))

{

cell.SetCellType(CellType.Numeric);

property.SetValue(obj, Convert.ToInt32(cell.NumericCellValue));

}

else if (property.PropertyType == typeof(decimal))

{

cell.SetCellType(CellType.Numeric);

property.SetValue(obj, Convert.ToDecimal(cell.NumericCellValue));

}

else if (property.PropertyType == typeof(DateTime))

{

property.SetValue(obj, cell.DateCellValue);

}

else if (property.PropertyType == typeof(bool))

{

cell.SetCellType(CellType.Boolean);

property.SetValue(obj, cell.BooleanCellValue);

}

else

{

property.SetValue(obj, Convert.ChangeType(cell.StringCellValue, property.PropertyType));

}

}

listResult.Add(obj);

currentRow++;

}

return listResult;

}

}

创建 ProductController

接下来,我们必须创建ProductController类。

ProductController类有两个注入参数,一个是DataContext实例,另一个是IWebHostEnvironment实例。DataContext负责与数据库通信,而IWebHostEnvironment保存与 Web 主机环境相关的信息。

ProductController类有一个操作方法Upload(),该方法接受包含产品请求数据的文件。该文件保存到uploads文件夹,然后使用该方法加载 Excel 表中的数据ExcelHelper.Import<ProductRequest>(filePath)。然后使用实体框架将数据保存到数据库。

using Microsoft.AspNetCore.Mvc;

namespace UploadExcel.WebApi.Controllers;

ApiController

Route("products")

public class ProductController : ControllerBase

{

private readonly DataContext _context;

private readonly IWebHostEnvironment _webHostEnvironment;

public ProductController(DataContext context, IWebHostEnvironment webHostEnvironment)

{

_context = context;

_webHostEnvironment = webHostEnvironment;

}

HttpPost("upload")

DisableRequestSizeLimit

public async Task<ActionResult> Upload(CancellationToken ct)

{

if (Request.Form.Files.Count == 0) return NoContent();

var file = Request.Form.Files[0];

var filePath = SaveFile(file);

// load product requests from excel file

var productRequests = ExcelHelper.Import<ProductRequest>(filePath);

// save product requests to database

foreach (var productRequest in productRequests)

{

var product = new Product

{

Id = Guid.NewGuid(),

Name = productRequest.Name,

Quantity = productRequest.Quantity,

Price = productRequest.Price,

IsActive = productRequest.IsActive,

ExpiryDate = productRequest.ExpiryDate

};

await _context.AddAsync(product, ct);

}

await _context.SaveChangesAsync(ct);

return Ok();

}

// save the uploaded file into wwwroot/uploads folder

private string SaveFile(IFormFile file)

{

if (file.Length == 0)

{

throw new BadHttpRequestException("File is empty.");

}

var extension = Path.GetExtension(file.FileName);

var webRootPath = _webHostEnvironment.WebRootPath;

if (string.IsNullOrWhiteSpace(webRootPath))

{

webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");

}

var folderPath = Path.Combine(webRootPath, "uploads");

if (!Directory.Exists(folderPath))

{

Directory.CreateDirectory(folderPath);

}

var fileName = $"{Guid.NewGuid()}.{extension}";

var filePath = Path.Combine(folderPath, fileName);

using var stream = new FileStream(filePath, FileMode.Create);

file.CopyTo(stream);

return filePath;

}

}

Program.cs

修改Program.cs以注册DataContext类并初始化数据库:

using Microsoft.EntityFrameworkCore;

using UploadExcel.WebApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<DataContext>(opt => opt.UseSqlite("Data Source=data.db"));

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())

{

app.UseSwagger();

app.UseSwaggerUI();

}

var context = app.Services.CreateScope().ServiceProvider.GetRequiredService<DataContext>();

context.Database.EnsureCreated();

app.UseHttpsRedirection();

app.MapControllers();
app.Run();
准备 Excel 文件

Excel 文件的第一行是我们要上传的产品数据的"列"。Excel 文件数据将如下所示:

使用 Postman 进行测试

我们使用Postman进行测试。为此,请按照以下步骤操作:

1、将 HTTP 方法设置为POST

2、将 URL 设置为https://localhost:PORT/products/upload

3、将请求主体类型设置为form-data

4、将Key列设置为File

5、在值列上选择 Excel 文件

从 Web 应用程序中使用 Axios

以下是如何使用 Axios 库从 React JS Web 应用程序上传文件的示例代码:

const [excelFile, setExcelFile] = React.useState(null);

const requestHeaders = {

headers: {

'Content-Type': 'multipart/form-data'

}

};

const handleUpload = async () => {

const formData = new FormData();

formData.append('file', excelFile);

await axios.post('/products/upload', formData, requestHeaders);

};

return (

<input type="file" onChange={(e) => setExcelFile(e.target.files[0])} />

<button onclick={handleUpload}>Upload</button>

);

本文示例代码: https://download.csdn.net/download/hefeng_aspnet/90174856

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
黄色茶杯20 小时前
AI编程工具TRAE解决日常问题之SQLite数据复制
数据库·sqlite
老华带你飞20 小时前
订票系统|车票管理系统|基于Java+vue的车票管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·订票系统
weixin_wx520-198320 小时前
骑士人才网全系与phpyun人才网系统数据转移或互转的技术文档和要领,和大家一起共勉
数据库·骑士人才网开源版·骑士人才网数据转移·phpyun人才网源码
聆风吟º20 小时前
国产化数据库选型深度剖析:金仓KES与达梦DM全生命周期成本对比
数据库·kingbasees
码农阿豪20 小时前
金仓KES vs. 达梦DM:全面对比解析迁移、运维与授权成本
运维·数据库·国产
qqxhb21 小时前
系统架构设计师备考第67天——数据库系统的安全&系统架构的脆弱性
数据库·安全·系统架构·访问控制·完整性·脆弱性·身份鉴别
百锦再21 小时前
金仓数据库提出“三低一平”的迁移理念
开发语言·数据库·后端·python·rust·eclipse·pygame
-Xie-1 天前
Redis(二)——数据类型二
数据库·redis·缓存
帅次1 天前
系统分析师-案例分析-数据库系统&数据仓库&反规范化技术&NoSQL&内存数据库
大数据·数据库·数据仓库·oracle·kafka·数据库开发·数据库架构
007php0071 天前
某游戏大厂的常用面试问题解析:Netty 与 NIO
java·数据库·游戏·面试·职场和发展·性能优化·nio