private async Task <string> GetHtmlSourceByPuppeteer(string url) { //增加一些状态消息 ShowStatusTextPuppeteer("正在下载Chromium浏览器"); //下载Chromium浏览器 await new PuppeteerSharp.BrowserFetcher().DownloadAsync(PuppeteerSharp.BrowserFetcher.DefaultRevision); ShowStatusTextPuppeteer("初始化浏览器"); var options = new PuppeteerSharp.LaunchOptions(); var showBrowerFlag = this.cbox_ShowChrome_Puppeteer.IsChecked.Value; //如果显示浏览器,需要设置为false options.Headless = showBrowerFlag == true ? false : true; //启动浏览器 var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options); //打开一个标签 var page = await browser.NewPageAsync(); ShowStatusTextPuppeteer($"打开网址{url}"); await page.GoToAsync(url); var html = await page.GetContentAsync(); //关闭浏览器 browser.Disconnect(); browser.Dispose(); ShowStatusTextPuppeteer("就绪"); return(html); }
public async Task <IActionResult> ReportSheet(long id, CancellationToken cancellationToken) { try { var model = await _appDb.MatchRepository.GetMatchReportSheetAsync(_siteContext.MatchPlanTournamentId, id, cancellationToken); if (model == null) { return(NotFound()); } #region ** Puppeteer PDF generation using Chromium ** var options = new PuppeteerSharp.LaunchOptions { Headless = true, Args = new[] { "--no-sandbox", "--disable-gpu", "--disable-extensions" }, ExecutablePath = Path.Combine(Directory.GetCurrentDirectory(), @"Chromium-Win\chrome.exe"), Timeout = 10000 }; // Use Puppeteer as a wrapper for the Chromium browser, which can generate PDF from HTML using var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options); using var page = await browser.NewPageAsync(); // page.GoToAsync("url"); var html = await _razorViewToStringRenderer.RenderViewToStringAsync( $"~/Views/{nameof(Match)}/{ViewNames.Match.ReportSheet}.cshtml", model); await page.SetContentAsync(html); // Bootstrap 4 is loaded from CDN var contentDisposition = new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); contentDisposition.SetHttpFileName($"{_localizer["Report Sheet"].Value} {model.Id}.pdf"); Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.ContentDisposition] = contentDisposition.ToString(); return(new FileStreamResult(await page.PdfStreamAsync(new PuppeteerSharp.PdfOptions { Scale = 1.0M, Format = PaperFormat.A4 }), "application/pdf")); #endregion // For development: return HTML // return View(ViewNames.Match.ReportSheet, model); } catch (Exception e) { _logger.LogCritical(e, $"{nameof(ReportSheet)} failed for match ID '{id}'"); throw; } }
public async Task <IActionResult> ReportSheet(long id, CancellationToken cancellationToken) { var pathToChromium = Path.Combine(Directory.GetCurrentDirectory(), _configuration["Chromium:ExecutablePath"]); MatchReportSheetRow model = null; try { model = await _appDb.MatchRepository.GetMatchReportSheetAsync(_tenantContext.TournamentContext.MatchPlanTournamentId, id, cancellationToken); if (model == null) { return(NotFound()); } if (System.IO.File.Exists(pathToChromium)) { #region ** Puppeteer PDF generation using Chromium ** var options = new PuppeteerSharp.LaunchOptions { // --use-cmd-decoder=passthrough causes Chromium error Headless = true, Args = new[] { "--no-sandbox", "--disable-gpu", "--disable-extensions", "--use-cmd-decoder=validating" }, ExecutablePath = pathToChromium, Timeout = 10000 }; // Use Puppeteer as a wrapper for the Chromium browser, which can generate PDF from HTML using var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(options).ConfigureAwait(false); using var page = await browser.NewPageAsync().ConfigureAwait(false); // page.GoToAsync("url"); var html = await _razorViewToStringRenderer.RenderViewToStringAsync( $"~/Views/{nameof(Match)}/{ViewNames.Match.ReportSheet}.cshtml", model); await page.SetContentAsync(html); // Bootstrap 4 is loaded from CDN var contentDisposition = new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); contentDisposition.SetHttpFileName($"{_localizer["Report Sheet"].Value} {model.Id}.pdf"); Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.ContentDisposition] = contentDisposition.ToString(); browser.Process?.Refresh(); _logger.LogInformation( "Chromium Process physical memory: {0:#,0} bytes. Start arguments: {1}", browser.Process?.WorkingSet64, browser.Process?.StartInfo.Arguments); // Test, whether the chromium browser renders at all /* return new FileStreamResult( * await page.ScreenshotStreamAsync(new PuppeteerSharp.ScreenshotOptions * {FullPage = true, Quality = 100, Type = ScreenshotType.Jpeg}).ConfigureAwait(false), * "image/jpeg"); */ // Todo: This part works on the development machine, but throws on the external web server var result = new FileStreamResult( await page.PdfStreamAsync(new PuppeteerSharp.PdfOptions { Scale = 1.0M, Format = PaperFormat.A4 }).ConfigureAwait(false), "application/pdf"); _logger.LogInformation("PDF stream created with length {0}", result.FileStream.Length); await browser.CloseAsync(); return(result); /* Todo: This is a working fallback code, which acts with Chromium directly, and requires the Url to the HTML content * var tempdir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); * if (Directory.Exists(tempdir)) Directory.CreateDirectory(tempdir); * var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); * var si = new System.Diagnostics.ProcessStartInfo(pathToChromium, * $"--disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=TranslateUI --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --headless --hide-scrollbars --mute-audio --no-sandbox --disable-gpu --disable-extensions --use-cmd-decoder=validating --no-margins --user-data-dir={tempdir} --print-to-pdf={tempFile} https://volleyball-liga.de/") * {CreateNoWindow = true, UseShellExecute = false}; * var proc = System.Diagnostics.Process.Start(si); * proc.WaitForExit(5000); * _logger.LogInformation("{0}", proc.ExitCode); * var stream = System.IO.File.OpenRead(tempFile); * return new FileStreamResult(stream, "application/pdf"); */ #endregion } } catch (Exception e) { _logger.LogCritical(e, $"{nameof(ReportSheet)} failed for match ID '{id}'"); } // without Chromium installed or throwing exception: return HTML Response.Clear(); return(View(ViewNames.Match.ReportSheet, model)); }