现在有许多将HTML导出PDF的第三方包,这里介绍使用的是Select.HtmlToPdf.NetCore
使用Select.HtmlToPdf.NetCore
-
整体思路是将cshtml内容读出来,然后再转为Pdf文档
-
读取cshtml内容有两种方法,第一种使用第三方包
RazorEngine.NetCore,第二种使用官方方法进行读取。(注意两种方法的cshtml内容略有不同).
效果图展示
我把所有的源代码都上传到了我的个人Github,有需要的请自取:https://github.com/WeiMing0803/ExportPdf

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

代码部分
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需要修改下面两处地方
删除
@model PdfReportModel将
@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(@"wwwroot\css\pdfReport.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><iclass="fab fa-twitter stroke-transparent"></i></a><a><iclass="fab fa-linkedin-in stroke-transparent"></i></a><a><iclass="fab fa-github stroke-transparent"></i></a></div><a id="edit-intro" href="#"><i class="fas fa-pen-alt blue"></i> </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> 专业技能</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> 工作检验</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> 自我评价</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的全部内容!