使用Net将HTML简历导出为PDF格式

现在有许多将HTML导出PDF的第三方包,这里介绍使用的是Select.HtmlToPdf.NetCore

使用Select.HtmlToPdf.NetCore

  1. 整体思路是将cshtml内容读出来,然后再转为Pdf文档
  2. 读取cshtml内容有两种方法,第一种使用第三方包 RazorEngine.NetCore,第二种使用官方方法进行读取。(注意两种方法的cshtml内容略有不同)

效果图展示

在线演示地址

我把所有的源代码都上传到了我的个人Github,有需要的请自取:https://github.com/WeiMing0803/ExportPdf

使用Net将HTML简历导出为PDF格式

首先使用ChatGPT生成个人简历信息

使用Net将HTML简历导出为PDF格式

代码部分

HomeController.cs :

public async Task<IActionResult> ToPdf() {     PdfDocument pdfDocument = new PdfDocument();     HtmlToPdf converter = new HtmlToPdf();//实例化一个html到pdf转换器对象     converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;//设置页面方向     converter.Options.PdfPageSize = PdfPageSize.A4;//设置页面大小     converter.Options.MarginTop = 10;//设置页边距     converter.Options.MarginBottom = 10;     converter.Options.MarginLeft = 10;     converter.Options.MarginRight = 10;      PdfReportModel model = new PdfReportModel { Name = "彭于晏", Email = "pengyuyan@outlook.com" };     //string htmlResult = readByEngineRazor(model);//第一种方法,使用RazorEngine.NetCore读取Cshtml文件     string htmlResult = await readCshtml(model);//第二种方法          if (!string.IsNullOrEmpty(htmlResult))     {         pdfDocument = converter.ConvertHtmlString(htmlResult);     }          string savePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $@"ExportPDF{DateTime.Now.ToString("yyyyMMdd")}");     Directory.CreateDirectory(savePath);     string filename = Path.Combine(savePath, $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.pdf");     pdfDocument.Save(filename);      byte[] bytes = System.IO.File.ReadAllBytes(filename);     return File(bytes, "application/pdf", Path.GetFileName(filename)); }   private string readByEngineRazor(PdfReportModel model) {     string template = System.IO.File.ReadAllText("Views/Report/PdfReport.cshtml");     string htmlResult = Engine.Razor.RunCompile(template, "PdfReport", typeof(PdfReportModel), model);     return htmlResult; }  private async Task<string> readCshtml(PdfReportModel model) {     string htmlResult = await _viewRenderService.RenderToStringAsync("Report/PdfReport", model);     return htmlResult; } 

TemplateGadgetProvider.cs :

public class TemplateGadgetProvider {     public static TemplateGadgetProvider _instance;     public static TemplateGadgetProvider Instance     {         get         {             if (_instance == null)                 _instance = new TemplateGadgetProvider();             return _instance;         }     }      public string Load(string virtualPath)     {         return File.ReadAllText(virtualPath);     } } 

pdfReport.css :

Css样式文件:点击查看详细内容
html {     font-family: 'Open Sans', sans-serif;     background: whitesmoke; }  a {     text-decoration: none;     color: black; }  hr {     background: grey; }  #container {     position: relative;     display: flex; }  #profile {     flex: 15%;     display: block;     position: relative;     margin: 5% 2% 0 10%;     width: 100%;     height: 100%; }  #info-cards {     flex: 55%;     display: block;     margin-top: 5%;     margin-right: 10%;     width: 100%;     height: 100%; }  #image {     position: relative;     overflow: hidden; }  #image, #profile-photo {     position: relative;     width: 80px;     height: 80px;     border-radius: 10px; }      #image > a {         position: absolute;         top: 0;         left: 0;         background: rgba(0, 0, 0, 0.5) !important;         height: 100%;         width: 100%;         display: none;     }          #image > a > i {             -webkit-text-stroke: 1px #ffffffdd;             padding: 40%;         }      #image:hover a {         display: block;     }  #name {     font-size: 23px !important;     line-height: 20px !important; }  #about, .card > ul > li {     padding: 0 0 0 15px;     position: relative;     display: inline-block;     width: 100%; }  #about {     font-size: 20px !important;     padding: 0 !important; }      #name,     #about > p {         font-weight: bolder;         font-family: 'Open Sans', sans-serif;     }  #email {     font-size: 15px !important;     font-weight: bold !important;     font-family: 'Cutive Mono', monospace; }  #college, #email, #year-graduation, #education, #more-about, #telephone, #fax {     color: #555;     font-size: 13.5px; }  strong, span {     color: black;     font-size: 16px; }  #social-links, #about {     display: inline-block; }  #social-links {     margin-bottom: 12px; }      #social-links a {         margin: 0 10px;     }  #edit-intro {     display: block;     color: #097bbf;     font-family: 'Nunito', sans-serif; }  .fab {     font-size: 1.1em; }  .fab, .fas {     color: whitesmoke; }  #about > a {     top: 4px;     right: 8px; }  .edit {     top: 19px;     right: 10px; }  #about > a, .edit {     position: absolute;     font-size: 15px !important; }  .stroke-transparent {     -webkit-text-stroke: 1px #000;     -webkit-text-fill-color: transparent; }  .blue {     color: #097bbf !important;     font-size: 13px; }  .stroke-transparent-blue {     -webkit-text-stroke: 1px #097bbf;     -webkit-text-fill-color: transparent; }  .card {     box-shadow: 0 3px 10px 0 rgba(0, 0, 0, .1);     overflow-x: hidden;     margin-bottom: 30px;     padding: 15px 30px 30px 30px;     background-color: #fff; }      .card > p {         color: #0e141e;         font-weight: bolder;         font-size: 18px;         line-height: 2;     }          .card > p > i {             font-size: 18px;         }      .card > a {         font-weight: 400;         font-size: 15px;         margin: 0;         margin-left: 25px;         padding: 0;         border: 0;         height: auto;         background: transparent;         color: #097bbf;         outline: none;         cursor: pointer;     }      .card > ul {         list-style-type: none;     }  .tags {     font-size: 17px;     font-weight: bolder; }      .tags ~ a {         display: none !important;     }      .tags span {         font-size: 14px;         font-weight: normal;         color: #0e141e;     }          .tags span span {             color: #738f93;         }  @media screen and (max-width:1090px) {     #profile {         margin-left: 5%;     } }  @media screen and (max-width:850px) {     #container {         display: block;     }      #profile {         width: 90%;     }      .card {         margin: 0 5%;         margin-bottom: 30px;     } } 

PdfReport.cshtml :

使用RazorEngine.NetCore需要修改下面两处地方

  1. 删除 @model PdfReportModel
  2. @Html.Raw(@style) 修改为 @@Raw(@style)
视图文件:点击查看详细内容
@using exportPdf.common @model PdfReportModel     <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>Document</title>     @{         string style = TemplateGadgetProvider.Instance.Load(@"wwwrootcsspdfReport.css");     }     <style>@Html.Raw(@style)</style> </head>  <body>     <div id="inner-nav"></div>     <div id="container">         <div id="profile">             <div id="image">                 <img id="profile-photo" src="https://img2023.cnblogs.com/blog/233608/202303/233608-20230308165653594-2049775608.jpg" alt="Profile-Image">                 <a href="#"><i class="fas fa-pen stroke-transparent"></i></a>             </div>             <p id="name">@Model.Name<br><span id="email">@Model.Email</span></p>             <p id="designation">前端开发工程师<br><span id="college">天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为也,所以动心忍性,增益其所不能。——《孟子》 </span></p>             <div id="social-links"><a href="#"><i class="fab fa-facebook-f stroke-transparent"></i></a><a><i                         class="fab fa-twitter stroke-transparent"></i></a><a><i                         class="fab fa-linkedin-in stroke-transparent"></i></a><a><i                         class="fab fa-github stroke-transparent"></i></a></div>             <a id="edit-intro" href="#"><i class="fas fa-pen-alt blue"></i>&nbsp;&nbsp;</a>             <hr width="100%">             <div id="about">                 <p style="display:inline;">个人详情</p>                 <a href="#"><i class="fas fa-pen stroke-transparent-blue"></i></a>             </div>             <p id="year-graduation">预计毕业年份<br><strong>2023年6月</strong></p>             <p id="education">学历<br><strong>湖南大学 本科</strong></p>             <p id="more-about">专业<br><strong> 计算机科学与技术专业</strong></p>             <p id="telephone">电话<br><strong>0532-2271351</strong></p>             <p id="fax">传真<br><strong>+91-532-25453441</strong></p>         </div>         <div id="info-cards">             <div class="card">                 <p><i class="fas fa-briefcase stroke-transparent"></i>&nbsp;&nbsp;&nbsp;专业技能</p>                 <ul>                     <li>                         <p class="tags">1. 熟练掌握HTML、CSS、JavaScript等前端基础技术</p>                     </li>                     <li>                         <p class="tags">2. 熟悉jQuery、Bootstrap等常用前端框架和库</p>                     </li>                     <li>                         <p class="tags">3. 了解Node.js、Express等后端开发技术</p>                     </li>                     <li>                         <p class="tags">4. 掌握Git、Webpack等常用开发工具</p>                     </li>                     <li>                         <p class="tags">5. 具备良好的编码风格和文档习惯</p>                     </li>                 </ul>             </div>             <div class="card">                 <p><i class="fas fa-briefcase stroke-transparent"></i>&nbsp;&nbsp;&nbsp;工作检验</p>                 <ul>                     <li>                         <p class="tags">1. 依帆网站首页制作(个人项目)<br>     - 使用HTML、CSS、JavaScript实现了一个响应式的网站首页<br>     - 使用Bootstrap进行布局和样式美化,使用jQuery实现轮播图和导航栏效果<br>     - 使用Webpack进行打包和优化,使用Git进行版本控制和部署</p>                     </li>                     <li>                         <p class="tags">2. 艺风网站后台管理系统(实习项目)<br>     - 参与了一个基于Node.js和Express的后台管理系统的开发<br>     - 负责前端页面的编写,使用EJS模板引擎渲染数据<br>     - 使用Ajax和Fetch进行数据交互,使用Element UI组件库提升用户体验<br>     - 遵循MVC架构,使用Mongoose操作MongoDB数据库</p>                     </li>                 </ul>             </div>             <div class="card">                 <p><i class="fas fa-graduation-cap stroke-transparent"></i>&nbsp;&nbsp;&nbsp;自我评价</p>                 <ul>                     <li>                         <p class="tags">具备较强的学习能力和逻辑思维能力,喜欢接触新技术和新知识</p>                     </li>                     <li>                         <p class="tags">具备良好的沟通能力和团队协作能力,能够积极配合团队完成任务</p>                     </li>                     <li>                         <p class="tags">具备一定的创新能力和解决问题能力,能够针对不同需求提出合理方案</p>                     </li>                 </ul>                 <a href="#">+ Add new</a>             </div>         </div>     </div> </body> </html> 

ViewRenderService :

public class ViewRenderService {     private readonly IRazorViewEngine _razorViewEngine;     private readonly ITempDataProvider _tempDataProvider;     private readonly IServiceProvider _serviceProvider;      public ViewRenderService(IRazorViewEngine razorViewEngine,         ITempDataProvider tempDataProvider,         IServiceProvider serviceProvider)     {         _razorViewEngine = razorViewEngine;         _tempDataProvider = tempDataProvider;         _serviceProvider = serviceProvider;     }      public async Task<string> RenderToStringAsync(string viewName, object model)     {         var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };         var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());          using (var sw = new StringWriter())         {             var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);              if (viewResult.View == null)             {                 throw new ArgumentNullException($"{viewName} does not match any available view");             }              var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())             {                 Model = model             };              var viewContext = new ViewContext(                 actionContext,                 viewResult.View,                 viewDictionary,                 new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),                 sw,                 new HtmlHelperOptions()             );              await viewResult.View.RenderAsync(viewContext);             return sw.ToString();         }     } } 

Program.cs :

builder.Services.AddTransient<ViewRenderService>(); 

以上就是使用Select.HtmlToPdf.NetCore将HTML导出为PDF的全部内容!

作者:百宝门-明维

原文地址:https://blog.baibaomen.com/97-2/

发表评论

相关文章