.Net 7.0 Core 文件导入接口的实现

主要是使用C# .Net 7.0 Core Webapi接口,通过调用这个接口,将文件上传到服务器,并读取文件,返回文件的数据

文章目录

代码

FileController-文件控制类

csharp 复制代码
using HS_Marketing_Department_BI_Backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;

namespace HS_Marketing_Department_BI_Backend.Controllers
{

    /// <summary>
    /// 文件控制器
    /// </summary>
    //[Authorize]
    [Route("[controller]")]
    [ApiController]
    public class FileController : ControllerBase
    {
        //日志
        private readonly ILogger<FileController> _logger;
        private string return_json;
        private ReturnData returnData;
        private string exStr;

        public FileController(ILogger<FileController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 文件上传接口
        /// </summary>
        /// <returns>返回结果</returns>
        [HttpPost("UploadFile")]
        public async Task<IActionResult> UploadFile(IFormFile file, string tableName)
        {
            string ext;
            char status;
            var savePath = Path.Combine(Directory.GetCurrentDirectory(), "uploads", file.FileName);
            var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
            if (file == null || file.Length == 0)
                return BadRequest("No file uploaded.");

            //.txt,T && T
            //.XLSX T %% F
            //.XLS F && T
            ext = Path.GetExtension(file.FileName).ToLower();
            if (ext != ".xlsx" && ext != ".xls")
            {
                //写入日志
                _logger.LogError("请选择导入文件为.xlsx的后缀名!");
                //返回
                return StatusCode(400, new { code = "E", msg = "请选择导入文件为.xlsx的后缀名!", data = "" });
            }
            try
            {
                //如果路径不存在
                if (!Directory.Exists(path))
                {
                    //创建路径
                    Directory.CreateDirectory(path);
                }
                using (var stream = new FileStream(savePath, FileMode.Create))
                {
                    IWorkbook workbook;

                    //异步将上传文件的内容复制到stream流中。程序会暂停当前方法的执行,把线程释放去处理其他请求
                    await file.CopyToAsync(stream);
                    stream.Position = 0; // 关键:重置流位置到文件开头,否则EOF in header
                    //根据文件流创建excel数据结构
                    if (ext == ".xlsx")
                    {
                        workbook = new XSSFWorkbook(stream); // .xlsx 文件
                    }
                    else
                    {
                        workbook = new HSSFWorkbook(stream); //.xls文件
                    }
                    //导入文件,读取表格内容
                    returnData = ExcelImportUtil.Import(workbook, tableName, out status);

                }
            }
            catch (Exception ex)
            {
                exStr = "文件读取异常。请检查文件格式或者是否是加密文档,仅支持解密文档;异常消息:" + ex.Message;

                //写入日志
                _logger.LogError(exStr);
                //报500错误
                return StatusCode(500, new { code = "E", msg = exStr, data = "" });
            }
            return_json = JsonConvert.SerializeObject(returnData);

            if (returnData.code == "S") //读取成功
            {
                _logger.LogInformation(return_json); //写入日志
                return Ok(new { code = returnData.code, msg = returnData.msg, data = returnData.data });  
            }
            else //读取失败
            {
                _logger.LogError(return_json); //写入日志
                return Ok(new { code = returnData.code, msg = returnData.msg, data = returnData.data }); 
            }
        }

        /// <summary>
        /// 文件保存接口
        /// </summary>
        /// <returns>返回结果</returns>
        [HttpPost("SaveFile")]
        public IActionResult SaveFile(List<TestModel> tests, string tableName)
        {
            ReturnData returnData = new ReturnData();
            string return_json;
            string data;
            try
            {
                switch (tableName)
                {
                    case "test":
                        returnData = TestBLL.SaveTestTable(tests, tableName);
                        break;
                }
                return_json = JsonConvert.SerializeObject(returnData);
            }
            catch (Exception ex)
            {
                exStr = $"保存失败。异常消息:{ex.Message}";
                _logger.LogError(exStr);
                return StatusCode(500, new { code = "E", msg = exStr, data = "" });
            }

            if (returnData.code == "S")
            {
                _logger.LogInformation(return_json);
                return Ok(new { code = returnData.code, msg = returnData.msg, data = returnData.data });
            }
            else
            {
                _logger.LogError(return_json);
                return Ok(new { code = returnData.code, msg = returnData.msg, data = returnData.data });
            }
        }

    }
}

ExcelImportUtil-Excel文件导入工具类

csharp 复制代码
using HS_Marketing_Department_BI_Backend.Models;
using Newtonsoft.Json;
using NPOI.SS.UserModel;
using System.Data;

namespace HS_Marketing_Department_BI_Backend
{
    public class ExcelImportUtil
    {
        /// <summary>
        /// 导入文件,获取表格内容
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="tableName"></param>
        /// <param name="status"></param>
        /// <returns>返回参数</returns>
        public static ReturnData Import(IWorkbook workbook, string tableName, out char status)
        {
            ReturnData returnData = new ReturnData();
            status = 'S';
            string result;
            string info;
            DataTable dataTable = new DataTable();

            //判断表名,按照表名生成不同的表结构
            switch (tableName)
            {
                //如果是test表
                case "test":
                    dataTable = new TestTable();
                    break;
            }

            //获取Excel第一个sheet 
            var sheet = workbook.GetSheetAt(0);
            //判断是否获取到 sheet 
            if (sheet != null)
            {
                //从第2行开始导,第一行是标题不导入
                for (int i = 1; i <= sheet.LastRowNum; i++)
                {
                    var row = sheet.GetRow(i);
                    DataRow dr = dataTable.NewRow();
                    for (int j = 0; j < row.Count(); j++)
                    {
                        ICell cell = row.GetCell(j);
                        //空单元格直接跳过
                        if (cell == null)
                        {
                            continue;
                        }
                        //判断单元格的格式
                        switch (cell.CellType)
                        {
                            case CellType.String:
                                //输出每个单元格的数据
                                Console.WriteLine($"第{i}行数据:第{j}个数据值:{cell.ToString()}");
                                dr[j] = cell.ToString();
                                break;
                            case CellType.Numeric:
                                // 判断是否为日期格式
                                if (DateUtil.IsCellDateFormatted(cell))
                                {
                                    try
                                    {
                                        // 安全地获取日期值
                                        DateTime dateValue = cell.DateCellValue;
                                        string str;
                                        //纯时间数值范围:0 <= 数值 <= 1(无日期整数部分)
                                        if (cell.NumericCellValue >= 0 && cell.NumericCellValue <= 1)
                                        {
                                            Console.WriteLine($"Time: {dateValue.ToString("HH:mm:ss")}");
                                            str = dateValue.ToString("HH:mm:ss");
                                        }
                                        else
                                        {
                                            Console.WriteLine($"Date: {dateValue.ToString("yyyy-MM-dd HH:mm:ss")}");
                                            str = dateValue.ToString("yyyy-MM-dd HH:mm:ss");
                                        }
                                        dr[j] = str;
                                    }
                                    catch (NullReferenceException ex)
                                    {
                                        // 处理 DateCellValue 为 null 的情况
                                        status = 'E';
                                        info = $"文件读取异常;DateCellValue is null for cell {cell.RowIndex},{cell.ColumnIndex}.Numeric value(could be date): {cell.NumericCellValue}. Exception: {ex.Message}";
                                        returnData.code = "E";
                                        returnData.msg = info;
                                        return returnData;
                                    }
                                }
                                //普通数字格式
                                else
                                {
                                    dr[j] = cell.ToString();
                                }
                                break;
                        }
                    }

                    //将数据行添加到数据表
                    dataTable.Rows.Add(dr);
                }
                Console.WriteLine("读取完毕!");
            }

            result = JsonConvert.SerializeObject(dataTable);
            returnData.code = "S";
            returnData.msg = "文件上传成功,并读取成功!";
            returnData.data = result;
            return returnData;

        }
    }
}

运行结果

相关推荐
贾修行2 小时前
Kestrel:.NET 的高性能 Web 服务器探秘
服务器·前端·kestrel·.net·net core·web-server·asp.net-core
工业甲酰苯胺2 小时前
C#中的多级缓存架构设计与实现深度解析
缓存·c#·wpf
聊聊MES那点事2 小时前
如何在FastReport.NET中自定义就绪报表查看器(Viewer)
.net·报表工具·fastreport
ye902 小时前
C#中的线程Threads与任务Tasks
c#
Traced back11 小时前
# C# + SQL Server 实现自动清理功能的完整方案:按数量与按日期双模式
开发语言·c#
yj爆裂鼓手12 小时前
c#万能变量
开发语言·c#
不绝19113 小时前
C#进阶:委托
开发语言·c#
喜欢喝果茶.13 小时前
跨.cs 文件传值(C#)
开发语言·c#
就是有点傻13 小时前
C#中如何和欧姆龙进行通信的
c#