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

问题描述

我正在尝试创建一个API,该API将接受来自客户端的Excel文件的表示形式。我希望在处理完第一张工作表后将List >返回为JSON数组。但是,我无法将文件写入磁盘,并且所有处理必须必须在内存中进行 。有哪些方法可以实现?

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

  1. 从POST请求正文中接受文件的base-64表示形式
  2. 接受文件作为多部分/表单数据请求的一部分
  3. 接受文件的其他任何标准请求格式

唯一的条件是API应该返回电子表格的JSON数组表示形式。

解决方法

在这里,我正在将文件作为multipart / form-data请求的一部分发送到以.NET Core编写的API。

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

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

这是我面临的一个问题,.NET核心中的解决方案。

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

要解决此问题,请将依赖项添加到包System.Text.Encoding.CodePages中,然后添加代码以在API的开头注册代码页

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); 这是解析使用DOS时代代码页编码的二进制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;
        }