PHP Print to Network Printer
Asked Answered
C

3

20

What I'm trying to do

Print a PDF document on a network printer while passing printing parameters for things such as colour, orientation, duplex, etc.

More information

  • We have multiple network printers, for which the IPs are static and known (i.e. 192.168.0.10)
  • I found a document containing a list of parameters/options that can be passed to the printer for changing print settings here (most of which can be found on page 25)
  • We are creating a process by which we will be printing a document in black and white EXCEPT the second page. This means that the first page, as well as page 3 and beyond are printed in black and white; page 2 is to be printed in colour. (This is due to cost of colour printing, plus our other pages don't contain colour, so printing them in colour is EXTREMELY pointless and approx. 8x more expensive - This process will be printing thousands of pages each month, which adds up to a lot of $$$)

What I've been somewhat successful with

I logged into one of the printers (192.168.0.10 - Ricoh MP C5503 [if you really must know]) and added FTP access

Printing a document using the command prompt in Windows works!

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

What I've tried to do

Attempt 1 using PHP's exec() function

I've tried MANY ways to make exec work, but to no avail. I have not been able to run multiline commands using PHP's exec function (ideally, running the following). When running the following inside exec(), I am unable to connect to FTP since each line must be executed after the previous line has run. I have found nothing online (multiple Google searches yield no results [except how to echo multiple output lines from cmd - not how to insert multiple cmd lines consecutively])

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

Attempt 2 using PHP's exec() function

I attempted to run the ftp command by passing a text file as some answers on this post suggest. This solution does not work as expected. When running ftp -i -s:test.txt from a command prompt, this works; in PHP, it does not.

PHP File

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

Text File (test.txt)

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

Attempt 3 using PHP's FTP functions

What I can't figure out now, is how to send the file to the printer over ftp and how to set the printer settings

$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';
}

Ideally...

I'm looking for a solution that would work on both Windows and Linux systems as we are also in the process of moving from IIS to NGINX (thank god...). The method that I believe would be the best implementation is using ftp for Windows and rcp or rsh for Linux (since the printer documentation I attached under More information in the What I'm trying to do section mentions these methods for print).

I'd also like if we did not have to generate txt files or some other file type in order to print these documents. Our users may be processing hundreds of files at once, which I understand we can uniquely name each txt file and then delete after the script has successfully run, although I'd much prefer a clean solution where we can pass in parameters such as printer (IP or name from gethostbyaddr() function), username, password, file to be printed, options (i.e. colour, duplex, filetype, orientation, binding, etc.). We are using MPDF to generate our PDF files, so a method that would place the file without actually creating it on our server where we would then have to delete it would be preferred (i.e. MPDF string attachment for email) but these are not required.

Additionally

The solution must work with PHP.

I will continue to investigate more methods for printing documents on network printers after I post this until a viable solution has been found and update my post accordingly following each attempt.

Any help regarding this is greatly appreciated.



Edits


Unsuccessful methods

Method: PHP Printer functions

The printer functions do allow for printing, however they do not allow for control over the print jobs (options such as color/black and white printing, filetype, duplex, etc.). Thus, this options (unless someone has a "hack", will not work)

Method: JavaScript/AJAX

Although JavaScript/AJAX would work for printing (and allow print settings), we will be processing potentially hundreds of pages at once and the processing may be pushing print jobs to multiple printers (i.e. in different offices). The idea is to automate our printing for this process and for future processes alike.


Untested methods

Methods: Not yet tested


Solution?

I ended up creating a C# script to accomplish everything I needed to do. Since my requirements are fairly specific with regards to print settings, here's a link to Microsoft's System.Drawing.Printing namespace. Using this namespace, I was able to create appropriate methods for my needs. A few StackOverflow questions/answers below that provide more details on usage:

How to run C# in PHP? That's up to you. You can interface with a C# API (having C# run on another web server for example), reference the .NET DLL, use PeachPie, or inject declarations at runtime.


You may also be able to conjure up something using PowerShell (see PrintManagement documentation here). This would allow you to run the script using exec() - see this question regarding the execution of PowerShell from PHP.

Clymer answered 6/12, 2016 at 14:56 Comment(8)
Have you considered using IPP rather than FTP to talk to the printers?Pluri
@Pluri I have not. I will investigate it now. Thank youClymer
Did you try using printer_open ([ string $printername ] ) PHP func?Hypnosis
@Hypnosis I did investigate the PHP Printer functions, and although they seemed promising, I was unable to find a printer option that allows to specify colour vs black and white printing. See this page: php.net/manual/fa/function.printer-set-option.php for a list of options. I was, however, confused by the PRINTER_TEXT_COLOR and PRINTER_BACKGROUND_COLOR optionsClymer
Damn, that is so silly... how about looking for a Javascript Library that deals with printers and sending those requests via AJAX?Hypnosis
@Hypnosis That might be possible, however, if someone decides to process ~300 files, it may take a few minutes to generate. If they click off the page, it would stop running. This would also mean that they would have to select the printer. We have multiple offices and our employees may process documents for another office (which means it should be printed there). We're looking to automate the process and prevent user error.Clymer
This looks interesting: printnode.com/docs/introductionHypnosis
Thank you for reminding me how a SO question should look like and that there is still hope!Whitleather
I
3

Try this:

$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';
    }
}

Let me know what you get.

Update: from the printer's manual on page 19, you can use the following command to send a file and set the device options at the same time:

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

In that example, file1 is the local file name that you want to send, filetype=postscript,tray=tray1,copies=3,resolution=600 is the remote file name. To be precise, the actual FTP command is:

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

Using PHP's FTP functions, the PHP code is:

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

Where $ftp is the connection handle from a successful call to ftp_connect().

Putting it to my first example, the code becomes:

$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';
    }
}

Give it a try.

Insulate answered 14/12, 2016 at 1:23 Comment(4)
Although using PHP ftp functions may work for uploading a file to the printer via ftp, there is no way to specify printer settings while doing so. The ftp_put function does not allow for arguments (unless another ftp_* function does). Also, I don't believe the code you provided would work correctly as the second parameter for ftp_put must be the remote file (i.e. myfile.pdf) according to the docs: php.net/manual/en/function.ftp-put.phpClymer
According to the manual you provided the link to, it will. Give me a few minutes to update my answer.Insulate
I've upvoted this answer as this code allows for network printing and specifying attributes associated with the overall print job, which others may find userful, however, we are still unable to process 1 print job with specifying colour/monochrome settings for individual pages. One option could be to create 3 print jobs where the first and third are monochrome and the second is colour, however, this would go through as 3 separate print jobs, which does not allow for finishes (such as stapling) and there is also the possibility for other print jobs to go through between the 3 print jobs.Clymer
@Clymer To keep 1 print job per document, have you try rendering your PDF documents in black except for page 2 and configure your printer to automatically detect black-only pages? I configured my printer to do that and I save a lot of CMY toner. Your printer seems to be a lot more sophisticated than mine, so I imagine it should be able to do the same. Perhaps ask Ricoh support for a similar configuration.Insulate
P
0

I found a way that work with some printers. I create a pdf with fpdf then send directly to printer:

//This is the final output from fpdf
$pdf -> Output('tmp/lbl.pdf', 'F');

if (($conp = fsockopen("10.0.0.100", 9100, $errno, $errstr)) === false)
    echo 'Connection Failed' . $errno . $errstr;
else {
    fputs($conp, file_get_contents('tmp/lbl.pdf'));
    fclose($conp);
}

This work with a Xerox but not in a Sharp, I found the fpdf creates on version 1.4 and some printers doesn't support. For that I send it as tiff format, converting the pdf with ghostscript.

This code is using gs x32 in windows 10 x64 with apache (WAMP) installed:

    shell_exec("\"c:\\program files (x86)\\gs\\gs9.56.1\\bin\\gswin32c\" -sDEVICE=tiffg4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=tmp\\lbl.tiff tmp\\lbl.pdf");
    fputs($conp, file_get_contents('tmp/lbl.tiff'));

On windows server 2019 x64 with IIS I have to switch to gs 64 and only change the next line:

shell_exec("\"c:\\program files\\gs\\gs9.56.1\\bin\\gswin64c\" -q -dNOPAUSE -sDEVICE=tiffg4 -sOutputFile=tmp\\lbl.tiff tmp\\lbl.pdf -c quit");

I have to use the full gs route on both to make it work.

Phyto answered 21/4, 2022 at 23:0 Comment(0)
D
-1

Although, much of my try failed to print on network printer and can't find proper solution. Also shell_exec("AcroRd32.exe") and via "other pdfprinter" not working as my WAMP server need special permission for GUI programs. Now I've finally find a solution that work for me.

This is for windows only solution

Download PDFtoPrinter

Code to print on network/local printer

$command = escapeshellcmd('PDFtoPrinter YOURFILE.PDF "\\\YOURSERVERNAME\YOURPRINTERNAME"');
$output = shell_exec($command);
echo $output;
Demulsify answered 9/7, 2018 at 6:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.