从PHP打印到网络打印机

10

如何从php直接打印(我的情况是现有pdf),将其打印到局域网打印机?目前我尝试了一些方法,但都没有成功,不知道应该继续探索哪个方向。我正在运行Windows SBS 2008上的Apache和PHP 5.3.9。

目前我所知的方法:

  • shell_exec()
  • phpprintipp - 如果能让它工作,这似乎是最好的方法
  • php_printer.dll - 目前没有存在的dll

看起来这应该是一个简单的任务,已经有广泛接受的方法,但到目前为止我还没有找到。谢谢!


2
不确定在您的情况下是否可能,但为了避免尝试从Web服务器到打印机出现各种问题,我们正在使用打印机的FTP模式来完成此操作。 我们只需将PDF转储到打印机本身具有的ftp-spool工具上,然后就完成了(一旦您能够将所有内容转换为PDF)。 只有在您的打印机支持此功能时才有用,这就是为什么您会得到一个评论而不是答案的原因;) - Nanne
1
使用 php_printer.dll。它有什么问题吗?为什么它对你不起作用?不要通过直接与IP打印机通信来重新发明轮子。 - Brad
为什么不让操作系统处理打印机呢?如果您的脚本试图连接“默认打印机”,但网络(或打印机路由)不可用,会发生什么情况呢? - PenguinCoder
@Brad - 我能成功连接到打印机,然后使用fopen/fread获取pdf内容,也没有出现任何错误。如果我将PRINTER_MODE更改为RAW,则不会出现错误,但是什么都不会发生。如果我不更改打印机模式,则会得到15页垃圾。在搜索时,我发现当Apache以SYSTEM用户身份运行时可能会出现一些问题,但是我正在以具有管理员特权的不同用户身份运行Apache,因此这里不应该有问题。 - Tim
2个回答

4

这是一个棘手的问题。我曾经在使用Ruby从Windows打印时遇到过一些麻烦,但我找到了几个可以使用的潜在解决方案,它们通过调用外部命令来实现,在PHP中,这个命令是system()exec()(不要忘记escapeshellcmd()/escapeshellarg()——它们往往会使这些事情更加容易,特别是在Windows上)。所有这些解决方案都假定Windows知道打印机并且可以通过名称进行引用。

  1. You can literally just redirect the file to the networked printer, e.g.:

    copy /b \path\to\filename.pdf > \\Printer_Machine\Printer_Queue
    

    The /b switch specifies a binary file, but I'm 80% sure it's not strictly now, in 2012.

  2. You can try the print command:

    print /d:\\Printer_Machine\Printer_Queue \path\to\filename.pdf
    

    \d stands for "device." I haven't actually tried this one and I'm not sure if it works with PDF or only, owing to its DOS origins, text files.

  3. Install Adobe Reader and use its command line facilities:

    AcroRd32.exe /t \path\to\filename.pdf "Printer Name" "Driver Name" "Port Name"
    

    I'm not sure if your server environment can accommodate Reader but this is the solution I've been most successful with. You can find documentation here (PDF, pg. 24). Printer Name and Driver Name should match exactly what you see in the printer's properties in Control Panel. Port_Name can usually be omitted, I think.

  4. Print using Ghostscript. I've never tried this on Windows but the documentation is here and there's more info here. The command goes something like this:

    gswin32.exe -sDEVICE=mswinpr2 -sOutputFile="%printer%Printer Name" \path\to\filename.pdf
    

    mswinpr2 refers to Windows' own print drivers (see the second link above), "%printer%" is literal and required and "Printer Name" should, again, match the printer's name from Control Panel exactly. Ghostscript has many, many options and you'll likely have to spend some time configuring them.

最后,一个通用的提示:您可以使用net use命令注册网络打印机,并为其设备命名,例如:
C:\> net use LPT2 \\Printer_Machine\Printer_Queue /persistent:yes

这样做可以让你在大多数命令中使用LPT2LPT2:代替\\Printer_...。希望这对你有所帮助!

感谢您的回答。选项1(复制)确实导致打印机打印了一张纸,但只是显示“1个文件已复制”,并没有打印我的PDF文件。使用选项2(打印)时,我总是收到“无法初始化设备'打印机'”的错误提示。使用选项3(Adobe Reader),我能够成功地从服务器的命令提示符中打印,但在从PHP运行时却没有任何反应。我输出了我传递给exec的命令行,它与我手动输入的完全相同,但仍然没有任何反应。对此有什么想法吗? - Tim
我猜这是一个路径问题,可能是PDF文件或可执行文件的路径问题;当您使用exec()运行AcroRd32.exe时,输出是什么? - Jordan Running
Tim,你复制后发送了 control+z(EOF)到打印机了吗? - Brad
@Jordan:我没有得到任何结果。如果我提供一个输出变量,它会返回一个空数组(array(0) { })。 - Tim
嗯,如果您从命令行运行它,是否有任何输出?您可以尝试在阅读器文档中使用其他选项,例如使用 exec() 打开阅读器,看看是否能够解决问题。 - Jordan Running
@Jordan:这是我传递给exec()的内容(在脚本运行时回显):“C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe" /t "\CCASERVER\Data\CCA Proposals\test.pdf" "bizhubC252" "KONICA MINOLTAC252/C252P VXL"。当我在命令提示符中使用完全相同的内容时,它可以正常工作。它在php中应该看起来不同吗?我没有从命令提示符中得到任何输出,但也无法通过php打开Reader。 - Tim

3

不确定是否适用于所有打印机,但这可以通过发送ZPL文件到Zebra标签打印机来完成工作:

<?php 
if(($conn = fsockopen('192.168.10.112',9100,$errno,$errstr))===false){
    echo 'Connection Failed' . $errno . $errstr;
}

$data = <<<HERE
    ^XA
    ^FT50,200
    ^A0N,200,200^FDTEST^FS
    ^FT50,500
    ^A0N,200,200^FDZebra Printer^FS
    ^XZ
HERE;

#send request
$fput = fputs($conn, $data, strlen($data));

#close the connection
fclose($conn);
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接