ASP.NET Core html生成pdf 轉

轉   https://www.jianshu.com/p/81ff83d18534

 

本文,主要記錄在處理.NET Core Web API項目時使用DinkToPDF庫輕鬆生成PDF。

本文源碼 https://github.com/forestGzh/HtmlToPdf

DinkToPdf,是一個跨平臺的庫,是Webkit HTML to PDF庫的包裝。它使用WebKit引擎將HTML轉換爲PDF。它可以在.NET Core項目中將HTML字符串生成PDF文檔,或者從現有的HTML頁面創建PDF文檔。

由於官方的DinkToPdf https://github.com/rdvojmoc/DinkToPdf 最新的更新已經是三年前的了,原來的DinkToPdf需要引入幾個dll,這些dll也沒有更新,導致目前在linux系統中,還有docker容器環境中無法使用。(github上也有很多issue都是關於這些問題的,好像都沒有特別好的處理辦法)。

後來發現了一個Haukcode.DinkToPdf這個庫,是作者根據DinkToPdf改造的(https://www.nuget.org/packages/Haukcode.DinkToPdf/
),將一些dll整合進去了,也兼容容器環境了。

安裝,在.csproj中加上下面這行,然後restore一下。或者直接去NuGet包管理器搜索安裝也是一樣的。

<PackageReference Include="Haukcode.DinkToPdf" Version="1.1.2" />

Install-Package Haukcode.DinkToPdf -Version 1.1.2

在Startup.cs中添加:

services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));//DinkToPdf注入

創建IPDFService

using System;
namespace HtmlToPdf.Services
{
    /// <summary>
    /// 與pdf相關
    /// </summary>
    public interface IPDFService
    {
        /// <summary>
        /// 創建PDF
        /// </summary>
        /// <param name="htmlContent">傳入html字符串</param>
        /// <returns></returns>
        byte[] CreatePDF(string htmlContent);
    }
}

創建PDFService

using System;
using DinkToPdf;
using DinkToPdf.Contracts;

namespace HtmlToPdf.Services
{
    /// <summary>
    /// 與pdf相關
    /// </summary>
    public class PDFService : IPDFService
    {
        private IConverter _converter;
        public PDFService(IConverter converter)
        {
            _converter = converter;
        }

        /// <summary>
        /// 創建PDF
        /// </summary>
        /// <param name="htmlContent">傳入html字符串</param>
        /// <returns></returns>
        public byte[] CreatePDF(string htmlContent)
        {
            var globalSettings = new GlobalSettings
            {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
                //Margins = new MarginSettings
                //{
                //    Top = 10,
                //    Left = 0,
                //    Right = 0,
                //},
                DocumentTitle = "PDF Report",
            };

            var objectSettings = new ObjectSettings
            {
                PagesCount = true,
                HtmlContent = htmlContent,
                // Page = "www.baidu.com", //USE THIS PROPERTY TO GENERATE PDF CONTENT FROM AN HTML PAGE  這裏是用現有的網頁生成PDF
                //WebSettings = { DefaultEncoding = "utf-8", UserStyleSheet = Path.Combine(Directory.GetCurrentDirectory(), "assets", "styles.css") },
                WebSettings = { DefaultEncoding = "utf-8" },
                //HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true },
                //FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer" }
            };

            var pdf = new HtmlToPdfDocument()
            {
                GlobalSettings = globalSettings,
                Objects = { objectSettings }
            };

            var file = _converter.Convert(pdf);

            //return File(file, "application/pdf");

            return file;

        }
    }
}

在Startup.cs中依賴注入:

services.AddTransient<IPDFService, PDFService>();

創建TemplateGenerator,生成html字符串

using System;
using System.Text;

namespace HtmlToPdf
{
    public static class TemplateGenerator
    {
        /// <summary>
        /// 獲取HTML字符串
        /// </summary>
        /// <returns></returns>
        public static string GetPDFHTMLString()
        {

            StringBuilder sb = new StringBuilder();

            sb.Append(@"
<html>
  <head>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <style>
      
    </style>
  </head>

  <body>
    <div>
        這是一個網頁!
    </div>
  </body>
</html>
            ");

            return sb.ToString();
        }
    }
}

修改ValuesController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HtmlToPdf.Services;
using Microsoft.AspNetCore.Mvc;

namespace HtmlToPdf.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private IPDFService _PDFService;

        public ValuesController(IPDFService pDFService)
        {
            _PDFService = pDFService;
        }

        [HttpGet("pdf")]
        public FileResult GetPDF()
        {
            //獲取html模板
            var htmlContent = TemplateGenerator.GetPDFHTMLString();

            //生成PDF
            var pdfBytes = _PDFService.CreatePDF(htmlContent);

            return File(pdfBytes, "application/pdf");
        }
    }
}

測試:
瀏覽器輸入 https://localhost:5001/api/values/pdf

 
image.png

可以看到html字符串已經生成了pdf文檔

本文項目部署的環境是在Docker容器中,採用ASP.NET Core官方的鏡像。
這個鏡像是精簡的,所以沒有一些字體,那就這樣部署到docker容器中的話網頁會亂碼。
所以,要手動添加字體。如下,下載字體文件simsun.ttc。
在dockerfile文件中添加:

ADD ./simsun.ttc /usr/share/fonts/simsun.ttc

構建鏡像部署即可



作者:GongZH丶
鏈接:https://www.jianshu.com/p/81ff83d18534
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章