c# - 如何从 ASP.NET core 导出 CSV 文件

标签 c# asp.net-core-mvc export-to-csv csv-write-stream

我正在尝试将代码从 ASP.net 迁移到 ASP.net core。

ASP.net 代码如下所示,

var progresses = db.Progresses.Where(p => p.UserId == id).Include(p => p.User.UserMetaData).Include(p => p.Quiz).Include(p => p.User.Groups).OrderByDescending(p => p.UpdatedAt).ToList();

List<ReportCSVModel> reportCSVModels = new List<ReportCSVModel>();
const string downloadName = "Reports.csv";
var csv = new CsvWriter(Response.Output);

csv.Configuration.RegisterClassMap<ReportCSVMap>();

Response.ClearContent();

Response.ContentType = "application/octet-stream";

Response.AddHeader("Content-Disposition",
   "attachment; filename=" + downloadName);

csv.WriteHeader<ReportCSVModel>();
foreach (var progress in progresses)
{
    var reportCSVModel = new ReportCSVModel();
    reportCSVModel.Quiz = progress.Quiz.Title;
    reportCSVModel.Score = (progress.CorrectAnswersCount * progress.PointsPerQuestion).ToString();
    reportCSVModel.Status = progress.Status;
    reportCSVModel.CompletedDate = progress.UpdatedAt.ToString();
    reportCSVModel.Location = progress.User.UserMetaData != null ? progress.User.UserMetaData.Location : "";
    reportCSVModel.Group = progress.User.Groups.FirstOrDefault() != null ? progress.User.Groups.FirstOrDefault().Name : "";

    csv.WriteRecord<ReportCSVModel>(reportCSVModel);
}
Response.Flush();
Response.End();
return null;

但是在 ASP.NET core 中使用它时,我将其转换为,

var progresses = _elearnContext.Progress.Where(p => p.UserId == id).Include(p => p.User.UserMetaData).Include(p => p.Quiz).Include(p => p.User.Groups).OrderByDescending(p => p.UpdatedAt).ToList();

// List<ReportCSVModel> reportCSVModels = new List<ReportCSVModel>();
List<ReportCSVModel> reportCSVModels = new List<ReportCSVModel>();
const string downloadName = "Reports.csv";

System.IO.TextWriter writeFile = new StreamWriter(Response.Body.ToString());
CsvWriter csv = new CsvWriter(writeFile);
csv.Configuration.RegisterClassMap<GroupReportCSVMap>();
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.Headers.Add("Content-Disposition", "attachment; filename=" + downloadName);


csv.WriteHeader<ReportCSVModel>();
foreach (var progress in progresses)
{
    var reportCSVModel = new ReportCSVModel();
    reportCSVModel.Quiz = progress.Quiz.Title;
    reportCSVModel.Score = (progress.CorrectAnswersCount * progress.PointsPerQuestion).ToString();
    reportCSVModel.Status = progress.Status;
    reportCSVModel.CompletedDate = progress.UpdatedAt.ToString();
    reportCSVModel.Location = progress.User.UserMetaData != null ? progress.User.UserMetaData.Location : "";
    reportCSVModel.Group = progress.User.Groups.FirstOrDefault() != null ? progress.User.Groups.FirstOrDefault().Name : "";

    csv.WriteRecord<ReportCSVModel>(reportCSVModel);
}

Response.Clear();
return null;

在 ASP.net 中,Response.Output 可用,但在核心中不可用。所以我尝试像 Response.Body

一样使用它

谁能告诉我,我哪里做错了?

最佳答案

考虑改变方法以与当前建议的语法更加一致。

构造 CSV 并返回 FileResult,这使得代码不必直接操作 Response 对象。

[HttpGet]
public IActionResult MyExportAction() {
    var progresses = _elearnContext.Progress.Where(p => p.UserId == id)
        .Include(p => p.User.UserMetaData)
        .Include(p => p.Quiz)
        .Include(p => p.User.Groups)
        .OrderByDescending(p => p.UpdatedAt)
        .ToList()
        .Select(progress => 
            new ReportCSVModel() {
                Quiz = progress.Quiz.Title,
                Score = (progress.CorrectAnswersCount * progress.PointsPerQuestion).ToString(),
                Status = progress.Status,
                CompletedDate = progress.UpdatedAt.ToString(),
                Location = progress.User.UserMetaData != null ? progress.User.UserMetaData.Location : "",
                Group = progress.User.Groups.FirstOrDefault() != null ? progress.User.Groups.FirstOrDefault().Name : ""
            }
        );

    List<ReportCSVModel> reportCSVModels = progresses.ToList();

    var stream = new MemoryStream();
    using(var writeFile = new StreamWriter(stream, leaveOpen: true)) {
        var csv = new CsvWriter(writeFile, true);
        csv.Configuration.RegisterClassMap<GroupReportCSVMap>();            
        csv.WriteRecords(reportCSVModels);
    }
    stream.Position = 0; //reset stream
    return File(stream, "application/octet-stream", "Reports.csv");
}

关于c# - 如何从 ASP.NET core 导出 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52741533/

相关文章:

c# - Entity Framework 6.1 和使用新关键字隐藏成员

c# - List<T> 实现 IQueryable<T>

asp.net - 日期时间数据注释在 ASP.NET Core RC2 应用程序中不起作用

angularjs - Angular JS MVC Web API 模型/参数未绑定(bind) .NET Core

java - 如何在Java中读取树形结构制表符分隔的文本文件

line-breaks - 从 pgadmin 导出读取字段单元格中的换行符并创建不可读的 Excel

mysql - 通过 MySQL 创建 CSV 文件 - 有任何限制吗?

c# - 是什么让 Enum.HasFlag 这么慢?

c# - 调用 C++ dll 时出现 System.AccessViolationException

c# - 异步组件在 MVC 6 中不起作用