首页 > 其他分享 >.net core使用Html模板转PDF文件并下载的业务类封装

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

时间:2023-06-16 17:46:15浏览次数:32  
标签:core string filePath detail Html File PDF var new

  前言:我这里文件下载的模板选型优先考虑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[fileStream.Length];
                    await fileStream.ReadAsync(myByteArray, 0, (int)fileStream.Length);
                }
                if (isDeleteSourceFile)
                {
                    File.Delete(filePath);
                }
            }

            return myByteArray ?? new byte[0];
        }


        /// <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-控制器方法示例:

[HttpGet("DownloadSettlement")]
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[0]);
}

 

  3-前台JS下载文件字节流示例:

<script>
    var dataURLtoBlob = function (baseData, dataFileType) {
        var bstr = atob(baseData)
        var n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: dataFileType });
    };

    var dataByteArray = "后台方法返回的文件字节流数据"
    var dataIsZip = true;
    var dataIsPDF = false

    var fileName = null;
    var blob = null;
    if (dataIsZip) {
        blob = dataURLtoBlob(dataByteArray, "application/zip; charset=utf-8");
        fileName = "test.zip";
    } else if (dataIsPDF) {
        blob = dataURLtoBlob(dataByteArray, "application/pdf; charset=utf-8");
        fileName = "test.pdf";
    }
    var url = window.URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
</script>

 

 

 

标签:core,string,filePath,detail,Html,File,PDF,var,new
From: https://www.cnblogs.com/lxhbky/p/17486147.html

相关文章

  • Latex生成pdf过程中遇到cannot run的问题怎么处理?
    如:Latex生成pdf过程中遇到cannotrun的问题怎么处理?提示在生成pdf过程中出现了问题。这说明使用的pdf浏览器地址有问题为了后面修改代码过程中不会出现代码修改了pdf没变的情况,建议直接添加sumatraPDF阅读器直接到官网下载安装包即可。查看准确的安装位置右键->属性 在Late......
  • Html中空格的区别和使用
    1.半角不断行空格(&nbsp;)作用:用于在HTML中插入一个空格。相同点:与普通空格相比,该空格不会被浏览器忽略或合并。注意事项:这个空格占据的宽度受字体影响很明显。在中文布局中可能会出现上下两行对齐差生偏差的问题。2.半角空格(&ensp;)作用:用于在HTML中插入一个半角空格。相同点:与"......
  • C#/VB.NET:快速而简单的免费SVG到PDF转换技巧
    在日常工作中,我们常常需要将SVG转换为PDF格式。这是因为SVG格式的图像在打印时可能会出现问题,例如失去分辨率或无法正确适应纸张大小。与此相比,PDF格式则专门用于打印和共享文档,可以确保高质量输出,并且能够自动适应不同的纸张大小。在本文中,我们将介绍如何使用编程方式将SVG文件转......
  • How Do ASP.NET Core Services Validate JWT Signature Signed by AAD?
    TableofcontentsBackgroundConfigurationHandleAuthenticationValidateTokenSummaryBackgroundIfweneedtouseJWTBearertokensissuedbyAAD(toeitherauserorserviceprincipal)forauthentication,usuallywecanaddbelowcodeto ConfigureSe......
  • .net core 跨域访问
    varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddCors(options=>{   //这定义了一个名为``default``的CORS策略   options.AddPolicy("default",policy=>    {       policy.AllowAnyOrigin()   ......
  • 视频直播源码,html2canvas 前端保存页面为图片
    视频直播源码,html2canvas前端保存页面为图片转换方法如下: /***将页面指定节点内容转为图片*1.拿到想要转换为图片的内容节点DOM;*2.转换,拿到转换后的canvas*3.转换为图片*///生成局部图片GenerateImg(){ letelement=this.$refs.canvasImgObj; //console.warn(el......
  • html页面解析
    getElementsByTagName和getElementsByClassName这两个方法查找多个dom元素,返回的是htmlcollection类型,是伪数组而不是真数组,故不能使用数组的方法。我们可以使用数组原型配合slice方法,利用call,apply,bind方法将伪数组转为真数组。varx=document.getElementById("main......
  • vue+html2canvas生成寄几想要的海报
    需求:点击弹出一个弹窗,其中是某个作品内容的海报,需要呈现作品的内容+二维码 思路:获取作品内容渲染到弹窗中,生成包含分享链接的二维码,将整个界面转为图片,用户可以长按保存,并扫描识别。 方案及步骤:1.引入html2canvas实现生成图片的功能npminstall--savehtml2canvas 2......
  • Qt+QtWebApp开发笔记(六):http服务器html实现静态相对路径调用第三方js文件
    前言  前面做了一些交互,网页是直接通过html对response进行返回的,这里QtWebApp与传统的web服务器不同,传统的web服务器可以调用同级目录相对路径或者绝对路径下的js,而QtWebApp的httpserver是response返回当前页面的问题,默认是无法调用的。  为了解决调用一些依赖的如echarts......
  • vue在线预览pdf、word、xls、ppt等office文件
    perview(row){consttypeArr=['doc','docx','ppt','pptx','xls','xlsx']letarr=row.url.split('.')letfileType=arr[arr.length-1]leturl=''......