экспортировать файл с asp.net

#c# #asp.net-core

#c# #asp.net-core

Вопрос:

Этот проект является ASP.Проект Net Api с Angular. Что я пытаюсь сделать, так это экспортировать данные из таблицы базы данных в файл Excel. So far, I've managed to export all the table data into an excel file, but struggle to select 2 or 3 fields in the table to export.

         [HttpGet("download")]
        public IActionResult DownloadExcel(string field)
        {
            string dbFileName = "DbTableName.xlsx";


            FileInfo file = new FileInfo(dbFileName);
            byte[] fileContents;

            var stream = new MemoryStream();
            using (ExcelPackage package = new ExcelPackage(file))
            {

                IList<UserTable> userList = _context.UserTable.ToList();

                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("DbTableName");
                int totalUserRows = userList.Count();


            }


            return File(fileContents, fileType, dbFileName);
        }
  

Ответ №1:

Нет необходимости записывать так много if ... else if ... else if ... else if ... , чтобы получить связанные имена полей.

Более приятный способ — это

  1. Используйте список полей ( IList<string> ) в качестве параметра.
  2. А затем сгенерировать список обязательных полей с помощью intersect .
  3. Наконец, мы могли бы использовать отражение для извлечения всех связанных значений.

Реализация

     public IActionResult DownloadExcel(IList<string> fields)
    {
        // get the required field list
        var userType = typeof(UserTable);
        fields = userType.GetProperties().Select(p => p.Name).Intersect(fields).ToList();

        if(fields.Count == 0){ return BadRequest(); }

        using (ExcelPackage package = new ExcelPackage())
        {
            IList<UserTable> userList = _context.UserTable.ToList();
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("DbTableName");

            // generate header line
            for(var i= 0; i< fields.Count; i   ){
                var fieldName = fields[i];
                var pi= userType.GetProperty(fieldName);
                var displayName =  pi.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
                worksheet.Cells[1,i 1].Value = string.IsNullOrEmpty(displayName ) ? fieldName : displayName ;
            }

            // generate row lines
            int totalUserRows = userList.Count();
            for(var r=0; r< userList.Count(); r  ){
                var row = userList[r];
                for(var c=0 ; c< fields.Count;c  ){
                    var fieldName = fields[c];
                    var pi = userType.GetProperty(fieldName);
                    // because the first row is header 
                    worksheet.Cells[r 2, c 1].Value = pi.GetValue(row);
                }
            }
            var stream = new MemoryStream(package.GetAsByteArray());
            return new FileStreamResult(stream,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        }
    }
  

Вы могли бы настроить отображаемое имя с помощью DsiplayNameAttribute :

     public class UserTable
    {
        public int Id{get;set;}

        [DisplayName("First Name")]
        public string fName { get; set; }

        [DisplayName("Last Name")]
        public string lName { get; set; }

        [DisplayName("Gender")]
        public string gender { get; set; }

    }
  

Можно добавлять любые свойства по своему усмотрению без жесткого кодирования в вашем DownloadExcel методе.

ДЕМОНСТРАЦИЯ :

передача списка полей fields[0]=fNameamp;fields[1]=lNameamp;fields[2]=Non-Exist приведет к созданию Excel, как показано ниже:

введите описание изображения здесь

[Обновить]

Чтобы экспортировать все поля, мы могли бы предположить, что клиент не передаст fields параметр. Это означает, что когда поля будут null или если fields.Count==0 , мы экспортируем все поля:

     [HttpGet("download")]
    public IActionResult DownloadExcel(IList<string> fields)
    {
        // get the required field list
        var userType = typeof(UserTable);
        var pis= userType.GetProperties().Select(p => p.Name);

        if(fields?.Count >0){
            fields = pis.Intersect(fields).ToList();
        } else{
            fields = pis.ToList();
        }

        using (ExcelPackage package = new ExcelPackage()){
           ....
        }
    }
  

A

Комментарии:

1. Боже мой @itminus! Это сработало так хорошо!. Большое вам спасибо за помощь.

2. Если бы я хотел экспортировать все данные из таблицы, разве я не мог бы сделать что-то вроде fields = null? или поля =все?

3. @JennyFromtheBlock Я обновил свой ответ. Если клиент не укажет параметр fields (что означает fields==null или fields.Count==0 ), мы экспортируем все поля.

4. Не знаю, как вас отблагодарить! Я многому научился! Я надеюсь, что это поможет и другим!

Ответ №2:

если вы хотите использовать datatable, то мы можем определить, что вам нужно выбрать из datatable таким образом

 string[] selectedColumns = new[] { "Column1","Column2"};
DataTable dt= new DataView(fromDataTable).ToTable(false, selectedColumns);
  

или же, если вы хотите составить список, вы можете использовать linq для выбора определенных столбцов

 var xyz = from a in prod.Categories
                           where a.CatName.EndsWith("A")
                           select new { CatName=a.CatName, CatID=a.CatID, CatQty = a.CatQty};