将 Azure Blob (PDF) 合并到一个 Blob 中并通过 C# ASP.NET 下载给用户

Posted

技术标签:

【中文标题】将 Azure Blob (PDF) 合并到一个 Blob 中并通过 C# ASP.NET 下载给用户【英文标题】:Merge Azure Blobs (PDFs) into one Blob and download to user via C# ASP.NET 【发布时间】:2021-12-31 14:01:30 【问题描述】:

我有一个用 C# 编写的 ASP.NET Azure Web 应用程序,它涉及用户将不同的 pdf 文件上传到 Azure Blob 存储。我希望用户稍后以特定顺序下载包含先前上传的 blob 的组合 PDF。对实现此目的的最佳方法有任何想法吗?

【问题讨论】:

您是否已将其分解为更小的组件并进行了尝试?下载所有相关的 blob,使用库来组合 PDF,将生成的文件提供给用户?你有什么问题? Stack Overflow 不只是在这里为您编写代码,因此您应该尝试一下。如果您遇到困难,请提供minimal reproducible example,然后您就会有一个有效的问题。 @mason,感谢您的评论。我按照 SwethaKandikonda-MT 的概述创建了一个 Azure 函数,它取得了成功。我了解您对我的一般性询问不满意,尽管这是为了征求不同的回应。最好的问候。 我对你的问题是否满意无关紧要。更重要的是,您了解在这里提出问题的人的期望。我们不是在这里概述如何做事。由你来分解你的问题,计划你需要做的事情,并尝试实施它们。如果你被某个特定部分卡住了,你需要解释你在做什么,什么对你的尝试不起作用。每次。这不是为了取悦任何人,而是为了满足网站的要求。 【参考方案1】:

您可以尝试以下两种解决方法

    Azure 函数的使用。 将 pdf 文件从 Azure Blob 下载到本地计算机,然后合并它们。

Azure 函数的使用

    创建一个 azure 函数项目并使用 HTTP 触发器。 确保在开始编码之前安装以下软件包。 创建函数代码。 在门户中创建 Azure 函数。 发布代码。

我们已经准备好开始编写代码了。我们需要两个文件:

    ResultClass.cs – 将合并的文件作为列表返回。 Function1.cs – CCode 从 URL 中获取文件名,从存储帐户中获取它们,将它们合并为一个,然后返回下载 URL。

ResultClass.cs

using System;
using System.Collections.Generic;

namespace FunctionApp1


    public class Result
    

        public Result(IList<string> newFiles)
        
            this.files = newFiles;
        

        public IList<string> files  get; private set; 
    

Function1.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;

namespace FunctionApp1

    public class Function1
    

        static Function1()
        

            // This is required to avoid the "No data is available                         for encoding 1252" exception when saving the PdfDocument
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

        

        [FunctionName("Function1")]
        public async Task<Result> SplitUploadAsync(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestMessage req,
            //container where files will be stored and accessed for retrieval. in this case, it's called temp-pdf
            [Blob("temp-pdf", Connection = "")] CloudBlobContainer outputContainer,
            ILogger log)
        
            //get query parameters

            string uriq = req.RequestUri.ToString(); 
            string keyw = uriq.Substring(uriq.IndexOf('=') + 1);

            //get file name in query parameters
            String fileNames = keyw.Split("mergepfd&filenam=")[1];

            //split file name
            string[] files = fileNames.Split(',');

            //process merge
            var newFiles = await this.MergeFileAsync(outputContainer, files);

            return new Result(newFiles);

        

        private async Task<IList<string>> MergeFileAsync(CloudBlobContainer container, string[] blobfiles)
        
            //init instance
            PdfDocument outputDocument = new PdfDocument();

            //loop through files sent in query
            foreach (string fileblob in blobfiles)
            
                String intfile = $"" + fileblob;

                // get file
                CloudBlockBlob blob = container.GetBlockBlobReference(intfile);

                using (var memoryStream = new MemoryStream())
                
                    await blob.DownloadToStreamAsync(memoryStream);

                    //get file content
                    string contents = blob.DownloadTextAsync().Result;
                   
                    //open document
                    var inputDocument = PdfReader.Open(memoryStream, PdfDocumentOpenMode.Import);

                    //get pages
                    int count = inputDocument.PageCount;
                    for (int idx = 0; idx < count; idx++)
                    
                        //append
                        outputDocument.AddPage(inputDocument.Pages[idx]);
                    


                
            


            var outputFiles = new List<string>();
            var tempFile = String.Empty;

            //call save function to store output in container
            tempFile = await this.SaveToBlobStorageAsync(container, outputDocument);

            outputFiles.Add(tempFile);

            //return file(s) url
            return outputFiles;
        

        private async Task<string> SaveToBlobStorageAsync(CloudBlobContainer container, PdfDocument document)
        

            //file name structure
            var filename = $"merge-DateTime.Now.ToString("yyyyMMddhhmmss")-Guid.NewGuid().ToString().Substring(0, 4).pdf";

            // Creating an empty file pointer
            var outputBlob = container.GetBlockBlobReference(filename);

            using (var stream = new MemoryStream())
            
                //save result of merge
                document.Save(stream);
                await outputBlob.UploadFromStreamAsync(stream);
            

            //get sas token
            var sasBlobToken = outputBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
            
                SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
                Permissions = SharedAccessBlobPermissions.Read
            );

            //return sas token
            return outputBlob.Uri + sasBlobToken;
        
    

将 pdf 文件从 Azure Blob 下载到本地计算机,然后合并它们

 internal static void combineNormalPdfFiles()
        
            String inputFilePath1 = @"C:\1.pdf";
            String inputFilePath2 = @"C:\2.pdf";
            String inputFilePath3 = @"C:\3.pdf";
            String outputFilePath = @"C:\Output.pdf";
            String[] inputFilePaths = new String[3]  inputFilePath1, inputFilePath2, inputFilePath3 ;

            // Combine three PDF files and output.
            PDFDocument.CombineDocument(inputFilePaths, outputFilePath);
        

参考:

    Azure Function to combine PDF Blobs in Azure Storage Account (Blob container) C# Merge PDF SDK: Merge, combine PDF files in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF

【讨论】:

SwethaKandikonda-MT,这是一个了不起的解决方案,我已成功将其整合到我的网站中。我衷心感谢您的回复!在您发表评论之前,我没有使用过 Azure Functions,但我现在知道的更多了。在此之前,我几乎放弃了将上传的 azure blob PDF 订购和编译成一个 PDF。 如果我的回答对您有帮助,您可以接受它作为答案(单击答案旁边的复选标记,将其从灰色切换为填写)。这对其他社区成员可能是有益的。谢谢

以上是关于将 Azure Blob (PDF) 合并到一个 Blob 中并通过 C# ASP.NET 下载给用户的主要内容,如果未能解决你的问题,请参考以下文章