日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# Winform 使用 PuppeteerSharp 进行网页截图、生成pdf等操作

發布時間:2023/12/16 C# 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# Winform 使用 PuppeteerSharp 进行网页截图、生成pdf等操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目背景

? ? ? ? 公司某項目上有一需求:要對合同、驗收、付款申請單等審批頁面進行截圖,并生成Pdf文件回傳到影像系統做最終的歸檔。然后衍生出來了一個WinForm的自動截圖工具,其大致的實現邏輯是:定時請求數據庫,抓取帶截圖的數據,組裝得到審批頁面地址,winfrom中引用WebView進行加載地址,在OnLoadingFinish加載完成方法里面,通過ScreenShot()獲取等到Bitmap對象,然后在進行pdf文檔的生成。

? ? ? ? 弊端:因為是前后端分離的項目,OnLoadingFinish中無法判定ajax請求是否完畢,還需要定時器進行延遲截圖、保存;其次是穩定性不高,可能是技術問題,經常導致程序奔潰,并且winform無法捕獲到異常,但是另外一個項目崩潰幾率很小,可能是數據量小吧

重構

? ? ? ? 基于原項目使用的WebVIew,控件老舊,并且功能不太優化,所以采用了PuppeteerSharp進行了重構。

運行環境:Windows 服務器 開發環境:Vs@2017、.net framework 4.6以及以上,本項目4.8

PuppeteerSharp?

????????Puppeteer是一個通過 DevTools Protocol 控制 headless chrome 的 high-level Node 庫,也可以通過設置使用 非 headless Chrome。

我們手工可以在瀏覽器上做的事情,Puppeteer 都能勝任:

  • 生成網頁截圖或者 PDF
  • 爬取大量異步渲染內容的網頁,基本就是人肉爬蟲
  • 模擬鍵盤輸入、表單自動提交、UI 自動化測試????????
  • ????????PuppeteerSharp是官方Node.JS Puppeteer API的.NET移植。

    ? ? ? ? 1.由于Puppeteer-Sharp是NetStandard 2.0庫,因此最低平臺版本是.NET Framework 4.6.1和.NET Core 2.0

    ? ? ? ? 2.支持WebSocket庫的最低Windows版本是Windows 8和Windows Server 2012,具體參見?System.Net.WebSockets Namespace | Microsoft Docs

    安裝

    ? ? ? ? 1.使用Nuget搜索PuppeteerSharp,找到PuppeteerSharp點擊安裝即可。

    PuppeteerSharp的使用? ? ?

    ? ? ? ? ?1.獲取Browsers對象

    private async Task<Browser> Browsers(){try{await slimLock.WaitAsync();// 已經拷貝了.local-chromium,不需要再下載了//await new BrowserFetcher().DownloadAsync();if (_browser == null){_browser = await Puppeteer.LaunchAsync(new LaunchOptions{Headless = true, DefaultViewport = null,//Args = new string[] {// "--disable-infobars",//隱藏 自動化標題// "--no-sandbox", // 沙盒模式// "--start-maximized" // 最大化//}}); ;return _browser;}return _browser;}catch (Exception ex){throw ex;}finally{slimLock.Release();}}

    ? ? ? ? 2.生成Pdf,注意看注釋,方法中有倆種邏輯【一種是先生成圖片,然后圖片轉成pdf;一種是官方的生成pdf的方法,只不過官方的會有分頁,長頁面看著不太優化,所以采用了第一種方式】

    private async Task BrowsersPageToPdf(string loadUrl, string savePath){var page = await _browser.NewPageAsync();// 設置頁面分辨率await page.SetViewportAsync( new ViewPortOptions(){ Width = 1400, Height = 1050 });ScreenshotLoading("頁面加載完成,等待數據渲染");//load: window.onload事件被觸發時候完成導航,某些情況下它根本不會發生。//domcontentloaded: Domcontentloaded事件觸發時候認為導航成功//networkidle0: 在 500ms 內沒有網絡連接時就算成功(全部的request結束),才認為導航結束//networkidle2: 500ms 內有不超過 2 個網絡連接時就算成功(還有兩個以下的request),就認為導航完成//加載時長 networkidle0 > networkidle2 > load > domcontentloadedawait page.GoToAsync(loadUrl, new NavigationOptions() { WaitUntil = new WaitUntilNavigation[] { WaitUntilNavigation.Networkidle0 } });ScreenshotLoading("頁面加載完成,數據渲染完成,頁面截圖中....");ScreenshotOptions screenshotOptions = new ScreenshotOptions();//screenshotOptions.Clip = new PuppeteerSharp.Media.Clip() { Height = 0, Width = 0, X = 0, Y = 0 };//設置截剪區域screenshotOptions.FullPage = true; //是否截取整個頁面screenshotOptions.OmitBackground = false;//是否使用透明背景,而不是默認白色背景screenshotOptions.Quality = 100; //截圖質量 0-100(png不可用)screenshotOptions.Type = ScreenshotType.Jpeg; //截圖格式var saveFile = System.IO.Path.GetDirectoryName(savePath);if (!Directory.Exists(saveFile)){FileInfo fi = new FileInfo(saveFile);Directory.CreateDirectory(fi.DirectoryName);}string imgUrl = saveFile + "\\" + CurrentHandlerData.DataKey + "_" + Guid.NewGuid() + ".jpg";await page.ScreenshotAsync(imgUrl, screenshotOptions);ScreenshotLoading("頁面截圖完成,正在轉Pdf文件...");//var stream = await page.ScreenshotStreamAsync();CommonHelper.ConvertJpg2Pdf(imgUrl, savePath);ScreenshotLoading("頁面截圖完成,Pdf文件生成成功!");CommonHelper.FileDel(imgUrl);ScreenshotLoading("頁面截圖文件刪除成功!");//官方生成Pdf方法//設置PDF選項//PdfOptions pdfOptions = new PdfOptions();//pdfOptions.DisplayHeaderFooter = false; //是否顯示頁眉頁腳//pdfOptions.FooterTemplate = ""; //頁腳文本//pdfOptions.Format = new PuppeteerSharp.Media.PaperFormat(11.27m, 30m); //pdf紙張格式 英寸為單位 pdfOptions.Format = PaperFormat.A4;//pdfOptions.PrintBackground = true; // false pdf文件為灰白色,一些背景色也顯示出來; true 頁面為彩色//pdfOptions.HeaderTemplate = ""; //頁眉文本//pdfOptions.Landscape = false; //紙張方向 false-垂直 true-水平//pdfOptions.MarginOptions = new PuppeteerSharp.Media.MarginOptions() { Bottom = "0px", Left = "0px", Right = "0px", Top = "0px" }; //紙張邊距,需要設置帶單位的值,默認值是None//pdfOptions.Scale = 1m; //PDF縮放,從0-1//await page.PdfAsync(savePath, pdfOptions);await page.DisposeAsync();}

    坑點:

    ? ? ? ? 1.puppeteer需要Chromium 內核用以加載網頁,所以要先調用類庫的下載sdk,他自動幫你下載Chromium ,這也可能導致第一次沒有Chromium會卡一陣子,因為在下載 ,完成之后,再程序根目錄【bin/Debug】下會發現.local-chromium 的一個文件夾

    ? ? ? ? 2.獲取Browser對象時,如果LaunchOptions.Headless設置為false,不能進行pdf文件生成,可以截圖,同時可以看到程序調用的headless chrome的窗口

    ? ? ? ? 3.LaunchOptions.DefaultViewport 為null,瀏覽的頁面會默認瀏覽器窗口大小,也可以自定義其大小【沒有試過】,否則的話,在chrome中可以看到,右邊會有部分留白

    ? ? ? ? 4.截圖之前最好設置下分辨率:SetViewportAsync,否則圖可能截不全

    ? ? ? ? 5.有的復雜網頁可能要加載一段時間,不然截圖是空白或者不完整的,可以延時或者使用類庫提供的等待方法【特別是前后端分離的項目,注意看生成pdf方法中的注釋】

    其他

    ????????PuppeteerSharp還可以進行:向網頁中注入HTML、執行Javascript(js)代碼、連接到遠程瀏覽器等等其他功能,也可以用于爬蟲場景,其他功能可以看下官方介紹

    ? ? ? ? 圖片轉Pdf方法:

    public static void ConvertJpg2Pdf(string jpgfile, string pdf){var document = new Document();using (var stream = new FileStream(pdf, FileMode.Create, FileAccess.Write, FileShare.None)){var pdfWriter = PdfWriter.GetInstance(document, stream);using (var imageStream = new FileStream(jpgfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){var image = iTextSharp.text.Image.GetInstance(imageStream);pdfWriter.CloseStream = false;document.SetPageSize(new iTextSharp.text.Rectangle(image.Width + 72f, image.Height + 72f));//(WWidth + 72f, HHeight + 72f));document.Open();image.Alignment = iTextSharp.text.Image.ALIGN_MIDDLE;document.Add(image);}document.Close();}}

    總結

    以上是生活随笔為你收集整理的C# Winform 使用 PuppeteerSharp 进行网页截图、生成pdf等操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。