2017-04-02 2 views
1

OpenXml-SDKを使用してExcelファイルをダウンロードして開くC#Azure関数を記述しようとしています。azureファイルをダウンロードしてazure関数でコンテンツを読む

OfficeがAzure機能で利用できないため、Office Interopはここでは機能しません。

OpenXml-SDKを使用してファイルを開いて読み込もうとしていますが、リモートURLからダウンロードしたURLやストリームではなく、保存したファイルへのパスが必要です。

Azure関数でExcelファイルを一時的に格納する方法がわからないことがわかったので、私はAzure File Storageを使用しました。

urlからExcelファイルをAzureファイルストレージにアップロードしましたが、OpenXML-SDKでExcelファイルを開くことができません。

Azure File StorageでExcelファイルをテストしましたが、OpenXML.SpreadsheetDocumentフォームを開くときにファイルが壊れているというエラーが表示されます。

ファイルUri(https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-files#develop-with-file-storage)を渡すSpreadsheetDocumentを開こうとすると、アドレスは260文字の制限を超えます。

私はOpenXML以外のライブラリを使用していますが、理想的にはExcelファイルを保存する必要はありません。

答えて

2

Open XML SDKはAzure機能で正常に動作します。私は私の側でそれをテストしました。ここに完全なコードがあります。 enter image description here

#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 "); 
} 

がOpen XMLを使用するには、あなたがあなたの関数フォルダの下のbinフォルダを作成し、それにDocumentFormat.OpenXml.dllとWindowsBase.dllをアップロードしていることを確認してください。

"File contains corrupted data".

別のエクセルファイルを試して、問題が特定のエクセルファイルに関連しているかどうかを確認しましたか?私はあなたのコードを再度テストするための新しい簡単なエクセルを作成することをお勧めします。

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

Excelファイルをダウンロードして、それがExcelファイルの古いバージョン(.xls)であることが判明しました。

例外を修正するには、Excelを最新バージョン(.xlsx)に変換するか、別のExcel解析ライブラリを選択します。 ExcelDataReaderは任意のバージョンのExcelファイルで動作します。このライブラリをインストールするには、NuGetを使用して 'ExcelDataReader'を検索します。以下は、.xls形式のファイルを解析する方法のサンプルコードです。 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 "); 
} 

上部のコードを実行する前に、あなたの関数のbinフォルダに "Excel.dll" ファイルを追加してください。

+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ファイルです参照してください。私はまた、オフィスinterop COMをローカルで使用したときにファイルを開いて読み込めました。この場合、私はwebclient.DownloadFile(theRemoteUrl、theLocalTempFile)とSpreadsheetDocument.Open(theLocalTempFile、false)を使用しました。ありがとうございました! – donquijote

関連する問題