我正在创建一个MVC控制器操作,其中传入方法的JSON数据将写入excel文件。现在,我正在使用基于this blog post示例的数据表中的硬编码数据来测试功能。
这是我的代码:
[HttpPost]
public ActionResult ExportData()
{
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook worKbooK;
Microsoft.Office.Interop.Excel.Worksheet worKsheeT;
Microsoft.Office.Interop.Excel.Range celLrangE;
try
{
excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false;
worKbooK = excel.Workbooks.Add(Type.Missing);
worKsheeT = (Microsoft.Office.Interop.Excel.Worksheet)worKbooK.ActiveSheet;
worKsheeT.Name = "StudentRepoertCard";
worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[1, 8]].Merge();
worKsheeT.Cells[1, 1] = "Student Report Card";
worKsheeT.Cells.Font.Size = 15;
int rowcount = 2;
foreach (DataRow datarow in ExportToExcel().Rows)
{
rowcount += 1;
for (int i = 1; i <= ExportToExcel().Columns.Count; i++)
{
if (rowcount == 3)
{
worKsheeT.Cells[2, i] = ExportToExcel().Columns[i - 1].ColumnName;
worKsheeT.Cells.Font.Color = System.Drawing.Color.Black;
}
worKsheeT.Cells[rowcount, i] = datarow[i - 1].ToString();
if (rowcount > 3)
{
if (i == ExportToExcel().Columns.Count)
{
if (rowcount % 2 == 0)
{
celLrangE = worKsheeT.Range[worKsheeT.Cells[rowcount, 1], worKsheeT.Cells[rowcount, ExportToExcel().Columns.Count]];
}
}
}
}
}
celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[rowcount, ExportToExcel().Columns.Count]];
celLrangE.EntireColumn.AutoFit();
Microsoft.Office.Interop.Excel.Borders border = celLrangE.Borders;
border.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
border.Weight = 2d;
celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[2, ExportToExcel().Columns.Count]];
worKbooK.SaveAs("\\root\\test.xlsx");
worKbooK.Close();
excel.Quit();
}
catch (Exception ex)
{
return Json(new { saveSuccess = false }, JsonRequestBehavior.AllowGet);
}
finally
{
worKsheeT = null;
celLrangE = null;
worKbooK = null;
}
return Json(new { saveSuccess = true }, JsonRequestBehavior.AllowGet);
}
//private void Form1_Load(object sender, EventArgs e)
//{
// dataGridView1.DataSource = ExportToExcel();
//}
public System.Data.DataTable ExportToExcel()
{
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Sex", typeof(string));
table.Columns.Add("Subject1", typeof(int));
table.Columns.Add("Subject2", typeof(int));
table.Columns.Add("Subject3", typeof(int));
table.Columns.Add("Subject4", typeof(int));
table.Columns.Add("Subject5", typeof(int));
table.Columns.Add("Subject6", typeof(int));
table.Rows.Add(1, "Amar", "M", 78, 59, 72, 95, 83, 77);
table.Rows.Add(2, "Mohit", "M", 76, 65, 85, 87, 72, 90);
table.Rows.Add(3, "Garima", "F", 77, 73, 83, 64, 86, 63);
table.Rows.Add(4, "jyoti", "F", 55, 77, 85, 69, 70, 86);
table.Rows.Add(5, "Avinash", "M", 87, 73, 69, 75, 67, 81);
table.Rows.Add(6, "Devesh", "M", 92, 87, 78, 73, 75, 72);
return table;
}
现在,代码一直运行直到保存发生。由于某种原因,找不到文件位置。我假设文件的名称必须在包含文件夹之后的路径末尾列出才能提供名称,但这可能不是指定文件路径的正确方法。
我实际需要做的是允许用户在文件资源管理器中选择文件位置,提供名称,然后保存文件。由于这种情况,必须动态提供文件路径。我看过很多SO帖子和文章,但我还没有看到如何做到这一点的明确例子。
如何修改代码以便用户能够指定文件名和路径?
答案 0 :(得分:2)
您无法选择从浏览器中保存文件。您需要提供文件并让他们下载并将其保存在他们喜欢的地方。
此外,您希望部署到可能的生产ASP.NET应用程序的服务器没有安装Excel的副本(即使它确实是互操作会得到一点点混乱的恕我直言)所以你可能想要使用一个openXml库,比如EPPlus。
这可以让你做这样的事情:
public IActionResult ExportData()
{
using (var excel = new ExcelPackage())
{
var wks = excel.Workbook.Worksheets.Add("StudentReportCard");
wks.Cells[1,1].LoadFromCollection(GetStudentRecords(), PrintHeaders:true);
return File(excel.GetAsByteArray(),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx");
};
}
private static IEnumerable<StudentRecord> GetStudentRecords()
{
yield return new StudentRecord
{
Id = 1,
Name = "John",
Subject = "Maths",
Score = 77.9
};
yield return new StudentRecord
{
Id = 2,
Name = "Jane",
Subject = "Maths",
Score = 78.9
};
yield return new StudentRecord
{
Id = 3,
Name = "Jo",
Subject = "Maths",
Score = 99.9
};
}
发送一个名为'export.xlsx'的文件,供用户从浏览器中保存: