.Net Core 導出Html到PDF


前言

  最近由於項目的需求問題,涉及到了在.Net Core中導出PDF的一個問題,最后選擇方式是后端拼接到Html頁面然后再通過Html導出到PDF。中間也嘗試了許多的NuGet包、但是並不如意,可用並且好用的的比較少。下面將最近最幾天嘗試的使用方法分享給大家。

NuGet包

Select.HtmlToPdf.NetCore        簡單好用,缺點是僅支持Windows,部署Linux不支持

HtmlToPDFCore             免費 支持Windows Linux  但是功能簡單,樣式不穩定

PdfSharpCore            Html內容轉PDF較為麻煩

DinkToPdf           依賴wkhtmltopdf,需要附帶exe應用程序

iTextSharp             5.0以后的收費了,而且NuGet包最低都在5.0以上,也就是收費

iTextSharp.LGPLv2.Core       Html內容轉PDF太復雜

PDF.Core                收費 

HTML-Renderer.Core        較久沒有維護支持,不兼容

HTML-Renderer.PdfSharp       可以使用但是不兼容Core

Spire.PDF               收費

ExpertPdf.HtmlToPdf.NetCore   收費

hiqpdf.free             免費不兼容Core

Select.HtmlToPdf.NetCore 操作案例

  還有一些其他的沒有列舉出來,但是部分都是收費的,而且還有部分都是需要依賴wkhtmltopdf做PDF導出,最后嘗試使用的還是Select.HtmlToPdf.NetCore 。但是也僅限在Windows平台。但是使用確實比較方便。我們看下具體操作:

  首先安裝Select.HtmlToPdf.NetCore NuGet包

  

  我們首先看下簡單的一個Html內容和Url導出為PDF文件的例子:

  

        //獲取項目路徑使用
 IHostingEnvironment hostingEnv; public ValuesController(IHostingEnvironment hostingEnv) { this.hostingEnv = hostingEnv; } /// <summary>
        /// Html導出PDF /// </summary>
        /// <returns></returns>
 [HttpGet] public ActionResult<IEnumerable<string>> Get() { //測試Html素材
            string htmlString = @"<!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <title></title> <style> body { margin: 0; padding: 0; min-width: 2000px; } .m_table { border-collapse: separate; margin: 100px auto 0; min-width: 1900px; text-align: center; font: 500 17px '微軟雅黑'; border-spacing: 0; border: 1px solid #EBEEF5; } .m_table th { background-color: #F7F3F7; } .m_table th, .m_table td { border-right: 1px solid #EBEEF5; border-bottom: 1px solid #EBEEF5; padding: 5px; height: 60px; width: 60px; } </style> </head> <body> <table class='m_table'> <tr> <th colspan='9' style='text-align:center;font-size:28px;'>期末學生綜合評價表1</th> </tr> <tr> <th colspan='9' style='text-align:center;font-size:23px;'>班級:一年級一班 姓名:測試 班主任:測試</th> </tr> <tr> <th rowspan='2' style='text-align:center;font-size:24px;'>學科</th> <th colspan='2' rowspan='2' style='text-align:center;font-size:24px;'>過程性評價</th> <th colspan='2' rowspan='2' style='text-align:center;font-size:24px;'>表現性評價</th> <th colspan='2' style='text-align:center;font-size:20px;'>考試性評價</th> <th colspan='2' style='text-align:center;font-size:20px;'>綜合性評價</th> </tr> <tr> <th style='text-align:center;font-size:18px;'>卷面分</th> <th style='text-align:center;font-size:18px;'>權重分</th> <th style='text-align:center;font-size:18px;'>總分</th> <th style='text-align:center;font-size:18px;'>等級</th> </tr> <tr><td> 數學 </td><td> 作業評價/4 </td><td> 課堂表現/4 </td><td> 學科必選/10 </td><td> 學科自選/7 </td><td> 98 </td><td> 68.6 </td><td> 93.6 </td><td> A </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr> </table> </body> </html>"; HtmlToPdf Renderer = new HtmlToPdf(); //設置Pdf參數
            Renderer.Options.PdfPageOrientation = PdfPageOrientation.Landscape;//設置頁面方式-橫向 PdfPageOrientation.Portrait 豎向
            Renderer.Options.PdfPageSize = PdfPageSize.A4;//設置頁面大小,30種頁面大小可以選擇
            Renderer.Options.MarginTop = 10;   //上下左右邊距設置 
            Renderer.Options.MarginBottom = 10; Renderer.Options.MarginLeft = 10; Renderer.Options.MarginRight = 10; //設置更多額參數可以去HtmlToPdfOptions里面選擇設置
            var docHtml = Renderer.ConvertHtmlString(htmlString);//根據html內容導出PDF
            var docUrl = Renderer.ConvertUrl("https://fanyi.baidu.com/#en/zh/");//根據url路徑導出PDF
            string webRootPath = hostingEnv.ContentRootPath;  //獲取項目運行絕對路徑
            var path = $"/ExportPDF/{DateTime.Now.ToString("yyyyMMdd")}/";//文件相對路徑
            var savepathHtml = $"{webRootPath}{path}{Guid.NewGuid().ToString()}-Html.pdf";//保存絕對路徑
            if (!Directory.Exists(Path.GetDirectoryName(webRootPath + path))) { Directory.CreateDirectory(Path.GetDirectoryName(webRootPath + path)); } docHtml.Save(savepathHtml); var savepathUrl = $"{webRootPath}{path}{Guid.NewGuid().ToString()}-Url.pdf";//保存絕對路徑
 docUrl.Save(savepathUrl); return new string[] { savepathHtml, savepathUrl }; }

 

  下面我們看Html內容導出一個PDF文件多個頁面的例子:

  

        /// <summary>
        /// Html導出PDF一個文件多頁
        /// </summary>
        /// <param name="PageSize"></param>
        /// <returns></returns>
        [HttpGet("HtmlToPdfList")]
        public ActionResult<string> HtmlToPdfList(int PageSize = 1)
        {
            //測試Html素材
            string htmlString = @"<!DOCTYPE html>
                        <html>
                        <head>
                            <meta charset='utf-8' />
                            <title></title>
                             <style>
                               body {
                                 margin: 0;
                                 padding: 0;
                                 min-width: 2000px;
                              }
                              .m_table {
                                 border-collapse: separate;
                                 margin: 100px auto 0;
                                 min-width: 1900px;
                                 text-align: center;
                                 font: 500 17px '微軟雅黑';
                                 border-spacing: 0;
                                 border: 1px solid #EBEEF5;
                              }
                        
                              .m_table th {
                                 background-color: #F7F3F7;
                              }
                        
                              .m_table th,
                              .m_table td {
                                 border-right: 1px solid #EBEEF5;
                                 border-bottom: 1px solid #EBEEF5; 
                                 padding: 5px;
                                 height: 60px;
                                 width: 60px;
                              }
                           </style>
                        </head>
                        
                        <body>
                            
                            <table class='m_table'> 
                                <tr>
                                    <th colspan='9' style='text-align:center;font-size:28px;'>期末學生綜合評價表1</th>
                                </tr>
                                <tr>
                                    <th colspan='9' style='text-align:center;font-size:23px;'>班級:一年級一班  姓名:測試  班主任:測試</th> 
                                </tr>
                                <tr>
                                    <th  rowspan='2' style='text-align:center;font-size:24px;'>學科</th>
                                    <th  colspan='2'  rowspan='2' style='text-align:center;font-size:24px;'>過程性評價</th>
                                    <th colspan='2' rowspan='2' style='text-align:center;font-size:24px;'>表現性評價</th>
                                    <th colspan='2'  style='text-align:center;font-size:20px;'>考試性評價</th>
                                    <th colspan='2' style='text-align:center;font-size:20px;'>綜合性評價</th>
                                </tr>
                                <tr> 
                                    <th   style='text-align:center;font-size:18px;'>卷面分</th>
                                    <th  style='text-align:center;font-size:18px;'>權重分</th>
                                    <th   style='text-align:center;font-size:18px;'>總分</th>
                                    <th  style='text-align:center;font-size:18px;'>等級</th>
                                </tr> 
                                
                                <tr><td> 數學 </td><td> 作業評價/4 </td><td> 課堂表現/4 </td><td> 學科必選/10 </td><td> 學科自選/7 </td><td> 98 </td><td> 68.6 </td><td> 93.6 </td><td> A </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr><tr><td> 英語 </td><td> 作業評價/4.5 </td><td> 課堂表現/5 </td><td> 學科必選/1.7 </td><td> 學科自選/1.7 </td><td> 59 </td><td> 41.3 </td><td> 54.2 </td><td> D </td></tr>
                            </table>  
                        </body>
                        </html>";
            PdfDocument docHtml = null;
            for (int j = 0; j < PageSize; j++)
            {
                HtmlToPdf Renderer = new HtmlToPdf();
                //設置Pdf參數
                Renderer.Options.PdfPageOrientation = PdfPageOrientation.Landscape;//設置頁面方式-橫向  PdfPageOrientation.Portrait  豎向
                Renderer.Options.PdfPageSize = PdfPageSize.A4;//設置頁面大小,30種頁面大小可以選擇
                Renderer.Options.MarginTop = 10;   //上下左右邊距設置  
                Renderer.Options.MarginBottom = 10;
                Renderer.Options.MarginLeft = 10;
                Renderer.Options.MarginRight = 10;
                //設置更多額參數可以去HtmlToPdfOptions里面選擇設置

                if (docHtml == null)
                    docHtml = Renderer.ConvertHtmlString(htmlString);//根據html內容導出PDF 
                else
                    //在上一個pdf元素頁面下面追加Pdf頁面,官方文檔對於一個pdf文件打印多頁的處理提供了分頁符,在你想打印一頁的元素外面加上   <div style="font-size: 28px; page-break-after: always">元素
                    //也就是分頁符,但是試用感覺效果並不理想,下面這個Append追加一個pdf頁面效果會更好點,但是可能會損耗一些性能
                    docHtml.Append(Renderer.ConvertHtmlString(htmlString));
            }
            string webRootPath = hostingEnv.ContentRootPath;  //獲取項目運行絕對路徑
            var path = $"/ExportPDF/{DateTime.Now.ToString("yyyyMMdd")}/";//文件相對路徑
            var savepathHtml = $"{webRootPath}{path}{Guid.NewGuid().ToString()}-Html.pdf";//保存絕對路徑
            if (!Directory.Exists(Path.GetDirectoryName(webRootPath + path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(webRootPath + path));
            }
            docHtml.Save(savepathHtml);
            return savepathHtml;
        } 

 

  整個項目Git地址

 


    世界上那些最容易的事情中,拖延時間最不費力。堅韌是成功的一大要素,只要在門上敲得夠久夠大聲,終會把人喚醒的。

     歡迎大家掃描下方二維碼,和我一起學習更多的知識😊

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM