Upload .csv file to HTML table MAUI BLAZOR

Kalyan A 380 Reputation points
2025-03-01T15:05:30.2233333+00:00

I am getting .csv file from

https://www.nseindia.com/reports-indices-historical-index-data and I want to show it in a table in

.NET MAUI BLAZOR C#

@page "/Forecast"
@using NSEBlazor.Models
namespace NSEBlazor.Models;
@inject CsvService CsvService
<PageTitle>Stock Data</PageTitle>
<h3>Stock Data</h3>
<input type="file" id="fileInput" style="display:none" @onchange="OnFileChange" />
<button @onclick="TriggerFileInput">Upload CSV</button>
@if (stockData == null)
{
    <p>Loading...</p>
}
else
{
    <table>
        <thead>
            <tr>
                <th>Date</th>
                <th>Open</th>
                <th>High</th>
                <th>Low</th>
                <th>Close</th>
                <th>Shares Traded</th>
                <th>Turnover</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var data in stockData)
            {
                <tr>
                    <td>@data.Date.ToShortDateString()</td>
                    <td>@data.Open</td>
                    <td>@data.High</td>
                    <td>@data.Low</td>
                    <td>@data.Close</td>
                    <td>@data.SharesTraded</td>
                    <td>@data.Turnover</td>
                </tr>
            }
        </tbody>
    </table>
}
@code {
    private IEnumerable<StockData> stockData;
    private async Task OnFileChange(InputFileChangeEventArgs e)
    {
        var file = e.File;
        if (file != null)
        {
            using var stream = file.OpenReadStream();
            using var reader = new StreamReader(stream);
            var csvData = await reader.ReadToEndAsync();
            stockData = await Task.Run(() => CsvService.LoadCsvFromString(csvData));
        }
    }
    private void TriggerFileInput()
    {
        var fileInput = document.getElementById("fileInput");
        fileInput.click();
    }
}


here is the service from Models Folder

using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
namespace NSEBlazor.Models;
internal class CsvService
{
    public IEnumerable<StockData> LoadCsv(string filePath)
    {
        using (var reader = new StreamReader(filePath))
        using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)))
        {
            return csv.GetRecords<StockData>().ToList();
        }
    }
    public IEnumerable<StockData> LoadCsvFromString(string csvData)
    {
        using (var reader = new StringReader(csvData))
        using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)))
        {
            return csv.GetRecords<StockData>().ToList();
        }
    }
}
public class StockData
{
    public DateTime Date { get; set; }
    public decimal Open { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Close { get; set; }
    public int SharesTraded { get; set; }
    public decimal Turnover { get; set; }
}}
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using NSEBlazor.Models;
namespace NSEBlazor
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });
            // Register CsvService for dependency injection
             
        builder.Services.AddSingleton<CsvService>();
            builder.Services.AddMauiBlazorWebView();
#if DEBUG
    		builder.Services.AddBlazorWebViewDeveloperTools();
    		builder.Logging.AddDebug();
#endif
            return builder.Build();
        }
    }
}
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,969 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 80,211 Reputation points Microsoft External Staff
    2025-03-03T06:50:09.5066667+00:00

    Hello,

    Because the header names of the CSV file do not exactly match the expected header names in the code. Specifically:

    Expected header names: Date, Open, High, Low, Close, SharesTraded

    Actual header names: Date, Open, High, Low, Close, Shares Traded, Turnover

    As you can see, the actual header names contain extra spaces (e.g. Date instead of Date), and SharesTraded is written as Shares Traded (with a space in between).

    If you cannot change the value of CSV file, you can Ignore header validation errors and Ignore missing headers by setting CsvConfiguration in LoadCsvFromString method.

    public  IEnumerable<StockData> LoadCsvFromString(string csvData)
      {
          var config = new CsvConfiguration(CultureInfo.InvariantCulture)
          {
              // Ignore header validation errors
              HeaderValidated = null,
              // Ignore missing headers
              MissingFieldFound = null
          };
     
          using (var reader = new StringReader(csvData))
          using (var csv = new CsvReader(reader, config))
          {
              return csv.GetRecords<StockData>().ToList();
          }
      }
    

    And I find <input > tag cannot set the InputFileChangeEventArgs, I change it to <InputFile>tag, and use <label> to warp it, you do not need to add TriggerFileInput method to implement the click event.

    
    @inject CsvService CsvService
     
    <PageTitle>Stock Data</PageTitle>
    <h3>Stock Data</h3>
     
    <label class="btn btn-primary">
    <InputFile style="display: none" OnChange="OnFileChange" />
    	Choose csv File
    </label>
     
    @if (stockData == null)
    {
    <p>Loading...</p>
    }
    else
    {
    <table>
    <thead>
    <tr>
    <th>Date</th>
    <th>Open</th>
    <th>High</th>
    <th>Low</th>
    <th>Close</th>
    <th>Shares Traded</th>
    <th>Turnover</th>
    </tr>
    </thead>
    <tbody>
    			@foreach (var data in stockData)
    			{
    <tr>
    <td>@data.Date.ToShortDateString()</td>
    <td>@data.Open</td>
    <td>@data.High</td>
    <td>@data.Low</td>
    <td>@data.Close</td>
    <td>@data.SharesTraded</td>
    <td>@data.Turnover</td>
    </tr>
    			}
    </tbody>
    </table>
    }
     
    @code {
    	private IEnumerable<StockData> stockData;
     
     
    	private async Task OnFileChange(InputFileChangeEventArgs e)
    	{
     
    		var file = e.File;
    		if (file != null)
    		{
    			using var stream = file.OpenReadStream();
    			using var reader = new StreamReader(stream);
    			var csvData = await reader.ReadToEndAsync();
    			stockData = await Task.Run(() => CsvService.LoadCsvFromString(csvData));
    		}
    	}
    }
     
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.