Printing a page to different printers in a web app - printing

I want to write a web app that can process a users presentation which when submitted, gets sent to their local system printers - one part of the order will go to B&W laser printer and another part goes to another printer for another process.
Ideally, this will be able to run on any of the major systems - Linux, OSX or Windows.
It could be a packaged Chrome or Firefox app or extension, but I can't tell if there is sufficient access to the system printers. (I can see all the printers available to my current chrome installation - but are they available to an extension?). I can't see the code in any demos or libraries.
I've seen reference to NPAPI, but I can't tell if that's what I need either - if so would I need to write an app for each of the major platforms or each kind of printer?

In Firefox it is possible to print from an extension. Using only javascript, that is (you're free to mess about with C++ if you like).
Extensions are essentially the browser: Everything the browser can do, an extension can, too.
There is however not much documentation about using the printer. To be precise, there is none that I'm aware of. However, the browser is open source, and the UI is mostly Javascript, so you can just read the code.
printUtils.js would be a good starting point to check out how this might work. Also there is a component implementing nsIPrinterEnumerator. See the firefox-addon info section for a collection of "Getting started" and documentation resources about add-on development in general.
I don't think the Chrome extension API provides ways to control printing the way you'd need.
The NPAPI plugin API does not provide enough control over printing. You just basically get a buffer to draw into, but no way to control printing setting or initiate printing yourself. You could cheat of course, and have your plugin directly print something via OS bypassing the browser, like e.g. those PDF readers do. However, it should be noted that NPAPI plugins are the past... Don't develop new ones, if possible.

Related

What's the most reliable way to programmatically control a Chromium instance?

I'm researching reliable ways to programmatically control instances of Chrome/Chromium to leverage its capabilities of rendering web pages in Node.js/C#/Java application. In short, things I want to do are as follows:
Open/close a browser window.
Minimize, maximize browser window.
Navigate to a certain URL.
Set cookies.
To make it more clear: I need a headful browser to display web pages to the end users. It can be either embedded to my app or can be a standalone browser (separately shipped instance of Chromium for example).
I was not able to find information about any public APIs in Chrome/Chromium that I can use from the Node.js/C#/Java environment. The ones available for Chrome Extensions are not applicable to my project, as I want to control the browser from the outside, like Selenium WebDriver does for example. So far I found the following ways to control the browser the way I need:
To use Puppeteer/WebDriver APIs.
Use chrome-remote-interface NodeJS library.
Rely on Chrome Embedded Framework capabilities.
Rely on Electron.js capabilities.
Build my own library that somehow includes the Chromium modules as dependencies (similar to what Electron team implemented for example).
First two options are similar from the perspective of all the mentioned libraries eventually leveraging Chrome Devtools Protocol. The risk of CDP being retired/deprecated is quite substantial for our project. The other concern is that the intention of CDP is debugging and test automation and not application development. Moreover, having an open debugging port in Chrome open on user's machine seems vulnerable.
CEF and Electron paths concern me due to dependency on the embedded Chromium updates cadence. Although Electron team is targeting to update with every other release of Chromium it still can be a security concern due to inability to update the Chromium version right after a new version released with a security patch, for example. Moreover, in case when I need the real browser experience (and that's the case) I won't have it out of the box and I'll have to implement browser features like buttons, tabs address bar etc. myself.
Option #5 seems to be extremely complex in implementation as it seems to require team's competency on Chromium internals, C++ development and C++ build tooling.
Anything I missed in the options list? Anything I missed in my assumptions? Any tips, thoughts, suggestions will be greatly appreciated!
Some of your options are about controlling a browser (#1, #2) while others are about embedding a browser (#3, #4). These are two different use cases and what you need depends on what your goal is.
Controlling a browser
If you want to control a browser to execute tasks, maybe even in the background without the end user noticing, you should go for option 1 (puppeteer) or 2 (chrome-remote-interface).
I recommend to use puppeteer as this is the library developed by the Google Chrome developers and it comes with many functions for your use case (opening browser windows, navigating, setting cookies).
I do not see any reason to worry about the Chrome DevTools Protocol being abandoned anytime soon. The Chrome DevTools fully rely on this protocol. In addition, Firefox (Mozilla bug tracker: #1316741,#1523097) and Edge are already partly supporting the protocol making it even more unlikely to be abandoned in the future. (more information)
Embedding a browser
If you need to embed a browser, meaning you are trying to show a browser inside your application, you should focus on the options 3 (Chrome Embedded Framework) or 4 (Electron).
The Chrome Embedded Framework is a more low-level approach putting a separate browser into your application. But I cannot go into detail here, as I have never used this one myself.
Electron on the other hand is a browser, meaning the whole application is developed as web application. You can embed another browser window (webview) into your browser, which you can essentially control (similar to what puppeteer can do).
Directly using the Chromium code (option 5)
Although the Chromium project is split into multiple components, it sounds like you need a full browser. I once compiled the Chromium source code myself and it takes literally hours. Keep in mind, that he code consists of roughly 35 million lines of code (source). Even if you figure out what parts of the code to use, it is more realistic that some low-level parts of the code change and break your implementation than the DevTools Protocol being abandoned. So, I definitely recommend to not follow this idea.
Alternatives
Depending on your use case, you could also take a look at DOM simulation libraries like jsdom or cheerio. These libraries are very limited in terms of their functionality and you might have to implement parts of the browser yourself, e.g. downloading the document, reading and setting headers to deal with cookies, etc.
All in all, I recommend to go for puppeteer if you want to control a browser to execute tasks primarily in the background. If you need a browser window as part of your application go for Electron.

Does the Firefox add-on sdk allow direct modification of the http response byte stream?

I am working on a project I intended as an academic exercise for myself. What I am basically doing is trying to add a custom compression type between an IIS server and a web browser, but getting mired in the browser aspects of it. What is basically needed is to be able to alter the byte stream on the server before it is sent to the client, and on the client browser side, be able to alter received response byte stream before other normal DOM parsing and such take place. On the server side this turned out to be pretty trivial, but I am at a loss in how to do this in chrome or firefox. If anyone has insight for chrome, please share, but I'll focus on Firefox for now. My understanding is that previously Firefox had rather low level access available to extensions but that they are tightening the restrictions a bit going forward with their Firefox add-on sdk. I don't want to bother learning the old methods if they are slated to be removed so does anyone definitively know if the add-on sdk allows you to alter the byte stream directly in this manner? If so, do you have an example of such usage?
(I am aware that I need to have the compression negotiated with the Accept-Encoding header)
I don't want to bother learning the old methods if they are slated to be removed
There are no plans now, or in the future, to remove legacy add-on support. At least that's what add-on SDK folks and extension manager folks told me repeatedly.
Back to your question: The add-on sdk does not provide an explicit API for stuff like this, but you can always go even more low-level, even in the SDK (via the chrome module and/or window/utils).
To implement additional compression methods, you'd need to implement the nsIStreamConverter interface and properly register your component under the #mozilla.org/streamconv;1#?from=<yourcompression>&to=uncompressed contract. Then Firefox should be able to decode yourcompression.
See https://developer.mozilla.org/ for more information on how to implement and register XPCOM components in either javascript or C++.
Using the SDK or implementing your add-on restartless will require you register the component yourself instead of relying on chrome.manifest. There are a couple of add-on doing so already, e.g. Adblock Plus.
Binary (C++) components should be avoided because you'll obviously need to compile your component for each supported platform and you'll need to re-compile it for each Gecko version. If you have to go binary, a javascript component stub + js-ctypes might be better.
See the mozilla source code on how to implement nsIStreamConverter in the first place.
You may also need to modify the network.http.accept-encoding preference so that the compression may be actually negotiated with the server.

Printing from web pages (reports especially) with greater precision

I am re-engineering a windows application to be ported to web. One area that has been worrying is 'printing'.
The application is data intensive and complex reports need to be generated. The erstwhile windows application takes advantage of printer APIs and extends sophisticated control to the users. It supports functions like page break, avoiding printing on printed parts of the sheet (like letterhead), choice of layouts and orientation, etc. Please note that these setting are not done only while printing, they are part of report definition sometimes.
From what I know, we cannot have this kind of control while printing web pages. I am in a process of identifying options at my disposal. While I prefer to first look into something that will help me print from raw web pages, following are other thoughts:
Since reports can also be exported to .xls & .pdf versions, let user download one and print directly. This however limits my solution to the area of application that have export feature.
Use Silverlight (4.0) for report layout definition and print. I think Silverlight 4.0 (in beta right now) provides adequate control over the printer. I have so far been avoiding the need of any RIA plugin.
Meticulously generate reports on web with fixed dimensions. I am not sure how far this will go.
Please share practices that can be applied easily in my scenario.
For reporting in the past on the web, using .NET, I like to generate PDF, Excel, Word or CSV files. I really like iTextSharp which allows for creating of PDF's.
Word can accept HTML, so that is usually quote easy. For more control you can get into the Word interops http://nishantrana.wordpress.com/2007/11/03/creating-word-document-using-c/, but they left me frustrated. Not for implementation, but I felt the clean up was poor.
CSV are great for raw data dumps and that is it.
For HTML, you can get nice control using a style sheet targeted to print media. There are just certain things you cannot control, like browser header and footer.
Flash also has better print controls than plain HTML, though you might not know it since these features are rarely used by flash developers. Almost everyone should have Flash installed these days, so it's not like Silverlight where there's a good chance of someone needing to install a plugin (doubly so for a beta version). I am not sure how the Flash printer APIs compare to Silverlight's printer APIs and if they give you the level of control you need, but their documentation is public so you can look into it.
Also I think exporting to PDF is a good idea. I don't see why you can't extend this to cover all places that would need to print a report. Basically instead of printing directly from the windows app running on their desktop, the same exact code runs on your server and generates a PDF that they can then print themselves.
I don't think you're going to have much luck trying to do it with raw HTML unfortunately. For one of our clients, we went with the "generate PDF" route and it worked out quite well. PDFs have the additional advantage that you don't have to print them out: you can just email them to the boss/accountant/whatever saving a bit of paper.
PDF is the way to go, if you want absolute control over printed output. As bonus, you can also provide the option to download PDFs in your application.
With HTML, you are at the mercy of user's browser settings for page size, margin and how page breaks will be handled.

Delphi printing primer

I need to add printing capabilities to an app and I have been looking around for information about printing. Logical/physical sizes, dpi, font scaling, etc, lots to digest since I never programmed printing into any app before.
Are there any sites that would offer a primer on the topics of page sizes, margins and all the other elements required to understand printing on Windows? I've been looking around for a while but what I find is either cryptic or years old...
I've been playing around with TPrinter, but I would like to build solid printing functionalities and understand what I'm doing better.
Using a report solution is not an option, even though I'm sure it would provide better results much sooner.
Two links to get you started:
Printing with TPrinter
Printing via the TPrinter Canvas
I think that you are looking too lowlevel.
Try looking at the build reporting tools (Rave or whatever is in your product).
Personally i am using a product called Report Builder from Digital Metaphors.
But if you want to do the lowlevel stuff lot og good information can be found at efg's computer lab - printing
Well, I have done things a variety of ways in the past, including the "hard way" with TPrinter. In fact, I recently had to do that again to run a special inventory label printer.
On the other hand, sometimes you are better off taking work others have done and using it for your benefit. I agree that ReportSmith isn't so great, and also it's Delphi (and Windows) specific. Using Excel or Word has those limitations, plus the fact that the user has to actually have them installed.
One thing I have done to make printing easy for some simple applications is just to generate an HTML file and call the user's web browser, then they can print it. HTML tables can be created relatively easily for numerical data, and you can include photos, etc. as well. This works well for some applications, and works on every platform where a web browser is installed. The downside, of course, is that HTML isn't the most precise layout language.
The version of Delphi you´re using is important. A number of Delphis came with print engines like ReportSmith (ugh). Another option thinking laterally is to use MS Word as a print engine. I´ve hooked into instances of Word & Excel before & utilised their functionality. As to raw printing using TPrinter or the print method of TForm you´d have to be pretty desperate. I seem to recall the Pacheo / Texeira Delphi books coming with a pretty good overview so you might want to see if you can find a copy of that somewhere.

Web-based printing solutions

I'm building a new web-based product. The problem is that many clients have specific printers to print specific documents. Just think reports,barcodes,invoices etc. All on a special printer with the right paper etc...
Usually when printing from the web you cannot make the software choose a printer or change the settings. However it's just that that I want to do.
I want to print without a dialog. And enter the printer + settings with my software
The only solution I know of now is the commercial version of acrobat that has some javascript printing support..
Does anyone know of any other alternatives ?
Thanks in advance !
small-medium business
No heavy installion but common stuff is ok
ie. flash/silverlight/acrobat/whatever is possible
I generate what is necessary for printing (PDF/Tiff etc)
Who are your customers -- enterprises or SOHO? Are you generating PDFs? Or, raw tiffs? If you are generating PDFs there is something called a JDF file where you can specify the print settings to your heart's content. The flip side is the device needs to be capable of understanding JDFs. You can then attach the JDF with the PDF as a mime package. If you are generating tiffs, I think there isn't much need of printer settings except for the correct device profile(s) to be installed.
Because of security reasons, you cannot control that from within the browser.
If I where in your shoes, I'd create a small program for my clients to install, registering a specific file extension to this program and creating files in this format on the website, and have the program do the printing for me.
Your easy choices are either PDF or Microsoft's Reporting/Report Viewer

Resources