Search code examples
c#asp.net-mvccsvhelper

use csvhelper to download files to a specific location


I want to use the linq and then let the user download a csv file to their speicifc location.

I learn something from internet and learning a csvhelper. I write something which works and download to a specific location (D:\export.csv) as below.

    public ActionResult YRecordReport()
    {
        using (var sw = new StreamWriter(@"d:\export.csv", true, Encoding.GetEncoding("big5")))
        using (var writer = new CsvWriter(sw))
        {
            var abc = from t in db.TRecordDBSet
                      join s in db.SInfoDBSet on t.SId equals s.SId
                      orderby s.sId, t.StartToEndDate
                      select new TRecord()
                      {
                          StaffId = t.SId,
                          Date = t.StartToEndDate,
                          Name = s.Cname,
                          CourseName = t.Tname,
                          Organizer = t.Organizer,
                          Hour = t.Hour,
                          Score = t.Score
                      };

            var source = abc.ToList();

            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<TRecord, TRecord_Data>();
            });

            config.AssertConfigurationIsValid();
            Mapper.Initialize(cfg => cfg.CreateMap<TRecord, TRecord_Data>());
            writer.Configuration.Encoding = Encoding.GetEncoding("big5");

            var mapper = config.CreateMapper();

            List<TRecord_Data> records = Mapper.Map<List<TRecord>, List<TRecord_Data>>(source);

            foreach (var item in records)
            {
                writer.WriteRecord(item);
            }
      }
}

Because I want to let the user to download the files to their specific location, I modified the code as below, it runs ok and the export.csv files is empty. Is that I write anything not specified? and how can i let the user download and use their filename?

    [MyAuthFilter(Auth = "Admin")]
    public ActionResult YearTrainingRecordReport()
    {
        var memoryStream = new MemoryStream();
        var stream = new StreamWriter(memoryStream);
        var writer = new CsvWriter(stream);

        var abc = from t in db.TRecordDBSet
                      join s in db.SInfoDBSet on t.SId equals s.SId
                      orderby s.SId, t.StartToEndDate
                      select new TRecord()
                      {
                          Sd = t.SId,
                          Date = t.StartToEndDate,
                          Name = s.Cname,
                          CourseName = t.Tname,
                          Organizer = t.Organizer,
                          Hour = t.Hour,
                          Score = t.Score
                      };

            var source = abc.ToList();

            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<TRecord, TRecord_Data>();
            });

            config.AssertConfigurationIsValid();
            Mapper.Initialize(cfg => cfg.CreateMap<TRecord, TRecord_Data>());
            writer.Configuration.Encoding = Encoding.GetEncoding("big5");

            var mapper = config.CreateMapper();

            List<TRecord_Data> records = Mapper.Map<List<TRecord>, List<TRecord_Data>>(source);

            foreach (var item in records)
            {
                writer.WriteRecord(item);
            }

            return File(memoryStream, "text/csv", "export.csv");

}

Solution

  • You need to flush your writer and reset the stream.

    writer.Flush();
    stream.Position = 0;
    

    If you're using CsvHelper 3.0 or later (currently in pre-release), you'll also need to force a new record.

    writer.NextRecord();