如何处理内存中的 Excel 个文件?

How to process Excel file in memory?

我正在尝试创建一个 API 来接受来自客户端的 Excel 文件的表示。我希望在处理第一个 sheet 之后 return 一个 List> 作为 JSON 数组。但是,我无法将文件写入磁盘,所有处理 必须 发生在 内存中 。可以通过哪些方式实现?

我试过参考互联网上的各种解决方案,但所有解决方案都涉及将文件写入磁盘,然后使用该文件进行进一步处理。我愿意接受涉及

的解决方案
  1. 接受来自 POST 请求正文的文件的 base-64 表示
  2. 接受文件作为 multipart/form-data 请求的一部分
  3. 接受文件的任何其他标准请求格式

唯一的条件是 API 应该 return 传播的 JSON 数组表示sheet。

在这里,我将文件作为 multipart/form-data 请求的一部分发送到 API,它是用 .NET 核心编写的。

支持 .xlsx 、 .xls 和 .csv 格式

使用 ExcelDataReader 和 ExcelDataReader.DataSet NuGet 包读取 excel 并在数据集中转换。

这是我在 .NET Core 中遇到的一个问题和解决方案。

默认情况下,ExcelDataReader 抛出 NotSupportedException“没有可用于编码 1252 的数据。”在 .NET Core 上。

要修复,请向包 System.Text.Encoding.CodePages 添加依赖项,然后添加代码以在 API

的开头注册代码页

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); 这是解析用 DOS-era 代码页编码的二进制 BIFF2-5 Excel 文档中的字符串所必需的。这些编码默认在完整的 .NET Framework 中注册,但在 .NET Core 中没有注册。

       public ActionResult ExcelOrCsvToArray()
        {
            if (Request.Form.Files.Count > 0)
            {
                IFormFile file = Request.Form.Files[0];
                string fileName = file.FileName;
                string fileContentType = file.ContentType;
                System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
                Stream stream = file.OpenReadStream();
                try
                {
                    if (fileName.EndsWith(".csv"))
                    {
                        using (var reader = ExcelReaderFactory.CreateCsvReader(stream))
                        {
                            var result = SetAsDataSet(reader);
                            DataTable table = result.Tables[0];
                            return new OkObjectResult(table);
                        }
                    }
                    else
                    {
                        using (var reader = ExcelReaderFactory.CreateReader(stream))
                        {
                            var result = SetAsDataSet(reader);
                            DataTable table = result.Tables[0];
                            return new OkObjectResult(table);
                        }
                    }
                }
                catch (Exception e)
                {
                    return new BadRequestObjectResult(e);
                }
            }
            else
            {
                return new BadRequestResult();
            }
        }

        private DataSet SetAsDataSet(IExcelDataReader reader)
        {
            var result = reader.AsDataSet(new ExcelDataSetConfiguration()
            {
                ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
                {
                    UseHeaderRow = true,
                }
            });
            return result;
        }