Mình đang làm site có 1 module export excel aspx dính tới việc export 1 List ra Excel. Và mình cũng đã tìm hiểu và nghiên cứu rất nhiều chỗ. Nhưng mà khổ nỗi là những ký tự đặc biệt export ra đều bị lỗi hết. Do đó mình sẽ chia sẽ cho các bạn những ai đang gặp issue như mình ha.
Đầu tiên các bạn phải query DB và trả về 1 list
private AppDBEntities _context = new AppDBEntities(); public List<Company> Company() { var q = _context.FMCompanies; return q.ToList(); }
Sau đó các bạn tạo 1 class Utility với nội dung như sau.
Mục đích là mình sẽ sử dụng class này để xử lý convert data và export dữ liệu
Đầu tiên tạo class
public class Utilities { public Utilities() { // // TODO: Add constructor logic here // } }
Sau đó tạo phương thức Convert từ List qua Datatable Object. Mục đích của việc này là chúng ta sẽ tạo dữ liệu phẳng ra để bắt đầu Export
public DataTable ListToDataTable<T>(List<string> listHeaderFields, List<T> items) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); DataTable table = new DataTable(); for (int i = 0; i < listHeaderFields.Count; i++) { table.Columns.Add(listHeaderFields[i]); } object[] values = new object[properties.Count]; foreach (T item in items) { DataRow row = table.NewRow(); for (int i = 0; i < values.Length; i++) { var getValueProp = properties[i].GetValue(item); if (getValueProp != null) { row[listHeaderFields[i]] = getValueProp; } } table.Rows.Add(row); } return table; }
Tiếp theo chúng ta sẽ tạo phương thức Export ra Excel
/// <summary> /// Export Data Table To CSV /// </summary> /// <param name="Response"></param> /// <param name="fileName"></param> /// <param name="dt"></param> public void ExportDataTableToCSV(HttpResponse Response, string fileName, DataTable dt) { if (dt.Rows.Count > 0) { Response.Clear(); Response.ContentType = "text/csv"; Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName)); Response.ContentEncoding = System.Text.Encoding.Unicode; Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble()); // To do StringBuilder strBuilder = new StringBuilder(); foreach (DataColumn dtRow in dt.Columns) { strBuilder.Append(dtRow.ColumnName.Trim().Replace(",", "").Replace("'", "") + "\t"); } strBuilder.Append(","); strBuilder.Replace(",", System.Environment.NewLine, strBuilder.Length - 1, 1); foreach (DataRow dtRow in dt.Rows) { for (int i = 0; i < dt.Columns.Count; i++) { var stringResult = System.Web.HttpUtility.HtmlDecode(dtRow[i].ToString()); strBuilder.Append("\"" + stringResult.Replace(",", "") + "\"\t"); } strBuilder.Append(","); strBuilder.Replace(",", Environment.NewLine, strBuilder.Length - 1, 1); } Response.Write(strBuilder); Response.Flush(); Response.End(); } else { return; } }
Và đây là 1 class Utility hoàn chỉnh.
public class Utilities { public Utilities() { // // TODO: Add constructor logic here // } /// <summary> /// Export Data Table To CSV /// </summary> /// <param name="Response"></param> /// <param name="fileName"></param> /// <param name="dt"></param> public void ExportDataTableToCSV(HttpResponse Response, string fileName, DataTable dt) { if (dt.Rows.Count > 0) { Response.Clear(); Response.ContentType = "text/csv"; Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName)); Response.ContentEncoding = System.Text.Encoding.Unicode; Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble()); // To do StringBuilder strBuilder = new StringBuilder(); foreach (DataColumn dtRow in dt.Columns) { strBuilder.Append(dtRow.ColumnName.Trim().Replace(",", "").Replace("'", "") + "\t"); } strBuilder.Append(","); strBuilder.Replace(",", System.Environment.NewLine, strBuilder.Length - 1, 1); foreach (DataRow dtRow in dt.Rows) { for (int i = 0; i < dt.Columns.Count; i++) { var stringResult = System.Web.HttpUtility.HtmlDecode(dtRow[i].ToString()); strBuilder.Append("\"" + stringResult.Replace(",", "") + "\"\t"); } strBuilder.Append(","); strBuilder.Replace(",", Environment.NewLine, strBuilder.Length - 1, 1); } Response.Write(strBuilder); Response.Flush(); Response.End(); } else { return; } } public DataTable ListToDataTable<T>(List<string> listHeaderFields, List<T> items) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); DataTable table = new DataTable(); for (int i = 0; i < listHeaderFields.Count; i++) { table.Columns.Add(listHeaderFields[i]); } object[] values = new object[properties.Count]; foreach (T item in items) { DataRow row = table.NewRow(); for (int i = 0; i < values.Length; i++) { var getValueProp = properties[i].GetValue(item); if (getValueProp != null) { row[listHeaderFields[i]] = getValueProp; } } table.Rows.Add(row); } return table; } }
Xong chưa nhỉ?. Chưa đâu. Còn sử dụng nó nữa
Các bạn gọi Utitili và truyền vào List mình đã Query ra từ trước để bắt đầu convert nha
Note: Các bạn chú ý truyền vào HeaderFields cho đúng nha.
var reportCompanyInfo = _company.GetCompany(comId); var listHeaderFields = new List<string> { "BU", "PG", "Country", "Company", "Currency", "Company Active?", "Customer Type", "Section", "Name", "User Active?", "AID", "Title", "Sequence", "Term Level", "CL Range" }; var ultility = new Utilities(); var datatable = ultility.ListToDataTable(listHeaderFields, reportFMCompanyInfo); string filename = String.Format("{0}_CompanyDetail_{1}.csv", comId, DateTime.Now.ToShortDateString()); ultility.ExportDataTableToCSV(this.Context.Response, filename, datatable);
Done!
Nếu có thắc mắc gì các bạn cứ comment bên dưới nhé. 🙂