Print PDF client side using javascript/jquery/java - javascript

I am trying to print the pdf using following code:
$('#print').click(function() {
var data = $(this).data('loc-subject');
alert(data);
var myWindow=window.open(data,'','width=500,height=500');
var doc = myWindow.document;
myWindow.document.writeln('<embed type="application/pdf" src="'+data+'" id="pdfDocument" width="100%" height="100%" />');
myWindow.document.writeln('<script type="text/javascript">');
myWindow.document.writeln('function load()');
myWindow.document.writeln('{');
myWindow.document.writeln('window.focus();');
doc.writeln('setTimeout(function() {window.print();}, 3000);');
myWindow.document.writeln('}');
myWindow.document.writeln('</scr'+'ipt>');
myWindow.document.writeln("<body onload=load()>");
myWindow.document.writeln("</body>");
myWindow.document.close();
});
But It has several flaws:
Not properly working in IE.
In Firefox its working fine but only printing the first page of pdf.
Using Iframe also giving the same result.
The PDF file is present server side on crx and I just want to print the pdf to the client machine on a link click.
If anybody has working code or guidance on this it would really help me here.
Thanks.

Related

Displaying and downloading a pdf in an iframe

I am using wix and in order to customize any html you need to use an embed object which creates a sandboxed iframe on the site. I have a decent grasp of how this works and posting messages to it but what I am having difficulties with is generating a pdf into this iframe.
I have done some reading and I think I get the overall concept. While traditionally you would just set the source to some document on a server somewhere I am generating the content dynamically based on user action. So it looks like something like pdfkit and creating a blob is the way to go.
I think I am able to generate the pdf without issues as well as a blob url no problem
[![console image][1]][1]
I can manually open the console and get that URL and paste it in the browser and the document opens exactly how I expect it. However I can't get it to display normally in the browser.
I have tried setting the src of various elements = to the blob url without luck.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
blah
<script src="https://github.com/foliojs/pdfkit/releases/download/v0.11.0/pdfkit.standalone.js"></script>
<script src="https://github.com/devongovett/blob-stream/releases/download/v0.1.3/blob-stream.js">
</script>
</head>
<body>
<script>
const doc = new PDFDocument
const stream = doc.pipe(blobStream())
doc.fontSize(25).text('Testing document', 100, 80);
console.log(doc);
doc.end();
stream.on('finish', function() {
window.src = stream.toBlobURL('application/pdf');
const a = document.createElement('a');
a.href = stream.toBlobURL('application/pdf');
a.download = 'ShoppingList' || 'download';
console.log("download IS",a)
});
</script>
</body>
</html>
In addition to setting the window.src I have tried document.src iframe.src which returns an error.
displaying isn't strictly necessary but a download link would be. Is there some other way I can do this to get this data? I feel I am missing something very simple.
I have had to change the examples as given on [http://pdfkit.org/docs/getting_started.html][2] but I don't think this is any issue as the package is working as expected and the document is being created.
Edit:
I have made some progress on this but am getting stuck in downloading it. What I did was these 2 things.
<input type="button" id = "dload" onclick="location.href='';" value="Download Shopping List" />
document.getElementById("dload").onclick = function(){location.href = stream.toBlobURL('application/pdf')};
the pdf actually shows in the iframe as expected with the full capabilities of a pdf preview however the download doesn't work at all it just says failed - network error and the filetype is not a pdf which makes sense. Is there something else I can add to get this working?
Edit2: Tried one more thing that doesn't work very well since popups are mostly blocked
window.open(stream.toBlobURL('application/pdf'), '_blank');
this, while it technically works is really messy and is causing a number of problems. Also it works differently on mobile vs desktop. There has to be some simple way to just show a pdf but it seems to just result in more questions the more I search.
[1]: https://i.stack.imgur.com/le6o9.png
[2]: http://pdfkit.org/docs/getting_started.html
I have partially solved my question and it is good enough for what I need. Here is what I did.
<html>
<head>
<script src="https://github.com/foliojs/pdfkit/releases/download/v0.11.0/pdfkit.standalone.js"></script>
<script src="https://github.com/devongovett/blob-stream/releases/download/v0.1.3/blob-stream.js"></script>
<script type="text/javascript">
window.onmessage = (event) => {
if (event.data) {
// create a document and pipe to a blob
var doc = new PDFDocument();
var stream = doc.pipe(blobStream());
doc.font('Helvetica');
doc.fontSize(20);
doc.text('Some Text',200,20);
// end and display the document in the iframe to the right
doc.end();
stream.on('finish', function() {
const blob = stream.toBlob('application/pdf')
const a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = "YourFileName";
a.style.position = 'fixed';
a.target = '_blank';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
};
};
</script>
</head>
<body>
</body>
</html>
while I can't see the pdf using this method it does download correctly which was the more important piece. Technically I could combine the two but since the download button on the iframe doesn't work I think it would be confusing for someone having a separate button to actually download it. So I have a separate button outside the frame that triggers the "onmessage" it is a function of wix. This triggers all document generation and download.

Get Image From Google Drive for Script-Based Web Page

I am trying to get a png image in google drive to appear on a google apps script html page. I can get the image to appear on the script html page if it is just at a URL somewhere on the web (see commented out line below), but not from google drive. Here is part of the code where I am trying to get as a blob and then use it in an image tag:
function getImage() {
//The next 2 lines don't produce the image on the page
var image = DriveApp.getFileById('File Id Goes Here').getBlob().getAs('image/png');
var image = '<img src = "' + image + '" width = "90%">'
//Note, the next line uncommented produces an image on the page
//var image = '<img src = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" width = "90%">'
return image
}
function doGet() {
var htmlToAppend = getImage();
var html = HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('Google Image').append(htmlToAppend).setSandboxMode(HtmlService.SandboxMode.IFRAME);
return html;
}
The result is a missing image on the html page produced by the script, with the URL for the missing image ending in script.googleusercontent.com/Blob
Info on Blob is here: https://developers.google.com/apps-script/reference/base/blob (open in a separate page/tab)
Any help is appreciated.
If you can see the Using base64-encoded images with HtmlService in Apps Script or Displaying files (e.g. images) stored in Google Drive on a website, there are some workaround to get the image from drive.
One workaround is using the IFRAME sandbox mode, but this doesn't support old browsers.
All that's required is to call setSandboxMode() on your template, and your data URIs should work as expected:
var output = HtmlService.createHtmlOutput(
'<img src="data:' + contentType + ';base64,' + encoded + '"/>'
);
output.setSandboxMode(HtmlService.SandboxMode.IFRAME);
The second is using the permalink of the file:
https://drive.google.com/uc?export=view&id={fileId}
But be noted that Serving images in an Apps Script through HtmlService is deprecated .
<img src="https://googledrive.com/host/0B12wKjuEcjeiySkhPUTBsbW5j387M/my_image.png" height="95%" width="95%">
Also, refrain from using same variable names to avoid error from occuring
Hope this helps.

Encoded URI doesn't work like the src attribute for iframe in IE11

I try to generate src attribute for the iframe on the fly doing this:
var iframe = document.createElement('iframe');
var html = '<html> <head></head> <body></body> </html>';
var eventListener = '<script>window.addEventListener("message", someListenerFunction)</script>';
iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html) + encodeURI(eventListener);
iframe.sandbox = 'allow-scripts';
This actually works fine in chrome/firefox/safari, but it doesn't work with ie11. Inside the iframe window it returns:
Cannot display the webpage
And in the console I get the error:
SCRIPT5: Access is denied.
File: unknowprotocol.htm, Line:1, Column:1
The problem I think in the encoded URI address.
The reason I do this - I need to generate lots of iframes and I don't want to create a static webpages for each of them.
Hope for your help. Thank you in advance.

Copying to clipboard using javascript/flash

I am currently working on a PHP/HTML/Javascript project and I am trying to automatically copy text to the user clipboard when they press a button.
I've done some research and found that this can be done easily in IE, but every other browser doesn't support this, so instead a flash file is embedded which does the copying. Howver, this doesn't seem to be working.
Below is the code that does the copying
function copyToClipboard()
{
//Copy to clipbord if IE
if (window.clipboardData && clipboardData.setData)
{
window.clipboardData.setData('text', 'I am copied');
}
else //other browsers
{
alert("other browser");
var flashcopier = 'flashcopier';
if(!document.getElementById(flashcopier)) {
var divholder = document.createElement('div');
divholder.id = flashcopier;
document.body.appendChild(divholder);
}
document.getElementById(flashcopier).innerHTML = '';
var divinfo = '<embed src="_clipboard.swf" FlashVars="clipboard='+encodeURIComponent('other browser copied')+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
document.getElementById(flashcopier).innerHTML = divinfo;
}
}
It appears to be working fine when using IE, but when using Chrome, nothing gets copied to the clipboard. There aren't any errors either in the chrome development tools.
I know the flash file is embedded OK using the above code as, if I change the src to say clipboard.swf_rubbish then the chrome development console says its can't find the file.
Thanks for any help you can provide.
That solution no longer works with the release of Flash Player 10. Because of security restrictions on accessing clipboard data. You can find a workaround here

Can't access YouTube API from Adobe Air (using JavaScript)

I'm really new to Adobe Air, and I'm trying to get a list of YouTube videos by a specific user using the YouTube API through JavaScript.
I've tried several examples that all seem to work great when I simply click on it (inside Aptana Studio) and Run as a JavaScript Web Application.
As soon as I try to run the same thing as an Adobe Air Application, I don't get any data. Why is that? I don't know if there's something very obvious that I'm overlooking or what.
This is what I was looking at most recently:
http://code.google.com/apis/youtube/2.0/developers_guide_json.html
Can someone point me in the right direction or tell me why this isn't working in Adobe Air?
Update: OK, here's how I got it working, for anybody visiting from 2019 (tip of the hat to http://xkcd.com/979/):
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"
backgroundColor="#000000" verticalAlign="middle" horizontalAlign="center"
creationComplete="init()" borderStyle="solid">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
public var html : HTMLLoader = null;
protected var url : String = null;
protected function init()
{
/* Your embedded html with all the youtube REST calls is in the "local"
subdirectory of the application directory. Note the relation between
the local url, the sandbox root and the remote url. */
var localUrl : String = "app:/local/yt.html";
var sandboxRoot : String = "http://youtube.com/";
var remoteUrl : String = "http://youtube.com/local/yt.html";
html = new HTMLLoader();
html.addEventListener(Event.COMPLETE, htmlLoaded);
/* Embed your youtube html in an iframe that is loaded dynamically. You
could also just have this html code in a separate html file and load
it through html.load() instead of html.loadString(). */
var htmlString : String = "<html>"
+ "<body><center>"
+"<iframe width='100%' height='100%' src='" +remoteUrl
+"' sandboxRoot='"+sandboxRoot+"' documentRoot='app:/' "
+" allowCrossDomainXHR='true'" /* May not be necessary */
+" id='yt' name='yt'></iframe>"
+ "</center></body></html>";
/* The next line is needed to allow the REST API in the embedded html
to call home when loading through loadString. */
html.placeLoadStringContentInApplicationSandbox = true;
html.loadString(htmlString);
}
protected function htmlLoaded(e:Event):void
{
html.removeEventListener(Event.COMPLETE, htmlLoaded);
frame.addChild(html);
trace("html load complete.");
}
]]>
</mx:Script>
<mx:UIComponent id="frame" width="100%" height="100%" visible="true"/>
</mx:HBox>
Note that this is a cleaned up version of my code and I haven't tried running it, so it may not work out of the box, but that's essentially it.
I believe the reason is that AIR does not allow external JavaScript files to be loaded:
http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7f0e.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7ef7
I guess one option is to muck about with their cross-scripting and sandboxing stuff...

Categories