c上传一个excle表格,获取表格的表头,将表头内容创建实体类,并将实体类创建数据库表

c# webapi实现前端的上传一个excle表格,获取表格的表头,将表头内容创建实体类,并将实体类创建数据库表,用户每次上传表,就删除数据库中的原始表,在进行上述流程,然后能对数据库数据进行分页查询

1.创建数据库上下文

复制代码
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }
}

2.模型类

复制代码
public class UploadModel
{
    public IFormFile File { get; set; }
    public string TableName { get; set; }
}

public class QueryModel
{
    public string TableName { get; set; }
    public int Page { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}

public class PagedResult
{
    public List<Dictionary<string, object>> Data { get; set; }
    public int Total { get; set; }
    public int Page { get; set; }
    public int PageSize { get; set; }
}

3.简化的excel上传控制器

复制代码
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using OfficeOpenXml;
using System.Data;

[ApiController]
[Route("api/excel")]
public class ExcelController : ControllerBase
{
    private readonly IConfiguration _configuration;
    
    public ExcelController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    
    // 1. 上传Excel并创建表
    [HttpPost("upload")]
    public async Task<IActionResult> UploadExcel([FromForm] UploadModel model)
    {
        if (model.File == null || model.File.Length == 0)
            return BadRequest("请选择文件");
            
        if (string.IsNullOrEmpty(model.TableName))
            return BadRequest("请输入表名");
            
        using var stream = model.File.OpenReadStream();
        using var package = new ExcelPackage(stream);
        var worksheet = package.Workbook.Worksheets[0];
        
        // 获取表头
        var headers = new List<string>();
        for (int col = 1; col <= worksheet.Dimension.Columns; col++)
        {
            var header = worksheet.Cells[1, col].Text?.Trim();
            if (!string.IsNullOrEmpty(header))
                headers.Add(header);
        }
        
        if (headers.Count == 0)
            return BadRequest("Excel中没有表头");
        
        // 分析数据类型(简单版本,只检查第一行数据)
        var columnTypes = new List<string>();
        for (int col = 1; col <= headers.Count; col++)
        {
            var cellValue = worksheet.Cells[2, col].Text;
            columnTypes.Add(GetColumnType(cellValue));
        }
        
        // 创建数据库表
        var connectionString = _configuration.GetConnectionString("DefaultConnection");
        using var connection = new SqlConnection(connectionString);
        await connection.OpenAsync();
        
        // 删除已存在的表
        var dropSql = $"IF OBJECT_ID('{model.TableName}', 'U') IS NOT NULL DROP TABLE [{model.TableName}]";
        using var dropCmd = new SqlCommand(dropSql, connection);
        await dropCmd.ExecuteNonQueryAsync();
        
        // 创建新表
        var columns = new List<string>();
        columns.Add("[Id] INT IDENTITY(1,1) PRIMARY KEY");
        for (int i = 0; i < headers.Count; i++)
        {
            columns.Add($"[{headers[i]}] {columnTypes[i]}");
        }
        
        var createSql = $"CREATE TABLE [{model.TableName}] ({string.Join(", ", columns)})";
        using var createCmd = new SqlCommand(createSql, connection);
        await createCmd.ExecuteNonQueryAsync();
        
        // 插入数据
        for (int row = 2; row <= worksheet.Dimension.Rows; row++)
        {
            var values = new List<string>();
            for (int col = 1; col <= headers.Count; col++)
            {
                var cellValue = worksheet.Cells[row, col].Text;
                var sqlValue = FormatSqlValue(cellValue, columnTypes[col - 1]);
                values.Add(sqlValue);
            }
            
            var insertSql = $"INSERT INTO [{model.TableName}] ({string.Join(", ", headers)}) VALUES ({string.Join(", ", values)})";
            using var insertCmd = new SqlCommand(insertSql, connection);
            await insertCmd.ExecuteNonQueryAsync();
        }
        
        return Ok(new { 
            Success = true, 
            TableName = model.TableName, 
            Rows = worksheet.Dimension.Rows - 1 
        });
    }
    
    // 2. 分页查询数据
    [HttpPost("query")]
    public async Task<IActionResult> QueryData([FromBody] QueryModel model)
    {
        var connectionString = _configuration.GetConnectionString("DefaultConnection");
        using var connection = new SqlConnection(connectionString);
        await connection.OpenAsync();
        
        // 获取总行数
        var countSql = $"SELECT COUNT(*) FROM [{model.TableName}]";
        using var countCmd = new SqlCommand(countSql, connection);
        var total = Convert.ToInt32(await countCmd.ExecuteScalarAsync());
        
        // 分页查询数据
        var offset = (model.Page - 1) * model.PageSize;
        var querySql = $@"
            SELECT * FROM [{model.TableName}]
            ORDER BY Id
            OFFSET {offset} ROWS
            FETCH NEXT {model.PageSize} ROWS ONLY";
            
        using var queryCmd = new SqlCommand(querySql, connection);
        using var reader = await queryCmd.ExecuteReaderAsync();
        
        var result = new List<Dictionary<string, object>>();
        
        while (await reader.ReadAsync())
        {
            var row = new Dictionary<string, object>();
            for (int i = 0; i < reader.FieldCount; i++)
            {
                row[reader.GetName(i)] = reader.IsDBNull(i) ? null : reader.GetValue(i);
            }
            result.Add(row);
        }
        
        return Ok(new PagedResult
        {
            Data = result,
            Total = total,
            Page = model.Page,
            PageSize = model.PageSize
        });
    }
    
    // 3. 获取所有表名
    [HttpGet("tables")]
    public async Task<IActionResult> GetTables()
    {
        var connectionString = _configuration.GetConnectionString("DefaultConnection");
        using var connection = new SqlConnection(connectionString);
        await connection.OpenAsync();
        
        var sql = @"
            SELECT TABLE_NAME 
            FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_TYPE = 'BASE TABLE' 
            AND TABLE_NAME NOT LIKE 'sys%'
            ORDER BY TABLE_NAME";
            
        using var cmd = new SqlCommand(sql, connection);
        using var reader = await cmd.ExecuteReaderAsync();
        
        var tables = new List<string>();
        while (await reader.ReadAsync())
        {
            tables.Add(reader.GetString(0));
        }
        
        return Ok(tables);
    }
    
    // 4. 删除表
    [HttpDelete("table/{tableName}")]
    public async Task<IActionResult> DeleteTable(string tableName)
    {
        var connectionString = _configuration.GetConnectionString("DefaultConnection");
        using var connection = new SqlConnection(connectionString);
        await connection.OpenAsync();
        
        var sql = $"IF OBJECT_ID('{tableName}', 'U') IS NOT NULL DROP TABLE [{tableName}]";
        using var cmd = new SqlCommand(sql, connection);
        await cmd.ExecuteNonQueryAsync();
        
        return Ok(new { Success = true, Message = $"表 {tableName} 已删除" });
    }
    
    // 辅助方法:确定列类型
    private string GetColumnType(string value)
    {
        if (string.IsNullOrEmpty(value))
            return "NVARCHAR(255)";
            
        if (int.TryParse(value, out _))
            return "INT";
            
        if (decimal.TryParse(value, out _))
            return "DECIMAL(18,2)";
            
        if (DateTime.TryParse(value, out _))
            return "DATETIME";
            
        return "NVARCHAR(255)";
    }
    
    // 辅助方法:格式化SQL值
    private string FormatSqlValue(string value, string columnType)
    {
        if (string.IsNullOrEmpty(value))
            return "NULL";
            
        if (columnType.StartsWith("NVARCHAR") || columnType.StartsWith("DATETIME"))
            return $"'{value.Replace("'", "''")}'";
            
        return value;
    }
}
相关推荐
半路_出家ren2 小时前
Python操作MySQL(详细版)
运维·开发语言·数据库·python·mysql·网络安全·wireshark
共享家95272 小时前
MYSQL-内外连接
开发语言·数据库·mysql
古城小栈2 小时前
Go 语言 Flight Recorder:低开销性能分析工具实战
数据库·golang
weixin_446260852 小时前
Turso 数据库——以 Rust 编写的高效 SQL 数据库
数据库·sql·rust
前方一片光明9 小时前
SQL SERVER——生成sql:删除所有log表中,user_name是某用户的数据
数据库·sql·oracle
Gauss松鼠会10 小时前
【GaussDB】在duckdb中查询GaussDB的数据
数据库·sql·database·gaussdb
虹科网络安全10 小时前
艾体宝洞察 | Redis vs ElastiCache:哪个更具成本效益?
数据库·redis·缓存
自在极意功。10 小时前
MyBatis 动态 SQL 详解:从基础到进阶实战
java·数据库·mybatis·动态sql
老邓计算机毕设10 小时前
SSM校园订餐系统7z0dm(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·菜品管理系统·ssm 框架·ssm 框架开发·校园线上订餐平台