假设您有一个kendo网格,并希望将数据导出为Excel或CSV文件格式。
使用通用的Kendo方法,您会发现它变得非常困难,因为它还会带来大量元数据。这将使大型擅长无用。
使用下面的方法,您可以导出到Excel,CSV,并考虑过滤器和其他。
答案 0 :(得分:1)
首先在cshtml
文件中定义JS函数和kendo网格:
@section scripts{
<script>
function DownloadExcelFile(e)
{
if(e != "undefined")
e.preventDefault();
var grid = $("#mainGrid").data("kendoGrid");
var parameterMap = grid.dataSource.transport.parameterMap;
var data = parameterMap({ sort: grid.dataSource.sort(), filter: grid.dataSource.filter(), group: grid.dataSource.group() });
window.location = "Report/GetSummaryExcelReport?" + "filter=" + data.filter + "&sort=" + data.sort + "&group=" + data.group;
return false;
}
</script>
}
<div class="col-md-12 col-sm-12 col-xs-12 text-center padding-0 inner">
<div class="grid-area">
@(Html.Kendo().Grid<SummaryGridRowModel>().Name("mainGrid")
</div>
</div>
在此之后,您在控制器中声明一个函数,该函数将生成已排序的数据并调用帮助程序以生成EXCEL / CSV / ZIP文件。
public FileResult GetSummaryExcelReport([DataSourceRequest] DataSourceRequest request)
{
var query = DbContext.vwReportSummary.AsQueryable();
var summaryGridRowModelList = query.Select(SummaryRequestsSelector);
var dsResult = summaryGridRowModelList.ToDataSourceResult(request);
string fileName = string.Format("RequestDetailsExcelReport_{0}.xlsx", DateTime.Now.ToString("yyyyMMdd_HHmmss"));
ExcelFileCreator fileCreator = new ExcelFileCreator();
//var result = fileCreator.CreateExcelFileFileStreamResult<SummaryGridRowModel>(dsResult.Data as IEnumerable<SummaryGridRowModel>, fileName);
var result = fileCreator.CreateZipFileFileContentResult<SummaryGridRowModel>(dsResult.Data as IEnumerable<SummaryGridRowModel>, fileName);
return result;
}
最后但并非最不重要的是,定义将生成EXCEL / CSV / ZipArchive文件创建者的帮助程序。
Excel File Creator助手
public class ExcelFileCreator
{
/// <summary>
/// Generates a FileStreamResult containing a Excel file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the Excel file</param>
/// <param name="fileName">The file name of the Excel</param>
/// <returns>FileStreamResult</returns>
public FileStreamResult CreateExcelFileFileStreamResult<T>(IEnumerable<T> objectList, string fileName)
{
var ms = new MemoryStream();
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
try
{
ExcelPackage excelPackage = new ExcelPackage(ms);
excelPackage.Compression = OfficeOpenXml.CompressionLevel.BestCompression;
var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
var firstRow = workSheet1.Row(1);
if(firstRow != null)
firstRow.Style.Font.Bold = true;
excelPackage.SaveAs(ms);
ms.Seek(0, SeekOrigin.Begin);
var fsr = new FileStreamResult(ms, contentType);
fsr.FileDownloadName = fileName;
return fsr;
}
catch (Exception ex)
{
if (ms != null)
{
ms.Dispose();
}
throw;
}
}
/// <summary>
/// Generates a FileStreamResult containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>FileStreamResult</returns>
public FileContentResult CreateZipFileFileContentResult<T>(IEnumerable<T> objectList, string fileName)
{
var contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
using (var memoryStream = new System.IO.MemoryStream())
{
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
using (var package = new OfficeOpenXml.ExcelPackage())
{
var workSheet1 = package.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
var firstRow = workSheet1.Row(1);
if (firstRow != null)
firstRow.Style.Font.Bold = true;
zip.AddEntry(fileName, package.GetAsByteArray());
zip.Save(memoryStream);
var fcr = new FileContentResult(memoryStream.ToArray(), contentType); //NOTE: Using a File Stream Result will not work.
fcr.FileDownloadName = fileName + ".zip";
return fcr;
}
}
}
}
/// <summary>
/// Generates a HttpResponseMessage containing a Excel file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the Excel file</param>
/// <param name="fileName">The file name of the Excel</param>
/// <returns>HttpResponseMessage</returns>
public HttpResponseMessage CreateExcelFileHttpResponseMessage<T>(IEnumerable<T> objectList, string fileName)
{
using (var ms = new MemoryStream())
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
using (ExcelPackage excelPackage = new ExcelPackage(ms))
{
var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
}
result.Content = new ByteArrayContent(ms.GetBuffer());
result.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
return result;
}
}
/// <summary>
/// Generates a HttpResponseMessage containing a zip file with the EXCEL file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the EXCEL file</param>
/// <param name="fileName">The file name of the EXCEL</param>
/// <returns>HttpResponseMessage</returns>
public HttpResponseMessage CreateZipFileHttpResponseMessage<T>(IEnumerable<T> objectList, string fileName)
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
using (var ms = new MemoryStream())
{
using (var archive = new System.IO.Compression.ZipArchive(ms, System.IO.Compression.ZipArchiveMode.Create, true))
{
var newEntry = archive.CreateEntry(fileName, System.IO.Compression.CompressionLevel.Fastest);
using (var newEntryStream = newEntry.Open())
using (ExcelPackage excelPackage = new ExcelPackage(ms))
{
var workSheet1 = excelPackage.Workbook.Worksheets.Add("Sheet1");
workSheet1.Cells["A1"].LoadFromCollection<T>(objectList, true);
}
}
ms.Seek(0, SeekOrigin.Begin);
result.Content = new ByteArrayContent(ms.ToArray());
result.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName + ".zip"
};
return result;
}
}
}
CsvFile Creator助手
/// <summary>
/// Enumerator for the CSV file separator
/// </summary>
public enum CsvFileSeparatorType
{
/// <summary>
/// Values will be separated by a comma: ", "
/// </summary>
Comma
,
/// <summary>
/// Values will be separated by a tab delimiter: "\t "
/// </summary>
Tab
,
/// <summary>
/// Values will be separated by a semicolon: "; "
/// </summary>
Semicolon
}
/// <summary>
/// This class helps create a CSV file
/// </summary>
public class CsvFileCreator
{
public CsvFileSeparatorType CsvFileSeparatorType
{
get
{
CsvFileSeparatorType csvFileSeparatorType = CsvFileSeparatorType.Tab;
switch (ConfigurationManager.AppSettings["CsvFileSeparatorType"])
{
case "Comma":
csvFileSeparatorType = CsvFileSeparatorType.Comma;
break;
case "Tab":
csvFileSeparatorType = CsvFileSeparatorType.Tab;
break;
case "Semicolon":
csvFileSeparatorType = CsvFileSeparatorType.Semicolon;
break;
default:
csvFileSeparatorType = CsvFileSeparatorType.Tab;
break;
}
return csvFileSeparatorType;
}
}
/// <summary>
/// Generates a HttpResponseMessage containing a zip file with the CSV file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the CSV file</param>
/// <param name="fileName">The file name of the CSV</param>
/// <returns>HttpResponseMessage</returns>
public HttpResponseMessage CreateZipFileHttpResponseMessage<T>(IEnumerable<T> objectList, string fileName)
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
using (var ms = new MemoryStream())
{
using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
var csvEnumerable = CreateCsvEnumerable<T>(objectList, CsvFileSeparatorType);
var newEntry = archive.CreateEntry(fileName, CompressionLevel.Fastest);
using (var newEntryStream = newEntry.Open())
using (var streamWriter = new StreamWriter(newEntryStream))
{
foreach (var csvLine in csvEnumerable)
{
streamWriter.WriteLine(csvLine);
}
streamWriter.Flush();
}
}
ms.Seek(0, SeekOrigin.Begin);
result.Content = new ByteArrayContent(ms.ToArray());
result.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName + ".zip"
};
return result;
}
}
/// <summary>
/// Generates a HttpResponseMessage containing a CSV file in it
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the CSV file</param>
/// <param name="fileName">The file name of the CSV</param>
/// <returns>HttpResponseMessage</returns>
public HttpResponseMessage CreateCsvFileHttpResponseMessage<T>(IEnumerable<T> objectList, string fileName)
{
using (var ms = new MemoryStream())
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
using (var streamWriter = new StreamWriter(ms))
{
var csvEnumerable = CreateCsvEnumerable<T>(objectList, CsvFileSeparatorType);
foreach (var csvLine in csvEnumerable)
{
streamWriter.WriteLine(csvLine);
}
streamWriter.Flush();
}
result.Content = new ByteArrayContent(ms.GetBuffer());
result.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("text/csv");
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
return result;
}
}
/// <summary>
/// Generates an Enumerable containing the CSV data in it. First row contains the headers
/// </summary>
/// <typeparam name="T">Type of object in the object list parameter</typeparam>
/// <param name="objectList">The object list enumerable. This contains the data for the CSV file</param>
/// <param name="separatorType">Enumerator for the CSV file separator</param>
/// <returns>IEnumerable</returns>
private IEnumerable<string> CreateCsvEnumerable<T>(IEnumerable<T> objectlist, CsvFileSeparatorType separatorType)
{
string separator = ", ";
switch (separatorType)
{
case CsvFileSeparatorType.Comma:
separator = ", ";
break;
case CsvFileSeparatorType.Semicolon:
separator = "; ";
break;
case CsvFileSeparatorType.Tab:
separator = "\t ";
break;
}
PropertyInfo[] properties = typeof(T).GetProperties();
yield return "\"" + String.Join(separator, properties.Select(f => f.Name).ToArray()) + "\"";
foreach (var o in objectlist)
{
yield return "\"" + HttpUtility.HtmlDecode(string.Join(separator, properties.Select(f => (f.GetValue(o) ?? "").ToString()).ToArray())) + "\"";
}
}
}