乐笄扬 发表于 2023-6-16 18:17:50

.net core使用Html模板转PDF文件并下载的业务类封装

  前言:我这里文件下载的模板选型优先考虑html模板,上手容易,前后端通用,有了模板后就需要有转换了,html转PDF采用第三方包:SelectPdf,下面是代码核心类:
 
  1-PDFService:
using Microsoft.AspNetCore.Hosting;
using SelectPdf;

namespace MeShop.Domain.PDF
{
    /// <summary>
    /// PDF业务类
    /// </summary>
    public class PDFService
    {
      private readonly IHostingEnvironment hostingEnvironment;

      public PDFService(IHostingEnvironment hostingEnvironment)
      {
            this.hostingEnvironment = hostingEnvironment;
      }


      /// <summary>
      /// 将Html替换参数后转成PDF字节流
      /// </summary>
      /// <param name="htmlFilePath">html模板文件路径</param>
      /// <param name="saveFileName">PDF文件名</param>
      /// <param name="replaceParamDic">变量替换字典</param>
      /// <returns></returns>
      public async Task<string> HtmlToPDFFile(string htmlFilePath, string saveFileName, Dictionary<string, string> replaceParamDic)
      {
            HtmlToPdf Renderer = new HtmlToPdf();
            //设置Pdf参数
            //设置页面方式-横向PdfPageOrientation.Portrait竖向
            Renderer.Options.PdfPageOrientation = PdfPageOrientation.Landscape;
            //设置页面大小,30种页面大小可以选择
            Renderer.Options.PdfPageSize = PdfPageSize.A4;
            //上下左右边距设置
            Renderer.Options.MarginTop = 10;
            Renderer.Options.MarginBottom = 10;
            Renderer.Options.MarginLeft = 10;
            Renderer.Options.MarginRight = 10;

            //设置更多额参数可以去HtmlToPdfOptions里面选择设置
            //根据html内容导出PDF
            string docHtml = await File.ReadAllTextAsync(htmlFilePath, Encoding.UTF8);
            foreach (var item in replaceParamDic)
            {
                docHtml = docHtml.Replace(item.Key, item.Value);
            }

            PdfDocument pdfDocument = Renderer.ConvertHtmlString(docHtml);
            string saveFilePath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{saveFileName}";
            if (File.Exists(saveFilePath))
            {
                File.Delete(saveFilePath);
            }
            pdfDocument.Save(saveFilePath);

            return saveFilePath;
      }

      /// <summary>
      /// 读取文件字节流
      /// </summary>
      /// <param name="filePath">资源文件(包含路径)</param>
      /// <param name="isDeleteSourceFile">是否删除资源文件</param>
      /// <returns></returns>
      public async Task<byte[]> GetByteByFile(string? filePath, bool isDeleteSourceFile = false)
      {
            byte[]? myByteArray = null;
            if (filePath != null && File.Exists(filePath))
            {
                using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
                {
                  fileStream.Seek(0, SeekOrigin.Begin);
                  myByteArray = new byte;
                  await fileStream.ReadAsync(myByteArray, 0, (int)fileStream.Length);
                }
                if (isDeleteSourceFile)
                {
                  File.Delete(filePath);
                }
            }

            return myByteArray ?? new byte;
      }


      /// <summary>
      /// 压缩多个文件为zip文件
      /// </summary>
      /// <param name="zipFileName">zip压缩文件名</param>
      /// <param name="filePaths">资源文件列表(包含路径)</param>
      /// <param name="isDeleteSourceFile">是否删除资源文件</param>
      /// <returns></returns>
      public string CompressFileToZip(string zipFileName, string[] filePaths, bool isDeleteSourceFile = false)
      {
            string? zipFilePath = null;
            if (!string.IsNullOrWhiteSpace(zipFileName) && filePaths.Length > 0)
            {
                string zipDirectoryPath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}";
                if (!Directory.Exists(zipDirectoryPath))
                {
                  Directory.CreateDirectory(zipDirectoryPath);
                }

                zipFilePath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\Download\{zipFileName}";
                if (File.Exists(zipFilePath))
                {
                  File.Delete(zipFilePath);
                }

                foreach (var filePath in filePaths)
                {
                  string? fileName = filePath.Split('\\').LastOrDefault();
                  string copyFilePath = @$"{zipDirectoryPath}\{fileName}";
                  if (isDeleteSourceFile)
                  {
                        File.Move(filePath, copyFilePath);
                  }
                  else
                  {
                        File.Copy(filePath, copyFilePath);
                  }
                }
                CompressionHelper.Compression(zipDirectoryPath, zipFilePath);

                //压缩完成后,删除压缩使用文件夹及其子项
                Directory.Delete(zipDirectoryPath, true);
            }
            return zipFilePath ?? "";
      }
    }
}   2-控制器方法示例:

public async Task<JsonModel<byte[]>> DownloadSettlement(string settlementIDS)
{
    byte[]? byteArray = null;
    string[] settlementIDArray = settlementIDS.Split(',');

    string templateHtmlPath = @$"{this.hostingEnvironment.ContentRootPath}\staticfiles\agentusersettlement.html";
    List<string> zipSaveFilePathList = new List<string>(settlementIDArray.Length);

    Base_shop baseShop = await this.shopService.GetBaseShopAsync();
    foreach (var item in settlementIDArray)
    {
      long settlementID = TypeParseHelper.StrToInt64(item);
      ResponseAgentUserSettlementDetail? detail = await this.agentUserSettlementService.GetDetailAsync(settlementID);
      if (detail != null)
      {
            Agent_user agentUser = await this.agentUserService.GetAsync(detail.AgentUserID) ?? new Agent_user();

            Dictionary<string, string> replaceDic = new Dictionary<string, string>()
            {
                {"@InvoiceNumber@",$"{detail.UpdateTime.ToString("yyyyMMdd")}{detail.ID}" },
                {"@UpdateTime@",$"{detail.UpdateTime.ToString("yyyyMMdd")}" },
                {"@AgentUserCompanyName@",$"{agentUser.CompanyName}" },
                {"@AgentUserCompanyAddress@",$"{agentUser.CompanyAddress}" },
                {"@BeginDate@",$"{detail.BeginDate.ToString("yyyy/MM/dd")}" },
                {"@EndDate@",$"{detail.EndDate.ToString("yyyy/MM/dd")}" },
                {"@TotalPoint@",$"{detail.TotalPoint.ToString("F3")}" },
                {"@AccountCompanyName@",$"{baseShop.CompanyName}" },
                {"@AccountCompanyAddress@",$"{baseShop.CompanyAddress}" },
                {"@AccountEmail@",$"{baseShop.ServiceEmail}" }
            };

            zipSaveFilePathList.Add(await this.pdfService.HtmlToPDFFile(templateHtmlPath, $"{settlementID}.pdf", replaceDic));

            //设置导出状态
            await this.agentUserSettlementService.SetExportStateAsync(settlementID, (int)EState.启用);
      }
    }

    if (zipSaveFilePathList.Count == 1)
    {
      byteArray = await this.pdfService.GetByteByFile(zipSaveFilePathList.FirstOrDefault());
    }
    else
    {
      string zipFilePath = this.pdfService.CompressFileToZip($"{settlementIDS.Replace(',', '_')}.zip", zipSaveFilePathList.ToArray(), true);
      byteArray = await this.pdfService.GetByteByFile(zipFilePath);
    }

    return base.SuccessResult(byteArray ?? new byte);

  3-前台JS下载文件字节流示例:
 
 
 
来源:https://www.cnblogs.com/lxhbky/archive/2023/06/16/17486147.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: .net core使用Html模板转PDF文件并下载的业务类封装