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

使用Select.HtmlToPdf.NetCore

  1. 整体思路是将cshtml内容读出来,然后再转为Pdf文档
  2. 读取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需要修改下面两处地方

  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(@"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><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/

最新文章

  1. HTML的doctype和编码
  2. H3 BPM初次安装常见错误详解5-7
  3. windows2008安装IIS
  4. jboss服务器修改端口说明
  5. imx6 otg host support
  6. C语言中进制知识总结
  7. use tomcat to access the file cross the environment
  8. beginBackgroundTaskWithExpirationHandle
  9. java中的静态变量
  10. 腾讯ISUX网页前端代码分析
  11. 201521123079《java程序设计》第12周学习总结
  12. 如何在CentOS上安装一个2048小游戏
  13. 数据库索引------Hash索引的使用限制
  14. dubbo框架提供Main方法运行容器的几种方式(转)
  15. 滑动时候报错:Unable to preventDefault inside passive event listener, 移动端滑动性能优化
  16. ABP入门系列之3——创建实体/Code First创建数据表
  17. Python 计数器
  18. Flash网页小游戏开发教程
  19. 【LG4070】[SDOI2016]生成魔咒
  20. Educational Codeforces Round 13 D. Iterated Linear Function 水题

热门文章

  1. HCIP-ICT实战进阶03-OSPF高级特性
  2. 基于工业5G网关的建筑机器人应用
  3. linux火狐添加flash插件
  4. Pytest+allure+requests接口自动化
  5. c++学习 5 预处理
  6. 后台传回来的Map类型的数据在前台中的JS代码中使用
  7. 【jinja2】Python根据模板生成HTML文件并加载进QWebEngineView
  8. android studio 隐式Internet跳转
  9. Mongodb+Stadio 3
  10. hdu: You Are the One(区间DP)