将 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 下载给用户的主要内容,如果未能解决你的问题,请参考以下文章

我是不是必须将 Azure Blob 存储中的 PDF 文件存储到 OCR 并为其编制索引?

附加 Blob 未正确连接 pdf 页面

使用 powershell 将两个 azure blob 合并为单个 blob

将同一文件的多个 blob 合并为一个以获取原始 pdf 文件

合并和压缩 Azure Blob 存储中的多个大文件

将 Azure BLOB 存储同步到 Amazon S3