douxiajia6104 2015-06-15 13:16
浏览 76
已采纳

在php打印解决方案中选择纸张来源

Hi I've got a PHP printing solutions using sockets. Using this 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."
");
            $this->debug .= "Confirmation of receive cmd:".ord(fread($stream, 1))."
";

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

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






            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
";
                    $data = fopen($this->data, "rb");//Force binary in Windows.
                } else {
                    $this->debug .= "Operating system is not Windows
";
                    $data = fopen($this->data, "r");
                }

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

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

                fclose($data);

            } else {                      

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

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

            }
        }

    }

All is well with it but I can't seem to control the paper source/tray that the printer then selects. Does anyone know how to do this?

Or perhaps a different solution that I an use, I like this one because I can send the ip address (no need for install), postscript file and it prints out. So if there is another solution that requires the same things then I can use that.

I'm using PHP, iis, windows. Richard

  • 写回答

2条回答 默认 最新

  • douruanfan3030 2015-06-18 10:37
    关注

    I think this is more a question about the printing system on the OS you are using (you don't seem to say what that is). I also can't see where the print job is taking place, is this C# code ?

    All printer have properties, included in which are things like the tray setup. When printing you need to configure the device, the steps for doing that are going to be different per OS. For example, on Windows 8+ you would need to set up a job ticket. I don't recall exactly how its done on earlier versions of Windows, some complicated structure as I recall. On Linux it would depend if you are using CUPS, if you are you would probably need to set up a CUPS pipeline for the specific tray you wanted to use.

    I see there is some code testing to see whether the OS is Windows or something else. I guess you will need to figure out wht to do in there.

    [added later]

    OK so now I understand better what you are doing. Since you are using Ghostscript to create PostScript from your PDF file the question does make more sense.

    The link you noted above and the PSDocOptions and PSPageOptions is what you need, combined with luser_droog's points about tray selection.

    So first you need to find out what your printer expects in the way of PostScript in order to change trays. Your PPD file contains ths:

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

    So to select 'cassette' 1 the required PostScript is:

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

    Now assuming you are using a recent version of Ghostscript (ie at least version 9.16) you can then add, as part of your PDF to PostScript command line;

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

    Which will set the current tray to tray 1 before starting the job. Note that your PostScript file is no longer device-independent, it will now only work reliably on that class of printer.

    If you wanted (for example) page 1 to be printed on cassette 1 and page 2 on cassette 2 you would need to use PSPageOptions, eg:

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

    I'm assuming that you are deploying this in a particular organisation, rather than open to the world. However it might be good to stick a note somewhere that Ghostscript is AGPL licenced, and if this was ever made available as a general service, the entire source code would probably have to be made available (the AGPL covers software as a service).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?