Today I have a hard challenge with php+javascript+html+css:
I'm creating an application to "authorization+print it": the app must run in a local apache(under windows preferably), and need a conection to a DB in the cloud. That's easy. With the user authenticated, a list of authorized files must be shown, another easy task too. It's working. But now comes the crazy: I want to print them without let the user select and see any print option, only a button "Print". The print configuration comes in a .txt file and I need to configure the printing, sending the file and the configuration to the printer.
I searched a lot, but I only see the "print this page" buttons or shell solutions (gsview and gsprint for windows, but I cannot use that because I cannot configure the print options). I need anything more complex. Could you help me? (Im trying now fpdf, but...omg, I cannot understand If this could be used to do that I want.
Non-free/installed solutions could be in help too.
In addition, I need to print multiple files, but that's optional (I can do anything like "while")
PD: sorry for my english level.
Print from client-side = form the browser via javascript
It's not possible to do this from client-side (= from inside the Browser).
There are hackish solutions out there, which might work for IE, like the one here: HTML / Javascript One Click Print (no dialogs), but in general "if you try to print, the dialog will pop up" = default behaviour of "window.print()".
Print from server-side
Basically you use the server-side (PHP) to print the document, instead of the client.
So you might use an Ajax request (user clicks on the print button) handing the filename or the content to print over to the "print.php" file on the server, which does the job of pushing the content to the printer.
Of course, you'd have to know which printer the user wants the content to be printed at...
There are several ways to print from PHP.
One option would be to use the php_printer extension:
$handle = printer_open();
printer_set_option($handle, PRINTER_MODE, "raw");
printer_write($handle,$myfile);
printer_close($handle);
Or just copyor print to the printer:
exec('copy C:\file.txt com1');
exec('copy C:\file.txt lpt1');
exec('print /d:LPT1: C:\file.txt');
If you have network printer, you could try to send your content to the network address.
There are some PHP utils around to work with LPR: https://github.com/Craswer/PhpNetworkLprPrinter
Referencing: https://stackoverflow.com/a/5695181/1163786
Question from comment: How can i set printer options from PHP on Windows?
This very easy on Linux because lpr accepts options lpr <options> - but that's not the case on Windows. So, here are some Windows specific tricks to configure the printer:
Windows7 has PRINTUI.EXE - a shorthand for RUNDLL32 PRINTUI.DLL,PrintUIEntry
Please see PrintUI Reference for examples.
You can configure your printer manually, for instance activate duplex mode,
then save the settings file and re-use it, when printing from PHP.
This allows to work with multiple printer configuration files.
The easiest way is to configure the printer in your env and then access it by name,
"Printer-HP-XY-DuplexOn-2PagesOn1". In other words: it's configured outside and not from within PHP, only accessed from there.
Related
I am working on a quite big eWeb tool which includes lots of .js & .php files and this tool is developed by someone else that I can not reach.
Assume that a customer buys some stuff and at the end, as a seller, I am supposed to confirm the customer's shopping by clicking the 'confirm order' button in some table. Now, I want to print a PDF file (which is either located in my local disk or on the server of the eWeb tool depends on the difficulty) when I click the confirm button. I can reach the printer and print the PDF file by following PHP code in my localhost when I directly call it:
<?php
$printer ="HP Officejet Pro X476dw MFP PCL 6 (Network)";
$path = "C:/Test_PDF/TestPDF.pdf";
$fileName = "TestPDF.pdf";`
if($ph = printer_open($printer)) {
$filecontents = file_get_contents($path);
printer_set_option($ph, PRINTER_MODE, "RAW");
printer_write($ph, $filecontents);
printer_close($ph);
}
?>
Now, what I want is to print the PDF file also from the web tool when I click the 'confirm order' button! I do not want to load the PDF file in a hidden iframe or embed it somewhere because, as I said before, the tool is quite big and I do not want to cause any problem somewhere else for now.
Can anybody give me some ideas about the solutions please?
Assuming that PHP is a server-side language, as some people said before, you can't send a print request to a client. The request is originated in the server, so...
What you can do:
1.- Load the pdf in the webpage.
2.- Handle the body onLoad as follows:
<body onload="window.print();">
That way the client will use it's printer if any.
I know that you don't want to load the pdf in a webpage but... This seems like the only solution.
P.D.: I'm not sure if you want to print the receipt for the customer or the seller. Explain yourself better and I will try to help you :)
I'm working on an HTML/javascript app intended to be run locally.
When dealing with img tags, it is possible to set the src attribute to a file name with a relative path and thereby quickly and easily load an image from the app's directory. I would like to use a similar method to retrieve a text file from the app's directory.
I have used TideSDK, but it is less lightweight. And I am aware of HTTP requests, but if I remember correctly only Firefox has taken kindly to my use of this for local file access (although accessing local images with src does not appear to be an issue). I am also aware of the FileReader object; however, my interface requires that I load a file based on the file name and not based on a file-browser selection as with <input type="file">.
Is there some way of accomplishing this type of file access, or am I stuck with the methods mentioned above?
The browser will not permit you to access files like that but you can make javascript files instead of text files like this:
text1.js:
document.write('This is the text I want to show in here.'); //this is the content of the javascript file
Now call it anywhere you like:
<script type="text/javascript" src="text1.js"></script>
There are too many security issues (restrictions) within browsers making many local web-apps impossible to implement so my solution to a similar problem was to move out of browsers and into node-webkit which combines Chromium + Node.js + your scripts, into an executable with full disk I/O.
http://nwjs.io/
[edit] I'm sorry I thought you wanted to do this with TideSDK, I'll let my answer in case you want to give another try to TideSDK [/edit]
I'm not sure if it's what you're looking for but I will try to explain my case.
I've an application which allow the user to save the state of his progress. To do this, I allow him to select a folder, enter a filename and write this file. When the user open the app, he can open the saved file, and get back his progress. So I assume this enhancement is similar of what you are looking for.
In my case, I use the native File Select to allow the user to select a specific save (I'm using CoffeeScript) :
Ti.UI.currentWindow.openFileChooserDialog(_fileSelected, {
title: 'Select a file'
path: Ti.Filesystem.getDocumentsDirectory().nativePath()
multiple: false
})
(related doc http://tidesdk.multipart.net/docs/user-dev/generated/#!/api/Ti.UI.UserWindow-method-openFileChooserDialog)
When this step is done I will open the selected file :
if !filePath?
fileToLoad = Ti.Filesystem.getFile(scope.fileSelected.nativePath())
else
fileToLoad = Ti.Filesystem.getFile(filePath)
data = Ti.JSON.parse(fileToLoad.read())
(related doc http://tidesdk.multipart.net/docs/user-dev/generated/#!/api/Ti.Filesystem)
Please note that those snippets are copy/paste from my project and they will not work without the rest of my code but I think it's enough to illustrate you how I manage to open a file, and read his content.
In this case I'm using Ti.JSON.parse because there is only javascript object in these files but in your case you can just get the content. The openFileChooserDialog isn't mandatory, if you already know the file name, or if you get it from another way you can use Ti.Filesystem in your own way.
I don't know that this is necessarily important, but I'm using Infragistics iggrid for my grid and their Reports stuff to export to PDF.
The underlying issue I have is that my data that I want to export is in the browser and I would prefer that I don't have to create a server-side file to download. We have an icon on the screen that the user clicks to download the PDF.
So what I'm doing on the client, is collecting all the data. This has to be done client-side because I want to export the data as the user has it sorted, filtered, and column-ordered (otherwise I could just collect the data server-side which would make this simpler). I then send the data to the server via a POST.
On the server-side I generate the PDF file. Now, obviously, I could save the PDF server-side and redirect to the generated file, but that adds maintenance of temporary files which I'd prefer to avoid (but worst case, I can go there. Just fishing for options right now).
I tried returning the data base64 encoded and then doing:
window.open("data:application/pdf;base64," + encodedData);
This doesn't work (at least in IE) because the URL limit is a bit over 2K.
I tried using the downloadDataURI javascript function here: http://code.google.com/p/download-data-uri/
But that only appears to work with Chrome (even after commenting out the webkit check) and I'm apparently not clever enough to figure out why.
I'm sure I'm missing some obvious possibility that doesn't require creating a server-side file, but I'm just not seeing it. (disclaimer: My daughter woke me up horribly early this morning so the answer could be really trivial and I will feel stupid tomorrow when my brain is working).
On the server-side I generate the PDF file. Now, obviously, I could
save the PDF server-side and redirect to the generated file, but that
adds maintenance of temporary files which I'd prefer to avoid (but
worst case, I can go there. Just fishing for options right now).
You don't need to save it on the server. You can simply stream the PDF File (I assume you have it in some sort of Stream or byte[]) to the user. All you need to do is something like
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "filename.pdf");
Response.BinaryWrite(bytes);
Response.Flush();
Response.Close();
Response.End();
And this will prompt the user to either save the file or open it in Adobe Reader. The file won't be created on the server at all.
I'd like to make an XML document in JavaScript then have a save dialog appear.
It's OK if they have to click before the save can occur.
It's *not* OK if I *have* to use IE to achieve this (I don't even need to support it at all). However, Windows is a required platform (so Firefox or Chrome are the preferred browsers if I can only do this in one browser).
It's *not* OK if I need a web server. But conversely, I don't want to require the JavaScript to be run on a local file only, i.e. elevated privileges -- if possible. That is, I'd like to to run locally or on a *static* host. But just locally is OK.
It's OK to have to bend over backwards to do this. The file won't be very big, but internet access might either be there, be spotty or just not be a possibility at all -- see (3).
So far the only ideas I have seen are to save the XML to an iframe and save that document -- but it seems that you can only do this in IE? Also, that I could construct a data URI and place that in a link. My fear here is that it will just open the XML file in the window, rather than prompt the user to save it.
I know that if I require the JavaScript to be local, I can raise privileges and just directly save the file (or hopefully cause a save dialog box to appear). However, I'd much prefer a solution where I do not require raised privileges (even a Firefox 3.6 only solution).
I apologize if this offends anyone's sensibilities (for example, not supporting every browser). I basically want to write an offline application and Javascript/HTML/CSS seem to be the best candidate considering the complexity of the requirements and the time available. However, I have this single requirement of being able to save data that must be overcome before I can choose this line of development.
How about this downloadify script?
Which is based on Flash and jQuery, which can prompt you dialog box to save file in your computer.
Downloadify.create('downloadify',{
filename: function(){
return document.getElementById('filename').value;
},
data: function(){
return document.getElementById('data').value;
},
onComplete: function(){
alert('Your File Has Been Saved!');
},
onCancel: function(){
alert('You have cancelled the saving of this file.');
},
onError: function(){
alert('You must put something in the File Contents or there will be nothing to save!');
},
swf: 'media/downloadify.swf',
downloadImage: 'images/download.png',
width: 100,
height: 30,
transparent: true,
append: false
});
Using a base64 encoded data URI, this is possible with only html & js. What you can do is encode the data that you want to save (in your case, a string of XML data) into base64, using a js library like jquery-base64 by carlo. Then put the encoded string into a link, and add your link to the DOM.
Example using the library I mentioned (as well as jquery):
<html>
<head>
<title>Example</title>
</head>
<body>
<script>
//include jquery and jquery-base64 here (or whatever library you want to use)
document.write('click to make save dialog');
</script>
</body>
</html>
...and remember to make the content-type something like application/octet-stream so the browser doesn't try to open it.
Warning: some older IE versions don't support base64, but you said that didn't matter, so this should work fine for you.
Without any more insight into your specific requirements, I would not recommend a pure Javascript/HTML solution. From a user perspective you would probably get the best results writing a native application. However if it will be faster to use Javascript/HTML, I recommend using a local application hosting a lightweight web server to serve up your content. That way you can cleanly handle the file saving server-side while focusing the bulk of your effort on the front-end application.
You can code up a web server in - for example - Python or Ruby using very few lines of code and without 3rd party libraries. For example, see:
Making a simple web server in python
WEBrick - Writing a custom servlet
python-trick-really-little-http-server - This one is really simple, and will easily let you server up all of your HTML/CSS/JS files:
"""
Serves files out of its current directory.
Doesn't handle POST requests.
"""
import SocketServer
import SimpleHTTPServer
PORT = 8080
def move():
""" sample function to be called via a URL"""
return 'hi'
class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
#Sample values in self for URL: http://localhost:8080/jsxmlrpc-0.3/
#self.path '/jsxmlrpc-0.3/'
#self.raw_requestline 'GET /jsxmlrpc-0.3/ HTTP/1.1rn'
#self.client_address ('127.0.0.1', 3727)
if self.path=='/move':
#This URL will trigger our sample function and send what it returns back to the browser
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write(move()) #call sample function here
return
else:
#serve files, and directory listings by following self.path from
#current working directory
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
httpd = SocketServer.ThreadingTCPServer(('localhost', PORT),CustomHandler)
print "serving at port", PORT
httpd.serve_forever()
Finally - Depending on who will be using your application, you also have the option of compiling a Python program into a Frozen Binary so the end user does not have to have Python installed on their machine.
Javascript is not allowed to write to a local machine. Your question is similar to this one.
I suggest creating a simple desktop app.
Is localhost PHP server ok? Web traditionally can't save to hard drive because of security concerns. PHP can push files though it requires a server.
Print to PDF plugins are available for available for all browsers. Install once, print to PDF forever. Then, you can use a javascript or Flash to call a Print function.
Also, if you are developing for an environment where internet access is spotty, conwider using VB.NET or some other desktop language.
EDIT:
You can use the browser's Print function.
Are you looking for something like this?
If PHP is ok, if would be much easier.
With IE you could use document.execCommand, but I note that IE is not an option.
Here's something that looks like it might help, although it will not prompt with SaveAs dialog, https://developer.mozilla.org/en/Code_snippets/File_I%2F%2FOL.
One simple but odd way to do this that doesn't require any Flash is to create an <a/> with a data URI for its href. This even has pretty good cross-browser support, although for IE it must be at least version 8 and the URI must be < 32k. It looks like someone else on SO has more to say on the topic.
Why not use a hybrid flash for client and some server solution server-side. Most people have flash so you can default to client side to conserve resources on the server.
How can I check to see if a file is already open by another user in javascript? As it is right now, the program I'm trying to fix will open/edit a file then fail on trying to save if the file is already in use.
Also, is there an easy way to add a lock on the file so another process knows it's in use?
Edit: the program is a .hta using Active X Objects.
i guess i should have been more specific, here's some code about how it is opening/editing/saving the files.
var FileSystem = new ActiveXObject( "Scripting.FileSystemObject" );
var xmlDoc = new ActiveXObject( "Msxml2.DOMDocument.3.0" );
var fFile = FileSystem.GetFile( strPath );
xmlDoc.load( fFile.Path );
// some method's to edit documentElement in xmlDoc...
xmlDoc.save( fFile.Path );
Are you sure it's just JavaScript and not a combo of maybe an ActiveX or flash component? Is the file on the client or server? If server, this question makes more sense to me (ie. using some AJAX solution).
I'm not too familiar with ActiveX, but maybe when you open a file you could create a temporary file like file.ext.lock (and delete it when you save the file), so when another user tries to open the same file and sees the .lock file exists, you know it's being used.
You would probably need a server side locking feature. The javascript would call the server's 'save' script, which would return either a 'successful' status, or 'file locked'.
The simplest lock method that most programs use is creating another file with the same name but an extension such as '.lock'. A process checks if the file exists when opening the original, if so the file is in use and can only be opened as read only. If not, the lock file is created and the original can be edited.
will open/edit a file then fail on trying to save.
Javascript cannot open files or save them.
That may be your problem.
It could "edit" them - you can use JS to manipulate or edit an HTML page. [Even running a whole Rich Text Editor.]
But you then have to pass the page back to some other script to actually save those changes.
This is actually not true if you have Aptana or similar server side Javascript, or if it is being used [mozdev] to pass data to SQLite which can save its own data. If this is your case you should specify, as it is hardly typical Javascript usage.