Командная строка --print-to-pdf
По умолчанию --print-to-pdf
пытается создать PDF-файл в каталоге пользователей. По умолчанию в этом каталоге пользователя хранится фактический двоичный файл Chrome, который является папкой конкретной версии для используемой версии, например C: \ Program Files (x86) \ Google \ Chrome \ Application \ 61.0.3163.100. . И по умолчанию ... Хрому запрещена запись в эту папку. Вы можете посмотреть, как он пытается и терпит неудачу, добавляя --enable-logging
в свою команду.
К сожалению, по умолчанию эта команда не работает. *
Вы можете решить эту проблему, указав путь в аргументе, где Chrome может писать - например,
--print-to-pdf="C:\Users\Jane\test.pdf"
Или вы можете изменить каталог пользователей:
--user-data-dir="C:\Users\Jane"
Одна из причин, по которой вы можете предпочесть изменить каталог пользователей, заключается в том, что вы хотите, чтобы PDF-файл автоматически получал свое имя с веб-страницы; Chrome просматривает тег заголовка, а затем выгружает его как <title>My Page</title>
= ›My-Page.pdf
* Я думаю, что это поведение по умолчанию очень сбивает с толку и должно быть зарегистрировано как ошибка Chrome. Однако, по-видимому, часть команды Chrome категорически возражает против простого существования этой опции командной строки и вместо этого считает, что было бы лучше заставить всех, кто ее использует, получить сборку node.js с Puppeteer и полностью удаленным флагом.
Ограничения командной строки в Windows
Вызов хрома таким образом будет работать нормально, например, в локальной среде разработки на IIS Express с Visual Studio, но он не будет работать даже в режиме без головы на сервере, на котором запущен IIS, потому что пользователям IIS не предоставлены интерактивные разрешения / разрешения рабочего стола и способ, которым Chrome захватывает этот PDF-файл, на самом деле требует интерактивных разрешений / разрешений рабочего стола. Существуют сложные способы предоставления этих разрешений, но везде, где вы читали о том, как начинается с НЕ ПРЕДОСТАВЛЯЙТЕ ИНТЕРАКТИВНЫЕ РАЗРЕШЕНИЯ / РАЗРЕШЕНИЯ ДЛЯ НАСТОЛЬНОГО ПК. Кроме того, вышеупомянутый риск того, что Chrome однажды избавится от командной строки, еще больше усложняет работу, чтобы заставить его работать сомнительное предложение.
Альтернативы командной строке Chrome
wkhtmltopdf
За кулисами Chrome просто использует wkhtmltopdf. Я не пробовал, но, скорее всего, это сделает работу. Единственный незначительный риск заключается в том, что при создании PDF-файлов в Chrome тестирование очевидно: просмотрите страницу в Chrome. Откройте предварительный просмотр печати, если вы нервничаете. В wkhtmltopdf на самом деле это другая сборка Chromium, и это может привести к различиям в рендеринге. Может быть.
Селен
Другой вариант - опередить группу, желающую избавиться от --print-to-pdf
и использовать API разработчика браузера (через Selenium) по своему усмотрению. **
private static void pdfSeleniumImpl(string url, string pdfPath)
{
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
options.AddArgument("headless");
using (var chrome = new OpenQA.Selenium.Chrome.ChromeDriver(options))
{
chrome.Url = url;
var printToPdfOpts = new Dictionary<string, object>();
var resultDict = (Dictionary<string, object>)
chrome.ExecuteChromeCommandWithResult(
"Page.printToPDF", printToPdfOpts);
dynamic result = new DDict(resultDict);
string data = result.data;
var pdfFile = Convert.FromBase64String(data);
System.IO.File.WriteAllBytes(pdfPath, pdfFile);
}
}
DDict выше - это GracefulDynamicDictionary из другого моего ответа.
https://www.nuget.org/packages/GracefulDynamicDictionary/
https://github.com/b9chris/GracefulDynamicDictionary
https://stackoverflow.com/a/24192518/176877
В идеале это было бы асинхронно, поскольку все вызовы Selenium на самом деле являются сетевыми командами, и запись этого файла может потребовать много операций ввода-вывода на диск. Данные, возвращаемые из Chrome, также являются потоком. Однако традиционно используемая библиотека Selenium, к сожалению, вообще не использует асинхронность, поэтому потребуется обновить эту библиотеку или определить надежную асинхронную библиотеку Selenium для .Net, чтобы действительно сделать это правильно.
https://github.com/puppeteer/puppeteer/blob/master/lib/Page.js#L1007
https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
** Команда Page.pdf
chrome Dev API также устарела, поэтому, если этот контингент добьется своего, ни командная строка, ни Dev API не будут работать. Тем не менее, похоже, что те, кто пытался его разрушить, отказались от этого 2 года назад.
person
Chris Moschini
schedule
04.11.2019