• C#使用wkhtmltopdf,把HTML生成PDF(包含分页)


    最近花了2天多的时间终于把HTML生成PDF弄好了。步骤如下:

    1、首先是技术选型。看了好多都是收费的就不考虑了。

    免费的有:

    1. jsPDF(前端生成,清晰度不高,生成比较慢)
    2. iText(严格要求html标签。这个好像也是收费的)
    3. wkhtmltopdf(简单、配置选项多、生成快、支持跨平台、也支持HTML生成图片) 

    因此选择wkhtmltopdf。

    2、前期准备,首先需要下载wkhtmltopdf.exe(下载地址:https://wkhtmltopdf.org/downloads.html)阅读配置参数(https://wkhtmltopdf.org/usage/wkhtmltopdf.txt

    常用参数:

    1. -T 0 :设置上下左右margin-top=0(-B 0 -L 0 -R 0 -T 0,上下左右都设置一下)
    2. -s A4:设置A4纸大小,默认A4
    3. --disable-smart-shrinking:禁止缩放(不设置这个,生成的pdf会缩放)
    4. --zoom 1:设置缩放系数,默认为1。如果--disable-smart-shrinking设置了,--zoom就不用设置了。
    5. --cookie name value:设置cookie,如果下载的url需要登录(用cookie),那么这个参数很重要。

    3、设置需要打印的页面(核心是分页)

    A4纸大小:210mm×297mm,因此页面的每个div大小也是A4纸大小。

    这里的页面设置很重要。另外,设置了分页的页码,示例如下:

    <style>
    #view {
        height: 100%;
        margin: auto;
        padding: 0;
         210mm;
    }
    
    /*设置A4打印页面*/
    /*备注:由于@是否特殊符号,样式放在css文件中没问题,放在cshtml文件就不行了,需要@@。*/
    @preview-item {
        size: A4;
        margin: 0;
    }
     
    @media print {
        .preview-item {
            margin: 0;
            border: initial;
            border-radius: initial;
             initial;
            min-height: initial;
            box-shadow: initial;
            background: initial;
            page-break-after: always;
        }
    }
    .preview-item {
         100%;
        height: 297mm;
        position: relative;
    }
    
    .page-view {
        position: absolute;
         100%;
        text-align: center;
        height: 60px;
        line-height: 60px;
        bottom: 0;
    }
    </style>
    
    <div id="view">
        <div class="preview-item">
            <div class="preview-item-body">这是第一页</div>
            <div class="page-view">1/3</div>
        </div>
        <div class="preview-item">
            <div class="preview-item-body">这是第二页</div>
            <div class="page-view">2/3</div>
        </div>
        <div class="preview-item">
            <div class="preview-item-body">这是第三页</div>
            <div class="page-view">3/3</div>
        </div>
    </div>

      

    4、C#代码实现(核心是Arguments的设置)

            /// <summary>
            /// HTML生成PDF
            /// </summary>
            /// <param name="url">url地址(需要包含HTTP://)</param>
            /// <param name="path">PDF存放路径(可以是aaa.pdf,也可以用路径,只能是绝对地址,如:D://aaa.pdf)</param>
            public static bool HtmlToPdf(string url, string path)
            {
                path = HttpContext.Current.Server.MapPath(path);string cookie = "cookieKey cookieValue";//改为为你自己的
                string Arguments = "-q  -B 0 -L 0 -R 0 -T 0 -s A4 --no-background --disable-smart-shrinking --cookie " + cookie + " " + url + " " + path; //参数可以根据自己的需要进行修改
    
                try
                {
                    if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(path))
                        return false;
                    var p = new Process();
                    string str = HttpContext.Current.Server.MapPath("/htmlToPDF/wkhtmltopdf.exe");
                    if (!File.Exists(str))
                        return false;
                    p.StartInfo.FileName = str;
                    p.StartInfo.Arguments = Arguments;
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardInput = true;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.RedirectStandardError = true;
                    p.StartInfo.CreateNoWindow = false;
                    p.Start();
                    p.WaitForExit();
                    System.Threading.Thread.Sleep(1000);
    
                    return true;
                }
                catch (Exception ex)
                {
                    LogHelper.WriteError(ex);
                }
                return false;
            }

    方法的调用:

                string url = Request.Url.AbsoluteUri.Replace("DownloadPDF", "Detail");//DownloadPDF是下载页面,Detail是上面的HTML页面
                string pdfDirectory = "/Data/PDF/";
                if (!System.IO.Directory.Exists(HttpContext.Current.Server.MapPath(pdfDirectory)))
                {
                    System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(pdfDirectory));
                }
                string path = pdfDirectory + Guid.NewGuid() + ".pdf";
                HtmlToPdf(url, path);
    
                if (!System.IO.File.Exists(Utils.GetMapPath(path)))//如果生成失败,重试一次
                {
                    HtmlToPdfHelper.HtmlToPdf(url, path);
                }
    
                if (!System.IO.File.Exists(Utils.GetMapPath(path)))//如果生成失败,重试一次
                {
                    HtmlToPdfHelper.HtmlToPdf(url, path);
                }    
    

      

    5、ok,采坑结束~

  • 相关阅读:
    Java类对象转json字符串,servlet或js的json字符串转json对象或数组
    大三下每周总结--第一周
    阅读架构漫谈九篇博客有感-1500字
    大三上寒假15天--第15天
    大三上寒假15天--第14天
    大三上寒假15天--第13天
    jenkins+appium android app自动化测试
    windows jenkins 卸载
    jenkins运行Python
    pytest+jenkins安装+allure导出报告
  • 原文地址:https://www.cnblogs.com/amusement1992/p/9939384.html
Copyright © 2020-2023  润新知