Consume PDF stream into jsp - javascript

I am trying to display PDF report inside jsp
I have PDFstream available using following code
private void generatePDFReport(OutputStream stream, JasperPrint jasperPrint) throws JRException {
JRPdfExporter jrpdfexporter = new JRPdfExporter();
jrpdfexporter.setExporterInput(new SimpleExporterInput(jasperPrint));
jrpdfexporter.setExporterOutput(new SimpleOutputStreamExporterOutput(stream));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
jrpdfexporter.setConfiguration(configuration);
jrpdfexporter.exportReport();
}
now I am outputstream which is basically PDF Stream which i want to display into jsp, I dont want to set whole response contenttype as application/pdf but i want to embed pdf into part of jsp output
So i convrted pdfstream output into bytearray and trying to display using following
<script language="Javascript">
function loadDoc() {
alert('called loadDoc');
var xhr = new XMLHttpRequest();
alert('called xhr');
xhr.responseType = 'arraybuffer';
alert('called responseType');
alert('called xhr.onload ');
// Create the Blob URL:
var buffer = xhr.response;
var blob = new Blob([<%=byteCharSet%>], {
type: 'application/pdf'
});
var objectURL = URL.createObjectURL(blob);
alert(objectURL);
// Create an iframe to demonstrate it:
var iframe = document.createElement('iframe');
iframe.className = 'sample-iframe';
iframe.src = objectURL;
document.body.appendChild(iframe);
console.log(objectURL);
//xhr.open('GET', 'https://cors-anywhere.herokuapp.com/http://www.xmlpdf.com/manualfiles/hello-world.pdf', true);
//xhr.send();
}
</script>
but when I am trying to execute javascript couldn't understand bytearray output it simply getting failed blob value getting displayed as below in view page source
var blob = new Blob([%PDF-1.4
%����
3 0 obj
<</Filter/FlateDecode/Length 625>>stream
x���M��0#��>��um�'�v�������C
^���V�����Ķ�H����3�?�}� � �q�D3�
q�`�e��˼'��Do?1�(Ξ�h��2s�S(^�����gĈ^�/b��a�r"\"���_���Г�Lw

I used Iframe to solve this issue.
In iframe for src i used another jsp.
out.write("<iframe src= displayPDF.jsp" + " " + "type=application/pdf width=100% height=600px ");
out.write("</iframe>");
following is the displayPDF.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%><%
byte[] pdfByteArray = (byte[]) session.getAttribute("PDFbyteArray");
if (pdfByteArray == null)
System.out.println("pdfByteArray is null");
response.setHeader("Content-Disposition", "inline; filename=\"MyFile.pdf\"");
response.setContentType("application/pdf; name=\"MyFile.pdf\"");
ServletOutputStream serv_out = response.getOutputStream();
serv_out.write(pdfByteArray);
serv_out.flush();
serv_out.close();
out.clear();
session.removeAttribute("PDFbyteArray");%>

Related

How to get src from URL which requires basic auth

In our app we have the following HTML code
<audio controls="controls" src="http://user:password#server:port/searchapi?command=replay&id=9203732824369002191_2"> Your browser does not support the HTML5 Audio element. </audio>
It goes to the URL above and supposed to get an audio file.
However, it's not supported in every browser, so we decided to do the following:
Instead of that authorization execute JS code which sends a GET request
In a src attribute put the file itself.
The code looks like this:
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'server:port/searchapi?command=replay&id=9203732824369002191_2', false);
myRequest.setRequestHeader('Authorization', 'Basic ' + btoa('user:password'));
myRequest.send();
The question is how do we execute it on a page while it's rendering? I mean put that code directly in src tag name?
Also, is there any way to determine mime-type dynamically? In the answer it's hardcoded and they process an image, not audio. Is there a difference?
I wrote the following (without auth):
<audio id= "audioElement" controls="controls" [src]="getAudio()"> Your browser does not support the HTML5 Audio element. </audio>
<script>
function getAudio()
{
var oReq = new XMLHttpRequest();
oReq.open('GET', 'https://upload.wikimedia.org/wikipedia/ru/6/62/Meow.ogg', true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent)
{
var arrayBuffer = oReq.response;
if (arrayBuffer) {
var u8 = new Uint8Array(arrayBuffer);
var b64encoded = btoa(String.fromCharCode.apply(null, u8));
var mimetype="audio/ogg";
document.getElementById("audioElement").src="data:"+mimetype+";base64,"+b64encoded;
oReq.send(null);
}
}
</script>
But it doesn't work.
What's the problem?
Thanks in advance.
Well , it seems the the proper way to implement such behaviour is the following:
<audio id= "audioElement" controls="controls"> Your browser does not support the HTML5 Audio element. </audio>
<script>
window.onload = function()
{
var oReq = new XMLHttpRequest();
oReq.open('GET', 'https://upload.wikimedia.org/wikipedia/ru/6/62/Meow.ogg', true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent)
{
var arrayBuffer = oReq.response;
if (arrayBuffer)
{
var u8 = new Uint8Array(arrayBuffer);
var b64encoded = btoa(String.fromCharCode.apply(null, u8));
var mimetype="audio/ogg"; // or whatever mime type is
document.getElementById("audioElement").src="data:"+mimetype+";base64,"+b64encoded;
}
}
oReq.send(null);
}
</script>
Hopefully, it will work with basic auth too...

Convert HTML to Word then to pdf

I need to convert HTML to PDF. I have tried with jsPDF and read a lot of questions here on stackoverflow about this. I have tried all the methods that exist, html(), fromHtml, html2pdf and html2canvas. But all of them have various problems. Either missing content, fuzzy content or margins are completely off.
So I am trying a different route. I found following code snippet to convert to word document. And this works.
function exportHTML(){
var header = "<html xmlns:o='urn:schemas-microsoft-com:office:office' "+
"xmlns:w='urn:schemas-microsoft-com:office:word' "+
"xmlns='http://www.w3.org/TR/REC-html40'>"+
"<head><meta charset='utf-8'><title>Export HTML to Word Document with JavaScript</title></head><body>";
var footer = "</body></html>";
var sourceHTML = header+document.getElementById("source-html").innerHTML+footer;
var source = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(sourceHTML);
var fileDownload = document.createElement("a");
document.body.appendChild(fileDownload);
fileDownload.href = source;
fileDownload.download = 'document.doc';
fileDownload.click();
document.body.removeChild(fileDownload);
}
However I do not want the word file to be downloaded. I need to capture it and convert it to a base64 string because then I can send it to a rest api that can convert the word document to pdf. That rest api does not support html directly otherwise I would just send the html. Hence the workaround to word then to pdf. ps I cannot use an online pdf solution due to sensitive information, the rest api is an internal service.
However I do not want the word file to be downloaded. I need to capture it and convert it to a base64 string because then I can send it to a rest api that can convert the word document to pdf.
Then no need to insert it into a download link. Just base64 encode the string with btoa:
function exportHTML(){
var header = "<html xmlns:o='urn:schemas-microsoft-com:office:office' "+
"xmlns:w='urn:schemas-microsoft-com:office:word' "+
"xmlns='http://www.w3.org/TR/REC-html40'>"+
"<head><meta charset='utf-8'><title>Export HTML to Word Document with JavaScript</title></head><body>";
var footer = "</body></html>";
var sourceHTML = header+document.getElementById("source-html").innerHTML+footer;
var source = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(sourceHTML);
// encode here instead of creating a link
var encoded = window.btoa(source);
return encoded;
}
Then you'll be free to use XMLHttpRequest to send the encoded string to your API endpoint. E.g.:
var encodedString = exportHTML();
var xhr = new XMLHttpRequest();
xhr.open('POST', '/my-conversion-endpoint', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// request finished
alert(xhr.responseText);
}
}
xhr.send('encodedString=' + encodedString);
Use "new Blob" by file's construct:
function exportHTML(){
var header = "<html xmlns:o='urn:schemas-microsoft-com:office:office' "+
"xmlns:w='urn:schemas-microsoft-com:office:word' "+
"xmlns='http://www.w3.org/TR/REC-html40'>"+
"<head><meta charset='utf-8'><title>Export HTML to Word Document with JavaScript</title></head><body>";
var footer = "</body></html>";
var sourceHTML = header+document.getElementById("source-html").innerHTML+footer;
var source = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(sourceHTML);
//var fileDownload = document.createElement("a");
//document.body.appendChild(fileDownload);
//fileDownload.href = source;
//fileDownload.download = 'document.doc';
//fileDownload.click();
//document.body.removeChild(fileDownload);
var my_file=new Blob([source]);
getBase64(my_file);
}
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
exportHTML();
<div id="source-html">Hi <b>World</b>!</div>

Turn a blob url into a upload file for FormData() and send it via AJAX to a PHP file

I want to convert a blob URL AKA (window.URL.createObjectURL(blob);) into a file object so I can use it with FormData() so I can use that as an upload image file for AJAX but I am not able to do that successfully and I can't find a way to make the blob URL into a file
object for my code situation and I know its possible to do this according to the posts I visited on here it can be done here's one of posts that claim that you can do that How to convert Base64 String to javascript file object like as from file input form? but the reason why I'm not using any of those posts methods because I don't know how to integrate their methods to my code situation or its too complicated to understand.
This is my code that I been working on.
index.php
<script>
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('#image-input').addEventListener('change',createABlobUrlForAImgSrcAndUseThatAsAFileUploadFile);
function createABlobUrlForAImgSrcAndUseThatAsAFileUploadFile(){
//Creating a blob URL
var image_input = document.querySelector('#image-input').files[0];
var file_type= image_input.type;
var blob = new Blob([image_input], { type: file_type || 'application/*'});
var blob_url= window.URL.createObjectURL(blob); //<-Example blob:http://localhost/ed6761d2-2bb4-4f97-a6d8-a35c84621ba5
//
//Form data
var formData= new FormData();
formData.append('blob_url', blob_url);
//
//<AJAX>
var xhr= new XMLHttpRequest();
xhr.onreadystatechange= function(){
if(xhr.readyState == 4){
document.querySelector('#output').innerHTML= xhr.responseText;
//<Allow JS in AJAX request>
var exJS= document.querySelectorAll('#output script');
var enableAll= exJS.length;
for(var i=0; i < enableAll.length; i++){
eval(exJS[i].text);
}
//</Allow JS in AJAX request>
}
}
xhr.open('POST','x');
xhr.send(formData);
//</AJAX>
}
});
</script>
<input id='image-input' type='file'>
<div id='output'></div>
x.php
<?php
$file=$_FILES['blob_url']['name'];
$location='images/'.$file;
move_uploaded_file($_FILES['blob_url']['tmp_name'],$location);
?>
I know my code is not logically correct and I will have to change my code to be able to do what I want to do so I am aware it is not logically correct. Just trying to show you guys what I mean.
This is how I got it done in my project. But in my case, I wanted to convert a blob to a wav file and then send to the back-end.
//Save your blob into a variable
var url = URL.createObjectURL(blob);
//Now convert the blob to a wav file or whatever the type you want
var wavefilefromblob = new File([blob], 'filename.wav');
//Pass the converted file to the backend/service
sendWavFiletoServer(wavefilefromblob);
//This is my function where I call the backend service to send the wav file in Form data
function sendWavFiletoServer(wavFile) {
var formdata = new FormData();
formdata.append("file", wavFile);
var ajax = new XMLHttpRequest();
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "https://yourserviceurl/api/");
ajax.setRequestHeader('API_SECRET', UzI1NiIsInR5cCI6IkpXVCJ9eyLCJleHAiO');
ajax.send(formdata);
}
I think uploading form data should be a blob object, not a blob URL
javascrip:
var image_input = document.querySelector('#image-input').files[0];
var blob_url= window.URL.createObjectURL(image_input);
//Form data
var formData= new FormData();
// ...
// here , content-type: multipart/form-data
formData.append('upload_file', image_input);
php:
$file=$_FILES['upload_file']['name'];
$location='images/'.$file;
move_uploaded_file($_FILES['upload_file']['tmp_name'],$location);
I had the same question and found a way.
This will give you a Blob object:
let blob = await fetch(url).then(r => r.blob());

How to pass a Blob object from javascript to Android?

I have a Blob object inside my WebView, how can I pass it to Android?
I want to save it to local file on device.
I been trying to use:
var url = webkitURL.createObjectURL(myBlob);
But I wasn't been able to download it to device.
I found a solution by converting the blob to Base64 String
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
// send base64data string to android as a method param
}
I haven't tried this, but i was able to found some information pointing to the usage of Javascript Interfaces with WebViews. Basically you can assign Java Classes to work like Javascript classes in your WebView (and exchange information between both sides).
I'm not a pro at JavaScript object types, so i'll leave that to you.
First, create a JavaScriptHandler class with a reference to your activity that controls the WebView:
public class JavaScriptHandler {
MyActivity parentActivity;
public JavaScriptHandler(MyActivity activity) {
parentActivity = activity;
}
public void doSomething(<Your blob format> data){
// .............
// ..Some code..
// .............
}
}
After that you'll be adding your JavaScriptHandler to your WebView in your main Activity. Don't forget to enable JavaScript in your WebView!
myWebView = (WebView)this.findViewById(R.id.myWebView);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new JavaScriptHandler(this), "MyHandler");
The first parameter passed to addJavaScriptInterface() is the JavaScript interface object itself. The second parameter is the name of the global JavaScript variable which the JavaScript interface object is bound to.
Now all you gotta do is call your Java method with JavaScript.
<html>
<head>
<script type="text/javascript">
function sendBlob() {
MyHandler.doSomething(<Your Blob>);
}
</script>
</head>
<body>
<form>
<input type="button" value="Click me!" onclick="sendBlob()" />
</form>
</body>
</html>
You can use simple file downloader using JavaScript.
Here is a sample to download blob as file.
var saveData = (function() {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function(data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {
type: "octet/stream"
}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var data = {
x: 42,
s: "hello, world",
d: new Date()
},
fileName = "my-download.json";
saveData(data, fileName);

Downloading mp3 files using html5 blobs in a chrome-extension

I am trying to create a google-chrome-extension that will download an mp3 file. I am trying to use HTML5 blobs and an iframe to trigger a download, but it doesn't seem to be working. Here is my code:
var finalURL = "server1.example.com/u25561664/audio/120774.mp3";
var xhr = new XMLHttpRequest();
xhr.open("GET", finalURL, true);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
bb.append(xhr.responseText);
var blob = bb.getBlob("application/octet-stream");
var saveas = document.createElement("iframe");
saveas.style.display = "none";
saveas.src = window.webkitURL.createObjectURL(blob);
document.body.appendChild(saveas);
delete xhr;
delete blob;
delete bb;
}
}
xhr.send();
When looked in the console, the blob is created correctly, the settings look right:
size: 15312172
type: "application/octet-stream"
However, when I try the link created by the createObjectURL(),
blob:chrome-extension://dkhkkcnjlmfnnmaobedahgcljonancbe/b6c2e829-c811-4239-bd06-8506a67cab04
I get a blank document and a warning saying
Resource interpreted as Document but
transferred with MIME type
application/octet-stream.
How can get my code to download the file correctly?
The below code worked for me in Google chrome 14.0.835.163:
var finalURL = "http://localhost/Music/123a4.mp3";
var xhr = new XMLHttpRequest();
xhr.overrideMimeType("application/octet-stream");
//xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.open("GET", finalURL, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
var res = xhr.response;
if (res){
var byteArray = new Uint8Array(res);
}
bb.append(byteArray.buffer);
var blob = bb.getBlob("application/octet-stream");
var iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = window.webkitURL.createObjectURL(blob);
document.body.appendChild(iframe);
};
xhr.send(null);
I'm not sure, but i think this is your server's trouble. I've just tried your piece of code to download some sample blob of mp3-file and everything went ok. So maybe:
this file doesn't exist on your server
you server outputs wrong mime type for mp3 files

Categories