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 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符
  • ¥15 NX MCD仿真与博途通讯不了啥情况
  • ¥15 win11家庭中文版安装docker遇到Hyper-V启用失败解决办法整理
  • ¥15 gradio的web端页面格式不对的问题
  • ¥15 求大家看看Nonce如何配置
  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问