2012-01-31 87 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結構相同。

對於保存文檔,你必須使用一個通用處理器:

​​