【发布时间】:2016-08-04 23:59:46
【问题描述】:
我搜索了高低,发现类似的问题都有类似的答案,但似乎没有一个能解决我的问题。我的最终目标是允许用户将数据表保存到在 excel 中打开(不保存)的 excel 文档中,如果他们愿意,他们可以选择保存它。这可以通过单击用 c# 编写的网页上的按钮来完成。
有很多关于如何做到这一点的例子,有很多不同的方式,其中很多看起来很简单——我似乎无法找到一种在我所处的环境中完全有效的方法(中等信任的生产环境和这不能更改)。
本质上,当在网页上单击一个按钮时,我的代码会使用 EPPlus 创建一个 excel 文件:
ExcelPackage p = new ExcelPackage();
p.Workbook.Worksheets.Add(worksheetname);
ExcelWorksheet workSheet = p.Workbook.Worksheets[1];
workSheet.Cells[1,1].LoadFromDataTable(dt, true);
var range = workSheet.Cells[1,1,dt.Rows.Count,dt.Columns.Count];
var table = workSheet.Tables.Add(range, "results");
table.ShowTotal = false;
table.TableStyle = TableStyles.Medium4;
workSheet.Cells.AutoFitColumns();
workSheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
workSheet.View.ShowGridLines = false;
Response.Clear();
Response.ClearHeaders();
Response.BinaryWrite(p.GetAsByteArray());
//Also tried this instead of above line with same error: p.SaveAs(Response.OutputStream);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=" + filename + ".xlsx");
Response.End();
这段代码看起来很简单,可以在我的机器上本地运行。我单击该按钮,然后收到保存或打开的提示。我选择打开,文件在 Excel 中打开,这正是我的最终用户想要的。然后我将网站复制到我们的开发网络服务器(完全信任),它仍然运行良好。然后我复制到我们的暂存环境,这是中等信任,而不是完全信任并得到以下错误:System.Security.SecurityException Exception Message: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
我不是要保存文件,只是简单地显示给最终用户以便能够在 Excel 中打开它。然后,他们可以根据需要选择从 Excel 应用中另存为。
使用 Excel 互操作执行此操作很简单,而且我也可以在本地运行它,但是如果服务器上没有 Excel,我不认为这是一个可行的选择。因此我决定尝试 EPPlus,这似乎是答案,直到它在我们的暂存环境中不起作用。我能想到的唯一区别是我们的暂存环境是中等信任,而开发环境是完全信任。我需要一个在中等信任下工作的解决方案,但没有我在下面使用 html 尝试的其他选项的错误。
我以前是用html做的,用下面的代码打开,但由于不是真正的excel文件,所以当用户选择打开时,总是报错:“文件格式和扩展名不匹配. 文件可能已损坏或不安全。除非您信任其来源,否则不要打开它。您仍然要打开它吗?"。他们可以直接点击“是”,大多数情况下文件会打开并且表现得很好,其他时候它只会说“无法读取文件”,他们将不得不重新点击按钮——他们已经要求这个错误消失。这是我过去的做法(同样,这在大多数情况下都有效,并且在我们的中等信任环境中工作得很好,但是有那个讨厌的错误)。这就是为什么我决定走创建一个“真正的”excel文件的路线——以避免这个错误。
System.IO.StringWriter tw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
DataGrid dgGrid = new DataGrid();
dgGrid.DataSource = dt;
dgGrid.DataBind();
dgGrid.RenderControl(hw);
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.Expires = 0;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//Also tried these two ways to see if the "file format and extension don't match" error go away-it didn't
//also tried sending in filename with .xls and .xlsx extension with same results
//Response.ContentType = "application/vnd.ms-excel";
//Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename);
this.EnableViewState = false;
Response.Write(tw.ToString());
Response.Flush();
Response.Clear();
Response.End();
任何建议都会很棒!此外,如果有另一个开源工具可以完成这项工作,那也很好。我不能使用任何和所有的开源选项,但如果有人对另一个可以在中等信任下工作的工具提出建议,我可以看看它是否在我公司的批准列表中。
【问题讨论】:
-
不太可能,但请检查一下以防万一ad-thomas.blogspot.com/2013/09/…
-
“填充工作表”这一步是否还涉及任何文件 IO?也许您正在从文件系统中读取一些内容来填充数据?
-
Eric,您提供的链接讨论了在服务器上授予 dll 额外权限,这在我公司的环境中不是一个选项。
-
这是我最初用于填充工作表的代码。它不做任何文件 IO。我只是取一个填充了数据的数据表并将其传输到工作表:
-
@EricJ。抱歉,我不知道如何让我的代码在 cmets 中正确显示,所以我修改了我原来的帖子
标签: c# export-to-excel epplus