hello guys..
I am making a page in which i have to take excel file from user and read that file ..but all i know is to read a particular file by giving its address..for this i am using javascript and html ..here is my code for reading excel file
<input type="button" id="btnSubmit" onclick="readdata(1, 2)" value="Submit" />
<script>
function readdata(x,y) {
try {
var excel = new ActiveXObject("Excel.Application");
excel.Visible = false;
var excel_file = excel.Workbooks.Open("D:\\Test.xls");//
alert(excel_file.worksheets.count);
var excel_sheet = excel_file.Worksheets("Sheet1");
var data = excel_sheet.Cells(x, y).Value;
//alert(data);
drawWithexcelValue(data);
}
catch (ex) {
alert(ex);
}
// return data;
}
</script>
This is my code for reading excel file by defining path of a particular excel file...now i have to do is take the excel file from user..guys please help..
And any kind of help through code wil be really appreciated..
someone please help me
As #Alex K mentioned, this would work only in IE.
Here a possible solution:
Put all of your Excel files in the same folder. For example: C:\sheets\
(Edit: I think this is the easiest solution since I don't know of a way to get the full and real path of a file via javascript)
Now change your code to something along these lines:
<input type="file" id='excelFile' />
<button id='loadExcel'>Load Excel File</button>
<script type="text/javascript">
var EXCELDIR = "C:\\sheets\\";
var loadExcel = document.getElementById('loadExcel');
loadExcel.onclick = function() {
var filepath = EXCELDIR + document.getElementById('excelFile').value.split('\\')[2];
readdata(1,2, filepath);
}
function readdata(x,y,filepath) {
try {
var excel = new ActiveXObject("Excel.Application");
excel.Visible = false;
var excel_file = excel.Workbooks.Open(filepath);
alert(excel_file.worksheets.count);
var excel_sheet = excel_file.Worksheets("Sheet1");
var data = excel_sheet.Cells(x, y).Value;
//alert(data);
drawWithexcelValue(data);
}
catch (ex) {
alert(ex);
}
// return data;
}
</script>
Disclaimer: I didn't check the code since I'm on mac, hopefully this works.
Related
I am trying to read a csv file with jquery. I have passed the file with input tag of html but i am having some problems to read it. Below the code that i have written.
HTML code:
<div id="insertCSV" class = "formblacktransparent">
<input id="csv" type="file" accept=".csv" class="form-control" placeholder="Insert csv"> </input>
<button type="button" class="log-btn" id="confCsv"> Confirm </button>
</div>
Jquery code:
$("#confCsv").click(function(data){
var input = document.getElementById('csv');
var file = input.files[0];
alert(file[0]);
var fr = new FileReader();
fr.readAsDataURL(data);
alert(fr);
});
I don 't understand if in this way the file has been uploaded and how i can accede to it.
Any ideas? thank you in advance!!
I write below the code that i have used to resolve my problem. I hope it can be useful. Hello!
document.querySelector("#confCsv").addEventListener('click', function() {
if(document.querySelector("#csv").files.length == 0) {
alert('Error : No file selected');
return;
}
// first file selected by user
var file = document.querySelector("#csv").files[0];
// perform validation on file type & size if required
// read the file
var reader = new FileReader();
// file reading started
reader.addEventListener('loadstart', function() {
console.log('File reading started');
});
// file reading finished successfully
reader.addEventListener('load', function(e) {
// contents of file in variable
var text = e.target.result;
var row = text.split('\n');
row.forEach(function(e) {
var datiGiornalieri = e.split(';');
socket.emit('parameterRegistrationFile', {ID: patientID, paramdata: datiGiornalieri[0], parametername: 'alfa',parametervalue: datiGiornalieri[1] });
});
});
reader.readAsText(file);
});
To preface, I'm super new to programming in general, nevermind javascript.
I'm developing a web application where a user can upload a picture by clicking on a button. This action will upload pictures into a certain directory in my google drive with a unique folder and name.
Now, I'm trying to copy and paste the google drive link of a picture any time it has been uploaded.
I am able to successfully get the ID of the picture URL in my getFileUrl() method. But when I call that method within my doStuff1() function then later insert that info into userInfo.fileUrl, I am getting https://docs.google.com/document/d/undefined/ as the output in my spreadsheet.
How can call that value?
Updated: I am realizing that when I use "google.script.run.getFileUrl("fn","i"), that is when I'm getting "undefined". When I run the getFileUrl() function locally, I do get the value that I want. Please advise how I can use .WithSuccessHandler(function) correctly so that I can return the value of "fileId0".
This is the front end, where a user uploads the picture
page.html
<html>
<head>
<body>
<form action="#" method="post" enctype="multipart/form-data">
<div class="row">
<div class="file-field input-field">
<div class="waves-effect waves-light btn-small">
<i class="material-icons right">insert_photo</i>
<span>Import Picture</span>
<input id="files" type="file" name="image">
</div>
<div class="file-path-wrapper">
<input disabled selected type="text" class="file-path
validate" placeholder="Choose an image">
</div>
</div>
</div>
</form>
<?!= include("page-js"); ?>
</div> <!-- CLOSE CONTAINER-->
</body>
</html>
This is part of the javascript to put relevant info in an array, which will later be used to append a row in the google sheet
page-js.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="https://gumroad.com/js/gumroad.js"></script>
<script>
document.getElementById("addAnother").addEventListener("click",doStuff1);
var i=1;
var num={};
function doStuff1(){
num.picNum2=i;
var personName=document.getElementById("fn").value;
var fileId00=google.script.run.getFileUrl("fn","i");
var userInfo ={};
userInfo.firstName= document.getElementById("fn").value;
userInfo.number=i;
userInfo.fileUrl="https://docs.google.com/document/d/"+fileId00
+"/";
i++;
google.script.run.userClicked(userInfo);
}
This is part of the javascript to upload picture file into the Google drive
(still part of page-js.html)
var file,
reader = new FileReader();
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'- '+today.getDate();
reader.onloadend = function(e) {
if (e.target.error != null) {
showError("File " + file.name + " could not be read.");
return;
} else {
google.script.run
.withSuccessHandler(showSuccess)
.uploadFileToGoogleDrive(e.target.result,num.picNum,date,$('input#fn')
.val(),$('input#date').val());
}
};
function showSuccess(e) {
if (e === "OK") {
$('#forminner').hide();
$('#success').show();
} else {
showError(e);
}
}
function submitForm() {
var files = $('#files')[0].files;
if (files.length === 0) {
showError("Please select a image to upload");
return;
}
file = files[0];
if (file.size > 1024 * 1024 * 5) {
showError("The file size should be < 5 MB.");
return;
}
showMessage("Uploading file..");
reader.readAsDataURL(file);
}
function showError(e) {
$('#progress').addClass('red-text').html(e);
}
function showMessage(e) {
$('#progress').removeClass('red-text').html(e);
}
</script>
This part grabs the array "userInfo" and appends the content in a row within a designated google sheet. Any time, I click on the button in the front end, it creates a new row.
Code.gs
//google sheet web script
var url="https://docs.google.com/spreadsheets/d/XXXXX";
function getFileUrl(fn,i){
try{
var today0 = new Date();
var date0 = today0.getFullYear()+'-'+(today0.getMonth()+1)+'-'
+today0.getDate();
var dropbox0 = "OE Audit Pictures";
var folder0,folders0 = DriveApp.getFoldersByName(dropbox0);
while (folders0.hasNext())
var folder0=folders0.next();
var dropbox20=[date0,fn].join(" ");
var folder20,folders20=folder0.getFoldersByName(dropbox20);
while (folders20.hasNext())
var folder20=folders20.next();
var file0, files0= folder20.getFilesByName(i);
while (files0.hasNext())
var file0=files0.next();
var fileId0=file0.getUrl();
return fileId0;
} catch(f){
return f.toString();
}
}
function userClicked(userInfo){
var ss= SpreadsheetApp.openByUrl(url);
var ws=ss.getSheetByName("Data");
ws.appendRow([userInfo.number,new Date(),
userInfo.firstName,userInfo.fileUrl]);
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function uploadFileToGoogleDrive(data, file, fn, date) {
try {
var dropbox = "OE Audit Pictures";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var contentType = data.substring(5,data.indexOf(';')),
bytes =
Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
blob=Utilities.newBlob(bytes, contentType, file)
var dropbox2=[fn,date].join(" ");
var folder2, folders2=folder.getFoldersByName(dropbox2)
if (folders2.hasNext()){
folder2=folders2.next().createFile(blob);
} else {
file = folder.createFolder([fn,date].join(" ")).createFile(blob);
}
return "OK";
} catch (f) {
return f.toString();
}
}
In doStuff1() of "page-js.html", you want to give a value returned from getFileUrl() of "Code.gs" to userInfo.fileUrl.
If my understanding is correct, how about this modification?
Modification point:
google.script.run.getFileUrl() doesn't return values. When you want to use the values from getFileUrl(), you can use withSuccessHandler() as following modified script.
Modified script:
Please modify doStuff1() as follows.
function doStuff1() {
num.picNum2 = i;
var personName = document.getElementById("fn").value;
google.script.run.withSuccessHandler(doStuff2).getFileUrl("fn","i"); // Modified
}
// Added
function doStuff2(fileId00) {
var userInfo = {};
userInfo.firstName = document.getElementById("fn").value;
userInfo.number = i;
userInfo.fileUrl = "https://docs.google.com/document/d/"+fileId00 +"/";
i++;
google.script.run.userClicked(userInfo);
}
Note:
In this modification, I used doStuff2() for retrieving the values from getFileUrl(). If you want to modify the function name, please modify it.
Reference:
Class google.script.run
If I misunderstood your question and this was not the result you want, I apologize.
I make a form with Google script
but I don't know how to make it's field to be REQUIRED
following is my script but my gbchk(form) didn't work
The script will add a line in my excel in my google dive
but even there is no data in the form
How to make a required area in google script?
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var folderName = "Upload";
var sheetName = "ulist";
var folder;
var folders = DriveApp.getFoldersByName(folderName);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(folderName);
}
//handling uploading file
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by "+ form.myName);
var fileUrl = file.getUrl();
var FileIterator = DriveApp.getFilesByName(sheetName);
var sheetApp = "";
while (FileIterator.hasNext())
{
var sheetFile = FileIterator.next();
if (sheetFile.getName() == sheetName)
{
sheetApp = SpreadsheetApp.open(sheetFile);
}
}
if(sheetApp == "")
{
sheetApp = SpreadsheetApp.create(sheetName);
}
var sheet = sheetApp.getSheets()[0];
var lastRow = sheet.getLastRow();
var targetRange = sheet.getRange(lastRow+1, 2, 1, 1).setValues([[lastRow+1,form.myName]]);
return "Upload Success!"
} catch (error) {
return "Upload fail because:"+error.toString();
}
}
function gbchk(form)
{
if (form.myName.value == "")
{
alert("Enter your name!!");
form.myName.focus();
return (false);
}
return (true);
}
I would put a required tag on the html form input. The docs for this can be found here:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation#The_required_attribute
example:
<form>
<label for="choose">Would you prefer a banana or cherry?</label>
<input id="choose" name="i_like" pattern="banana|cherry" required>
<button>Submit</button>
</form>
I'm looking for a solution too.
Putting a required tag on the input fields would work. But the user can simply remove it throught the dev tools.
A slightly better approach is to set the required tags by JS. Users can still get around it, but this time they need to modify the JS itself.
Newbie here. The problem is that I currently have written a method which checks uploaded file size and extension in order to validate it. However, checking extensions is not a solution as that kind of validation may cause a lot of problems. What I want to do is to check the actual file type and validate it without using extension method. I have tried to use jQuery file validator but to no avail... This is a snippet from my current code:
<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />
Script:
App.Dispatcher.on("uploadpic", function() {
$(":file").change(function() {
if (this.files && this.files[0] && this.files[0].name.match(/\.(jpg|jpeg|png|gif)$/) ) {
if(this.files[0].size>1048576) {
alert('File size is larger than 1MB!');
}
else {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
} else alert('This is not an image file!');
});
function imageIsLoaded(e) {
result = e.target.result;
$('#image').attr('src', result);
};
});
It is called once the upload input changes and after validation it uploads and displays the image. For now, I only care about validation and any help or ideas would be greatly appreciated!
Try something like this:
JavaScript
const file = this.files[0];
const fileType = file['type'];
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png'];
if (!validImageTypes.includes(fileType)) {
// invalid file type code goes here.
}
jQuery
var file = this.files[0];
var fileType = file["type"];
var validImageTypes = ["image/gif", "image/jpeg", "image/png"];
if ($.inArray(fileType, validImageTypes) < 0) {
// invalid file type code goes here.
}
You don't need jquery here.
var mimeType=this.files[0]['type'];//mimeType=image/jpeg or application/pdf etc...
//ie image/jpeg will be ['image','jpeg'] and we keep the first value
if(mimeType.split('/')[0] === 'image'){
console.log('the file is image');
}
You can also create a function to check when a file is image.
function isImage(file){
return file['type'].split('/')[0]=='image');//returns true or false
}
isImage(this.file[0]);
Update (es6)
using es6 includes method, makes it even more simple.
const isImage = (file) => file['type'].includes('image');
Pls refer a related query here. The answer here suggests to load the image in an Image object and check for it's width and height properties to be non zero.
I think the technique can be used to solve your problem too.
I also worked out a fiddle for you to refer. Pertinent code below:
var img = new Image();
img.addEventListener("load",function(){
alert('success');
});
img.addEventListener("error",function(){
alert('error');
});
img.src = picFile.result;
Here is a quick tip if you just want to know if the file is an image:
var file = this.files[0];
var fileType = file["type"];
if (fileType.search('image') >= 0) {
...
}
What I want to do is to check the actual file type
Try accessing files[0].type property . See Using files from web applications
$(":file").on("change", function(e) {
console.log(this.files[0].type);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />
If anyone comes here who is using jQuery Validator, a simple method would be:
jQuery.validator.addMethod(
"onlyimages",
function (value, element) {
if (this.optional(element) || !element.files || !element.files[0]) {
return true;
} else {
var fileType = element.files[0].type;
var isImage = /^(image)\//i.test(fileType);
return isImage;
}
},
'Sorry, we can only accept image files.'
);
which is then added to the .validate() function.
A lot of convoluted answers here.
Simply check whether the file has an image mime-type (which would be of the format image/...
const isImage = file => file.type.startsWith("image/")
$('#direct_upload').change(function() {
if (this.files[0].type.includes('image')) {
document.getElementById('attach_file').src = window.URL.createObjectURL(this.files[0])
} else {
console.log('it is a doc');
}
}
You could try to convert file type in string and after that slice this string like that:
if(String(file.type).slice(0, 6) === 'image/') {....some code}
Using jQuery version 3.3.1:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<label class="custom-file-label" for="customFile">Select Image</label>
<br>
<input type="file" class="custom-file-input" id="customFile">
</body>
<script>
$(document).ready(function() {
$(document).on("change", ".custom-file-input", function() {
var myImg = this.files[0];
var myImgType = myImg["type"];
var validImgTypes = ["image/gif", "image/jpeg", "image/png"];
if ($.inArray(myImgType, validImgTypes) < 0) {
alert("Not an image")
} else {
alert("Is an image")
}
});
});
</script>
</html>
I have a form, which allows to select an item from a dropdown list and upload a file. The name and the ID of the item are saved in a Spreadsheet document. Works with one file...but I want to upload multiple files. Could you help me fixing the script?
The HTML part looks like this
<div class="col-md-4 col-sm-6 ">
<div class="caption">
<h3>Bildauswahl</h3>
<p align="center"><input type="file" name="myFiles[]" id="myFiles" multiple></p>
</div>
</div>
My script, which is not working, is the following:
var dropBoxId = "XYZ";
var logSheetId = "ABC";
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('InputForm.html');
}
function uploadFiles(formObject) {
try {
// Create a file in Drive from the one provided in the form
var folder = DriveApp.getFolderById(dropBoxId);
var input = document.getElementById('myFiles');
for (i = 0; i<input.files.length; i++) {
var blob = input.files[i];
var file = folder.createFile(blob);
var ss = SpreadsheetApp.openById(logSheetId);
var sheet = ss.getSheets()[0];
sheet.appendRow([file.getName(), file.getUrl(), formObject.myName]);
}
// Return the new file Drive URL so it can be put in the web app output
return file.getUrl();
} catch (error) {
return error.toString();
}
}
Thanks.
As of right now you have to use a work around to work with multiple files. The multiple attribute only works in IFRAME mode, but file inputs are broken in IFRAME mode.
To see this workaround take a look at the bug submission for this issue:
https://code.google.com/p/google-apps-script-issues/issues/detail?id=4610
Also in your code you have some mixing of server side and client side code that will not work:
var folder = DriveApp.getFolderById(dropBoxId); //server side
var input = document.getElementById('myFiles'); //client side
You will need to do your multiple file processing on the client side
I came up with a nice solution for multi-file uploading. Limitations are files must be under 10 MB.
CODE.GS
function doGet() {
return HtmlService.createHtmlOutputFromFile('index').setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function saveFile(data,name,folderId) {
var contentType = data.substring(5,data.indexOf(';'));
var file = Utilities.newBlob(Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)), contentType, name);
DriveApp.getFolderById(folderId).createFile(file);
}
index.html
<div>
<input type="file" id="myFiles" name="myFiles" multiple/>
<input type="button" value="Submit" onclick="SaveFiles()" />
</div>
<script>
var reader = new FileReader();
var files;
var fileCounter = 0;
var folderId = "";
reader.onloadend = function () {
google.script.run
.withSuccessHandler(function(){
fileCounter++;
postNextFile();
}).saveFile(reader.result,files[fileCounter].name,folderId);
}
function SaveFiles(){
var folderSelect = document.getElementById("folderSelectId");
folderId = folderSelect.options[e.selectedIndex].value;
files = document.getElementById("myFiles").files;
postNextFile();
}
function postNextFile(){if(fileCounter < files.length){reader.readAsDataURL(files[fileCounter]);}else{fileCounter=0;alert("upload done")}}
</script>