最近客户的管理系统导出PDF功能莫名其妙坏掉了,经过对导出流程的梳理,发现系统的导出流程大致分为如下两步:
(1)创建并设置WebBrowser,通过WebBrowser获取页面内容并保存为图片。
(2)调用ITextSharp,设定为A4纸大小,将(1)的图片按A4大小保存为PDF文件。
经过场景还原,发现系统是能导出PDF文件的,只是PDF内是一张无法导航到页面的图片,可以排除ITextSharp功能Bug的可能性,遂针对WebBrowser进行了一系列排查。
我对于WebBrowser并不了解,只能从头开始百度怎么用WebBrowser保存页面为图片,查找到的很多帖子都是给WebBrowser加事件(这里再次吐槽各个网站的照搬党们),该方法大致对于WebBrowser的使用流程如下:
(1)创建一个WebBrowser类型的变量:
WebBrowser webBrowser = new WebBrowser(); // 创建一个WebBrowser webBrowser.ScrollBarsEnabled = false; // 隐藏滚动条 webBrowser.Navigate(pageUrl); // 打开网页
(2)为变量添加DocumentCompleted(加载文档时触发)
private void Wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { WebBrowser webBrowser = (WebBrowser)sender; // 网页加载完毕才保存 while (webBrowser.ReadyState != WebBrowserReadyState.Complete) { System.Windows.Forms.Application.DoEvents(); } // 获取网页高度和宽度,也可以自己设置 int height = webBrowser.Document.Body.ScrollRectangle.Height; int width = webBrowser.Document.Body.ScrollRectangle.Width; // 调节webBrowser的高度和宽度 webBrowser.Height = height; webBrowser.Width = width; System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height); // 创建高度和宽度与网页相同的图片 System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(0, 0, width, height); // 绘图区域 webBrowser.DrawToBitmap(bitmap, rectangle); // 截图 bitmap.Save(ITextImagePath); // 保存图片 }
这个方法经过尝试最后放弃,因为流程走到事件里的while循环处每一次的判断条件都是false,WebBrowser变量的状态永远是Uninitialized(未加载文档)而不是Complete(文档加载完成),导致while变成一个无限循环。
后来发现其实没必要用事件,不要把WebBrowser变量和它的读取状态判断分开,直接写在一起就好。放弃使用Navigate方法加载网页,而是直接为WebBrowser变量设定Url属性,大致如下:
protected void Button2_Click(object sender, EventArgs e) { WebBrowser webBrowser = new WebBrowser(); // 创建一个WebBrowser webBrowser.ScrollBarsEnabled = false; // 隐藏滚动条 webBrowser.ScriptErrorsSuppressed = true; //不显示弹框,避免脚本错误提示 webBrowser.Size = new Size(842, 595);//设定网页大小 按需自定 webBrowser.Url = new Uri(pageUrl);//要加载的页面地址 while (webBrowser.ReadyState != WebBrowserReadyState.Complete) { System.Windows.Forms.Application.DoEvents(); } // 获取网页高度和宽度,也可以自己设置 int height = webBrowser.Document.Body.ScrollRectangle.Height; int width = webBrowser.Document.Body.ScrollRectangle.Width; System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height); // 创建高度和宽度与网页相同的图片 System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(0, 0, width, height); // 绘图区域 webBrowser.DrawToBitmap(bitmap, rectangle); // 截图 bitmap.Save(ITextImagePath); // 保存图片 }