[C#]使用第三方開源庫iText7.pdfHtml,將Html轉換成Pdf,以及如何以Html作為打印模板


使用第三方開源庫iText7.pdfHtml,將html和css轉成pdf,官方:https://itextpdf.com/en/demos/convert-html-css-to-pdf-free-online;

官方示例:

using System.IO;
using iText.Html2pdf;

namespace WebsiteDemoPdfHtml
{
    class Program
    {
        private static string ORIG = "/uploads/input.html";
        private static string OUTPUT_FOLDER = "/myfiles/";

        static void Main(string[] args)
        {
            string pdfDest = OUTPUT_FOLDER + "output.pdf";
            HtmlConverter.ConvertToPdf(new FileStream(ORIG, FileMode.Open), new FileStream(pdfDest, FileMode.Create));
        }
    }
}

官方可以下載到詳細的使用說明文檔:

設置默認打印紙張大小:

var pdfDest = "hello.pdf";
var pdfWriter = new PdfWriter (pdfDest);
var pdf = new PdfDocument (pdfWriter);

var pageSize = PageSize.A4; // 設置默認打印紙張大小,css @page規則可覆蓋這個
pdf.SetDefaultPageSize (pageSize);

支持css @page規則控制打印設置選項,例如css @page設置A3打印紙,橫向打印,這些規規將覆蓋上面的設置默認打印紙張大小:

@page {
    size: A3 landscape;
}

如果需要引入其他資源,比如插入圖片,需要設置根目錄,將資源文件放入根目錄或子文件夾下:

var properties = new ConverterProperties ();
properties.SetBaseUri ("wwwroot"); // 設置根目錄

默認不支持中文字體,需要修改默認字體提供者,使其支持系統字體:

var provider = new DefaultFontProvider (true, true, true); // 第三個參數為True,以支持系統字體,否則不支持中文
properties.SetFontProvider (provider);

支持css @media規則,使其在不同設備上顯示不同效果,比如在預覽時使用Screen設備顯示彩色效果,在打印時使用Print設備增強黑白效果:

var mediaDeviceDescription = new MediaDeviceDescription (MediaType.PRINT); // 指當前設備類型,如果是預覽使用SCREEN
mediaDeviceDescription.SetWidth (pageSize.GetWidth ());
properties.SetMediaDeviceDescription (mediaDeviceDescription);

最后是以html作為打印模板,加載數據,再轉成pdf;

官方推薦的是使用XSL轉換(xmlns:xsl="http://www.w3.org/1999/XSL/Transform"),將xml轉換成html,但該示例目前僅支持java,c#找不到相關源碼,並且該方式不支持模板預覽,不方便用戶修改模板:

所以還是推薦使用正則替換規則導入數據,下面是示例html:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <style type="text/css">
        @page {
            size: A4 landscape;
        }

        ul {
            margin-left: 0;
            padding-left: 0;
        }

            ul li {
                list-style: none;
            }

                ul li:after {
                    content: "";
                    display: block;
                    clear: both;
                }

                ul li p {
                    float: left;
                    margin-left: 2em;
                }

                    ul li p:first-child {
                        margin-left: 0;
                    }

                    ul li p img {
                        width: 36px;
                        height: 36px;
                    }
    </style>
</head>
<body>
    <h3>使用第三方庫iText7.pdfHtml,將Html轉換成Pdf,以及如何以Html作為打印模板</h3>
    <h5>{{ListOfNames}}</h5>
    <ul>
        <!--template-start-->
        <li>
            <p><img src="{{Avatar}}" /></p>
            <p>姓名:{{Name}}</p>
            <p>年齡:{{Age}}</p>
            <p>性別:{{Sex}}</p>
        </li>
        <!--template-end-->
    </ul>
</body>
</html>
View Code

使用雙大括號{{field}}作為書簽,但因為有列表數據,如果直接替換,可能將列表數據修改,所以應該先替換列表數據,在該示例中,以<!--template-start-->作為模板匹配頭,以<!--template-end-->作為模板匹配尾,然后不斷復制匹配字段,如果子模版又有子模版,則先替換子模版,以此類推,下面是完整代碼:

using iText.Html2pdf;
using iText.Html2pdf.Resolver.Font;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.StyledXmlParser.Css.Media;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace Demo
{
    class Program
    {
        static void Main(String[] args)
        {
            var pdfDest = "hello.pdf";
            var pdfWriter = new PdfWriter(pdfDest);
            var pdf = new PdfDocument(pdfWriter);

            var pageSize = PageSize.A4;       // 設置默認頁面大小,css @page規則可覆蓋這個
            pdf.SetDefaultPageSize(pageSize);

            var properties = new ConverterProperties();
            properties.SetBaseUri("wwwroot");     // 設置根目錄
            properties.SetCharset("utf-8");

            var provider = new DefaultFontProvider(true, true, true);       // 第三個參數為True,以支持系統字體,否則不支持中文
            properties.SetFontProvider(provider);

            var mediaDeviceDescription = new MediaDeviceDescription(MediaType.PRINT);      // 指當前設備類型,如果是預覽使用SCREEN
            mediaDeviceDescription.SetWidth(pageSize.GetWidth());

            properties.SetMediaDeviceDescription(mediaDeviceDescription);

            var peoples = new List<People>
            {
                new People { Avatar = "avatar.jpg", Name = "小明", Age = 23, Sex = "" },
                new People { Avatar = "avatar.jpg", Name = "小王", Age = 18, Sex = "" },
                new People { Avatar = "avatar.jpg", Name = "小櫻", Age = 19, Sex = "" },
                new People { Avatar = "avatar.jpg", Name = "小蘭", Age = 20, Sex = "" },
            };

            var htmlTemplate = File.ReadAllText("wwwroot/hello.html");

            Dictionary<String, String> dic = null;
            Regex regex = null;

            var start = "<!--template-start-->";
            var end = "<!--template-end-->";

            var match = Regex.Match(htmlTemplate, $@"{start}(.|\s)+?{end}");

            if (match != null && match.Value.Length > start.Length + end.Length)
            {
                var template = match.Value.Substring(start.Length, match.Value.Length - start.Length - end.Length);

                var sb = new StringBuilder(start);

                foreach (var people in peoples)
                {
                    dic = HtmlTemplateDataBuilder.Create(people);
                    regex = new Regex(String.Join("|", dic.Keys));
                    sb.Append(regex.Replace(template, m => dic[m.Value]));
                }

                sb.Append(end);

                htmlTemplate = htmlTemplate.Replace(match.Value, sb.ToString());
            }

            dic = new Dictionary<String, String> { ["{{ListOfNames}}"] = "人員列表" };
            regex = new Regex(String.Join("|", dic.Keys), RegexOptions.IgnoreCase);

            var html = regex.Replace(htmlTemplate, m => dic[m.Value]);
            HtmlConverter.ConvertToPdf(html, pdf, properties);
        }

        struct People
        {
            public String Avatar { get; set; }      // 頭像
            public String Name { get; set; }        // 姓名
            public Int32 Age { get; set; }          // 年齡
            public String Sex { get; set; }         // 性別
        }

        public static class HtmlTemplateDataBuilder
        {
            public static Dictionary<String, String> Create(Object obj)
            {
                var props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);

                var dic = new Dictionary<String, String>();

                foreach (var prop in props)
                {
                    dic.Add("{{" + prop.Name + "}}", prop.GetValue(obj, null).ToString());
                }

                return dic;
            }
        }
    }
}
View Code

 


免責聲明!

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



猜您在找 C# C/S程序使用HTML文件作為打印模板 使用Spire PDF for .NET將HTML轉換成PDF文檔 網絡采集軟件核心技術剖析系列(4)---使用C#語言如何將html網頁轉換成pdf(html2pdf) (轉)C# 打印PDF文件使用第三方DLL JAVA中將html轉換成pdf html,vue轉換成PDF html頁面轉換成pdf 根據第三方庫spire.pdf使用指定打印機打印pdf文件 C#將HTML表格
 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM
轉換成DataTable python 調用第三方庫壓縮png或者轉換成webp