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

问题描述

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

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

解决方法

免责声明:我为 SelectPdf 工作。

SelectPdf 确实支持 ASP.NET Core + Razor Page。可从 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;

        }
    }
}
,

我遇到了像 SelectPDF、WKHTMLTOPDF、PDFSharp 这样的免费库,但坦率地说,这些示例是 pre-asp.net 核心,无法安静地将它与 asp.net 核心 Razor Pages 集成。

我建议你可以使用客户端库。因为你提到的都是服务端库,它们都需要找到视图并转换为字符串。据我所知,似乎没有这种直接转换剃刀的方法pages 到 string。所以我建议你可以使用 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>
}
,

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...