PHP Печать на сетевой принтер

Что я пытаюсь сделать

Распечатайте документ PDF на сетевом принтере, передав параметры печати для таких вещей, как цвет, ориентация, двусторонняя печать и т. д.

Дополнительная информация

  • У нас есть несколько сетевых принтеров, для которых IP-адреса являются статическими и известными (например, 192.168.0.10).
  • Я нашел документ, содержащий список параметров/параметров, которые можно передать принтеру для изменения настроек печати здесь (большинство из них можно найти на странице 25)
  • Мы создаем процесс, с помощью которого мы будем печатать документ в черно-белом режиме, ЗА ИСКЛЮЧЕНИЕМ второй страницы. Это означает, что первая страница, а также страница 3 и далее напечатаны в черно-белом цвете; страница 2 должна быть напечатана в цвете. (Это связано со стоимостью цветной печати, плюс наши другие страницы не содержат цвета, поэтому печатать их в цвете ЧРЕЗВЫЧАЙНО бессмысленно и примерно в 8 раз дороже - этот процесс будет печатать тысячи страниц каждый месяц, что в сумме составляет много $$$)

В чем я несколько преуспел

Я зашел на один из принтеров (192.168.0.10 — Ricoh MP C5503 [если вам действительно нужно знать]) и добавил FTP-доступ.

Печать документа с помощью командной строки в Windows работает!

> ftp 192.168.0.10
> User (192.168.0.10:(none)): username
> Password: password
> put path\to\file.pdf filetype=PDF
> bye

Что я пытался сделать

Попытка 1 с использованием PHP-функции exec()

Я пробовал МНОГИЕ способы заставить exec работать, но безрезультатно. Мне не удалось запустить многострочные команды с помощью функции PHP exec (в идеале, выполнив следующее). При выполнении следующего внутри exec() я не могу подключиться к FTP, поскольку каждая строка должна выполняться после запуска предыдущей строки. Я ничего не нашел в Интернете (многократные поиски в Google не дают результатов [за исключением того, как вывести несколько строк вывода из cmd, а не как последовательно вставлять несколько строк cmd])

> ftp 192.168.0.10
> User (192.168.0.10:(none)): username
> Password: password
> put path\to\test.pdf filetype=PDF
> bye

Попытка 2 с использованием PHP-функции exec()

Я попытался запустить команду ftp, передав текстовый файл в качестве некоторых ответов на this предложить сообщение. Это решение не работает должным образом. При запуске ftp -i -s:test.txt из командной строки это работает; в PHP это не так.

PHP-файл

exec("ftp -i -s:test.txt");

Текстовый файл (test.txt)

open 192.168.0.10
username
password
put test.pdf filetype=PDF
bye

Попытка 3 с использованием функций PHP FTP

Чего я сейчас не могу понять, так это того, как отправить файл на принтер по ftp и как настроить параметры принтера.

$ftp = [
    'server'   => gethostbyaddr('192.168.0.10'),
    'username' => 'username',
    'password' => 'password',
];
$conn = ftp_connect($ftp['server']);
$login = ftp_login($conn, $ftp['username'], $ftp['password']);
if (is_readable($file)) {
    if (ftp_put($conn, $file, $file, FTP_ASCII)) {
        echo 'Successfully executed command';
    }
    else {
        echo 'Failed execution of command';
    }
}
else {
    echo 'File is not readable';
}

Идеально...

Я ищу решение, которое будет работать как в системах Windows, так и в Linux, поскольку мы также находимся в процессе перехода с IIS на NGINX (слава богу...). Метод, который, по моему мнению, был бы наилучшей реализацией, заключается в использовании ftp для Windows и rcp или rsh для Linux (поскольку документацию по принтеру я прикрепил в разделе Дополнительная информация в разделе Что я пытаюсь сделать). упоминаются эти методы для печати).

Я также хотел бы, чтобы нам не приходилось генерировать текстовые файлы или файлы какого-либо другого типа для печати этих документов. Наши пользователи могут одновременно обрабатывать сотни файлов, и я понимаю, что мы можем дать уникальное имя каждому текстовому файлу, а затем удалить его после успешного запуска сценария, хотя я бы предпочел чистое решение, в котором мы можем передавать такие параметры, как принтер ( IP или имя из функции gethostbyaddr()), имя пользователя, пароль, файл для печати, параметры (например, цвет, двусторонняя печать, тип файла, ориентация, переплет и т. д.). Мы используем MPDF для создания наших PDF-файлов, поэтому предпочтительным будет метод, который поместит файл, не создавая его на нашем сервере, где нам затем придется его удалить (т.е. MPDF строковое вложение для электронной почты), но это не обязательно.

Кроме того

Решение должно работать с PHP.

Я продолжу исследовать другие методы печати документов на сетевых принтерах после того, как опубликую это, пока не будет найдено жизнеспособное решение, и буду обновлять свой пост соответствующим образом после каждой попытки.

Любая помощь по этому поводу приветствуется.



Правки


Неудачные методы

Метод: функции PHP-принтера

функции принтера позволяют печатать, однако они не позволяют контролировать задания на печать (такие параметры, как цветная/черно-белая печать, тип файла, двусторонняя печать и т. д.). Таким образом, этот вариант (если только у кого-то нет хака, работать не будет)

Метод: JavaScript/AJAX

Хотя JavaScript/AJAX будет работать для печати (и разрешать настройки печати), мы потенциально будем обрабатывать сотни страниц одновременно, и обработка может отправлять задания на печать на несколько принтеров (т. е. в разные офисы). Идея состоит в том, чтобы автоматизировать нашу печать как для этого процесса, так и для будущих процессов.


Непроверенные методы

Методы: еще не проверены


Решение?

В итоге я создал сценарий C#, чтобы выполнить все, что мне нужно было сделать. Поскольку мои требования к параметрам печати довольно специфичны, вот ссылка на пространство имен Microsoft System.Drawing.Printing. Используя это пространство имен, я смог создать подходящие методы для своих нужд. Несколько вопросов/ответов StackOverflow ниже, которые содержат более подробную информацию об использовании:

Как запустить С# в PHP? Это зависит от вас. Вы можете взаимодействовать с C# API (например, запустив C# на другом веб-сервере), ссылаться на .NET DLL, использовать PeachPie или вводить объявления во время выполнения.


Вы также можете придумать что-нибудь с помощью PowerShell (см. Документация по управлению печатью здесь). Это позволит вам запустить скрипт с помощью exec() — см. этот вопрос относительно выполнения PowerShell из PHP.


person ctwheels    schedule 06.12.2016    source источник
comment
Рассматривали ли вы возможность использования IPP вместо FTP для связи с принтерами?   -  person Dezza    schedule 06.12.2016
comment
@ Дезза, у меня нет. Я буду исследовать это сейчас. Спасибо   -  person ctwheels    schedule 06.12.2016
comment
Вы пытались использовать printer_open ([ string $printername ] ) функцию PHP?   -  person odedta    schedule 06.12.2016
comment
@odedta Я исследовал функции PHP-принтера, и, хотя они казались многообещающими, мне не удалось найти параметр принтера, который позволяет указать цветную печать вместо черно-белой. См. эту страницу: php.net/manual/fa/function.printer- set-option.php для списка опций. Однако меня смутили варианты PRINTER_TEXT_COLOR и PRINTER_BACKGROUND_COLOR   -  person ctwheels    schedule 06.12.2016
comment
Черт, это так глупо... как насчет того, чтобы найти библиотеку Javascript, которая работает с принтерами, и отправлять эти запросы через AJAX?   -  person odedta    schedule 06.12.2016
comment
@odedta Это может быть возможным, однако, если кто-то решит обработать ~300 файлов, создание может занять несколько минут. Если они щелкнут со страницы, она перестанет работать. Это также означало бы, что им придется выбирать принтер. У нас несколько офисов, и наши сотрудники могут оформлять документы для другого офиса (то есть распечатывать их нужно там). Мы стремимся автоматизировать процесс и предотвратить ошибки пользователя.   -  person ctwheels    schedule 06.12.2016
comment
Это выглядит интересно: printnode.com/docs/introduction   -  person odedta    schedule 06.12.2016
comment
Спасибо, что напомнили мне, как должен выглядеть вопрос SO, и что надежда еще есть!   -  person DaGhostman Dimitrov    schedule 06.12.2016


Ответы (2)


Попробуй это:

$ftp = ftp_connect('192.168.0.10');
if(ftp_login($ftp,'username','password')){
    if(ftp_put($ftp,'filetype=PDF','yourfile.pdf',FTP_BINARY)){
        echo 'success';
    }
}

Дайте мне знать, что вы получите.

Обновление: из руководства по принтеру на стр. 19, вы можете использовать следующую команду для отправки файла и одновременной установки параметров устройства:

ftp> put file1 filetype=postscript,tray=tray1,copies=3,resolution=600

В этом примере file1 — это имя локального файла, который вы хотите отправить, а filetype=postscript,tray=tray1,copies=3,resolution=600 — это имя удаленного файла. Чтобы быть точным, фактическая команда FTP:

STOR filetype=postscript,tray=tray1,copies=3,resolution=600

Используя функции PHP FTP, код PHP:

ftp_put($ftp,'filetype=postscript,tray=tray1,copies=3,resolution=600','file1',FTP_BINARY);

Где $ftp — дескриптор соединения после успешного вызова ftp_connect().

Применительно к моему первому примеру код становится таким:

$ftp = ftp_connect('192.168.0.10');
if(ftp_login($ftp,'username','password')){
    if(ftp_put($ftp,'filetype=postscript,tray=tray1,copies=3,resolution=600','file1',FTP_BINARY)){
        echo 'success';
    }
}

Попробуйте.

person Rei    schedule 14.12.2016
comment
Хотя использование PHP-функций ftp может работать для загрузки файла на принтер через ftp, при этом нет возможности указать параметры принтера. Функция ftp_put не допускает аргументов (если только это не делает другая функция ftp_*). Кроме того, я не верю, что предоставленный вами код будет работать правильно, поскольку вторым параметром для ftp_put должен быть удаленный файл (т.е. myfile.pdf) в соответствии с документацией: php.net/manual/en/function.ftp-put.php - person ctwheels; 15.12.2016
comment
Согласно мануалу, на который вы дали ссылку, так и будет. Дайте мне несколько минут, чтобы обновить мой ответ. - person Rei; 15.12.2016
comment
Я проголосовал за этот ответ, так как этот код позволяет выполнять сетевую печать и указывать атрибуты, связанные с общим заданием на печать, что другим может показаться полезным, однако мы по-прежнему не можем обработать 1 задание на печать с указанием настроек цветного/монохромного изображения для отдельных страниц. Одним из вариантов может быть создание 3 заданий на печать, где первое и третье — монохромные, а второе — цветное, однако это будет выполняться как 3 отдельных задания на печать, что не допускает отделки (например, сшивания), а также возможность для других заданий на печать проходить между 3 заданиями на печать. - person ctwheels; 15.12.2016
comment
@ctwheels Чтобы сохранить 1 задание на печать для каждого документа, пробовали ли вы отображать свои PDF-документы черным цветом, за исключением страницы 2, и настраивать принтер для автоматического обнаружения только черных страниц? Я настроил свой принтер для этого и сэкономил много тонера CMY. Ваш принтер кажется намного более сложным, чем мой, поэтому я думаю, что он должен уметь делать то же самое. Возможно, обратитесь в службу поддержки Ricoh за подобной конфигурацией. - person Rei; 16.12.2016

Хотя большая часть моих попыток печатать на сетевом принтере не удалась, и я не могу найти подходящего решения. Также shell_exec ("AcroRd32.exe") и через "другой pdfprinter" не работают, поскольку моему серверу WAMP требуется специальное разрешение для программ с графическим интерфейсом. Теперь я, наконец, нашел решение, которое работает для меня.

Это решение только для Windows

Загрузите PDFtoPrinter

Код для печати на сетевом/локальном принтере

$command = escapeshellcmd('PDFtoPrinter YOURFILE.PDF "\\\YOURSERVERNAME\YOURPRINTERNAME"');
$output = shell_exec($command);
echo $output;
person Bhadresh    schedule 09.07.2018