Headless Chrome для печати PDF

Я пытаюсь использовать функцию Headless Chrome для преобразования HTML в PDF. Однако я вообще не получаю вывода. Консоль также не показывает никаких ошибок. Я запускаю команды ниже в своих окнах m / c.

хром --headless --disable-gpu --print-to-pdf

Я перепробовал все разные варианты. Ничего не создается. У меня хром версия 60


person user2580925    schedule 06.09.2017    source источник


Ответы (7)


Командная строка --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
comment
Не понимаю, почему для файлов в текущем каталоге требуется полный путь - например: C:\Users\User\Documents\XstReader>"C:\Program Files (x86)\Google\Chrome\Application\chrome" --headless --disable-gpu --print-to-pdf=C:\Users\User\Documents\XstReader\DemoEmail.pdf --no-margins "C:\Users\User\Documents\XstReader\Demo Email.html" - person flywire; 04.12.2019
comment
Поскольку Chrome игнорирует текущий каталог, вместо этого использует каталог данных пользователя. - person Chris Moschini; 05.12.2019
comment
это отличный ответ, должен набрать не менее 100 голосов. Особенно функция селена. Спасибо, см @ChrisMoschini - person Jeanno; 10.04.2020
comment
За кулисами Chrome просто использует wkhtmltopdf. - необходима ссылка. - person Bergi; 07.09.2020
comment
Большое спасибо за подсказку Selenium! Обратите внимание, что вариант без заголовка важен, поскольку в противном случае по умолчанию необходимое расширение будет отключено в Chrome, что приведет к ошибке PrintToPDF не реализовано. (В качестве альтернативы, предположительно, он может быть явно включен для режима без головы, но я этого не пробовал.) - person Otto G; 19.09.2020

Это работает:

chrome --headless --disable-gpu --print-to-pdf=file1.pdf https://www.google.co.in/

создает файл в папке: C:\Program Files (x86)\Google\Chrome\Application\61.0.3163.100.

person SURAJ    schedule 23.10.2017

Не забудьте открыть свой терминал / cmd с правами админа :) Иначе он просто не сохранит файл вообще.

person Dobromir Hristov    schedule 10.07.2018

Расширяя блестяще простой ответ suraj, я создал небольшую функцию, которая находится в моем исходном пути, поэтому она работает как инструмент CLI:

function webtopdf(){
    chromium-browser --headless --disable-gpu --print-to-pdf=$2 $1
}

так быстро

webtopdf https://goo.com/some-article some-article.pdf

делает работу за меня сейчас

person pascalwhoop    schedule 29.05.2018

Мне не хватало знака "=" после команды печати в PDF.

Правильная команда:

chrome --headless --disable-gpu --print-to-pdf="C:/temp/name.pdf" https://www.google.com/

Теперь работает.

person user2580925    schedule 06.09.2017
comment
Не используйте ответы как комментарии - person N-ate; 08.08.2018
comment
Это правильный ответ, ему нужен полный путь к файлу при печати в pdf, или он не работает в Windows по состоянию на 27.05.19 - person Max; 28.05.2019

Это сработало для меня в окнах

начать chrome --headless --disable-gpu --print-to-pdf = C: \ Users \ username \ pdfs \ chrome.pdf --no-margins https://www.google.com

person vipin cp    schedule 13.08.2019
comment
Вы можете использовать в Powershell (и в GitBash) --print-to-pdf="$(pwd)\output.pdf" для печати в текущей папке. На меня --no-margins не действуют. - person Kpym; 25.01.2020

В настоящее время это доступно только для Linux и Mac OS.

person Mrunal Brahmbhatt    schedule 27.03.2019