You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SAS在Blob存储中跨文件夹复制文件(基于Azure.Storage.Blobs)

实现方案:Blob内模板处理+结果上传(无本地下载)

核心思路

因为需要在Blob环境下完成邮件合并+结果存储,无法直接用Blob间的异步复制(中间需要文档加工),所以采用「内存流中转」的方式:读取模板Blob到内存流→SyncFusion处理→将处理后的流上传到目标Blob,全程不落地本地文件。

步骤1:配置依赖与权限

  • 安装NuGet包:
    • Azure.Storage.Blobs(Blob存储操作)
    • Syncfusion.DocIO.Net.Core(邮件合并,若为.NET Framework项目可替换为Syncfusion.DocIO.WinForms)
  • 确保SAS URI拥有模板Blob的读取权限和结果Blob的写入权限,推荐使用容器级SAS(覆盖Templates和Results文件夹)。

步骤2:代码实现

初始化容器客户端

用SAS URI创建容器客户端:

using Azure.Storage.Blobs;
using Syncfusion.DocIO.DLS;
using System.IO;

// 替换为你的容器级SAS URI
string containerSasUri = "https://yourstorageaccount.blob.core.windows.net/yourcontainer?sv=2023-11-03&ss=b&srt=c&sp=rwdlacupiytfx&se=2024-12-31T23:59:59Z&st=2024-01-01T00:00:00Z&spr=https&sig=xxx";
BlobContainerClient containerClient = new BlobContainerClient(new Uri(containerSasUri));

读取模板Blob到内存流

// 模板Blob路径,示例:Templates/invoice-template.docx
string templateBlobPath = "Templates/invoice-template.docx";
BlobClient templateBlobClient = containerClient.GetBlobClient(templateBlobPath);

MemoryStream templateStream = new MemoryStream();
await templateBlobClient.DownloadToAsync(templateStream);
templateStream.Position = 0; // 重置流指针,供SyncFusion读取

SyncFusion邮件合并处理

复用你本地已实现的邮件合并逻辑,直接基于内存流操作:

using WordDocument document = new WordDocument(templateStream, FormatType.Docx);

// 替换为你的实际邮件合并数据源
var mergeData = new List<Dictionary<string, string>>()
{
    new Dictionary<string, string>()
    {
        {"CustomerName", "张三"},
        {"InvoiceNumber", "INV-2024-001"},
        {"Amount", "1500.00"}
    }
};

// 执行邮件合并
document.MailMerge.Execute(mergeData);

// 将处理后的文档写入新内存流
MemoryStream resultStream = new MemoryStream();
document.Save(resultStream, FormatType.Docx);
resultStream.Position = 0; // 重置流指针,供Blob上传使用

上传处理后的结果到Results文件夹

// 结果Blob路径,示例:Results/invoice-2024-001.docx
string resultBlobPath = $"Results/invoice-{mergeData[0]["InvoiceNumber"]}.docx";
BlobClient resultBlobClient = containerClient.GetBlobClient(resultBlobPath);

// 上传内存流到Blob
await resultBlobClient.UploadAsync(resultStream, overwrite: true);

批量处理模板示例

如果需要处理Templates文件夹下的所有模板:

public async Task ProcessAllTemplates(string containerSasUri)
{
    BlobContainerClient containerClient = new BlobContainerClient(new Uri(containerSasUri));
    
    // 列出Templates文件夹下的所有文件Blob(跳过文件夹本身)
    await foreach (BlobItem blobItem in containerClient.GetBlobsAsync(prefix: "Templates/"))
    {
        if (blobItem.Name.EndsWith("/")) continue;
        string templateName = Path.GetFileName(blobItem.Name);
        
        // 读取模板流
        MemoryStream templateStream = new MemoryStream();
        await containerClient.GetBlobClient(blobItem.Name).DownloadToAsync(templateStream);
        templateStream.Position = 0;
        
        // SyncFusion邮件合并(替换为你的业务逻辑)
        using WordDocument document = new WordDocument(templateStream, FormatType.Docx);
        var mergeData = GetMergeData(templateName); // 自定义方法获取对应模板的数据源
        document.MailMerge.Execute(mergeData);
        
        // 生成结果流
        MemoryStream resultStream = new MemoryStream();
        document.Save(resultStream, FormatType.Docx);
        resultStream.Position = 0;
        
        // 上传结果
        string resultBlobPath = $"Results/{Path.GetFileNameWithoutExtension(templateName)}-{Guid.NewGuid()}.docx";
        await containerClient.GetBlobClient(resultBlobPath).UploadAsync(resultStream, overwrite: true);
        
        // 清理流资源
        templateStream.Dispose();
        resultStream.Dispose();
    }
}

// 自定义方法:根据模板名称返回对应数据源
private List<Dictionary<string, string>> GetMergeData(string templateName)
{
    // 替换为你的实际数据逻辑
    return new List<Dictionary<string, string>>()
    {
        new Dictionary<string, string>()
        {
            {"Field1", "Value1"},
            {"Field2", "Value2"}
        }
    };
}

关键注意事项

  • 流指针重置:每次读取或写入流后,必须将Position设为0,否则后续操作会从流的末尾开始,导致读取空内容。
  • SAS权限:确保SAS的sp参数包含r(读取模板)和w(写入结果),若需列出Blob需额外添加l。
  • 内存优化:处理大文档时,可使用临时FileStream替代MemoryStream,避免内存溢出;也可结合SyncFusion的分块处理API。
  • SyncFusion许可证:确保已配置有效许可证,避免处理后的文档出现水印。

内容的提问来源于stack exchange,提问作者user3792804

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:13:16