我如何更新和保存从asp.net mvc excel文件?
我有一个现有的delphi桌面应用程序,我改写为一个asp.net mvc应用程序。
桌面应用程序有大约120个Excel报告。 这些报告通常有几个命名单元格包含设置信息(客户端ID等),一些数据查询返回到SQL Server数据和几个关键表。
为了生成桌面应用程序的报告,我使用ole自动化
- 打开报告
- 用正确的数据填充命名的单元格
- 使用ActiveWorkbook.RefreshAll()更新查询和数据透视表
- 保存报告
我想在我的Web应用程序中执行此操作。 但是在服务器上不支持ole自动化,并且不起作用。 我看到的所有的Excel组件都不支持刷新查询和/或关键表。
目前我最好的select似乎是使用一些报告生成器重写报告,并将它们导出为excel。 然而,生成的文件需要更长的时间才能写入,function更less(没有关键表格),当然还有120个文件。
有关如何使用现有报告的build议?
更新
Excel安装在服务器上,与开发机器上的版本相同。
我的mvc代码是这样的:
objApp = new Application(); objBooks = objApp.Workbooks; objBook = objBooks.Open(FileName); objApp.DisplayAlerts = false; // don't warn if pivot table changed objApp.ActiveWorkbook.RefreshAll(); objBook.SaveAs(newFileName);
在开发机器上它工作正常,但在服务器上,它在第一行失败
objApp = new Application();
与System.UnauthorizedAccessException:检索具有CLSID {00024500-0000-0000-C000-000000000046}的组件的COM类工厂失败,原因如下:80070005访问被拒绝。 (从HRESULTexception:0x80070005(E_ACCESSDENIED))。
这是一个非常常见的错误,但需要在服务器上设置一些用于ASP.NET的项目。 通常,对此线程的build议就足够了: System.UnauthorizedAccessException:为Word Interop检索COM类工厂失败,错误为80070005 。
这似乎并没有得到妥善和彻底的处理。 后期约束也可能成为问题的一部分。
我没有使用图表,但是我完全推荐EPPlus ,它是一个用于创buildExcel工作簿的开源库。
看一眼
你是对的,你可能不想在服务器上做OLE自动化。 只是内存泄漏的风险和在后台运行非托pipe的Excel实例是不行的。
我们与Aspose.Cells有良好的经验。 也许它支持你正在寻找的刷新function?
也许你在几个月前遇到了同样的问题。 问题是,默认情况下Microsoft Excel作为COM对象只能由pipe理员,系统或交互式帐户激活。
这是一个详细的解决scheme,为我工作: http : //blog.crowe.co.nz/archive/2006/03/02/589.aspx
希望这可以帮助。
PS:怎么样OLE DB,是否有可能改变你的代码使用OleDbConnection?
几个月前,我发现这个类,我用excel写入excel。 它像一个魅力,我用它在很多ASP.net应用程序。 我真的不记得我在哪里,所以我不能给这个人创造,即使他们应得的全部。
/// <summary> /// Produces Excel file without using Excel /// </summary> public class ExcelWriter { private Stream stream; private BinaryWriter writer; private ushort[] clBegin = { 0x0809, 8, 0, 0x10, 0, 0 }; private ushort[] clEnd = { 0x0A, 00 }; private void WriteUshortArray(ushort[] value) { for (int i = 0; i < value.Length; i++) writer.Write(value[i]); } /// <summary> /// Initializes a new instance of the <see cref="ExcelWriter"/> class. /// </summary> /// <param name="stream">The stream.</param> public ExcelWriter(Stream stream) { this.stream = stream; writer = new BinaryWriter(stream); } /// <summary> /// Writes the text cell value. /// </summary> /// <param name="row">The row.</param> /// <param name="col">The col.</param> /// <param name="value">The string value.</param> public void WriteCell(int row, int col, string value) { ushort[] clData = { 0x0204, 0, 0, 0, 0, 0 }; int iLen = value.Length; byte[] plainText = Encoding.ASCII.GetBytes(value); clData[1] = (ushort)(8 + iLen); clData[2] = (ushort)row; clData[3] = (ushort)col; clData[5] = (ushort)iLen; WriteUshortArray(clData); writer.Write(plainText); } /// <summary> /// Writes the integer cell value. /// </summary> /// <param name="row">The row number.</param> /// <param name="col">The column number.</param> /// <param name="value">The value.</param> public void WriteCell(int row, int col, int value) { ushort[] clData = { 0x027E, 10, 0, 0, 0 }; clData[2] = (ushort)row; clData[3] = (ushort)col; WriteUshortArray(clData); int iValue = (value << 2) | 2; writer.Write(iValue); } /// <summary> /// Writes the double cell value. /// </summary> /// <param name="row">The row number.</param> /// <param name="col">The column number.</param> /// <param name="value">The value.</param> public void WriteCell(int row, int col, double value) { ushort[] clData = { 0x0203, 14, 0, 0, 0 }; clData[2] = (ushort)row; clData[3] = (ushort)col; WriteUshortArray(clData); writer.Write(value); } /// <summary> /// Writes the empty cell. /// </summary> /// <param name="row">The row number.</param> /// <param name="col">The column number.</param> public void WriteCell(int row, int col) { ushort[] clData = { 0x0201, 6, 0, 0, 0x17 }; clData[2] = (ushort)row; clData[3] = (ushort)col; WriteUshortArray(clData); } /// <summary> /// Must be called once for creating XLS file header /// </summary> public void BeginWrite() { WriteUshortArray(clBegin); } /// <summary> /// Ends the writing operation, but do not close the stream /// </summary> public void EndWrite() { WriteUshortArray(clEnd); writer.Flush(); } }
只需将此代码复制到.cs文件。
这是一个例子
ExcelWriter writer = null; FileStream stream = null; string result = string.Empty; string filepath = path; DateTime sd = Convert.ToDateTime(sdate); DateTime ed = Convert.ToDateTime(edate); string daterange = sd.Month.ToString() + sd.Day.ToString() + sd.Year.ToString() + "_" + ed.Month.ToString() + ed.Day.ToString() + ed.Year.ToString(); string xls = filepath + filename + "_" + daterange + ".xls"; if (File.Exists(xls)) { File.Delete(xls); } stream = new FileStream(xls, FileMode.Create); writer = new ExcelWriter(stream); writer.BeginWrite(); //write header writer.WriteCell(0, 0, "text"); writer.WriteCell(0, 1, "text"); writer.WriteCell(0, 2, "text"); //write data int row = 1; //Open Connection OpenDBConnection(); //get Case List List<Int32> caseList = getCaseList(sdate, edate); foreach (Int32 caseid in caseList) { writer.WriteCell(row, 0, caseid); writer.WriteCell(row, 1, caseid); writer.WriteCell(row, 2, caseid); row++; } writer.EndWrite(); stream.Close();`
你是对的,MS绝对不支持。 但是,自动化应该在服务器上工作。 这是愚蠢的问题,你有服务器上安装的Excel? 你能发送你的示例代码? 我通常使用interop。 这里是一个简单的例子: http : //dotnetperls.com/excel 。