Select 打印解决方案中的 php 纸张来源

Select paper source in php printing solution

您好,我有一个 PHP 使用套接字的打印解决方案。 使用这个 function/class.

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"; 

            }
        }

    }

一切正常,但我似乎无法控制打印机随后选择的纸张 source/tray。 有人知道怎么做吗?

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

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

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

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

我过去做过类似的打印,使用 unix telnet 命令指定 ip 地址和端口,并将输入重定向到我的 ps 文件。使用命令行 telnet 程序 windows shell 也应该可以实现同样的效果。

我认为这更多是关于您正在使用的 OS 上的打印系统的问题(您似乎没有说那是什么)。我也看不到打印作业在哪里进行,这是 C# 代码吗?

所有打印机都有属性,其中包括托盘设置等内容。打印时您需要配置设备,每个 OS 的步骤将有所不同。例如,在 Windows 8+ 上,您需要设置工作单。我不记得它在 Windows 的早期版本上是如何完成的,我记得有些复杂的结构。在 Linux 上,这取决于您是否使用 CUPS,如果是,您可能需要为要使用的特定托盘设置 CUPS 管道。

我看到有一些代码测试可以查看 OS 是 Windows 还是其他。我想你需要弄清楚在那里做什么。

[稍后添加]

好的,现在我更清楚你在做什么了。由于您使用 Ghostscript 从 PDF 文件创建 PostScript,这个问题确实更有意义。

你上面提到的 link 和 PSDocOptions 和 PSPageOptions 是你需要的,结合 luser_droog 关于托盘的要点 selection.

所以首先您需要了解您的打印机对 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"

因此 select 'cassette' 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 文件不再与设备无关,它现在只能在 class 打印机上可靠地工作。

如果您希望(例如)第 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 涵盖软件即服务)。