【问题标题】:How to use [Display(Name="")] as column headers with LoadFromCollection如何使用 [Display(Name="")] 作为 LoadFromCollection 的列标题
【发布时间】:2020-07-17 18:46:09
【问题描述】:

在我的 MVC 5 站点中,我有一个稳定的导出到 Excel 功能,但用户要求我将列标题设为“用户友好”。

在我的模型中,我使用了[Display(Name="Friendly Column Name")] 注释,它们在视图页面上按预期显示,但是当用户触发导出功能时,它们不会延续到导出的 Excel 文件中。而是出现了真名。

我知道我可以通过 LoadFromCollection 以外的其他方法加载工作表单元格,但我想知道是否仍然可以使用 LoadFromCollection 并使用模型的 Display( Name()) 注释。

这是我目前拥有的:

public ActionResult ExportToExcel(string _selectedCampus)
    {
        // This is the query result set the user wishes to export to file.
        IEnumerable<Mia1aSec1FayExport> exportQuery = unitOfWork
            .Mia1aSec1FayRepository.Get().Select(n => new Mia1aSec1FayExport
        {
            Campus = n.Campus,
            StudentName = n.StudentName,
            CreditsBeforeSchoolYear = n.CreditsBeforeSchoolYear,
            CreditsDuringSemester1 = n.CreditsDuringSemester1,
            EligibleFayCount = n.EligibleFayCount,
            EligibleFayMeetingGoal = n.EligibleFayMeetingGoal
        }).Where(n => n.Campus == _selectedCampus).OrderBy(n => n.StudentName)
        .AsEnumerable();

        // The current iteration saves the table contents, but without the   
        // [Display{Name"xxx)] annotation from the model.

        byte[] response;   
        using (var excelFile = new ExcelPackage())
        {
            excelFile.Workbook.Properties.Title = "MIA 1A (i) Eligible FAY Students";                
            var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");                   
            worksheet.Cells["A1"]
                .LoadFromCollection(Collection: exportQuery, PrintHeaders: true);
            response = excelFile.GetAsByteArray();
        }

        // Save dialog appears through browser for user to save file as desired.
        return File(response, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
            "Mia1aSec1Fay.xlsx");
    }

一种解决方法是覆盖标题单元格,但这是不可取的,原因有两个:(1)我已经在模型中将列名写为注释,这意味着我现在在两个不同的地方写了相同的信息, (2) 我必须手动保持信息同步,以防用户想要更多更改,而我可能会忘记这样做。

// This loads teh table as seen by the user in the index view.
            worksheet.Cells["A1"].LoadFromCollection(Collection: exportQuery, PrintHeaders: true);

            // Workaround overwrite header cells, as I'm not able to use Display Name annotation.
            worksheet.Cells[1, 1].Value = "Campus";
            worksheet.Cells[1, 2].Value = "Student Name";
            worksheet.Cells[1, 3].Value = "Credits Before SY";
            worksheet.Cells[1, 4].Value = "Credits During Semester 1";
            worksheet.Cells[1, 5].Value = "Legible Population";
            worksheet.Cells[1, 6].Value = "Eligible Students Earning 2+ Credits";                               

写到这里,我真的希望这不是唯一的选择。必须有一种方法可以在标题中写入显示名称值而不是真实名称。

【问题讨论】:

  • 您是否要为标题着色或设置某种格式?有worksheet.Cells[1, 1].AutoFitColumns() 可以根据内容调整单元格
  • 没有。我正在尝试用模型中的“显示名称”替换列标题的名称。我没有对格式化做任何事情。您会在我的第二个代码块中注意到我作为一种不受欢迎的解决方法所做的事情。这就是我需要的结果。我想要做的是使用模型数据注释中已经存在的信息来做到这一点。

标签: c# asp.net-mvc excel epplus


【解决方案1】:

LoadFromCollection 只响应DisplayNameDescription 属性,而不响应Display 属性。

因此,您可以尝试将这些属性之一添加到您当前的属性中。

[DisplayName("Friendly Column Name")]
[Display(Name = "Friendly Column Name")]
public string StudentName { get; set; }

同时确保在调用 LoadFromCollection 时将 PrintHeaders 参数设置为 true,但您说会显示真实名称,所以这可能已经可以了。

【讨论】:

  • 使用[DisplayName("User-friendly name")] 效果很好。我需要包含using System.ComponentModel
  • 从那以后我学会了如何使用视图模型。我有一个用于 Epplus 导出的类和一个用于模型的单独的类,这使我有机会更清楚地区分 Excel 文件外观和视图外观。
【解决方案2】:

#将记录导出到 csv 文件。
1.创建一个带有标题的模型类

               public class EmployeeDetails 
                {
                     [Name("ID")]
                    public string id{ get; set; }
            
                     [Name("Name")]
                    public string name{ get; set; }
            
                     [Name("Designation")]
                    public string  designation{ get; set; }
                }

2.使用 CSV Helper 类导出

       var data = new EmployeeDetails();
       List<EmployeeDetails> rows = new List<EmployeeDetails>() { data };
                   using (var memoryStream = new MemoryStream())
                   using (var streamWriter = new StreamWriter(memoryStream))
                   using (var csvWriter = new CsvWriter(streamWriter, CultureInfo.CurrentCulture))
                   {
                       csvWriter.WriteHeader(typeof(EmployeeDetails));
                       csvWriter.NextRecord();
                       csvWriter.WriteRecords(rows);
       
                       csvWriter.Flush();
                       streamWriter.Flush();
                       memoryStream.Position = 0;
       
                       return memoryStream;
                   }  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多