在现代软件开发中,自动化生成Excel文件并提供下载功能是常见的需求。本文将介绍如何利用C#编程语言和MVC框架,结合Ajax技术,实现这一功能。
本项目通过整合多个代码片段,实现了一个能够自动生成Excel文件并提供下载的解决方案。项目中包含了一个MVC页面,用户只需点击按钮,即可通过AjaxPOST请求自动下载生成的文件。
在下载并解压项目后,请确保在解决方案上点击右键并恢复NuGet包,以确保所有依赖项都已正确安装。
在构建此项目的过程中,合并了许多代码片段。以下是一些参考链接:
生成电子表格的过程非常简单,只需一行代码,提供DataSet、电子表格文件的完整路径以及是否启用自动筛选:
C#
CreateExcelFile.CreateExcelDocument(dataSet, fullPath, includeAutoFilter: true);
对原始的电子表格生成代码进行了优化,避免了在电子表格中查找行并缓存现有行,这大大提高了处理大量行和列时生成电子表格的速度。
以下是找到每列中所有行的最大文本并计算列的正确大小的代码:
C#
int numberOfColumns = dt.Columns.Count;
Columns columns = new Columns();
for (int colInx = 0; colInx < numberOfColumns; colInx++)
{
DataColumn col = dt.Columns[colInx];
string maxText = col.ColumnName;
foreach (DataRow dr in dt.Rows)
{
string value = string.Empty;
if (col.DataType.FullName == "System.DateTime")
{
DateTime dtValue;
if (DateTime.TryParse(dr[col].ToString(), out dtValue))
value = dtValue.ToShortDateString();
}
else
{
value = dr[col].ToString();
}
if (value.Length > maxText.Length)
{
maxText = value;
}
}
double width = GetWidth("Calibri", 11, maxText);
columns.Append(CreateColumnData((uint)colInx + 1, (uint)colInx + 1, width + 2));
}
worksheetPart.Worksheet.Append(columns);
以下是计算字体宽度的辅助函数:
private static double GetWidth(string font, int fontSize, string text)
{
System.Drawing.Font stringFont = new System.Drawing.Font(font, fontSize);
return GetWidth(stringFont, text);
}
private static double GetWidth(System.Drawing.Font stringFont, string text)
{
// 此公式基于此文章加上一个小的调整 ( + 0.2M )
// http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.width.aspx
System.Drawing.Size textSize = System.Windows.Forms.TextRenderer.MeasureText(text, stringFont);
double width = (double)(((textSize.Width / (double)7) * 256) - (128 / 7)) / 256;
width = (double)decimal.Round((decimal)width + 0.2M, 2);
return width;
}
当调用此函数时,它将下载电子表格:
JavaScript
function downloadSpreadsheet() {
$.ajax({
type: "POST",
url: '/Home/GenerateSpreadsheet',
success: function (data) {
if (data != null && (data.errorMessage == null || data.errorMessage == "")) {
if (data.fileName != "") {
window.location.href = "DownloadSpreadsheet/?file=" + data.fileName;
}
} else {
alert("An error occurred", data.errorMessage);
}
}
});
}
C#
[HttpPost]
public JsonResult GenerateSpreadsheet()
{
var path = Server.MapPath("~/temp");
var fileName = "Spreadsheet.xlsx";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
DataSet dataSet = new DataSet("Hospital");
dataSet.Tables.Add(Table());
string fullPath = Path.Combine(path, fileName);
CreateExcelFile.CreateExcelDocument(dataSet, fullPath, includeAutoFilter: true);
return Json(new { fileName = fileName, errorMessage = "" });
}
[HttpGet]
[NoCache]
public ActionResult DownloadSpreadsheet(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/temp"), file);
return File(fullPath, "application/vnd.ms-excel", file);
}