Can a PDF file's print dialog be opened with Javascript? - javascript

I know how to open a webpage in a new window and add javascript so the print dialog pops up. Is there a way to do a similar thing with a PDF file?

Yes you can...
PDFs have Javascript support. I needed to have auto print capabilities when a PHP-generated PDF was created and I was able to use FPDF to get it to work:
http://www.fpdf.org/en/script/script36.php

I usually do something similar to the approach given by How to Use JavaScript to Print a PDF (eHow.com), using an iframe.
a function to house the print trigger...
function printTrigger(elementId) {
var getMyFrame = document.getElementById(elementId);
getMyFrame.focus();
getMyFrame.contentWindow.print();
}
an button to give the user access...
(an onClick on an a or button or input or whatever you wish)
<input type="button" value="Print" onclick="printTrigger('iFramePdf');" />
an iframe pointing to your PDF...
<iframe id="iFramePdf" src="myPdfUrl.pdf" style="display:none;"></iframe>
Bonus Idea #1 - Create the iframe and add it to your page within the printTrigger(); so that the PDF isn't loaded until the user clicks your "Print" button, then the javascript can attack! the iframe and trigger the print dialog.
Bonus Idea #2 - Extra credit if you disable your "Print" button and give the user a little loading spinner or something after they click it, so that they know something's in process instead of clicking it repeatedly!

Just figured out how to do this within the PDF itself - if you have acrobat pro, go to your pages tab, right click on the thumbnail for the first page, and click page properties. Click on the actions tab at the top of the window and under select trigger choose page open. Under select action choose "run a javascript". Then in the javascript window, type this:
this.print({bUI: false, bSilent: true, bShrinkToFit: true});
This will print your document without a dialogue to the default printer on your machine. If you want the print dialog, just change bUI to true, bSilent to false, and optionally, remove the shrink to fit parameter.
Auto-printing PDF!

I use named action instead of javascript because javascript often is disabled, and if it isn't it gives a warning.
My web application creates a postscript file that then is converted with ghostscript to a pdf. I want it to print automatically because the user has already clicked on print inside my application. With the information about named actions from #DSimon above, I researched how to solve this. It all boils down to insert the string /Type /Action /S /Named /N /Print at the right place in the pdf.
I was thinking of writing a small utility, but it has to parse the pdf to find the root node, insert /OpenAction with a reference an object with the action, and recalculate the byte-offsets in xref.
But then I found out about pdfmark which is an extension to postscript to express, in postscript syntax, idioms that are converted to pdf by Adobes distiller or by ghostscript.
Since I'm already using ghostscript, all I have to do is append the following to the end of my postscript file:
%AUTOPRINT
[ /_objdef {PrintAction} /type /dict /OBJ pdfmark
[ {PrintAction} << /Type /Action /S /Named /N /Print >> /PUT pdfmark
[ {Catalog} << /OpenAction {PrintAction} >> /PUT pdfmark
and ghostscript will create the action, link it, and calculate the xref offsets. (In postscript % is a comment and PrintAction is my name for the object)
By looking at the PDF I see that it has created this:
1 0 obj
<</Type /Catalog /Pages 3 0 R
/OpenAction 9 0 R
/Metadata 10 0 R
>>
endobj
9 0 obj
<</S/Named
/Type/Action
/N/Print>>endobj
1 0 is object 1, revision 0, and 9 0 is object 9, revision 0. In the pdf-trailer is says that it is object 1 that is the root node. As you can see there is a reference from object 1, /OpenAction to run object 9 revision 0.
With ghostscript it's possible to convert a pdf to postscript (pdf2ps), append the text above, and convert it back to pdf with ps2pdf. It should be noted that meta-information about the pdf is lost in this conversion. I haven't searched more into this.

Embed code example:
<object type="application/pdf" data="example.pdf" width="100%" height="100%" id="examplePDF" name="examplePDF"><param name='src' value='example.pdf'/></object>
<script>
examplePDF.printWithDialog();
</script>
May have to fool around with the ids/names.
Using adobe reader...

If you know how PDF files are structured (or are willing to spend a little while reading the spec), you can do it this way.
Use the Named Action "Print" in the OpenAction field of the Catalog object; the "Print" action is undocumented, but Acrobat Reader and most of the other major readers understand it. A nice benefit of this approach is that you don't get any JavaScript warnings. See here for details: http://www.gnostice.com/nl_article.asp?id=157
To make it even shinier, I added a second Action, URI, directing the reader to go back to the page that originated the request. Then I attached this Action to the first Named action using its Next field. With content disposition set to "inline", this makes it so that when the user clicks on the print link:
It opens up Adobe Reader in the same tab and loads the file
It immediately shows the print dialog
As soon as the Print dialog is closed (whether they hit "OK" or "cancel"), the browser tab goes back to the webpage
I was able to do all these changes in Ruby easily enough using only the File and IO modules; I opened the PDF I had generated with an external tool, followed the xref to the existing Catalog section, then appended a new section onto the PDF with an updated Catalog object containing my special OpenAction line, and also the new Action objects.
Because of PDF's incremental revision features, you don't have to make any changes to the existing data to do this, just append an additional section to the end.

Why not use the Actions menu option to set this?
Do the following: If you have Acrobat Pro, go to your pages tab, right click on the thumbnail for the first page, and click page properties. Click on the actions tab at the top of the window and under select trigger choose page open. Under select action choose 'Execute a menu item'. Click the Add button then select 'File > Print' then OK. Click OK again and save the PDF.

If you are using the prawn gem for Ruby on Rails to generate your PDF, you can use the following additional gem to active the print dialog:
prawn-print

Another solution:
<input type="button" value="Print" onclick="document.getElementById('PDFtoPrint').focus(); document.getElementById('PDFtoPrint').contentWindow.print();">

if you embed the pdf in your webpage and reference the object id, you should be able to do it.
eg.
in your HTML:
<object ID="examplePDF" type="application/pdf" data="example.pdf" width="500" height="500">
in your javascript:
<script>
var pdf = document.getElementById("examplePDF");
pdf.print();
</script>
I hope that helps.

Related

JS Open print dialog page to print a pdf file [duplicate]

I know how to open a webpage in a new window and add javascript so the print dialog pops up. Is there a way to do a similar thing with a PDF file?
Yes you can...
PDFs have Javascript support. I needed to have auto print capabilities when a PHP-generated PDF was created and I was able to use FPDF to get it to work:
http://www.fpdf.org/en/script/script36.php
I usually do something similar to the approach given by How to Use JavaScript to Print a PDF (eHow.com), using an iframe.
a function to house the print trigger...
function printTrigger(elementId) {
var getMyFrame = document.getElementById(elementId);
getMyFrame.focus();
getMyFrame.contentWindow.print();
}
an button to give the user access...
(an onClick on an a or button or input or whatever you wish)
<input type="button" value="Print" onclick="printTrigger('iFramePdf');" />
an iframe pointing to your PDF...
<iframe id="iFramePdf" src="myPdfUrl.pdf" style="display:none;"></iframe>
Bonus Idea #1 - Create the iframe and add it to your page within the printTrigger(); so that the PDF isn't loaded until the user clicks your "Print" button, then the javascript can attack! the iframe and trigger the print dialog.
Bonus Idea #2 - Extra credit if you disable your "Print" button and give the user a little loading spinner or something after they click it, so that they know something's in process instead of clicking it repeatedly!
Just figured out how to do this within the PDF itself - if you have acrobat pro, go to your pages tab, right click on the thumbnail for the first page, and click page properties. Click on the actions tab at the top of the window and under select trigger choose page open. Under select action choose "run a javascript". Then in the javascript window, type this:
this.print({bUI: false, bSilent: true, bShrinkToFit: true});
This will print your document without a dialogue to the default printer on your machine. If you want the print dialog, just change bUI to true, bSilent to false, and optionally, remove the shrink to fit parameter.
Auto-printing PDF!
I use named action instead of javascript because javascript often is disabled, and if it isn't it gives a warning.
My web application creates a postscript file that then is converted with ghostscript to a pdf. I want it to print automatically because the user has already clicked on print inside my application. With the information about named actions from #DSimon above, I researched how to solve this. It all boils down to insert the string /Type /Action /S /Named /N /Print at the right place in the pdf.
I was thinking of writing a small utility, but it has to parse the pdf to find the root node, insert /OpenAction with a reference an object with the action, and recalculate the byte-offsets in xref.
But then I found out about pdfmark which is an extension to postscript to express, in postscript syntax, idioms that are converted to pdf by Adobes distiller or by ghostscript.
Since I'm already using ghostscript, all I have to do is append the following to the end of my postscript file:
%AUTOPRINT
[ /_objdef {PrintAction} /type /dict /OBJ pdfmark
[ {PrintAction} << /Type /Action /S /Named /N /Print >> /PUT pdfmark
[ {Catalog} << /OpenAction {PrintAction} >> /PUT pdfmark
and ghostscript will create the action, link it, and calculate the xref offsets. (In postscript % is a comment and PrintAction is my name for the object)
By looking at the PDF I see that it has created this:
1 0 obj
<</Type /Catalog /Pages 3 0 R
/OpenAction 9 0 R
/Metadata 10 0 R
>>
endobj
9 0 obj
<</S/Named
/Type/Action
/N/Print>>endobj
1 0 is object 1, revision 0, and 9 0 is object 9, revision 0. In the pdf-trailer is says that it is object 1 that is the root node. As you can see there is a reference from object 1, /OpenAction to run object 9 revision 0.
With ghostscript it's possible to convert a pdf to postscript (pdf2ps), append the text above, and convert it back to pdf with ps2pdf. It should be noted that meta-information about the pdf is lost in this conversion. I haven't searched more into this.
Embed code example:
<object type="application/pdf" data="example.pdf" width="100%" height="100%" id="examplePDF" name="examplePDF"><param name='src' value='example.pdf'/></object>
<script>
examplePDF.printWithDialog();
</script>
May have to fool around with the ids/names.
Using adobe reader...
If you know how PDF files are structured (or are willing to spend a little while reading the spec), you can do it this way.
Use the Named Action "Print" in the OpenAction field of the Catalog object; the "Print" action is undocumented, but Acrobat Reader and most of the other major readers understand it. A nice benefit of this approach is that you don't get any JavaScript warnings. See here for details: http://www.gnostice.com/nl_article.asp?id=157
To make it even shinier, I added a second Action, URI, directing the reader to go back to the page that originated the request. Then I attached this Action to the first Named action using its Next field. With content disposition set to "inline", this makes it so that when the user clicks on the print link:
It opens up Adobe Reader in the same tab and loads the file
It immediately shows the print dialog
As soon as the Print dialog is closed (whether they hit "OK" or "cancel"), the browser tab goes back to the webpage
I was able to do all these changes in Ruby easily enough using only the File and IO modules; I opened the PDF I had generated with an external tool, followed the xref to the existing Catalog section, then appended a new section onto the PDF with an updated Catalog object containing my special OpenAction line, and also the new Action objects.
Because of PDF's incremental revision features, you don't have to make any changes to the existing data to do this, just append an additional section to the end.
Why not use the Actions menu option to set this?
Do the following: If you have Acrobat Pro, go to your pages tab, right click on the thumbnail for the first page, and click page properties. Click on the actions tab at the top of the window and under select trigger choose page open. Under select action choose 'Execute a menu item'. Click the Add button then select 'File > Print' then OK. Click OK again and save the PDF.
If you are using the prawn gem for Ruby on Rails to generate your PDF, you can use the following additional gem to active the print dialog:
prawn-print
Another solution:
<input type="button" value="Print" onclick="document.getElementById('PDFtoPrint').focus(); document.getElementById('PDFtoPrint').contentWindow.print();">
if you embed the pdf in your webpage and reference the object id, you should be able to do it.
eg.
in your HTML:
<object ID="examplePDF" type="application/pdf" data="example.pdf" width="500" height="500">
in your javascript:
<script>
var pdf = document.getElementById("examplePDF");
pdf.print();
</script>
I hope that helps.

How to download files in bulk from browser console using JavaScript?

I have no experience with web programming, so my question would be a very simple one. I want to download a lot of files by filling out forms in a web page. The web page's extension is .aspx, and I am interested in only one field and a button. By fooling around with the console in my browser, I figured out that executing:
document.getElementById('TxtRegNo').value = 'blahblah`;
will fill the concerned field. Also doing a
__doPostBack("ImageButton1","Click");
will download the .pdf file curresponding to blahblah. The actual value which needs to be entered is a sequence like PAG-1200 to PAG-1900. I tried using a for loop, like this:
for (var i = 21618; i < 21621; i++)
{
document.getElementById('TxtRegNo').value = 'B14-' + i;
__doPostBack("ImageButton1","Click");
}
but it doesnot work as expected. only the last document gets downloaded, and I get this in the console:
Thought this error does not come whe nI run in FireFox's console, I can still run only one file. Could anyone tell me how to do this?
Try this:
Inject jQuery to the page via the console, as explained here: Include jQuery in the JavaScript Console
In your for loop clone the form, set the values as you wish and submit the form jQuery('form').clone().find('#TxtRegNo').val('blah').parent('form').submit();
If the page contains more than one form, you should specify it. 'form' works like css selectors here. This will find all forms on the page. Just use '#elementId' or '.elementsClassName' to be more concrete, if necessary.
Maybe you also need to change the name of the form (to be able to submit the forms simulatiously). I didn't try it, this is just a guess.
If you want to split the code to several lines you can also do this:
var myFormClone = jQuery('form').clone();
myFormClone.find('#TxtRegNo').val('blah');
myFormClone.attr('name', 'uniquename_' + iterationVariableOfForLoop);
myFormClone.submit();
If the submit failes, try:
myFormClone.get(0).submit();
Good luck!

Autofill Text box on a Web Page (Javascript/VBScript)

I really need to know how I can autofill text boxes on a web page.
What I really want to achieve is the following:
1) Go to http://show.websudoku.com
2) Replace all the empty cells with a 0 (zero).
Is that possible?
To fill the empty spaces of the Sudoku grid at http://show.websudoku.com with zero's, here is some JavaScript to do that. It is formatted for use as a "Bookmarklet":
javascript:(function(){var x,k,f,j,r;x=document.forms;for(k=0;k<x.length;++k){f=x[k];for(j=0;j<f.length;++j){r=(f[j].className.toLowerCase()+f[j].type.toLowerCase()+f[j].value);if(r=="d0text"){f[j].value="0";}else if(r=="d0text0"){f[j].value="";}}}})();
The setup:
Create a new Bookmark/Favorite. For now, the URL for the favorite can be anything. An easy way to do this is to drag ANY link/url from the browser address bar, or any web-page link, to the "Favorites Bar" or to the Bookmarks/Favorites sidebar.
Select the new favorite, and rename it to any name you like.
Copy the JavaScript code from above to the clipboard. It must remain as 1 continuous single line, and it must begin with "javascript:(" and end with ")();"
Edit the properties of the new favorite.
Remove the "URL" that is currently in the favorite and replace it by pasting in the JavaScript code from above, into the "URL" text field for the favorite, then save the changes.
To use the bookmarklet:
From the browser, navigate to http://show.websudoku.com as you normally would.
Click the new favorite (Bookmarklet) that you just edited.
All empty spaces in the Sudoku grid will be filled with 0's. Click the new favorite (Bookmarklet) again, and the 0's will be removed leaving empty spaces once again.
Here is what the Javascript code looks like expanded, with indents:
javascript:(function(){
var x,k,f,j,r;
x=document.forms;
for(k=0;k<x.length;++k){
f=x[k];
for(j=0;j<f.length;++j){
r=(f[j].className.toLowerCase()+f[j].type.toLowerCase()+f[j].value);
if(r=="d0text"){
f[j].value="0";
}
else if(r=="d0text0"){
f[j].value="";
}
}
}
}
)();
* Spoiler alert *
In case you want to "cheat", the JavaScript here will "solve" the Sudoku:
javascript:(function(){var x,k,f,j,ecl,etl,en,ev,s,e,c,d,dl,dr,n;x=document.forms;for(k=0;k<x.length;++k){f=x[k];for(j=0;j<f.length;++j){e=f[j];r=(e.name.toLowerCase());if(r=="cheat"){c=e.value;break;}}for(j=0;j<f.length;++j){e=f[j];ecl=e.className.toLowerCase();etl=e.type.toLowerCase();en=e.name;ev=e.value;if(etl=="text"){if(ecl=="d0"){dr=en.substr(en.length-1,1);dl=en.substr(en.length-2,1);d=(((Number(dr)-1)*9)+Number(dl))-1;n=c.substr(d,1);if(ev.length==0){e.value=n;}else{e.value="";}}}}}})();
Setup and use is the same as described above.
While it's not much fun to solve it like that (OK, maybe it's a little fun the first couple times), and definitely not challenging, if you are in a real-real-real hurry, you can solve it in 1 click.
Note: I have only tested these 2 bookmarklets with IE9.

How to disable google plus one (+1) button's hover bubble?

In my page, how can i remove the google +1 button's tooltip message?
Example: http://www.google.com/webmasters/+1/button/
Documentation: http://code.google.com/apis/+1button/
I tried many ways, but can't figure it out.
You are supposed not to do that as per the google policies that you agree to in using their API: http://www.google.com/webmasters/+1/button/policy.html .
You're not allowed to modify the button, its behavior included.
You can be controlled by Google's robots as stated in same page. If you don't want the button's behavior, don't use Google's +1 API.
I agree with #Kheldar, but as a teaching lesson, here is how you would do it:
When the popup shows up, the HTML starts with this:
<table cellpadding="0" cellspacing="0" style="width: 324px; height: 68px; " frame="void" rules="none" class="gc-bubbleDefault pls-container">
Just add some CSS to not show it:
.gc-bubbleDefault, .pls-container
{
display: none !important;
}
Firefox users: Print and follow these steps to turn off /disable/remove Google +1 Buttons from search results with or without AdBlock or AdBlock Plus and WITHOUT having to create a Google profile:
1) Go to Firefox Profiles folder on your hard drive.
To locate your Firefox Profiles in Windows XP, Vista, 7, press: [Windows Key]+[R] → Type in (minus the quotes):
“%APPDATA%\Mozilla\Firefox\Profiles” → click OK
or from the Taskbar click:START → RUN → Type in (minus the quotes):
“%APPDATA%\Mozilla\Firefox\Profiles” → click OK
The Profiles Folder will open. There will probably be only one folder in the Profiles folder.
2) Open the folder with the ".default" extension name.
3) Look for a folder named Chrome in the .default folder. If Chrome folder does not exist, you need to create it. (If the Chrome folder exists, skip to #4).
To create the Chrome folder: Right click inside the .default folder → Select NEW FOLDER → Type in (without the quotes): “Chrome”
4) Open the Chrome folder and create a .text file named userContent.css. (The contents of this file tells Firefox not to display +1 Buttons on web pages.)
To create a text file named userContent.css: Right click inside the Chrome folder → Select NEW → TEXT DOCUMENT → Type in (without the quotes): "userContent.css"
Windows will bring up “Rename” warning dialogue box that says: If you change a file name extension, the file may become unusable. Are you sure you want to change it? Yes No
Select YES
5)Open userContent.css. (It will open in Notepad with a box titled: userContent.css - Notepad).
6) Paste the following into Notepad (minus the quotes): " .esw { display:none!important; } /* Hides the +1 Button completely */ "
Be sure to include the period (.) before "esw" in the above.
7) Save the Notepad file and Close it: Select FILE → SAVE → FILE → CLOSE (or select X on folder title bar to Close)
8) Close remaining open folders.
9)If Firefox Browser is not closed, close it. Re-open Firefox Browser. Navigate to Google’s search page and perform a search. Google +1 Buttons will be gone from all future search results.
I got the same problem as I wanted to have the buttons
in the same layout as the facebook and twitter share buttons (from addthis)
without the g+ tooltip -- it's not the +1 rather the share
it does exist -- but is hidden ..
(needs url parameter -- https://plus.google.com/share?url={URL} )
on https://developers.google.com/+/plugins/share/
scroll down ... to "Share Link" .. with a code example
<a href="https://plus.google.com/share?url={URL}"
onclick="javascript:window.open(this.href,'',
'menubar=no,toolbar=no,resizable=yes,
scrollbars=yes,height=600,width=600');return false;">
<img src="https://www.gstatic.com/images/icons/gplus-64.png"
alt="Share on Google+"/></a>
well with addthis the class is addthis_button_google_plusone_share
not yet in their api docs as if they added it later on
-- am a bit annoyed about their inconsistence
(tw -> js:window.open vs fb, g+ -> url:_black)
-- adds to the url trackingcodes -- well it can be disabled
<script type="text/javascript">
var addthis_config = { data_track_clickback: false } </script>
facebook and twitter handle it exactly the same
-- get paramter in respective url
fb: http://www.facebook.com/sharer/sharer.php?u={URL}
tw: https://twitter.com/intent/tweet?text=XXXX&url={URL}&related=

Calling a javascript file (.js) via Excel VBA?

How to call a javascript file (.js) via Excel VBA?
So as i am opposed to the same kind of problem i'll try to submit you guys my case.
I am trying to automate datas extraction from valeo's catalogue using excel vba macro.
I have a list of références attached to valeo's automotive products (huge list, as more than 3000 thousands items). And i would like to import directly informations from the catalogue wich seems to run under javascript.
The datas i need is the list of every vehicules attached to a reference.
Here is the url: http://outcat-cs.tecdoc.net/ows/en/7FA2A0C501BC34CA4BECB04095663CF1.ows_cs2.srv?view=VIndexFramesetJsp
I'd like to access to the "Direct Article Search" tab, in order to copy a reference directly from an excel tab's cell and then simulate a clic on the reference in order to display the "linked vehicules section" and then to copy them in a new excel sheet.
I already succeede in doing this with html pure programmed webpage (oscaro.com) using the following code :
Set maPageHtml = IE.document
Set Helem = maPageHtml.getElementsByTagName("input")
For i = 0 To Helem.Length - 1
If Helem(i).getAttribute("name") = "toFind" Then Helem(i).Value = "819971" '819971 is the valeo reference searched
If Helem(i).getAttribute("name") = "submit" Then Set Monbouton = Helem(i)
Next
Monbouton.Click 'this does the click on my button Monbouton
But this technique can't be used with valeo website since I am not able (or at least I don't know yet how to do it) to select/click a button when the page is made on javascript, since it doesn't have a name, value or id for the button.
Also it seems that the url in the address field is the same before clicking on the "Direct Article Search" button and after having clicked....
Hope i am clear enought in spite of my english...
Greetings
All the previously suggested approaches sound hacky to me.
For a more reliable solution, embed the Javascript in a COM component via Windows Script Components, and call the Javascript-based COM component as you would any other COM component.
I don't think that there is a direct way to run JavaScript code in VBA.
What you could try to do is to embed the JavaScript code in an HTML form which you could open in a (hidden) browser control. Then fill the form controls via the DOM of the browser control and submit the form. The submit triggers the JavaScript function that you want to call.
Sample (not tested):
VBA:
oIE.Document.frmMain.param1.Value = 5
oIE.Document.frmMain.param2.Value = "6"
oIE.Document.frmMain.submit.click ' this line will call the JavaScript function
HTML:
<div id="submit" > Do Action</div>
<script>
function doAction()
{
// do whatever the code should do
}
</script>
You mean through windows scripting host?
You can shell (use the shell command) out to wscript.exe with the name of the .js file.
But this javascript object model won't be like the one you get in the browser.
It would be helpful if you told us what the javascript was supposed to do.

Categories