【问题标题】:Select paper source in php printing solution在php打印解决方案中选择纸张来源
【发布时间】:2015-06-15 13:16:32
【问题描述】:

您好,我有一个使用套接字的 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。 理查德

【问题讨论】:

标签: php printing postscript tray


【解决方案1】:

我认为这更多的是关于您正在使用的操作系统上的打印系统的问题(您似乎没有说那是什么)。我也看不到打印作业在哪里进行,这是 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"

所以要选择 '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 文件不再与设备无关,它现在只能在该类打印机上可靠地工作。

如果您想(例如)在纸盒 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 涵盖软件即服务)。

【讨论】:

  • 您好,这是一个 PHP 代码的 sn-p。它是 IIS,所以这就是 windows。当前设置是在 php (mpdf) 中生成 PDF。使用 ghostscript(命令行)创建使用 IP 地址发送到打印机的 PS 脚本。然后不必在服务器上安装打印机。这适用于拥有大量打印机的企业,因此变得简单。我想我在那个链接中有一个解决方案(上面的 bugs.ghostscript)我需要把手放在打印机上进行测试(对不起,应该是第 1 步),我会回复结果/答案。跨度>
  • 好神奇。你知道你的ghostscript。只是作为后续行动并充分完善答案。我的问题是,如果我有 x 页并且我希望它们都放在纸盒 2 上会怎样。我需要多个 &lt;&lt;/ManualFeed false&gt;&gt; setpagedevice statusdict begin 1 setpapertray end 每页一个吗?
  • 不,如果它是文档范围的设置,您可以使用 -dPSDocOptions。 PSPageOptions 每页工作一个(因此数组中的条目 1 附加到第 1 页,条目 2 附加到第 2 页,等等)。当它到达数组的末尾时,它会环绕。因此,如果您想将设置应用于奇数页和偶数页,您只需提供奇数和偶数选项即可。然后将条目 1 应用于第 1 页,将条目 2 应用于第 2 页,将条目 1 应用于第 3 页等。顺便说一句,答案中的语法可能不正确,这是从记忆中工作的,这对我来说尤其不可靠。它记录在 gs/doc 目录中的 ps2ps2.htm 中。
  • 为此干杯,我将不得不在一天结束时做一些时间刺痛。但是你让我走上了正确的道路,并给了我正确的变量来看待。为此,我会接受这个答案。当我让它工作时,我会添加我用过的栏,但它在一天结束时是打印机特定的东西,所以你不能从记忆中知道!感谢您的所有帮助
  • 我终于解决了这个问题,我尝试执行 "C:\Program Files (x86)\gs\gs9.15\bin\gswin32.exe" -dPSDocOptions="> setpagedevice statusdict begin 0 setpapertray end" -dNOPAUSE -dBATCH -sDEVICE=ps2write -sOutputFile="..." inputfile.pdf - 以各种不同的方式(-sPSDocOptions)删除空间等 - 没有 - 我得到错误-dName= 后面必须跟一个有效的令牌。想法?
【解决方案2】:

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

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

我过去做过类似的打印方式,通过使用 unix telnet 命令指定 ip 地址和端口,并将输入重定向到我的 ps 文件。使用命令行 telnet 程序的 windows shell 应该也可以做到这一点。

【讨论】:

  • 您好,感谢您的回复 - 只是想把我的头脑围绕在您所说的内容上。我有我的后记文件 - 检查。我有我的 ppd 文件 - 链接。 openprinting.org/download/PPD/Kyocera/en/… 你是说我必须将 ppd 文件中的规范放入我的 ps 文件中。我正在使用ghostscript(命令行)我可以用它来帮助我吗?为您的帮助干杯。
  • 进一步阅读这里,bugs.ghostscript.com/show_bug.cgi?id=690182 可能是答案............时间会证明一切
猜你喜欢
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 2016-08-21
  • 2012-02-26
  • 2015-04-16
相关资源
最近更新 更多