正文
现在有许多将html导出pdf的第三方包,这里介绍使用的是select.htmltopdf.netcore
使用select.htmltopdf.netcore
- 整体思路是将cshtml内容读出来,然后再转为pdf文档
- 读取cshtml内容有两种方法,第一种使用第三方包
razorengine.netcore
,第二种使用官方方法进行读取。(注意两种方法的cshtml内容略有不同)
效果图展示
我把所有的源代码都上传到了我的个人github,有需要的请自取:github.com/weiming0803…
首先使用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="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><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="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><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="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><i class="fas fa-pen-alt blue"></i> </a> <hr width="100%"> <div id="about"> <p style="display:inline;">个人详情</p> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><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="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >+ 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的全部内容!
发表评论