使用epplus从blob触发器azure函数访问excel文件



我已经创建了一个blob触发器azure函数,每当一个新文件(在我的情况下只有excel文件)被添加到blob存储时调用。有没有人建议如何从blob存储中获取文件的数据,并使用epplus将其转换为excel。

public void Run([BlobTrigger("myblobcontainer/{name}", Connection = "AzureStorage")]CloudBlockBlob myBlob, string name, ILogger log)
{
try
{
ProcessData(myBlob,name);
}
catch (Exception ex)
{
}
}
public int ProcessData(CloudBlockBlob myBlob, string name)
{
CloudStorageAccount IMAccount;
IMAccount = CloudStorageAccount.Parse("my azure storage connection");
var blobReference= //Get the path of file in blob
//Basically here I want to read 'myBlob' and convert it back into excel
}

我有点困惑如何在blob中获得文件的路径(在var blobReference中)并使用epplus将其转换为excel。谁来告诉我怎么做?

下面的示例代码将帮助您将我的excel数据从一个集合填充到您的blob容器,并创建一个新的CloudBlockBlob

[FunctionName("WriteExcelToBlob")]
public async Task Run(
[TimerTrigger("*/30 * * * * *")] TimerInfo timer,
[Blob("excelFiles", FileAccess.Write, Connection = "Storage")] CloudBlobContainer blobContainer,
ILogger log
)
{
var fileNameSuffix = DateTime.Now.ToString("yyyyMMdd_HHmmss");
var myCollection = new List<MyObject>();
var newBlobName = $"myFile_{fileNameSuffix}.xlsx";
var newBlob = blobContainer.GetBlockBlobReference(newBlobName);
using (var excel = new ExcelPackage())
{
var worksheet = excel.Workbook.Worksheets.Add("My Worksheet");
worksheet.Cells.LoadFromCollection(myCollection);
using (var stream = await newBlob.OpenWriteAsync())
{
excel.SaveAs(stream);
}
}
}
下面是使用类 的例子
using System.ComponentModel;
public class MyObject
{
[Description("Name")]
public string Name { get; set; }
[Description("Home Address")]
public string HomeAddress { get; set; }
}

链接EPPlus自定义标题列名将显示如何在输出excel中获取System.ComponentModel.Description的标题

正如DeepDave-MT建议的那样,我们不能直接从Blob中读取excel,我们需要下载它,下面是下载它的示例代码。

string connectionString = "";
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("test");
BlobClient blobClient = containerClient.GetBlobClient("sample.xlsx");

ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (var stream = await blobClient.OpenReadAsync(new BlobOpenReadOptions(true)))
using (ExcelPackage package = new ExcelPackage(stream))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets.FirstOrDefault();
int colCount = worksheet.Dimension.End.Column;  //get Column Count
int rowCount = worksheet.Dimension.End.Row;     //get row count
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value.ToString().Trim());
}
}

}


}

查看SO1和SO2。

如果您不想在文件存储到Blob中时立即读取文件,则需要使用BlobTrigger。下面是如何设置函数-

[FunctionName("XlsxFunction")]
public static async Task ReadXlsx(
[BlobTrigger("mycontainer/{fileName}.xlsx", Connection = "MyBlobConnection")] Stream file, string fileName,
ILogger log)
{
//install EPPlus nuget
//using OfficeOpenXml; 
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (var package = new ExcelPackage(file))
{
var worksheet = package.Workbook.Worksheets[0];

for(int row = 0; row < worksheet.Dimension.End.Row; row++)
{
for(int col = 0; col < worksheet.Dimension.End.Column; col++)
{
//process things;
}
}
//final thing here & save;
}
}

我从未使用过EPPlus,但这是如何开始使用库读取文件。

注意:

  1. 为了避免读取不必要的非excel文件,您可以看到我包含了.xlsx
  2. 您将需要EPPlus许可证才能将该库用于商业目的。除此之外,请注意,在商业公司内部使用库(仅用于内部目的)也需要商业许可证。有关EPPlus许可证的更多信息- https://www.epplussoftware.com/en/LicenseOverview/LicenseFAQ

你可以按照自述文件这里有不同的方式来添加许可证- https://github.com/EPPlusSoftware/EPPlus

最后,

在BlobTrigger中,我添加了Connection="MyBlobConnection",这意味着我需要在local.settings.json (&函数发布到Azure后的应用程序环境配置)。

它看起来像这样-

{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"MyBlobConnection": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}

从上面,注意你可以使用" azurewebjobsstorage;直接,而不是自定义的"myblobconnection"。这取决于您的用例。您的blob连接字符串可以在Azure门户的Azure存储服务中找到。有关更多信息-到Azure云存储帐户的连接字符串

另外,请注意我已经捕获了"fileName"用BlobTrigger。您可以使用它来确保如果文件名不是您所期望的,则不会运行代码。

。您可以在函数方法的开头添加此条件-

if(!fileName.Contains("accounts")) return;
// continue the processing of data;