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