【问题标题】:.Net Core: Reading data from CSV & Excel files.Net Core:从 CSV 和 Excel 文件中读取数据
【发布时间】:2019-04-15 11:53:34
【问题描述】:

在此处使用 .net core 和 c#。

我有一个用户界面,用户可以从中上传 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 文件存储在任何地方,所以不能使用 save as 将其另存为 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

【问题讨论】:

  • 如果我是你,我会使用最适合该格式的库,而不是试图找到一种万能的工具。如果您的代码是 Excel 文件,请使用 EPPlus,如果是 CSV 文件,请使用 CsvHelper。
  • @mason 谢谢,我只是想知道是否有这样的库可用,这样我就不必重复步骤了。是的,如果没有可用的,那么我可以按照您的建议使用 2 个库。

标签: c# excel csv asp.net-core epplus


【解决方案1】:

您可以使用 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);
    }     
}

【讨论】:

  • 我正在从 UI 上传文件,我需要将什么传递给新的 FileInfo(csvFile)。您拥有的 csvFile 是文件的物理位置,但我没有。
  • 这取决于您尝试加载的对象类型。您可以将内容放入一个字符串并从中加载。
  • 抱歉出差所以无法回复。我试过你的代码。它在读取 excel 时工作正常,但在从 csv 读取数据时出现问题。如果我的 csv 中有不止一行,它会用逗号分隔每个单元格数据,并且不区分下一行。请参阅我更新的帖子,了解我使用哪些代码来读取 excel 行。
【解决方案2】:

这里使用的是 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

【讨论】:

    【解决方案3】:

    请尝试以下代码

     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;
        }
    

    【讨论】:

      猜你喜欢
      • 2019-08-06
      • 2014-01-07
      • 2019-09-17
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 2019-05-03
      相关资源
      最近更新 更多