Auto printing a set of PDF from web on multiple printers.

While I am stuck at the ATTAG project again I had to solve a completely different problem. If you are running an online shop you probably came across the issue that you have to print different types of documents on different printers. Like product labels, invoices, shipping labels. It is pretty annoying if you have to handle multiple orders and every step requires a change of the print settings over and over again. This often leads to documents printed on the wrong printer, paper mess and so on.

So I was looking around if there are some ready-to-use solutions. And yes there are but at insane costs compared to triviality. For a long while we had a working solution that used javascript inside the pdf document to choose the correct printer. But this only worked for Firefox and after the newer generations seem to block this due to security issues.

So actually it is pretty simple but you need to create PDFs of your documents which then can be retrieved. I am not covering this part here. You may do this with FPDF or any other PDF generator on your shop server.

This guide expects WINDOWS to be used.

First step is you need to install these:

  1. A webserver package such as xampp, just the Apache webserver and php will be used
  2. Python (tested with 3.X)
  3. Ghostscript
  4. GSPrint

Since the browsers won’t allow you to execute a program on your local PC you need to let a local webserver do that. In XAMPP control you can set the Apache webserver to autostart with windows. You may have to run XAMPP with adminstrator priviledges for that!

Once you installed it, create a small print.php script containing the following:

<?php 
$pyscript = 'C:\\gs\\print.py'; // the path to python print script
$python = 'python.exe'; // you may need the absolute path of python here, like C:\\programs\\python\\python.exe or wherever you installed it
exec($python." ".$pyscript, $output);
echo "Printjobs started...";
?>

I extracted all the ghostscript / gsprint stuff to C:\gs, put it wherever you like but keep in mind where, you will need it later.

The following is the python script which chooses the correct printer per document and starts the printjob through ghostscript and gsprint. You may also use any other pdf viewer/printer for this which works with command line execution such as the PDF-XChange Viewer.

Of course you have to edit the paths, url and currentprinter according to your settings. Your python may need some packages used here, install them with

pip install requests

pip install win32api

pip install win32print

from windows command line (START-> cmd)

#!/usr/bin/env python
import win32print
import win32api
import requests

GHOSTSCRIPT_PATH = "C:/gs/bin/gswin32.exe"
GSPRINT_PATH = "C:/gs/gsprint.exe"

LOCAL_FILE = "C:/gs/invoices.pdf" 
currentprinter = "Samsung C1810 Series"
url='https://www.yourshopdomain.com/wherever_you_put_the_pdf_there/invoices.pdf'
r = requests.get(url, stream=True)
with open(LOCAL_FILE, 'wb') as f:
	f.write(r.content)
params = '-ghostscript "'+ GHOSTSCRIPT_PATH  +'" -printer "'+currentprinter+'" -portrait -copies 1 "'+LOCAL_FILE+'"'
win32api.ShellExecute(0, 'open', GSPRINT_PATH, params, '.',0)

LOCAL_FILE = "C:/gs/slabels.pdf" 
currentprinter = "BIXOLON SRP-770II"
url='https://www.yourshopdomain.com/wherever_you_put_the_pdf_there/shipping_labels.pdf'
r = requests.get(url, stream=True)
with open(LOCAL_FILE, 'wb') as f:
	f.write(r.content)
params = '-ghostscript "'+ GHOSTSCRIPT_PATH  +'" -printer "'+currentprinter+'"  -portrait -copies 1 "'+LOCAL_FILE+'"'
win32api.ShellExecute(0, 'open', GSPRINT_PATH, params, '.',0)


LOCAL_FILE = "C:/gs/plabels.pdf" 
currentprinter = "Colorlabel"
url='https://www.yourshopdomain.com/wherever_you_put_the_pdf_there/product_labels.pdf'
r = requests.get(url, stream=True)
with open(LOCAL_FILE, 'wb') as f:
	f.write(r.content)
params = '-ghostscript "'+ GHOSTSCRIPT_PATH  +'" -printer "'+currentprinter+'" -portrait -copies 1 "'+LOCAL_FILE+'"'
win32api.ShellExecute(0, 'open', GSPRINT_PATH, params, '.',0)

Your printjob can now be executed from within your webshop admin, once the PDF documents have been generated, with a simple link such as

<a href=”http://localhost/print.php”>print at once</a>

That is actually all, easy as that. Good luck. Of course you can also reduce this to 2 or 1 printer or add multiple more.

EDIT: 2024-03-08

Here is another version with PHP / Viewer only, so no GS or Python required:

<?php
$url = 'https://www.yourdomain.com/yourpdf.pdf';    
$file_name = basename($url); 
if (file_put_contents($file_name, file_get_contents($url))) { 
    echo "downloaded PDF"; 
} else  { 
    echo "download failed"; 
} 
echo "<br>";
echo "pdf will be printed...<br>";
echo 'C:\\Program Files\\Tracker Software\\PDF Viewer\\PDFXCview.exe /printto "BIXOLON SRP-770II" C:\\xampp\\htdocs\\yourpdf.pdf';
echo "<br>";
passthru('"C:\\Program Files\\Tracker Software\\PDF Viewer\\PDFXCview.exe" /printto "BIXOLON SRP-770II" C:\\xampp\\htdocs\\yourpdf.pdf', $output); 

?>

And if this still not enough you may check out the FPDF Javscript plugin:

http://fpdf.org/en/script/script36.php

This embeds a slim javascript code to the PDF which then points the PDF reader to open the correct printer, it looks like this:

12 0 obj
<<
/Names [(EmbeddedJS) 13 0 R]
>>
endobj
13 0 obj
<<
/S /JavaScript
/JS (var pp = this.getPrintParams\(\);pp.printerName = 'BIXOLON SRP-770II';this.print\(pp\);)
>>
endobj

However this might not work with the inline PDF parser of the browser so it is most likely required to set the options in the browser to open the PDF in an external viewer sucher as the PDF-X Change viewer. I am not sure which other viewers are executing the script but this one does.

Leave a Reply

Your email address will not be published. Required fields are marked *