Print multipage PDF on different printer-trays

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 08:19:28

It is not possible, as PDFs do not contain any information on the printer trays or other information. It is actually set in the printer instructions through the client's printer driver, who has to provide this information to the client program. If you need this functionality for batch processing, you'd have to leave PHP and get on the client side, e.g. through the Acrobat SDK, in which you can give this information, e.g. on a PostScript printer via the SetPageDevice-function

I use CUPS on an intranet website. I don't specify a tray and my code is ruby, but the principle definitely works.

Here's my code, see if you can adapt it for your scenario

def print(path)
  raise ArgumentError, "'#{path}' does not exist" unless File.file?(path)

  `lp -s -d printer_name -h 127.0.0.1 -o page-ranges=1-4 -o media=A4,Upper #{path}`

  $?.to_i == 0 ? true : false
end

The basic idea is to generate the PDF, save it to disk then call this method to shell out to CUPS. You might need to play with the media option to get it doing what you need. 'Upper' is the tray you're targeting.

Make sure path is sanitised before being passed to this method or you risk opening a security hole.

PHP can send some things to a print server like CUPS, but it can't get something to print on a client's machine save through JavaScript. JavaScript does not have the ability to control the individual's printer settings when being called from a browser. And while there are bindings for embedded PDF's in JS, there is no guarantee that the user will not simply have the file open in a standalone PDF reader (my computer at home is configured this way).

For future readers of this post, if a commercial library is a valid choice then it is possible to do this with Amyuni PDF Creator ActiveX (Delphi, C++, VB, PHP) or with Amyuni PDF Creator .Net (C#, VB.net, etc.) by changing the "PaperBin" property of a page object.

Possible values for this property can be found in the documentation for the DEVMODE structure in MSDN, examples: DMBIN_UPPER - 0x0001, DMBIN_LOWER - 0x0002, DMBIN_AUTO - 0x0007.

The code in C# would look like this:

Amyuni.PDFCreator.IacDocument pdfDoc = new Amyuni.PDFCreator.IacDocument();
using(FileStream fs = File.Open("MyDocument.pdf", FileMode.Open))
{
    pdfDoc.Open(fs, "");
}

const int DMBIN_MANUAL = 4;
for( int pageNumber = 1; i <= pdfDoc.PageCount; i++)
{
    pdfDoc.GetPage(pageNumber).AttributeByName("PaperBin").Value = DMBIN_MANUAL;
}

pdfDoc.Print("My Laser Printer", False); 

For PHP, you will need to use the ActiveX version, and create the document using the ProgID of the ActiveX control:

$pdfdoc = new COM("PDFCreactiveX.PDFCreactiveX");

Note that this approach is about printing to a specific tray using the library, as other answers have mentioned, it is not possible to store this information in the PDF file itself so that it can be used by other applications.

Disclaimer: I currently work for Amyuni Technologies.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!