使用Net將HTML簡(jiǎn)歷導(dǎo)出為PDF格式
現(xiàn)在有許多將HTML導(dǎo)出PDF的第三方包,這里介紹使用的是 Select.HtmlToPdf.NetCore
使用Select.HtmlToPdf.NetCore
整體思路是將cshtml內(nèi)容讀出來(lái),然后再轉(zhuǎn)為Pdf文檔
讀取cshtml內(nèi)容有兩種方法,第一種使用第三方包?
RazorEngine.NetCore
,第二種使用官方方法進(jìn)行讀取。(注意兩種方法的cshtml內(nèi)容略有不同)
效果圖展示
在線演示地址
我把所有的源代碼都上傳到了我的個(gè)人Github,有需要的請(qǐng)自?。篽ttps://github.com/WeiMing0803/ExportPdf

首先使用?ChatGPT
生成個(gè)人簡(jiǎn)歷信息

代碼部分
HomeController.cs :
public async Task<IActionResult> ToPdf()
{
? ?PdfDocument pdfDocument = new PdfDocument();
? ?HtmlToPdf converter = new HtmlToPdf();//實(shí)例化一個(gè)html到pdf轉(zhuǎn)換器對(duì)象
? ?converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;//設(shè)置頁(yè)面方向
? ?converter.Options.PdfPageSize = PdfPageSize.A4;//設(shè)置頁(yè)面大小
? ?converter.Options.MarginTop = 10;//設(shè)置頁(yè)邊距
? ?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樣式文件:點(diǎn)擊查看詳細(xì)內(nèi)容
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
需要修改下面兩處地方
刪除?
@modelPdfReportModel
將?
@Html.Raw(@style)
?修改為?@@Raw(@style)
視圖文件:點(diǎn)擊查看詳細(xì)內(nèi)容
@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">前端開(kāi)發(fā)工程師<br><span id="college">天將降大任于斯人也,必先苦其心志,勞其筋骨,餓其體膚,空乏其身,行拂亂其所為也,所以動(dòng)心忍性,增益其所不能?!睹献印?</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> </a>
? ? ? ? ? ?<hr width="100%">
? ? ? ? ? ?<div id="about">
? ? ? ? ? ? ? ?<p style="display:inline;">個(gè)人詳情</p>
? ? ? ? ? ? ? ?<a href="#"><i class="fas fa-pen stroke-transparent-blue"></i></a>
? ? ? ? ? ?</div>
? ? ? ? ? ?<p id="year-graduation">預(yù)計(jì)畢業(yè)年份<br><strong>2023年6月</strong></p>
? ? ? ? ? ?<p id="education">學(xué)歷<br><strong>湖南大學(xué) 本科</strong></p>
? ? ? ? ? ?<p id="more-about">專業(yè)<br><strong> 計(jì)算機(jī)科學(xué)與技術(shù)專業(yè)</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> 專業(yè)技能</p>
? ? ? ? ? ? ? ?<ul>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">1. 熟練掌握HTML、CSS、JavaScript等前端基礎(chǔ)技術(shù)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">2. 熟悉jQuery、Bootstrap等常用前端框架和庫(kù)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">3. 了解Node.js、Express等后端開(kāi)發(fā)技術(shù)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">4. 掌握Git、Webpack等常用開(kāi)發(fā)工具</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">5. 具備良好的編碼風(fēng)格和文檔習(xí)慣</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ?</ul>
? ? ? ? ? ?</div>
? ? ? ? ? ?<div class="card">
? ? ? ? ? ? ? ?<p><i class="fas fa-briefcase stroke-transparent"></i> 工作檢驗(yàn)</p>
? ? ? ? ? ? ? ?<ul>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">1. 依帆網(wǎng)站首頁(yè)制作(個(gè)人項(xiàng)目)<br>
? ?- 使用HTML、CSS、JavaScript實(shí)現(xiàn)了一個(gè)響應(yīng)式的網(wǎng)站首頁(yè)<br>
? ?- 使用Bootstrap進(jìn)行布局和樣式美化,使用jQuery實(shí)現(xiàn)輪播圖和導(dǎo)航欄效果<br>
? ?- 使用Webpack進(jìn)行打包和優(yōu)化,使用Git進(jìn)行版本控制和部署</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">2. 藝風(fēng)網(wǎng)站后臺(tái)管理系統(tǒng)(實(shí)習(xí)項(xiàng)目)<br>
? ?- 參與了一個(gè)基于Node.js和Express的后臺(tái)管理系統(tǒng)的開(kāi)發(fā)<br>
? ?- 負(fù)責(zé)前端頁(yè)面的編寫(xiě),使用EJS模板引擎渲染數(shù)據(jù)<br>
? ?- 使用Ajax和Fetch進(jìn)行數(shù)據(jù)交互,使用Element UI組件庫(kù)提升用戶體驗(yàn)<br>
? ?- 遵循MVC架構(gòu),使用Mongoose操作MongoDB數(shù)據(jù)庫(kù)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ?</ul>
? ? ? ? ? ?</div>
? ? ? ? ? ?<div class="card">
? ? ? ? ? ? ? ?<p><i class="fas fa-graduation-cap stroke-transparent"></i> 自我評(píng)價(jià)</p>
? ? ? ? ? ? ? ?<ul>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">具備較強(qiáng)的學(xué)習(xí)能力和邏輯思維能力,喜歡接觸新技術(shù)和新知識(shí)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">具備良好的溝通能力和團(tuán)隊(duì)協(xié)作能力,能夠積極配合團(tuán)隊(duì)完成任務(wù)</p>
? ? ? ? ? ? ? ? ? ?</li>
? ? ? ? ? ? ? ? ? ?<li>
? ? ? ? ? ? ? ? ? ? ? ?<p class="tags">具備一定的創(chuàng)新能力和解決問(wèn)題能力,能夠針對(duì)不同需求提出合理方案</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導(dǎo)出為PDF的全部?jī)?nèi)容!
原文地址:使用Net將HTML簡(jiǎn)歷導(dǎo)出為PDF格式 - 百寶門(mén)的博客 (baibaomen.com)