How to save pdf file from Firebase in local folder from web - javascript

How do I download and save a pdf file from Firebase storage.
During upload I save upload infomation on real time firebase node like this:
while my storage is as follow:
My save btn is linked to this function:
function savepdfFile(){
let selectedGroup = document.getElementById("groupname");
let selectedDate = document.getElementById("dateId");
let selectedGroupValue = selectedGroup.value;
let selectedDateValue = selectedDate.value;
let mdate = "";
mdate = changeDateForamat(selectedDateValue);
downloadPDFDoc(selectedGroupValue,mdate);
}
I retrieve information of this pdf file from firebase real time node as follow when a save button is clicked;
function downloadPDFDoc(groupname,mdate){
let pdfName, pdfUrl;
firebase.database().ref('SessionPDFStorage').once('value',function(snapshot){
snapshot.forEach(
function(ChildSnapshot){
//let mLocation = ChildSnapshot.val().province;
let mGroup = ChildSnapshot.val().selectedGroup;
let mydate = ChildSnapshot.val().currentDate;
let ddate = changeDateForamat(mydate);
if(groupname == mGroup && mdate == ddate){
pdfName = ChildSnapshot.val().fileName;
pdfUrl = ChildSnapshot.val().fileImageUri;
}
}
);
loadScannedImage(pdfName,pdfUrl);
});
}
How do I develop the loadScannedImage(pdfName,pdfUrl) funtion below to using the above information to save the file on the local folder dynamically? example automatically save this pdf to a local c:\download directory.
function loadScannedImage(pdfName,pdfUrl){
}
I have seen some implementation of FileSaver.js and Blob.js but it is not quite clear how I would use them.
Any help will be appreciated.

I created an anchor element and pass both pdf name and its url link as as attributes follow inside loadscnnedImage:
function loadScannedImage(pdfName,ImgUrl){
var element = document.createElement('a');
element.setAttribute('href',`${ImgUrl}`);
element.setAttribute('download', pdfName);
document.body.appendChild(element);
element.click()
}
but I would have liked to dynamically safe the pdf file directly to browsers default downloaded folder on the machine. But this works too

Related

Javascript: Use <input type="file"/> to compute SHA256 file hash

Motivation: I want to make a browser-based hashing utility so users can compute file hashes without installing software.
The approach I'm considering is a static page with "a file upload button" (except no upload takes place): the user picks a file, and the script computes and displays its hash.
So let's say we have this element on the page:
<input id="file-hasher" type="file" />
This creates a button that allows the users of the web page to select a file via an OS "File open..." dialog in the browser.
Let's say the user clicks said button, selects a file in the dialog, then clicks the "Ok" button to close the dialog.
The selected file name is now stored in:
document.getElementById("file-hasher").value
Here, I'm hoping to use a library like https://github.com/bitwiseshiftleft/sjcl/ to compute the hash of the chosen file. Is there a way to do this or does the browser's security model get in the way?
Yes, you can select a file using the file element, and take a hash of the file locally, 'in-browser', using javascript. The browser's security model does not prevent this; and the hash function from the native Web Crypto API can be used, so there is no need for any external crypto libraries.
Here is a working example:
function hashfile() {
readbinaryfile(fileselector.files[0])
.then(function(result) {
result = new Uint8Array(result);
return window.crypto.subtle.digest('SHA-256', result);
}).then(function(result) {
result = new Uint8Array(result);
var resulthex = Uint8ArrayToHexString(result);
divresult.innerText = 'result: ' + resulthex;
});
}
function readbinaryfile(file) {
return new Promise((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => {
resolve(fr.result)
};
fr.readAsArrayBuffer(file);
});
}
function Uint8ArrayToHexString(ui8array) {
var hexstring = '',
h;
for (var i = 0; i < ui8array.length; i++) {
h = ui8array[i].toString(16);
if (h.length == 1) {
h = '0' + h;
}
hexstring += h;
}
var p = Math.pow(2, Math.ceil(Math.log2(hexstring.length)));
hexstring = hexstring.padStart(p, '0');
return hexstring;
}
<h2>File Hash</h2>
<div>
Select file to take hash of:
<br/>
<input type="file" id="fileselector" onchange="javascript:hashfile();">
</div>
<br/>
<div id="divresult"></div>
The standard browser security model allows you to have the user pick a file and do what you will with it. I'm an older guy and thought surely this kinda mingling with a user's parts would require additional hoops/consent. So #ceving 's answer was best: "Do it and you will see."
Here's a link to a good article: https://humanwhocodes.com/blog/2012/05/08/working-with-files-in-javascript-part-1/
Apologies for not trying first before posting.

Get the image as file in angular

I am making angular application with image upload option which has the,
Html :
<label class="hoverable" for="fileInput">
<img [src]="url ? url : avatarImage">
<div class="hover-text">Choose file</div>
<div class="background"></div>
</label>
<br/>
<input id="fileInput" type='file' (change)="onSelectFile($event)">
<button *ngIf="url" (click)="delete()" >delete</button>
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar.png">
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar2.png">
Here what i am having is if the user clicks over the image he can select and update whatever image he has in local.
Same way if the user was not interested to update the profile image but interested to select any of the avatar image as per his/her wish which i have given like,
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar.png">
<img (click)="uploadPersonaImage($event)" class="avatar-images" src="https://www.w3schools.com/howto/img_avatar2.png">
And in ts made something like this,
uploadPersonaImage(e) {
this.url = e.target.src;
}
So on the click function the src that comes from the event.target was set to this.url..
But i need to convert it as file.. Because i need to send it as file to the service call so i need to update the avatar image.
So please help me to convert the avatar image selected/clicked by the user to the file/formdata so that it can be sent to the service as file format and can be updated as user selected image..
Example: https://stackblitz.com/edit/angular-file-upload-preview-85v9bg
You can use FormData to attach the read file and send to the API.
onSelectFile(event) {
if (event.target.files && event.target.files[0]) {
this.uploadToServer(event.target.files[0]);
... rest of the code
}
uploadToServer(file) {
let formData: FormData = new FormData();
formData.append('fileName', file);
// call your api service to send it to server, send formData
}
EDIT:
Try this out if you have no option to touch onSelectFile() or trigger a different function when you upload the file.
_url = ''
set url(val) {
this._url = val;
if (val) {
this.dataURLtoFile(val);
}
}
get url() {
return this._url;
}
uploadedImage: File ;
dataURLtoFile(dataurl) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const imageExtension = mime.split('/')[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
this.uploadedImage = new File([u8arr], `uploaded.${imageExtension}`);
}
On your API call, maybe when you click on a button,
uploadPersonaImage(e) {
// this.apiService.someMethod(this.uploadedImage);
}
If you want to trigger the API call just when you upload the image, add the code of dataURLtoFile() to uploadPersonaImage() and call uploadPersonaImage() from url setter
Clarification
Do you understand what does event.target.src mean (considering e as event)?
Here event means the click/change event you triggered when you
clicked onto upload photo.
event.target means the DOM element on which the event took place.
event.target.src will give you the src attribute value of the
DOM element on which you triggered the change event.
Now, you say won't it work? No, it won't because the element which you clicked is an HTMLInputElement but the src resides under the image in under the label tag. And how are you intending to call uploadPersonaImage()? what calls your method? You haven't answered that even after asking so many times.
In my last edit, I have added code under the setter of the url which will convert the dataUrlFile to an actual File, It completely depends on your server how you want to store the file. As a file or as a dataUrl? If you want to send it as a file then follow the conversions I added in the answer if you want to save as dataUrl then directly save the content of this.url on your API call.

Having YES/NO user interface buttons redirect to a link when clicked

Is it possible to disguise the YES button after an alert so that when clicked it goes to a google drive folder location that has just been created e.g.
var ui = SpreadsheetApp.getUi();
var response = ui.alert('Your CSV file has been saved in your Google drive', 'Do you wan to go to that file location?', ui.ButtonSet.YES_NO);
// Process the user's response.
if (response == ui.Button.YES) {
var folder = DriveApp.createFolder('test');
folder.getUrl()
}
I am having trouble with the last line of the code, i can't figure out how to get the YES button, such that when clicked, opens a new window to that google drive location.
For context here is where the unique folder is created
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var date = SpreadsheetApp.getActiveSheet().getRange(3,2).getValue();
var time = SpreadsheetApp.getActiveSheet().getRange(4,2).getValue();
var site = SpreadsheetApp.getActiveSheet().getRange(2,2).getValue();
// iterate through all sheets in the spreadsheet and rename them according to cell B2
for( var j = 0 ; j < sheets.length; j++) {
var sourceSheet = sheets[j];
// get contents of cell B2
var newSheetName = sourceSheet.getRange("B2").getValue();
// rename sheet
sourceSheet.setName(newSheetName);
}
// create a folder from the named SNOWSURVEYS with date
var folder = DriveApp.createFolder('SNOWSURVEYS' + '_' + date + '_'+ site);
// append ".csv" extension to the sheet name
fileName = SpreadsheetApp.getActiveSheet().getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
}
How about this sample script? In order to make users redirect to the folder URL, I propose the use of HtmlService. This script displays a dialog box with yes/no buttons. When user pushes yes, a folder is created and move to the folder in user's browser.
At first, please run openDialog(). By this, you can see a dialog box on Spreadsheet.
This is a sample script, if you want to change the style, please modify it.
Sample script :
function openDialog() {
var html = HtmlService.createHtmlOutput('<p>Your CSV file has been saved in your Google drive</p><p>Do you wan to go to that file location?</p><form><input type="button" value="yes" onclick="google.script.run.withSuccessHandler(go).getUrl()" /><input type="button" value="no" onclick="google.script.host.close()" /></form><script>function go(url) {open(url, "_blank");}</script>');
SpreadsheetApp.getUi().showModalDialog(html, 'sample');
}
function getUrl(){
var folder = DriveApp.createFolder('test');
return folder.getUrl();
}
HTML in above script
<p>Your CSV file has been saved in your Google drive</p>
<p>Do you wan to go to that file location?</p>
<form>
<input type="button" value="yes" onclick="google.script.run.withSuccessHandler(go).getUrl()" />
<input type="button" value="no" onclick="google.script.host.close()" />
</form>
<script>
function go(url) {
open(url, "_blank");
}
</script>
If I misunderstand your question, I'm sorry.
Edit :
In following script, If the folder with the foldername is existing, it opens the existing folder. If the folder is not existing, the folder with foldername is created. In order to use this script, please modify getUrl().
function getUrl() {
var foldername = "test"
return function(foldername){
var f = DriveApp.getFoldersByName(foldername);
return f.hasNext() ? f.next().getUrl() : DriveApp.createFolder(foldername).getUrl();
}(foldername);
}

How do I upload and process a file in Javascript?

I am creating a small html5 app that will allow users to change color properties of some elements. I want to give the user the option to save their changes and then upload them on later occasion (without registration). For this, I added a button that produces a text file of their properties, I want to add a button that will allow them to upload the file, I created a file picker dialog,
<label>
<input class="button"
type="file"
name="input-name"
style="display:none;"
onchange="read(event)"/>
<span id="input-file" >Select File</span>
</label>
But I can't figure how do I open this file in javascript and process its content. I know this should be similar to this
function read(evt){
var file = document.getElementById("input-file");
//checking for file reader
if (window.File && window.FileReader && window.FileList && window.Blob){
var r = new FileReader();
r.readAsText(file);
} else{
alert("Browser not supported");
}
}
But this doesn't work because file above is not the path to the file but the object. How do I get the path to the file? Is there a better way to do this?
You can read files via the File API, but you can't save them. You can create windows containing the text you want to save and then let the user save it, but it's a pain both when saving and loading.
Fortunately, for what you're talking about, you don't want files.
Instead, store the color preferences in web storage, specifically localStorage:
Loading (e.g., on page load or whenever):
var savedColor = localStorage.getItem("saved-color");
if (savedColor == null) {
// There wasn't one, use a default
}
Saving:
localStorage.setItem("saved-color", savedColor);
(localStorage in the above isn't a placeholder or anything; it's a global that's present on browsers that support local storage, which is [just about all of them2.)
Web storage values are always strings. You can use JSON if you need to store complex things.
Assuming your text file is in JSON (stringified format), i.e. your file.txt contains {"primary":"green","secondary":"#FF0000"}
<input type="file" id="file-picker" accept="text/plain" />
/*
Assuming JSON format in the text file - e.g:
var colors = {
primary: 'green',
secondary: '#FF0000'
}
JSON.stringify(colors);
output: '{"primary":"green","secondary":"#FF0000"}'
*/
var fileInput = document.querySelector('#file-picker');
function readFileJSON(file) {
return new Promise(function(resolve) {
var reader = new FileReader();
reader.onload = function(e) {
try {
resolve(JSON.parse(e.target.result));
} catch(ex) {
throw ex;
}
};
reader.readAsText(file);
});
}
fileInput.addEventListener('change', function(e) {
var file = e.target.files.item(0);
if (!file) {
return;
}
readFileJSON(file).then(function(colors) {
console.log('Colors:', colors);
});
});
JSBIN: https://jsbin.com/weriguhato/edit?html,js,output

sql.js GUI example - Force a specific database instead of select one

I'm trying to use SQL.JS in order to build a simple local SQLite database browser without any server interaction.
I'm using the GUI example page to test.
The HTML GUI example page uses <input type='file' id='dbfile'>
in order to allow the user to select the database file, then the HTML page calls GUI.JS like this:
var dbFileElm = document.getElementById('dbfile');
// Load a db from a file
dbFileElm.onchange = function() {
var f = dbFileElm.files[0];
var r = new FileReader();
r.onload = function() {
worker.onmessage = function () {
toc("Loading database from file");
// Show the schema of the loaded database
editor.setValue("SELECT `name`, `sql`\n FROM `sqlite_master`\n WHERE type='table';");
execEditorContents();
};
tic();
try {
worker.postMessage({action:'open',buffer:r.result}, [r.result]);
}
catch(exception) {
worker.postMessage({action:'open',buffer:r.result});
}
}
r.readAsArrayBuffer(f);
}
And it's working fine.
Now I would like to force a specific database name and location. I try to use :
<input type='text' value='<MY_DB_FILE>' id='dbfile'> (where MY_DB_FILE is the name of my DB file located in the same folder as the HTML page). I also change
dbFileElm.onchange = function() into dbFileElm.onload = function()
But nothing works and the ID dbfile doesn't seem to contain any usable data and the function is not called.

Categories