html2pdf 网页转PDF

Gayhub 链接

问遍谷歌百度,依然没有好的方案.

打开Gayhub ,发现万赞JS(html2PDF,HTML2canvas) 效果也就那个XX样,一张糊里糊涂的img 冒充精美的PDF?

经过一天的苦思冥想,借助HiqPDF (估计Itext , spirePDF 等类似的都可以,思路还用这个就可以了),终于实现了目前来看最完美的方案 - -而且,贼简单你敢信?

先来个效果图 (= ̄ω ̄=)

GayHub首页转PDF去水印效果.png

看到了吗 ,页眉的黄色 水印精确删除 ,不用PS ,文字成段的在文件里 ,可以随意加工 ,图片的位置 , 边缘都很完美 ... 放大了看,还是那么清晰 - -我草 ,牛B!

简单版本,读文件 - -好处是无视网站定制,坏处当然就是非自动化啦(,,・ω・,,)

在你的后台放一个接收器,java,golang,python版本的 ,改天懒癌减轻了就补:

        public ActionResult getWOW()
        {
            FileStream fs = new FileStream(Server.MapPath("/App_Data/wow.txt"), FileMode.OpenOrCreate, FileAccess.Read);//路径
            StreamReader sr = new StreamReader(fs, Encoding.UTF8);
            var htm = sr.ReadToEnd();
            sr.Close();
            fs.Close();
            // create the HTML to PDF converter
            HtmlToPdf htmlToPdfConverter = new HtmlToPdf();

            // set browser width
            htmlToPdfConverter.BrowserWidth = 1440;

            // set browser height if specified, otherwise use the default
            htmlToPdfConverter.BrowserHeight = htmlToPdfConverter.BrowserWidth * 2;

            // set HTML Load timeout
            //htmlToPdfConverter.HtmlLoadedTimeout = int.Parse(textBoxLoadHtmlTimeout.Text);

            // set PDF page size and orientation
            //htmlToPdfConverter.Document.PageSize = new PdfPageSize((float)(width / 2.4), (float)(height / 2.4));
            htmlToPdfConverter.Document.PageSize = new PdfPageSize(htmlToPdfConverter.BrowserWidth, htmlToPdfConverter.BrowserHeight);
            htmlToPdfConverter.Document.PageOrientation = PdfPageOrientation.Portrait;

            // set the PDF standard used by the document
            htmlToPdfConverter.Document.PdfStandard = PdfStandard.Pdf;//checkBoxPdfA.Checked ? PdfStandard.PdfA :

            // set PDF page margins
            htmlToPdfConverter.Document.Margins = new PdfMargins(0);

            // set whether to embed the true type font in PDF
            htmlToPdfConverter.Document.FontEmbedding = true;

            // set triggering mode; for WaitTime mode set the wait time before convert
            htmlToPdfConverter.TriggerMode = ConversionTriggerMode.Auto;

            // set header and footer
            //SetHeader(htmlToPdfConverter.Document);
            //SetFooter(htmlToPdfConverter.Document);

            // set the document security
            //htmlToPdfConverter.Document.Security.OpenPassword = textBoxOpenPassword.Text;
            htmlToPdfConverter.Document.Security.AllowPrinting = true;

            // set the permissions password too if an open password was set
            if (htmlToPdfConverter.Document.Security.OpenPassword != null && htmlToPdfConverter.Document.Security.OpenPassword != String.Empty)
                htmlToPdfConverter.Document.Security.PermissionsPassword = htmlToPdfConverter.Document.Security.OpenPassword + "_admin";

            //Cursor = Cursors.WaitCursor;

            // convert HTML to PDF
            string pdfFile = null;
            // convert URL to a PDF memory buffer
            //string url = formCollection["textBoxUrl"];
            byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htm, null);

            // send the PDF document to browser
            FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
            fileResult.FileDownloadName = "HtmlToPdf.pdf";

            return File(pdfBuffer, "application/octet-stream", "test.pdf");//最后一个双引号里面是回传的文件名,加个time值就可以避免重复了
        }

在浏览器按F12打开控制台(console)输入document.getElementsByTagName("html")[0].innerHTML

把得到的字符串拷贝到路径保存

然后把服务器跑起来,激活一下这个controller "http://localhost:3095/"

然后你就就会下载一个PDF,打开看看,激不激动?开不开心?

进阶版本- -前后端交互

  1. Controller:

        public ActionResult GetPDFfromHtmlCode(int width, int height, string htm)
        {
            htm = Server.UrlDecode(htm);
            //var path = Server.MapPath("/").Replace("\\", "/");
            var path = @"C:\Users\Public\Documents\DevExpress Demos 18.1\Components\ASP.NET\CS\ASPxCardViewDemos";
            htm = htm.Replace("/Content/",path+ "/Content/")
                .Replace("src=\"", "src=\""+path)
                //.Replace("<script src=\"", "<script src=\"" + path)
                //.Replace("type=\"text/css\" href=\"", "type=\"text/css\" href=\"" + path)
                .Replace("//","/")
                ;
            // create the HTML to PDF converter
            HtmlToPdf htmlToPdfConverter = new HtmlToPdf();

            // set browser width
            htmlToPdfConverter.BrowserWidth = 1440;

            // set browser height if specified, otherwise use the default
            htmlToPdfConverter.BrowserHeight = height;

            // set HTML Load timeout
            //htmlToPdfConverter.HtmlLoadedTimeout = int.Parse(textBoxLoadHtmlTimeout.Text);

            // set PDF page size and orientation
            //htmlToPdfConverter.Document.PageSize = new PdfPageSize((float)(width / 2.4), (float)(height / 2.4));
            htmlToPdfConverter.Document.PageSize = new PdfPageSize(htmlToPdfConverter.BrowserWidth, height);
            htmlToPdfConverter.Document.PageOrientation = PdfPageOrientation.Portrait;

            // set the PDF standard used by the document
            htmlToPdfConverter.Document.PdfStandard = PdfStandard.Pdf;//checkBoxPdfA.Checked ? PdfStandard.PdfA :

            // set PDF page margins
            htmlToPdfConverter.Document.Margins = new PdfMargins(0);

            // set whether to embed the true type font in PDF
            htmlToPdfConverter.Document.FontEmbedding = true;

            // set triggering mode; for WaitTime mode set the wait time before convert
            htmlToPdfConverter.TriggerMode = ConversionTriggerMode.Auto;

            // set header and footer
            //SetHeader(htmlToPdfConverter.Document);
            //SetFooter(htmlToPdfConverter.Document);

            // set the document security
            //htmlToPdfConverter.Document.Security.OpenPassword = textBoxOpenPassword.Text;
            htmlToPdfConverter.Document.Security.AllowPrinting = true;

            // set the permissions password too if an open password was set
            if (htmlToPdfConverter.Document.Security.OpenPassword != null && htmlToPdfConverter.Document.Security.OpenPassword != String.Empty)
                htmlToPdfConverter.Document.Security.PermissionsPassword = htmlToPdfConverter.Document.Security.OpenPassword + "_admin";

            //Cursor = Cursors.WaitCursor;

            // convert HTML to PDF
            string pdfFile = null;
            // convert URL to a PDF memory buffer
            //string url = formCollection["textBoxUrl"];
            byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htm, null);

            // send the PDF document to browser
            FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
            fileResult.FileDownloadName = "HtmlToPdf.pdf";

            return File(pdfBuffer, "application/octet-stream","test.pdf");
        }
  1. JS里面这个激活(注意转译html):
        var DownLoadFile = function (options) {
            var config = $.extend(true, { method: 'post' }, options);
            var $iframe = $('<iframe id="down-file-iframe" />');
            var $form = $('<form target="down-file-iframe" method="' + config.method + '" />');
            $form.attr('action', config.url);
            for (var key in config.data) {
                $form.append('<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />');
            }
            $iframe.append($form);
            $(document.body).append($iframe);
            $form[0].submit();
            $iframe.remove();
        }
         DownLoadFile({
                url: "http://localhost:3095/test/getPDFfromHtmlCode", //the URI of your controller
                data: { "height": $("body").outerHeight(), "width": $("body").outerWidth(), "htm": escape(document.getElementsByTagName("html")[0].innerHTML), "head": "test" }//the data in your request ,according to your controller
            });

最后说明

首先你要转的网页最好资源文件都是绝对路径的,因为巧妇难为无米之炊 ,你的服务器拿不到资源文件去渲染,当然就做不到给你一个完美的PDF

其次,如果是相对路径, 你需要在后端用replace大法,把相对路径转成服务器能获得的绝对路径

再其次,终极办法就是把网页里面的左右资源文件,你都给手动下载到服务器上,然后把相对地址都引用到这个位置, 除了太神奇的样式,基本都可以做到所见即所得

免费版本的hiqPDF会在文件的页眉位置打水印 ,这个时候就体现我们方法的好处了:导出的PDF不是图片而是真的PDF编码,所以可以用福昕 PDF 之类的软件打开把这个水印删除掉

(当然你也可以在后端直接替换编码,我这就不搞了,眼睛疼(๑´ڡ`๑))

开动一下脑筋,其实配合Markdown,在线Excel ,在线简历设计等等 东西,你可以很轻松的得到一份好看的PDF格式的 文档,图表,简历 ~~

所以不要纠结于我的代码是否好看,主要是思路 - -遇山劈山,逢海填海 :前端没法很好的渲染,那就放到后端; 后端拿不到相对路径 ,就转成绝对路径;手动麻烦 ,就封装成POST ,配合编解码函数`````

你看,html2canvas 2pdf 都有那么多的赞,效果其实就一张模糊的图片 ,而我们,用一个简单低级的思路, 得到了一份几乎完美的PDF文件 ,所以,思路啊老铁~~

声明:

  • 无意支持盗版,大家有hiqPDF使用权的就用就好了,试用免费版本的也不触犯法律,效果还是可以的~~
  • 对于非开发人员或者纯前端 ,这个方法还是稍微有点成本的 ,在此表示歉意
  • 介于第二点 ,我准备在工作安稳一点后搭建一个在线的网站, 实现思路已经有了,希望到时候有志同道合的大佬们多给建议,多给帮助~~

既然你都看到这里了,鼠标移到右上角给个star咯 ( ¯ ³¯)♡ㄘゅ

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容