在 ASP.net core 3.1 Razor Pages 中打印 PDF

Posted

技术标签:

【中文标题】在 ASP.net core 3.1 Razor Pages 中打印 PDF【英文标题】:Printing PDF in ASP.net core 3.1 Razor Pages 【发布时间】:2021-04-28 18:49:57 【问题描述】:

在学习 ASP.net core 的过程中,我使用 asp.net core 3.1 创建了一个简单的 CRUD 应用程序。我想将我的详细信息页面打印为发票。我环顾四周,似乎在完整的 .Net Framework 中打印 PDF 更可用。

谁能指出我正确的方向?我遇到过 SelectPDF、WKhtmlTOPDF、PDFSharp 等免费库,但坦率地说,这些示例是 pre-asp.net 核心,无法将其与 asp.net 核心 Razor Pages 集成。实际上,如果我没记错的话,上面提到的一些库与 Razor Pages Core 不兼容。

【问题讨论】:

【参考方案1】:

免责声明:我为 SelectPdf 工作。

SelectPdf 确实支持 ASP.NET Core + Razor 页面。示例可从 SelectPdf 网站下载。

这里的示例代码:

@page
@model SelectPdf.Samples.Pages.ConvertUrlToPdfModel
@
    Layout = "~/Pages/_Layout.cshtml";
    ViewData["Title"] = "SelectPdf Free Html To Pdf Converter for .NET Core - Convert from Url to Pdf - C# / ASP.NET Core MVC6";
    ViewData["Description"] = "SelectPdf Convert from Url to Pdf Sample for C# ASP.NET MVC. Pdf Library for .NET with full sample code in C# and VB.NET.";
    ViewData["Keywords"] = "convert from url to pdf, pdf library, sample code, html to pdf, pdf converter";


<form method="post">
    <article class="post type-post status-publish format-standard hentry">
        <header class="entry-header">
            <h1 class="entry-title">SelectPdf Free Html To Pdf Converter for .NET Core - Convert from Html to Pdf - C# / ASP.NET Core MVC6 Sample</h1>
        </header>
        <!-- .entry-header -->

        <div class="entry-content">
            <p>
                This sample shows how to use SelectPdf html to pdf converter to convert an url to pdf, also setting a few properties.
            </p>
            <p>
                Url:<br />
                <input type="text" style="width: 90%;" value="https://selectpdf.com" asp-for="TxtUrl" />
            </p>
            <div class="col2">
                Pdf Page Size:<br />
                <select asp-for="DdlPageSize" asp-items="Model.PageSizes"></select>
                <br />
                <br />
                Pdf Page Orientation:<br />
                <select asp-for="DdlPageOrientation" asp-items="Model.PageOrientations"></select><br />
                <br />
            </div>
            <div class="col2">
                Web Page Width:<br />
                <input type="text" style="width: 50px;" value="1024" asp-for="TxtWidth" /> px<br />
                <br />
                Web Page Height:<br />
                <input type="text" style="width: 50px;" value="" asp-for="TxtHeight" /> px<br />
                (leave empty to auto detect)<br />
                <br />

            </div>
            <div class="col-clear"></div>
            <p>
                <input type="submit" name="BtnConvert" value="Create PDF" class="mybutton" />
            </p>
        </div>
        <!-- .entry-content -->
    </article>
</form>

// C# code below

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace SelectPdf.Samples.Pages

    public class ConvertUrlToPdfModel : PageModel
    
        public void OnGet()
        
            DdlPageSize = "A4";
        

        [BindProperty]
        public string TxtUrl  get; set; 

        [BindProperty]
        public string DdlPageSize  get; set; 

        public List<SelectListItem> PageSizes  get;  = new List<SelectListItem>
        
            new SelectListItem  Value = "A1", Text = "A1" ,
            new SelectListItem  Value = "A2", Text = "A2" ,
            new SelectListItem  Value = "A3", Text = "A3" ,
            new SelectListItem  Value = "A4", Text = "A4" ,
            new SelectListItem  Value = "A5", Text = "A5" ,
            new SelectListItem  Value = "Letter", Text = "Letter" ,
            new SelectListItem  Value = "HalfLetter", Text = "HalfLetter" ,
            new SelectListItem  Value = "Ledger", Text = "Ledger" ,
            new SelectListItem  Value = "Legal", Text = "Legal" ,
        ;

        [BindProperty]
        public string DdlPageOrientation  get; set; 

        public List<SelectListItem> PageOrientations  get;  = new List<SelectListItem>
        
            new SelectListItem  Value = "Portrait", Text = "Portrait" ,
            new SelectListItem  Value = "Landscape", Text = "Landscape" ,
        ;

        [BindProperty]
        public string TxtWidth  get; set; 

        [BindProperty]
        public string TxtHeight  get; set; 

        public IActionResult OnPost()
        
            // read parameters from the webpage
            PdfPageSize pageSize =
                (PdfPageSize)Enum.Parse(typeof(PdfPageSize), DdlPageSize, true);

            PdfPageOrientation pdfOrientation =
                (PdfPageOrientation)Enum.Parse(typeof(PdfPageOrientation),
                DdlPageOrientation, true);

            int webPageWidth = 1024;
            try
            
                webPageWidth = System.Convert.ToInt32(TxtWidth);
            
            catch  

            int webPageHeight = 0;
            try
            
                webPageHeight = System.Convert.ToInt32(TxtHeight);
            
            catch  

            // instantiate a html to pdf converter object
            HtmlToPdf converter = new HtmlToPdf();

            // set converter options
            converter.Options.PdfPageSize = pageSize;
            converter.Options.PdfPageOrientation = pdfOrientation;
            converter.Options.WebPageWidth = webPageWidth;
            converter.Options.WebPageHeight = webPageHeight;

            // create a new pdf document converting an url
            PdfDocument doc = converter.ConvertUrl(TxtUrl);

            // save pdf document
            byte[] pdf = doc.Save();

            // close pdf document
            doc.Close();

            // return resulted pdf document
            FileResult fileResult = new FileContentResult(pdf, "application/pdf");
            fileResult.FileDownloadName = "Document.pdf";
            return fileResult;

        
    

【讨论】:

成功了。我也得到了上面的答案,但这绝对是我需要的。谢谢 能否提供此 ASP.net Core 示例的链接? selectpdf.com/download/SelectPdf-Samples-v20.2.0.zip【参考方案2】:

我遇到过 SelectPDF、WKHTMLTOPDF、PDFSharp 等免费库,但坦率地说,这些示例是 pre-asp.net 核心,无法将其与 asp.net 核心 Razor 页面集成。

我建议你可以使用客户端库。因为你提到的都是服务器端库,它们都需要找到视图并转换为字符串。据我所知,似乎没有这种直接的方法来转换剃须刀页面到字符串。所以我建议你可以使用jsPDF库。

这是一个完整的工作演示:

@page
@model DetailsModel
<div id="details">       //be sure add this id...

    <h1>Details</h1>

    <div>
        <h4>test</h4>
        <hr />
        <dl class="row">
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => model.test.Name)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(model => model.test.Name)
            </dd>
        </dl>
    </div>
    <div>
        <a asp-page="./Edit" asp-route-id="@Model.test.Id">Edit</a> |
        <a asp-page="./Index">Back to List</a>
    </div>
</div>

<button onclick="javascript:demoFromHTML();">Generate PDF</button>

@section Scripts

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
    <script>
        function demoFromHTML() 
            var pdf = new jsPDF('p', 'pt', 'letter');
            // source can be HTML-formatted string, or a reference
            // to an actual DOM element from which the text will be scraped.
            source = $('#details')[0];

            // we support special element handlers. Register them with jQuery-style
            // ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
            // There is no support for any other type of selectors
            // (class, of compound) at this time.
            specialElementHandlers = 
                // element with id of "bypass" - jQuery style selector
                '#bypassme': function (element, renderer) 
                    // true = "handled elsewhere, bypass text extraction"
                    return true
                
            ;
            margins = 
                top: 80,
                bottom: 60,
                left: 40,
                width: 522
            ;
            // all coords and widths are in jsPDF instance's declared units
            // 'inches' in this case
            pdf.fromHTML(
                source, // HTML string or DOM elem ref.
                margins.left, // x coord
                margins.top,  // y coord
                'width': margins.width, // max width of content on PDF
                'elementHandlers': specialElementHandlers
            ,

                function (dispose) 
                    // dispose: object with X, Y of the last line add to the PDF
                    //          this allow the insertion of new lines after html
                    pdf.save('Test.pdf');
                , margins);
        
    </script>

【讨论】:

我去这个工作。嗯,这很简单。 (复制/粘贴)【参考方案3】:

您也可以查看 Syncfusion,他们有一个很棒的库。

https://www.syncfusion.com/pdf-framework/net-core/pdf-library

【讨论】:

以上是关于在 ASP.net core 3.1 Razor Pages 中打印 PDF的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net Core 3.1-如何从控制器返回到 Razor 页面?

在 ASP.net core 3.1 Razor Pages 中打印 PDF

ASP.NET Core 3.1 Razor 将字符串转换为日期时间

[ASP.NET Core 3.1 MVC Razor页面仅在模型成员有效时显示图标

创建基于ASP.NET core 3.1 的RazorPagesMovie项目-应用模型类配合基架生成工具生成Razor页面

ASP.NET Core 3.1 - 如何获取客户端的 IP 地址?