2017-04-02 36 views
1

我正在嘗試編寫一個C#Azure函數來下載並使用OpenXml-SDK打開excel文件。下載excel文件並使用azure函數讀取內容

Office Interop在此處不起作用,因爲辦公室不適用於Azure功能。

我想使用的OpenXML SDK來打開並閱讀這似乎需要對保存的文件,而不是網址或從遠程URL下載一個流的路徑中的文件。

鑑於我不知道的方式臨時存儲在Azure的功能Excel文件,我使用Azure的文件存儲。

我上傳從網址到Azure的文件存儲在Excel文件,但我無法打開Excel用的OpenXML SDK文件。

我測試了Azure文件存儲中的excel文件正在工作,但是,當我嘗試打開OpenMessage.SpreadsheetDocument窗體的MemoryStream時出現錯誤,指示文件已損壞。

如果我嘗試打開SpreadsheetDocument傳遞文件URI(https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-files#develop-with-file-storage),那麼地址通過260個字符的限制。

我願意用比其他的OpenXML圖書館和理想我寧願不具備存儲Excel文件。

回答

2

Open XML SDK在Azure功能中正常工作。我在我身邊測試了它。這是完整的代碼。

#r "DocumentFormat.OpenXml.dll" 
#r "WindowsBase.dll" 

using System.Net; 
using System.IO; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log) 
{ 
    log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}"); 

    WebClient client = new WebClient(); 

    byte[] buffer = client.DownloadData("http://amor-webapp-test.azurewebsites.net/Content/hello.xlsx"); 
    MemoryStream stream = new MemoryStream(); 
    stream.Write(buffer, 0, buffer.Length); 
    stream.Position = 0; 
    using (SpreadsheetDocument doc = SpreadsheetDocument.Open(stream, false)) 
    { 
     WorkbookPart workbookPart = doc.WorkbookPart; 
     SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First(); 
     SharedStringTable sst = sstpart.SharedStringTable; 

     WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); 
     Worksheet sheet = worksheetPart.Worksheet; 

     var cells = sheet.Descendants<Cell>(); 
     var rows = sheet.Descendants<Row>(); 

     log.Info(string.Format("Row count = {0}", rows.LongCount())); 
     log.Info(string.Format("Cell count = {0}", cells.LongCount())); 

     // One way: go through each cell in the sheet 
     foreach (Cell cell in cells) 
     { 
      if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString)) 
      { 
       int ssid = int.Parse(cell.CellValue.Text); 
       string str = sst.ChildElements[ssid].InnerText; 
       log.Info(string.Format("Shared string {0}: {1}", ssid, str)); 
      } 
      else if (cell.CellValue != null) 
      { 
       log.Info(string.Format("Cell contents: {0}", cell.CellValue.Text)); 
      } 
     } 
    } 

    return req.CreateResponse(HttpStatusCode.OK, "Hello "); 
} 

enter image description here

使用Open XML,請確保您有您的功能文件夾下創建一個bin文件夾,並上傳DocumentFormat.OpenXml.dll和WindowsBase.dll中它。

"File contains corrupted data".

你試過另一個Excel文件來檢查問題是否與特定的Excel文件。我建議你創建一個新的簡單的Excel來再次測試你的代碼。

"It didn't work on my file with the same "File contains corrupted data" message. "

我下載了你的excel文件,發現它是excel文件的舊版本(.xls)。

要修復異常,可以將excel轉換爲最新版本(.xlsx)或選擇另一個excel解析庫。 ExcelDataReader可以用於任何版本的Excel文件。你可以通過搜索'ExcelDataReader'來使用NuGet來安裝這個庫。以下是如何解析.xls格式excel文件的示例代碼。我在Azure功能上測試它,它確實工作正常。

#r "Excel.dll" 
#r "System.Data" 

using System.Net; 
using System.IO; 
using Excel; 
using System.Data; 

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log) 
{ 
    log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}"); 

    WebClient client = new WebClient(); 

    byte[] buffer = client.DownloadData("http://amor-webapp-test.azurewebsites.net/Content/abcdefg.xls"); 
    MemoryStream stream = new MemoryStream(); 
    stream.Write(buffer, 0, buffer.Length); 
    stream.Position = 0; 

    IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream); 

    DataSet result = excelReader.AsDataSet(); 

    for (int i = 0; i < result.Tables.Count; i++) 
    { 
     log.Info(result.Tables[i].TableName +" has " + result.Tables[i].Rows.Count + " rows."); 
    } 

    return req.CreateResponse(HttpStatusCode.OK, "Hello "); 
} 

請執行上面的代碼前加 「Excel.dll」 文件到你的函數的bin文件夾。

+0

感謝您的詳細代碼。它沒有在我的文件上使用相同的「文件包含損壞的數據」消息。在這一點上,我的問題的Azure功能方面已明確解決。我已經能夠下載該文件並在Excel中打開它。我還能夠在本地使用Office interop COM正確下載,讀取和解析它。在這一點上,問題可能與OpenXML有關。如果您可以使用我的文件進行測試,那將是非常好的:http://www2.nationalgrid.com/WorkArea/DownloadAsset.aspx?id=8589936879或者如果您會推薦OpenXML的替代方案。謝謝vm – donquijote

+0

感謝您的反饋。我根據您的評論更新了我的回覆。 – Amor

+0

未安裝的字體如何? –

2

如果您還需要保存臨時文件,Azure的功能有一個臨時文件夾的路徑%TEMP%環境變量。這是運行你的函數的vm本地的文件夾,不會被保存。

但是,將文件保存在本地/ Azure文件中是不必要的。您應該能夠從您的獲取請求的響應中獲得流,並將其直接傳遞給OpenXML

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(originalExcelUrl); 
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
using (Stream stream = response.GetResponseStream()) 
{ 
    var doc = SpreadsheetDocument.Open(stream, true); 
    // etc 
} 
+0

謝謝,我試過你粘貼的代碼,但它崩潰了。我用var doc = SpreadsheetDocument.Open(stream,false); (由於originalExcelUrl是網站中的鏈接,因此「true」不起作用)。錯誤消息是:「無法在不支持查找的流上操作」。我同意我不希望將文件存儲在臨時位置。你之前看過這個錯誤嗎?非常感謝 – donquijote

+0

隨着Temp變量的方法,我能夠在本地存儲文件,但然後嘗試在OpenXML中打開我會得到錯誤:「文件包含損壞的數據」。但是我看到本地Temp文件夾中的文件是一個可以打開的excel文件。當我在本地使用office interop COM時,我也能夠打開並讀取文件。在這種情況下,我只使用webclient.DownloadFile(theRemoteUrl,theLocalTempFile),然後SpreadsheetDocument.Open(theLocalTempFile,false)再次感謝! – donquijote

相關問題