经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML » 查看文章
使用Net将HTML简历导出为PDF格式
来源:cnblogs  作者:百宝门园地  时间:2023/3/22 9:27:29  对本文有异议

现在有许多将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 :

  1. public async Task<IActionResult> ToPdf()
  2. {
  3. PdfDocument pdfDocument = new PdfDocument();
  4. HtmlToPdf converter = new HtmlToPdf();//实例化一个html到pdf转换器对象
  5. converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;//设置页面方向
  6. converter.Options.PdfPageSize = PdfPageSize.A4;//设置页面大小
  7. converter.Options.MarginTop = 10;//设置页边距
  8. converter.Options.MarginBottom = 10;
  9. converter.Options.MarginLeft = 10;
  10. converter.Options.MarginRight = 10;
  11. PdfReportModel model = new PdfReportModel { Name = "彭于晏", Email = "pengyuyan@outlook.com" };
  12. //string htmlResult = readByEngineRazor(model);//第一种方法,使用RazorEngine.NetCore读取Cshtml文件
  13. string htmlResult = await readCshtml(model);//第二种方法
  14. if (!string.IsNullOrEmpty(htmlResult))
  15. {
  16. pdfDocument = converter.ConvertHtmlString(htmlResult);
  17. }
  18. string savePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $@"ExportPDF\{DateTime.Now.ToString("yyyyMMdd")}");
  19. Directory.CreateDirectory(savePath);
  20. string filename = Path.Combine(savePath, $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.pdf");
  21. pdfDocument.Save(filename);
  22. byte[] bytes = System.IO.File.ReadAllBytes(filename);
  23. return File(bytes, "application/pdf", Path.GetFileName(filename));
  24. }
  25. private string readByEngineRazor(PdfReportModel model)
  26. {
  27. string template = System.IO.File.ReadAllText("Views/Report/PdfReport.cshtml");
  28. string htmlResult = Engine.Razor.RunCompile(template, "PdfReport", typeof(PdfReportModel), model);
  29. return htmlResult;
  30. }
  31. private async Task<string> readCshtml(PdfReportModel model)
  32. {
  33. string htmlResult = await _viewRenderService.RenderToStringAsync("Report/PdfReport", model);
  34. return htmlResult;
  35. }

TemplateGadgetProvider.cs :

  1. public class TemplateGadgetProvider
  2. {
  3. public static TemplateGadgetProvider _instance;
  4. public static TemplateGadgetProvider Instance
  5. {
  6. get
  7. {
  8. if (_instance == null)
  9. _instance = new TemplateGadgetProvider();
  10. return _instance;
  11. }
  12. }
  13. public string Load(string virtualPath)
  14. {
  15. return File.ReadAllText(virtualPath);
  16. }
  17. }

pdfReport.css :

Css样式文件:点击查看详细内容
  1. html {
  2. font-family: 'Open Sans', sans-serif;
  3. background: whitesmoke;
  4. }
  5. a {
  6. text-decoration: none;
  7. color: black;
  8. }
  9. hr {
  10. background: grey;
  11. }
  12. #container {
  13. position: relative;
  14. display: flex;
  15. }
  16. #profile {
  17. flex: 15%;
  18. display: block;
  19. position: relative;
  20. margin: 5% 2% 0 10%;
  21. width: 100%;
  22. height: 100%;
  23. }
  24. #info-cards {
  25. flex: 55%;
  26. display: block;
  27. margin-top: 5%;
  28. margin-right: 10%;
  29. width: 100%;
  30. height: 100%;
  31. }
  32. #image {
  33. position: relative;
  34. overflow: hidden;
  35. }
  36. #image,
  37. #profile-photo {
  38. position: relative;
  39. width: 80px;
  40. height: 80px;
  41. border-radius: 10px;
  42. }
  43. #image > a {
  44. position: absolute;
  45. top: 0;
  46. left: 0;
  47. background: rgba(0, 0, 0, 0.5) !important;
  48. height: 100%;
  49. width: 100%;
  50. display: none;
  51. }
  52. #image > a > i {
  53. -webkit-text-stroke: 1px #ffffffdd;
  54. padding: 40%;
  55. }
  56. #image:hover a {
  57. display: block;
  58. }
  59. #name {
  60. font-size: 23px !important;
  61. line-height: 20px !important;
  62. }
  63. #about,
  64. .card > ul > li {
  65. padding: 0 0 0 15px;
  66. position: relative;
  67. display: inline-block;
  68. width: 100%;
  69. }
  70. #about {
  71. font-size: 20px !important;
  72. padding: 0 !important;
  73. }
  74. #name,
  75. #about > p {
  76. font-weight: bolder;
  77. font-family: 'Open Sans', sans-serif;
  78. }
  79. #email {
  80. font-size: 15px !important;
  81. font-weight: bold !important;
  82. font-family: 'Cutive Mono', monospace;
  83. }
  84. #college,
  85. #email,
  86. #year-graduation,
  87. #education,
  88. #more-about,
  89. #telephone,
  90. #fax {
  91. color: #555;
  92. font-size: 13.5px;
  93. }
  94. strong,
  95. span {
  96. color: black;
  97. font-size: 16px;
  98. }
  99. #social-links,
  100. #about {
  101. display: inline-block;
  102. }
  103. #social-links {
  104. margin-bottom: 12px;
  105. }
  106. #social-links a {
  107. margin: 0 10px;
  108. }
  109. #edit-intro {
  110. display: block;
  111. color: #097bbf;
  112. font-family: 'Nunito', sans-serif;
  113. }
  114. .fab {
  115. font-size: 1.1em;
  116. }
  117. .fab,
  118. .fas {
  119. color: whitesmoke;
  120. }
  121. #about > a {
  122. top: 4px;
  123. right: 8px;
  124. }
  125. .edit {
  126. top: 19px;
  127. right: 10px;
  128. }
  129. #about > a,
  130. .edit {
  131. position: absolute;
  132. font-size: 15px !important;
  133. }
  134. .stroke-transparent {
  135. -webkit-text-stroke: 1px #000;
  136. -webkit-text-fill-color: transparent;
  137. }
  138. .blue {
  139. color: #097bbf !important;
  140. font-size: 13px;
  141. }
  142. .stroke-transparent-blue {
  143. -webkit-text-stroke: 1px #097bbf;
  144. -webkit-text-fill-color: transparent;
  145. }
  146. .card {
  147. box-shadow: 0 3px 10px 0 rgba(0, 0, 0, .1);
  148. overflow-x: hidden;
  149. margin-bottom: 30px;
  150. padding: 15px 30px 30px 30px;
  151. background-color: #fff;
  152. }
  153. .card > p {
  154. color: #0e141e;
  155. font-weight: bolder;
  156. font-size: 18px;
  157. line-height: 2;
  158. }
  159. .card > p > i {
  160. font-size: 18px;
  161. }
  162. .card > a {
  163. font-weight: 400;
  164. font-size: 15px;
  165. margin: 0;
  166. margin-left: 25px;
  167. padding: 0;
  168. border: 0;
  169. height: auto;
  170. background: transparent;
  171. color: #097bbf;
  172. outline: none;
  173. cursor: pointer;
  174. }
  175. .card > ul {
  176. list-style-type: none;
  177. }
  178. .tags {
  179. font-size: 17px;
  180. font-weight: bolder;
  181. }
  182. .tags ~ a {
  183. display: none !important;
  184. }
  185. .tags span {
  186. font-size: 14px;
  187. font-weight: normal;
  188. color: #0e141e;
  189. }
  190. .tags span span {
  191. color: #738f93;
  192. }
  193. @media screen and (max-width:1090px) {
  194. #profile {
  195. margin-left: 5%;
  196. }
  197. }
  198. @media screen and (max-width:850px) {
  199. #container {
  200. display: block;
  201. }
  202. #profile {
  203. width: 90%;
  204. }
  205. .card {
  206. margin: 0 5%;
  207. margin-bottom: 30px;
  208. }
  209. }

PdfReport.cshtml :

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

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

ViewRenderService :
  1. public class ViewRenderService
  2. {
  3. private readonly IRazorViewEngine _razorViewEngine;
  4. private readonly ITempDataProvider _tempDataProvider;
  5. private readonly IServiceProvider _serviceProvider;
  6. public ViewRenderService(IRazorViewEngine razorViewEngine,
  7. ITempDataProvider tempDataProvider,
  8. IServiceProvider serviceProvider)
  9. {
  10. _razorViewEngine = razorViewEngine;
  11. _tempDataProvider = tempDataProvider;
  12. _serviceProvider = serviceProvider;
  13. }
  14. public async Task<string> RenderToStringAsync(string viewName, object model)
  15. {
  16. var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
  17. var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
  18. using (var sw = new StringWriter())
  19. {
  20. var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);
  21. if (viewResult.View == null)
  22. {
  23. throw new ArgumentNullException($"{viewName} does not match any available view");
  24. }
  25. var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
  26. {
  27. Model = model
  28. };
  29. var viewContext = new ViewContext(
  30. actionContext,
  31. viewResult.View,
  32. viewDictionary,
  33. new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
  34. sw,
  35. new HtmlHelperOptions()
  36. );
  37. await viewResult.View.RenderAsync(viewContext);
  38. return sw.ToString();
  39. }
  40. }
  41. }

Program.cs :

  1. builder.Services.AddTransient<ViewRenderService>();

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

作者:百宝门-明维

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

原文链接:https://www.cnblogs.com/baibaomen-org/p/17238845.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号