使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)

导出效果:
使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)

因为是基于wkhtmltopdf插件,所以服务器上都需安装一下wkhtmltopdf插件,并配置环境变量。

1、安装wkhtmltopdf插件

下载安装

官网下载地址:https://wkhtmltopdf.org/downloads.html
使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)
按需下载对应的版本,安装即可。我的安装在 C:\Program Files\ 下

网盘下载地址:https://pan.baidu.com/s/1LiTU5Q6FZopOCHB9740vrg
提取码:22nd

配置环境变量

在系统的path变量中添加 “C:\Program Files\wkhtmltopdf\bin;”

使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)
注意:C:\Program Files\wkhtmltopdf 为wkhtmltopdf的安装路径。我的安装在c盘 的 Program Files文件夹下

使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)

2、将wkhtmltopdf安装路径下的安装文件复制,粘贴到项目下(这一步也可省略,但在代码中需将执行命令的wkhtmltopdf.exe路径指向安装路径)

使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)
使用wkhtmltopdf.exe 将HTML内容转换为PDF(含分页)

3、上代码

我为了省事做了一个html模板页,其实也可以不做,写在代码里也是一样的。

export_to_pdf.html

<style>
    #view {
        height: 100%;
        margin: auto;
        padding: 0;
        width: 210mm;
    }

    /*设置A4打印页面*/
    /*备注:由于@是否特殊符号,样式放在css文件中没问题,放在cshtml文件就不行了,需要@@。*/
    @preview-item {
        size: A4;
        margin: 0;
    }

    @media print {
        .preview-item {
            margin: 0;
            border: initial;
            border-radius: initial;
            width: initial;
            min-height: initial;
            box-shadow: initial;
            background: initial;
            page-break-after: always;
        }
    }

    .preview-item-body{
        padding:0 20px;
    }
    .preview-item {
        width: 100%;
        height: 297mm;
        position: relative;
    }

    .page-view {
        position: absolute;
        width: 98%;
        text-align: right;
        padding-right:20px;
        height: 60px;
        line-height: 60px;
        bottom: 0;
    }

    .tab_top {
        width: 100%;
        font-size: 24px;
        text-align: center;
        margin: 20px 0;
    }

    .bb-table {
        width: 98%;
        font-size: 14px;
      
        border-right: 1px solid black;
        border-bottom: 1px solid black;
        border-collapse: collapse;
    }

        .bb-table tr th {
            height: 35px;
            border-top: 1px solid black;
            border-left: 1px solid black;
            text-align: left;
            padding-left: 5px;
        }

        .bb-table tr td {
            height: 35px;
            border-top: 1px solid black;
            border-left: 1px solid black;
            border-bottom: 1px solid black;
            text-align: center;
            padding: 2px;
        }
</style>

<div id="view">
    ${CONTENT}
</div>

ExportToPDFHelper.cs

 public static class ExportToPDFHelper
    {

        private static string exePath = System.Web.HttpContext.Current.Server.MapPath("\\wkhtmltopdf\\bin\\wkhtmltopdf.exe");//执行命令的wkhtmltopdf.exe路径

        /// <summary>
        /// HTML文本内容转换为PDF
        /// </summary>
        /// <param name="strHtml">HTML文本内容</param>
        /// <param name="exportFileName">文件名</param>
        /// <returns></returns>
        public static bool HtmlTextConvertToPdf(string strHtml, string exportFileName,string userMark = null)
        {
            bool flag = false;
            try
            {
                string htmlPath = HtmlTextConvertFile(strHtml);

                if (string.IsNullOrWhiteSpace(exportFileName))
                    exportFileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(1000, 10000);
                string fileName = exportFileName + ".pdf";
                flag = HtmlConvertToPdf(htmlPath, fileName, "Portrait","A4",userMark);

                if (File.Exists(htmlPath))
                {
                    File.Delete(htmlPath);
                }

            }
            catch
            {
                flag = false;
            }
            return flag;
        }
        /// <summary>
        /// HTML转换为PDF
        /// </summary>
        /// <param name="htmlPath">可以是本地路径,也可以是网络地址</param>
        /// <param name="savePath">PDF文件保存的路径</param>
        /// <param name="orientation">纵向-Portrait 横向-Landscape</param>
        /// <returns></returns>
        public static bool HtmlConvertToPdf(string htmlPath, string fileName, string orientation, string type = "A4", string userMark = null)
        {
            bool flag = false;
            string filepath = System.Web.HttpContext.Current.Server.NewTempFilePath(fileName, userMark);
            string savePathName = System.Web.HttpContext.Current.Server.MapPath(filepath);

            if (File.Exists(savePathName))
            {
                File.Delete(savePathName);
            }
            ///这个路径为程序集的目录,因为我把应用程序 wkhtmltopdf.exe 放在了程序集同一个目录下
            if (!File.Exists(exePath))
            {
                throw new Exception("No application wkhtmltopdf.exe was found.");
            }
            try
            {
                string Arguments = $"-q  -B 0 -L 0 -R 0 -T 0 -O {orientation} -s {type} --no-background --disable-smart-shrinking {htmlPath} {savePathName}"; //参数可以根据自己的需要进行修改
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.UseShellExecute = false;
                startInfo.RedirectStandardInput = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.FileName = exePath;
                startInfo.Arguments = Arguments;
                startInfo.CreateNoWindow = true;
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
               
                using (var cc = Process.Start(startInfo))
                {
                    cc.WaitForExit();
                    flag = true;
                }
                DownLoadFile(savePathName, fileName);
            }
            catch (Exception ex)
            {

                flag = false;
                throw ex;
            }
            return flag;
        }
        /// <summary>
        /// HTML文本内容转HTML文件
        /// </summary>
        /// <param name="strHtml">HTML文本内容</param>
        /// <returns>HTML文件的路径</returns>
        public static string HtmlTextConvertFile(string strHtml)
        {
            if (string.IsNullOrEmpty(strHtml))
            {
                throw new Exception("HTML text content cannot be empty.");
            }

            try
            {
                string path = System.Web.HttpContext.Current.Server.MapPath("\\FileTemp\\" + DateTime.Today.ToString("yyyyMMdd"));
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                string fileName = path + DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(1000, 10000) + ".html";
                using (FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    using (StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8))
                    {
                        streamWriter.Write(strHtml);
                        streamWriter.Flush();
                    }
                };
                return fileName;
            }
            catch
            {
                throw new Exception("HTML text content error.");
            }
        }
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileName">物理路径文件</param>
        /// <param name="fileName">下载的文件名</param>
        public static void DownLoadFile(string savePathName, string fileName)
        {
            if (File.Exists(savePathName))
            {
                FileInfo fi = new FileInfo(savePathName);
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ClearHeaders();
                HttpContext.Current.Response.Buffer = false;
                //HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                // HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName);
                //加上HttpUtility.UrlEncode()方法,防止文件下载时,文件名乱码,(保存到磁盘上的文件名称应为“中文名.gif”) 已测试:IE、谷歌、火狐、360浏览器
                //.Replace("+","%20") 空格转换后会变成+,这里将加密后+,替换成空格
                HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename*=UTF-8''" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8).Replace("+", "%20"));
                HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString());
                HttpContext.Current.Response.ContentType = "application/octet-stream;charset=utf-8";
                HttpContext.Current.Response.WriteFile(savePathName);
                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.End();
                fi.Delete();//将服务器文件删除
            }
        }
    }
		/// <summary>
        /// 打印模板内容
        /// </summary>
        /// <param name="tempFileName"></param>
        /// <returns></returns>
        private string GetPrintTempContent(string tempFileName)
        {
            Encoding code = Encoding.GetEncoding("utf-8");
            // 读取模板文件
            string temp = Server.MapPath(string.Format("/PrintTemp/{0}", tempFileName));
            StreamReader sr = null;
            string str = string.Empty;
            try
            {
                sr = new StreamReader(temp, code);
                str = sr.ReadToEnd(); // 读取文件
            }
            catch (Exception ex)
            {
                sr.Close();
               throw ex;
            }
            return str;
        }

		 public void _ExportPDF(){
			var str = GetPrintTempContent("export_to_pdf.html");
			var fileName="2021年XXXXX名单";
		    var list = .....;//数据源
		     if (list != null && list.Count > 0)
             {
            	StringBuilder sContent = new StringBuilder();
                int x = 0, xh = 1, pageSize = 22;//每页显示条数
                var total = list.Count;//总记录数
                int num = total % pageSize == 0 ? (total / pageSize) : (total / pageSize + 1);//总页数
                do
                {
                    sContent.Append("<div class=\"preview-item\"><div class=\"preview-item-body\">");
                    sContent.AppendFormat("<div class='tab_top'><p style='margin-top: 50px; padding-top:50px;'>{0}</p></div>", title);
                    sContent.Append("<table cellspacing = '0' cellpadding='0' style='border-bottom:none;' class='bb-table'>");
                    sContent.Append("<tr><td style=\"width:5%;\">序号</td><td style=\"width:27%;\">学校名称</td><td style=\"width:15%;\">姓名</td><td style=\"width:5%;\">性别</td><td style=\"width:23%;\">证件号码</td><td style=\"width:25%;\">备注</td></tr>");
                    for (int j = 0; j < ((num == 1 || (x + 1) == num) ? total - x * pageSize : pageSize); j++)
                  	{
                       	var index = x * pageSize + j;
                       	var item = list[index];
                       	sContent.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>",xh,item.DistrictName,item.SchoolName, item.StudentName, item.GenderName, item.IDCode,item.Remark);
                       	xh++;
                     }
                    sContent.AppendFormat("</table></div><div class=\"page-view\">第 {0} 页 共 {1} 页</div></div>", (x + 1), num);
                    x++;
				} while (x < num);
		         str = str.Replace("${CONTENT}", sContent.ToString());
		     }else{
 				str = str.Replace("${CONTENT}", "未找到相关信息"));
			}
		     ExportToPDFHelper.HtmlTextConvertToPdf(str,fileName, "");
		}
<form name="formmain" id="formmain" class="form-inline" method="post" onkeydown="if(event.keyCode==13){return false;}">
	 <input type="button" class="layui-btn btn2" onclick="javascript:OnExportPDF();" value="导出名单(PDF)" />
</form>

<script type="text/javascript">
	function OnExportPDF() {
		 $("#formmain").attr("action", "@Url.Action("_ExportPDF")").submit();
	}
</script>
上一篇:asp.net core cookie身份验证


下一篇:Dynamics CRM Form表单中通过javascript抓取触发change事件字段的属性名