#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 ...
, чтобы получить связанные имена полей.
Более приятный способ — это
- Используйте список полей (
IList<string>
) в качестве параметра. - А затем сгенерировать список обязательных полей с помощью
intersect
. - Наконец, мы могли бы использовать отражение для извлечения всех связанных значений.
Реализация
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()){
....
}
}
Комментарии:
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};