.Net Core:从CSV和Excel文件读取数据

问题描述 投票:0回答:4

这里使用.net core & c#。

我有一个 UI,用户可以从中上传 Excel 或 CSV 文件。一旦他们上传,就会转到我的 Web api,它处理从这些文件中读取数据并返回 json。

我的Api代码为:

 [HttpPost("upload")]
 public async Task<IActionResult> FileUpload(IFormFile file)
 {
     JArray data = new JArray();
     using (ExcelPackage package = new ExcelPackage(file.OpenReadStream()))
     {
        ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
        //Process, read from excel here and populate jarray
     }
      return Ok(data );
 }

在上面的代码中,我使用 EPPlus 来读取 Excel 文件。对于 excel 文件,一切正常,但无法读取 csv 文件,这是 EPPlus 的限制。

我搜索并找到了另一个库 CSVHelper:https://joshclose.github.io/CsvHelper/ 问题在于它反之亦然,可以从 CSV 读取,但不能从 Excel 读取。

是否有任何库支持从两者读取。

或者是否可以仅使用 EPPlus,但将上传的 CSV 即时转换为 Excel,然后读取。 (请注意,我没有将 Excel 文件存储在任何地方,因此无法使用“另存为”将其另存为 Excel)

请问有什么意见吗?

--更新 - 添加了从 excel 读取数据的代码---

 int rowCount = worksheet.Dimension.End.Row;
 int colCount = worksheet.Dimension.End.Column;

   for (int row = 1; row <= rowCount; row++)
   {
     for (int col = 1; col <= colCount; col++)
     {
         var rowValue = worksheet.Cells[row, col].Value;
     }
   }

//With the code suggested in the answer rowcount is always 1
c# excel csv asp.net-core epplus
4个回答
0
投票

您可以使用 EPPLus 和 MemoryStream 将 csv 文件打开到 ExcelPackage 中,而无需写入文件。下面是一个例子。您可能需要根据您的 CSV 文件规格更改一些参数。

[HttpPost("upload")]
public async Task<IActionResult> FileUpload(IFormFile file)
{
    var result = string.Empty;
    string worksheetsName = "data";

    bool firstRowIsHeader = false;
    var format = new ExcelTextFormat();
    format.Delimiter = ',';
    format.TextQualifier = '"';

    using (var reader = new System.IO.StreamReader(file.OpenReadStream()))
    using (ExcelPackage package = new ExcelPackage())
    {
         result = reader.ReadToEnd();
         ExcelWorksheet worksheet = 
         package.Workbook.Worksheets.Add(worksheetsName);
         worksheet.Cells["A1"].LoadFromText(result, format, OfficeOpenXml.Table.TableStyles.Medium27, firstRowIsHeader);
    }     
}

0
投票

这里使用的是 Aspose,不幸的是它不是免费的,但是它效果很好。我的 API 使用

Content-Type: multipart/form-data
的流功能,而不是
IFormFile
实现:

[HttpPut]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadSpreadsheet()
{
    if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
    {
        return BadRequest($"Expected a multipart request, but got {Request.ContentType}");
    }

    var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
    var reader = new MultipartReader(boundary, HttpContext.Request.Body);

    var section = (await reader.ReadNextSectionAsync()).AsFileSection();

    //If you're doing CSV, you add this line:
    LoadOptions loadOptions = new LoadOptions(LoadFormat.CSV);

    var workbook = new Workbook(section.FileStream, loadOptions);
    Cells cells = workbook.Worksheets[0].Cells;
    var rows = cells.Rows.Cast<Row>().Where(x => !x.IsBlank);

    //Do whatever else you want here

-1
投票

请尝试使用以下代码

 private string uploadCSV(FileUpload fl)
    {
        string fileName = "";
        serverLocation = Request.PhysicalApplicationPath + "ExcelFiles\\";
        fileName = fl.PostedFile.FileName;
        int FileSize = fl.PostedFile.ContentLength;
        string contentType = fl.PostedFile.ContentType;
        fl.PostedFile.SaveAs(serverLocation + fileName);

        string rpath = string.Empty, dir = string.Empty;
        HttpContext context = HttpContext.Current;
        string baseUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + context.Request.ApplicationPath.TrimEnd('/') + '/';

        try
        {
            rpath = serverLocation + fileName;//Server.MapPath(dir + fileName);

            using (Stream InputStream = fl.PostedFile.InputStream)
            {
                Object o = new object();
                lock (o)
                {
                    byte[] buffer = new byte[InputStream.Length];
                    InputStream.Read(buffer, 0, (int)InputStream.Length);
                    lock (o)
                    {
                        File.WriteAllBytes(rpath, buffer);
                        buffer = null;
                    }
                    InputStream.Close();
                }
            }

        }
        catch (Exception ex)
        {
            lblSOTargetVal.Text = ex.Message.ToString();
        }
        return rpath;
    }

-2
投票

使用Open XML SDK包并为其添加插入工作解决方案。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.