我如何更新和保存从asp.net mvc excel文件?

我有一个现有的delphi桌面应用程序,我改写为一个asp.net mvc应用程序。

桌面应用程序有大约120个Excel报告。 这些报告通常有几个命名单元格包含设置信息(客户端ID等),一些数据查询返回到SQL Server数据和几个关键表。

为了生成桌面应用程序的报告,我使用ole自动化

  1. 打开报告
  2. 用正确的数据填充命名的单元格
  3. 使用ActiveWorkbook.RefreshAll()更新查询和数据透视表
  4. 保存报告

我想在我的Web应用程序中执行此操作。 但是在服务器上不支持ole自动化,并且不起作用。 我看到的所有的Excel组件都不支持刷新查询和/或关键表。

目前我最好的select似乎是使用一些报告生成器重写报告,并将它们导出为ex​​cel。 然而,生成的文件需要更长的时间才能写入,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工作簿的开源库。

看一眼 NPOI

你是对的,你可能不想在服务器上做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 。