在php打印解决方案

时间:2015-06-15 13:16:32

标签: php printing postscript tray

您好我有一个使用套接字的PHP打印解决方案。 使用此功能/类。

public function printJob($queue){

        //Private static function prints waiting jobs on the queue.
        $this->printWaiting($queue);

        //Open a new connection to send the control file and data.
        $stream = stream_socket_client("tcp://".$this->host.":".$this->port, $this->errNo, $this->errStr, $this->timeout);
        if(!$stream){
            return $this->errNo." (".$this->errStr.")";
        } else {

            $job = self::getJobId();//Get a new id for this job

            //Set printer to receive file
            fwrite($stream, chr(2).$queue."\n");
            $this->debug .= "Confirmation of receive cmd:".ord(fread($stream, 1))."\n";

            //Send Control file.
            (isset($_SERVER['SERVER_NAME'])) ? $server = $_SERVER['SERVER_NAME'] : $server = "me";//Might be CLI and not have _SERVER
            $ctrl = "H".$server."\nPphp\nfdfA".$job.$server."\n";
            fwrite($stream, chr(2).strlen($ctrl)." cfA".$job.$server."\n");
            $this->debug .= "Confirmation of sending of control file cmd:".ord(fread($stream, 1))."\n";

            fwrite($stream, $ctrl.chr(0)); //Write null to indicate end of stream
            $this->debug .= "Confirmation of sending of control file itself:".ord(fread($stream, 1))."\n";






            if (is_readable($this->data)){

                //It's a filename, rather than just some ascii text that needs printing.  Open and stream.
                if (strstr(strtolower($_ENV["OS"]), "windows")){
                    $this->debug .= "Operating system is Windows\n";
                    $data = fopen($this->data, "rb");//Force binary in Windows.
                } else {
                    $this->debug .= "Operating system is not Windows\n";
                    $data = fopen($this->data, "r");
                }

                fwrite($stream, chr(3).filesize($this->data)." dfA".$job.$server."\n");
                $this->debug .= "Confirmation of sending receive data cmd:".ord(fread($stream, 1))."\n";

                while(!feof($data)){
                    fwrite($stream, fread($data, 8192));                     
                }
                fwrite($stream, chr(0));//Write null to indicate end of stream
                $this->debug .= "Confirmation of sending data:".ord(fread($stream, 1))."\n"; 

                fclose($data);

            } else {                      

                //Send data string
                fwrite($stream, chr(3).strlen($this->data)." dfA".$job.$server."\n");           
                $this->debug .= "Confirmation of sending receive data cmd:".ord(fread($stream, 1))."\n";

                fwrite($stream, $this->data.chr(0)); //Write null to indicate end of stream
                $this->debug .= "Confirmation of sending data:".ord(fread($stream, 1))."\n"; 

            }
        }

    }

一切顺利,但我似乎无法控制打印机随后选择的纸张来源/托盘。 有谁知道怎么做?

或者也许是我使用的不同解决方案,我喜欢这个,因为我可以发送ip地址(不需要安装),postscript文件并打印出来。 因此,如果有另一种解决方案需要相同的东西,那么我可以使用它。

我正在使用PHP,iis,windows。 理查德

2 个答案:

答案 0 :(得分:2)

这将需要特定于打印机的postscript代码。您应该搜索需要使用的特定打印机的.PPD文件(postscript打印机定义)。

.ppd文件是特殊格式的ascii文本,但很容易被人类阅读。打印机的任何特殊功能都无法通过标准postscript完成(但仍可通过postscript实现)以这种方式记录。

我过去使用unix telnet命令指定了ip-address和port,并将输入重定向为我的ps文件,从而完成了类似的打印方式。 Windows shell使用命令行telnet程序应该可以实现相同的目的。

答案 1 :(得分:2)

我认为这更像是关于您正在使用的操作系统上的打印系统的问题(您似乎不会说这是什么)。我也看不到打印作业的位置,这是C#代码吗?

所有打印机都具有属性,其中包括托盘设置等。打印时需要配置设备,执行此操作的步骤将因操作系统而异。例如,在Windows 8+上,您需要设置作业单。我不记得究竟是如何在早期版本的Windows上完成的,我回忆起一些复杂的结构。在Linux上,它取决于你是否使用CUPS,如果你是,你可能需要为你想要使用的特定托盘设置CUPS管道。

我看到有一些代码测试,看看操作系统是Windows还是其他东西。我想你需要弄清楚那里要做什么。

[稍后补充]

好的,现在我更了解你在做什么。由于您使用Ghostscript从PDF文件创建PostScript,因此问题更有意义。

您在上面提到的链接以及PSDocOptions和PSPageOptions是您需要的,并结合luser_droog关于托盘选择的要点。

首先,您需要了解您的打印机对PostScript的期望,以便更换托盘。您的PPD文件包含:

*InputSlot Internal/Cassette 1 (Internal): "<</ManualFeed false>> setpagedevice statusdict begin 0 setpapertray end"
*InputSlot PF60A/Cassette 2: "<</ManualFeed false>> setpagedevice statusdict begin 1 setpapertray end"
*InputSlot PF60B/Cassette 3: "<</ManualFeed false>> setpagedevice statusdict begin 4 setpapertray end"
*InputSlot PF60C/Cassette 4: "<</ManualFeed false>> setpagedevice statusdict begin 5 setpapertray end"
*InputSlot EF1/Envelope Feeder: "<</ManualFeed false>> setpagedevice statusdict begin 2 setpapertray end"

所以选择卡带&#39; 1所需的PostScript是:

<</ManualFeed false>> setpagedevice statusdict begin 0 setpapertray end

现在假设您使用的是最近版本的Ghostscript(即至少版本为9.16),然后您可以添加,作为PDF的一部分到PostScript命令行;

-dPSDocOptions="<</ManualFeed false>> setpagedevice statusdict begin 0 setpapertray end"

在开始作业之前,将当前纸盘设置为纸盘1。请注意,PostScript文件不再与设备无关,现在只能在该类打印机上可靠地运行。

如果您希望(例如)第1页打印在纸盒1和纸盒2上的第2页,则需要使用PSPageOptions,例如:

    -dPSpageOptions=["<</ManualFeed false>> setpagedevice statusdict begin 0 setpapertray end"
 "<</ManualFeed false>> setpagedevice statusdict begin 1 setpapertray end"]

我假设你要在特定的组织中部署它,而不是向世界开放。然而,在Ghostscript获得AGPL许可的某个地方贴一张便条可能会很好,如果这可以作为一般服务使用,则可能必须提供整个源代码(AGPL将软件作为服务)。 / p>