ASP.NET Core html生成pdf

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

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

DinkToPdf吁峻,是一個跨平臺的庫用含,是Webkit HTML to PDF庫的包裝。它使用WebKit引擎將HTML轉(zhuǎn)換為PDF缸夹。它可以在.NET Core項目中將HTML字符串生成PDF文檔,或者從現(xiàn)有的HTML頁面創(chuàng)建PDF文檔芽唇。

由于官方的DinkToPdf https://github.com/rdvojmoc/DinkToPdf 最新的更新已經(jīng)是三年前的了,原來的DinkToPdf需要引入幾個dll,這些dll也沒有更新疚膊,導(dǎo)致目前在linux系統(tǒng)中,還有docker容器環(huán)境中無法使用傀蚌。(github上也有很多issue都是關(guān)于這些問題的库继,好像都沒有特別好的處理辦法)榨惰。

后來發(fā)現(xiàn)了一個Haukcode.DinkToPdf這個庫,是作者根據(jù)DinkToPdf改造的(https://www.nuget.org/packages/Haukcode.DinkToPdf/
),將一些dll整合進去了,也兼容容器環(huán)境了嫁佳。

安裝,在.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注入

創(chuàng)建IPDFService

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

創(chuàng)建PDFService

using System;
using DinkToPdf;
using DinkToPdf.Contracts;

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

        /// <summary>
        /// 創(chuàng)建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  這里是用現(xiàn)有的網(wǎng)頁生成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>();

創(chuàng)建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>
        這是一個網(wǎng)頁瑞你!
    </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字符串已經(jīng)生成了pdf文檔

本文項目部署的環(huán)境是在Docker容器中嫩实,采用ASP.NET Core官方的鏡像。
這個鏡像是精簡的,所以沒有一些字體氧骤,那就這樣部署到docker容器中的話網(wǎng)頁會亂碼际歼。
所以,要手動添加字體颅筋。如下宙暇,下載字體文件simsun.ttc占贫。
在dockerfile文件中添加:

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

構(gòu)建鏡像部署即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谐宙,一起剝皮案震驚了整個濱河市烫葬,隨后出現(xiàn)的幾起案子搭综,更是在濱河造成了極大的恐慌兑巾,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡寓免,警方通過查閱死者的電腦和手機袜香,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門踩寇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事博脑≡饕遥” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵叉趣,是天一觀的道長泞边。 經(jīng)常有香客問我,道長疗杉,這世上最難降的妖魔是什么阵谚? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮烟具,結(jié)果婚禮上梢什,老公的妹妹穿的比我還像新娘。我一直安慰自己朝聋,他們只是感情好嗡午,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冀痕,像睡著了一般荔睹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上言蛇,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天僻他,我揣著相機與錄音,去河邊找鬼腊尚。 笑死吨拗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丢胚,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼翩瓜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了携龟?” 一聲冷哼從身側(cè)響起兔跌,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎峡蟋,沒想到半個月后坟桅,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蕊蝗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年仅乓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓬戚。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡夸楣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出子漩,到底是詐尸還是另有隱情豫喧,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布幢泼,位于F島的核電站紧显,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缕棵。R本人自食惡果不足惜孵班,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望招驴。 院中可真熱鬧篙程,春花似錦、人聲如沸忽匈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丹允。三九已至郭厌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雕蔽,已是汗流浹背折柠。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留批狐,地道東北人扇售。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓前塔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親承冰。 傳聞我的和親對象是個殘疾皇子华弓,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容