详解如何使用Net将HTML简历导出为PDF格式

目录
  • 正文
  • 使用Select.HtmlToPdf.NetCore
  • 效果图展示
    • 首先使用ChatGPT生成个人简历信息
    • 代码部分
    • pdfReport.css :

正文

现在有许多将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&lt;string&gt; 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的全部内容!

更多关于Net HTML导出为PDF格式的资料请关注我们其它相关文章!

(0)

相关推荐

  • .Net 对于PDF生成以及各种转换的操作

    前段时间公司的产品,要做一个新功能,签章(就是把需要的数据整理成PDF很标准的文件,然后在盖上我们在服务器上面的章) 然后我就在百度上找了找,发现搞PDF的类库很少,要么就要钱,要么就有水印,破解版的没找到. 先讲一讲我是怎么生成PDF的 1.生成PDF 这里用到了Spire.Pdf 这个类库可以在NuGet里面搜索到,上面带个小红标的就是免费版本. 当然也可以去他们的官网,上面还有文档(https://www.e-iceblue.cn/Introduce/Spire-PDF-NET.html)

  • 利用C#/VB.NET实现将PDF转为Word

    目录 将 PDF 转换为固定布局的 Doc/Docx 文档 完整代码 将 PDF 转换为流动形态的 Doc/Docx 文档 完整代码 效果图 众所周知,PDF 文档支持特长文件,集成度和安全可靠性都较高,可有效防止他人对 PDF 内容进行更改,所以在工作中深受大家喜爱.但是在工作中,我们不可避免的会对 PDF 文档进行修改或再编辑,这时我们可以将 PDF 转换为 Word 文档格式进行修改.本文将分为两部分介绍如何以编程的方式将 PDF 转换为 Word. 将 PDF 转换为固定布局的 Doc/

  • .NET使用DinkToPdf将HTML转成PDF的示例代码

    0.介绍 C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF. 最近浏览文章的时候发现DinkToPdf框架,可以利用HTML转换成PDF,与我早期使用ITextSharp 框架构建PDF的方式不太一样.DinkToPdf直接将HTML转成PDF,HTML的构造直观且简单.这种方式可能可以成为不错的选择! 下面为大家简单介绍DinkToPdf的使用方式.

  • 详解如何使用Net将HTML简历导出为PDF格式

    目录 正文 使用Select.HtmlToPdf.NetCore 效果图展示 首先使用ChatGPT生成个人简历信息 代码部分 pdfReport.css : 正文 现在有许多将HTML导出PDF的第三方包,这里介绍使用的是Select.HtmlToPdf.NetCore 使用Select.HtmlToPdf.NetCore 整体思路是将cshtml内容读出来,然后再转为Pdf文档 读取cshtml内容有两种方法,第一种使用第三方包 RazorEngine.NetCore,第二种使用官方方法进行

  • 详解Java如何实现百万数据excel导出功能

    目录 前言 1.异步处理 1.1 使用job 1.2 使用mq 2.使用easyexcel 3.分页查询 4.多个sheet 5.计算limit的起始位置 6.文件上传到OSS 7.通过WebSocket推送通知 8.总条数可配置 9.order by商品编号 总结 前言 最近我做过一个MySQL百万级别数据的excel导出功能,已经正常上线使用了. 这个功能挺有意思的,里面需要注意的细节还真不少,现在拿出来跟大家分享一下,希望对你会有所帮助. 原始需求:用户在UI界面上点击全部导出按钮,就能导

  • 详解AngularJS中module模块的导入导出

    AngularJS是一款来自Google的前端JS框架,它的核心特性有:MVC.双向数据绑定.指令和语义化标签.模块化工具.依赖注入.HTML模板,以及对常用工具的封装,例如$http.$cookies.$location等. 关于AngularJS中module的导入导出,在Bob告诉我之前还没写过,谢谢Bob在这方面的指导,给到我案例代码. 在AngularJS实际项目中,我们可能需要把针对某个领域的各个方面放在不同的module中,然后把各个module汇总到该领域的一个文件中,再由主mo

  • 详解thinkphp实现excel数据的导入导出(附完整案例)

    实现步骤: 一:在http://phpexcel.codeplex.com/下载最新PHPExcel放到Vendor下,注意位置:ThinkPHP\Extend\Vendor\PHPExcel\PHPExcel.php. 二:导出excel代码实现 /**方法**/ function index(){ $this->display(); } public function exportExcel($expTitle,$expCellName,$expTableData){ $xlsTitle =

  • 详解如何从TensorFlow的mnist数据集导出手写体数字图片

    在TensorFlow的官方入门课程中,多次用到mnist数据集. mnist数据集是一个数字手写体图片库,但它的存储格式并非常见的图片格式,所有的图片都集中保存在四个扩展名为idx3-ubyte的二进制文件. 如果我们想要知道大名鼎鼎的mnist手写体数字都长什么样子,就需要从mnist数据集中导出手写体数字图片.了解这些手写体的总体形状,也有助于加深我们对TensorFlow入门课程的理解. 下面先给出通过TensorFlow api接口导出mnist手写体数字图片的python代码,再对代

  • Python生成图文并茂的PDF报告的方法详解

    目录 安装第三方库 模块导入 封装不同内容对应的函数 生成报告 reportlab是Python的一个标准库,可以画图.画表格.编辑文字,最后可以输出PDF格式.它的逻辑和编辑一个word文档或者PPT很像.有两种方法: 1)建立一个空白文档,然后在上面写文字.画图等: 2)建立一个空白list,以填充表格的形式插入各种文本框.图片等,最后生成PDF文档. 因为需要产生一份给用户看的报告,里面需要插入图片.表格等,所以采用的是第二种方法. 安装第三方库 reportlab输入Python的第三方

  • filebeat收集json格式的tomcat日志详解

    目录 1.部署tomcat 1.1.部署tomcat 1.2.修改tomcat配置文件支持json格式日志输出 1.3.查看tomcat日志 2.配置filebeat收集tomcat日志 2.1.配置filebeat收集tomcat日志 2.2.使用ab压测工具生成1000行tomcat日志 2.3.查看es是否收集到日志 3.kibana关联es索引库进行数据查询 3.1.关联es索引库 3.2.查看收集来的tomcat日志 1.部署tomcat 公司中常用的web程序一般都是nginx和to

  • React特征学习之Form格式示例详解

    目录 Form 样式 React hook Form 样式 首先来看一个简单Form, 式样如下 import * as React from 'react'; const LoginForm = () => { return ( <form> <div> // Notice: 这里要用htmlFor,相当于id <label htmlFor="email">Email</label> <input id="emai

  • fastjson序列化时间自定义格式示例详解

    目录 Java8 的日期相关 API 首先建一个项目添加依赖 配置类中注入 Spriing 容器 写个接口做下测试 Java8 的日期相关 API Java8 的日期相关 API用起来是真香,但免不了遇到在用旧版 1.0 API 的情况.这不,跟另一个部门做对接,人家说你发过来的时间怎么带个 T,我这边没法解析...我回头就是一句xxx,情绪发泄完该做的事咱也得做不是,下面就看看怎么处理这个问题. 首先建一个项目添加依赖 <dependencies> <dependency> &l

  • 基于js的变量提升和函数提升(详解)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分. 上个简历的例子如: console.log(global); // undefined var global = 'global'; console.log(global); // global function fn () { console.log(a); // undefined var a = 'aaa';

随机推荐