OpenXml-SDKを使用してExcelファイルをダウンロードして開くためのC#Azure関数を作成しようとしています。
Azure FunctionでOfficeを使用できないため、Office相互運用機能はここでは機能しません。
OpenXml-SDKを使用してファイルを開いて読み取ろうとしていますが、URLやリモートURLからダウンロードしたストリームではなく、保存されたファイルへのパスが必要と思われます。
ExcelファイルをAzureFunctionsに一時的に保存する方法がわからないため、Azure FileStorageを使用しました。
ExcelファイルをURLからAzureFile Storageにアップロードしましたが、OpenXML-SDKでExcelファイルを開くことができません。
Azure File StorageでExcelファイルが機能していることをテストしましたが、MemoryStreamからOpenXML.SpreadsheetDocumentを開こうとすると、ファイルが破損していることを示すエラーが表示されます。
ファイルUriを渡してSpreadsheetDocumentを開こうとすると( https://docs.Microsoft.com/en-us/Azure/storage/storage-dotnet-how-to-use-files#develop-with- file-storage )次に、アドレスは260文字の制限を超えます。
私はOpenXML以外のライブラリを使用することにオープンであり、理想的にはExcelファイルを保存する必要がないことを望んでいます。
Open XML SDKは、AzureFunctionで正常に機能します。私は自分の側でそれをテストしました。これが完全なコードです。
#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をアップロードしたことを確認してください。
「ファイルに破損したデータが含まれています」。
別のExcelファイルを試して、問題が特定のExcelファイルに関連しているかどうかを確認しましたか。コードを再度テストするには、新しい単純なExcelを作成することをお勧めします。
「同じ「ファイルに破損したデータが含まれています」というメッセージが表示されたファイルでは機能しませんでした。」
Excelファイルをダウンロードしましたが、古いバージョン(.xls)のExcelファイルであることがわかりました。
例外を修正するには、Excelを最新バージョン(.xlsx)に変換するか、別のExcel解析ライブラリを選択します。 ExcelDataReader は、どのバージョンのExcelファイルでも機能します。 'ExcelDataReader'を検索すると、NuGetを使用してこのライブラリをインストールできます。以下は、.xls形式のExcelファイルを解析する方法のサンプルコードです。 Azure Functionでテストしましたが、正常に機能しました。
#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」ファイルを追加してください。
一時ファイルを保存する必要がある場合、AzureFunctionsには一時フォルダーへのパスを含む%TEMP%
環境変数があります。これは、関数を実行するvmに対してローカルであり、永続化されないフォルダーです。
ただし、ファイルをローカルに/ Azureファイルに保存する必要はありません。 getリクエストへの応答からストリームを取得し、それを 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
}