2012-01-31 84 views
1

问题:保存Excel文档在ASP.NET

我正在使用ASP.NET应用程序的Microsoft.Office.Interop.Excel库,我已经填充在一个工作簿中工作。我希望提示用户将文档保存到他们的机器,但我找不到一个方法来执行它(myWorkbook.SaveAs(...)不起作用)。

问:

我怎样才能获得工作簿保存到用户的机器?我已经使用Response.Write(...)来提示用户保存基于文本的文件(CSV),但我无法弄清楚如何为.xls文件执行此操作。

奖励:

如果这是不可能的使用Microsoft.Office.Interop.Excel库做的,是有一个免费(GPL小-ISH)库我可以使用呢?

我认为微软会对此有一个工具,但我们都知道什么假设呢?

+0

[使用Office 2010的COM asp.net web服务(可能重复http://stackoverflow.com/questions/7382704/asp -net-web-service-using-office-2010-com) – 2012-01-31 19:11:43

+0

您无法从服务进程中使用Office Automation。请参阅http://stackoverflow.com/questions/7382704/asp-net-web-service-using-office-2010-com。 – 2012-01-31 19:12:03

回答

2

像@Jason Meckley说,为了使用互操作在服务器上创建Excel文件,你需要在机器上安装的Office。解决方法:这是使用Open XML:

MSDN page

的Open XML SDK 2.0的Microsoft Office

此SDK是开放XML SDK 1.0的超集。除了Open XML SDK 1.0提供的功能之外,它还利用.NET 语言集成查询(LINQ),并提供类来构造和查询包内部件的内容。您可以使用功能 构造来组合文档,LINQ查询可以从文档中提取 信息。

这里有一对夫妇的 '入门' 的教程,我发现有用:

Formatted Excel using SDK 2.0 and .NET

OpenXML SDK 2.0: Export a DataTable to Excel

+0

我将此功能添加到使用Visual Studio 2005的旧项目中。我仍然可以使用OpenXML吗? – 2012-01-31 19:37:09

+0

@ Onion-Knight - Yep - 以下是MSDN网站上的一些摘录:http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=14386 – zeroef 2012-01-31 20:22:46

2

如果你引用的Excel的互操作性展示则需要先争优安装在服务器上创建Excel上文件。

你不能直接提示用户保存excel文件。该文件在服务器上生成。您需要将文件保存在服务器上,然后将文件加载到内存中,删除文件并将内存流发送到客户端。客户端可以选择保存文件。

相反,我会使用第三方库,可以生成excel文件没有excel。通常他们会生成一个xml-excel文档。工作原理相同,只是将文件创建为xml而不是二进制文件。

我已使用http://www.carlosag.net/tools/excelxmlwriter/多年来取得了巨大成功。我相信还有其他选择。 使用此方法的规则相同。构建工作簿。然后保存到流(不是文件)并将流发送到客户端。客户可以选择如何处理文件。

+0

我试图使用它(使用他们提供的ASP.NET帮助文件创建一个测试文件),但我得到了奇怪的错误:'不能在prolog之外有一个DOCTYPE声明。处理资源错误'Blah.aspx' – 2012-01-31 20:46:48

+0

是的,因为webforms希望你返回html。你正在返回一种不同类型的内容。为此你可以使用一个简单的通用处理程序。 ashx – 2012-01-31 21:35:20

0

尝试......

loConectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + pFullFilePath + 
         ";Extended Properties=\"Excel 12.0;HDR=No;IMEX=2\""; 
fillSourceFromExcel(loConectionString); 
private DataTable _loDtArchivoOrigen = null; 
private void fillSourceFromExcel(string pConectionString) 
{ 
     var loColumnasSelect = new StringBuilder(); 
     using (OleDbConnection oleDbConnection = new OleDbConnection(pConectionString)) 
     { 
      if (oleDbConnection.State == ConnectionState.Closed) oleDbConnection.Open(); 
      DataTable dbSchema = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables_Info, null); 
      DataTable dbColumns = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, dbSchema.Rows[0]["TABLE_NAME"], null }); 
      foreach (DataRow loRow in dbColumns.Rows) 
      { 
       loColumnasSelect.Append(" " + loRow["COLUMN_NAME"].ToString() + " as " + loRow["COLUMN_NAME"].ToString().Replace("F", "a") + ","); 
      } 
      using (OleDbCommand oleDbCommand = new OleDbCommand()) 
      { 
       oleDbCommand.Connection = oleDbConnection; 
       oleDbCommand.CommandText = 
        string.Format(
         "SELECT " + loColumnasSelect.Remove(loColumnasSelect.Length - 1, 1) + 
         " FROM [{0}]", dbSchema.Rows[0]["TABLE_NAME"].ToString()); 
       using (OleDbDataAdapter oleDbDataAdapter = new OleDbDataAdapter()) 
       { 
        oleDbDataAdapter.SelectCommand = oleDbCommand; 
        oleDbDataAdapter.Fill(_loDtArchivoOrigen); 
       } 
      } 
      oleDbConnection.Close(); 
     } 
} 
+1

-1为毫无价值的try/catch块。删除,我会upvote。 – 2012-01-31 19:08:59

0

我想在这种情况下使用EPPlus。它使用简单,几乎与Excel结构相同。

对于保存文档,你必须使用一个通用处理器:

​​