Opening an excel file using Protractor - javascript

Protractor Query: our application generate a excel file which contains aome formulas. Now until I don't open the excel, it won't readable by exceljs. Is there any way I can open the excel and close it like we do robot in selenium?
Please Note that if i Open the file and keep at specified location below code works fine, but when i download the same from application and try to read it it wont work.
function compareExcelFromScreen(VerificationSection, file, row, column, SheetName, callback) {
var wrkbook = new Excel.Workbook();
var valFromExcel = null;
var filteredExcelValue = null;
var filteredScreenvalue = null;
var temp = null;
wrkbook.xlsx.readFile(file.toString()).then(function () {
var worksheet = wrkbook.getWorksheet(SheetName);
valFromExcel = worksheet.getRow(parseInt(row)).getCell(parseInt(column)).value;
}
}

Related

Google Apps Script - batch download sheets as CSV file

This is a question that has been asked before but I'm struggling to adapt the answers to my needs.
references:
How to export to CSV from spreadsheet to drive or download folder
https://gist.github.com/mrkrndvs/a2c8ff518b16e9188338cb809e06ccf1
Initiate a download from google apps script
The structure seems to be:
create function in code.gs
create download.html
My workflow:
I have a bunch of files (20+) which I edit both manually and using a GAS.
To start with I've created a folder on Google Drive which I upload my CSV files to. I then run a standalone GAS to add a sum formula in column F to each file:
function addFormula() {
const folder = DriveApp.getFolderById('folderID');
const list = [];
const files = folder.getFiles();
while (files.hasNext()){
file = files.next();
let ssnameid = [];
ssnameid.push(file.getName(),file.getId());
list.push(ssnameid);
}
for (let g=0,len=list.length;g<len;g++) {
let id = list[g][1]; // list of Spreadsheet names[0] and ID numbers[1]
let csv = DriveApp.getFileById(id);
let docName = csv.getName();
let ss = SpreadsheetApp.openById(id);
let sheet = ss.getSheetByName(docName+'.csv');
let contents = sheet.getRange('A1:K100').getValues().filter(e => e[0]);
let rows = contents.length;
console.log(docName+' - number of rows: '+rows);
let cellF = 'F'+(rows+1);
let formulaF = '=SUM($F$2:$F$'+rows+')';
sheet.getRange(cellF).setValue(formulaF);
}
Then I go through each file, check if there are any other edits I need to make, and download as a CSV (File > Download > Comma Separated Values (.csv)). I was hoping to save time by also writing a function to download all the files as CSV.
So after making any manual edits, I then want to run a function in a standalone GAS to download all the files in the Google Drive folder as CSV files.
The answers I've found generally involve adding menu items and having pop-ups, and I don't know enough to make them suitable for a standalone GAS - I don't want any menu items or pop-ups, I just want to run a function which downloads a CSV.
For instance, how would I adapt this answer from Dr-Bracket?
Or this answer from soMarios, which works but only saves it to another folder in Google Drive, rather than downloading.
The reason I feel that having an HTML file work with a GS is that I've created a standalone function with this structure to send out emails. Using an HTML email template, I created a function in a standalone GAS to send out emails.
Is this the right approach for batch downloading files as CSV?
Thank you
Further references/clues:
https://developers.google.com/apps-script/guides/html/templates#code.gs https://developers.google.com/apps-script/guides/html/reference/run#index.html https://developers.google.com/apps-script/reference/drive/file#getDownloadUrl()
EDIT - My Solution
The workaround is to send all the files to a folder on Google Drive and then download the folder. So the benefit is only downloading one folder rather than downloading each file. Here's the code adapted from the soMarios answer linked to above:
function saveCSV() {
/** sourceFolder contains all the Google Sheets you want to save as CSV files */
const sourceFolder = DriveApp.getFolderById('folderID');
const list = [];
const files = sourceFolder.getFiles();
while (files.hasNext()){
file = files.next();
let ssnameid = [];
ssnameid.push(file.getName(),file.getId());
list.push(ssnameid);
}
console.log(list);
for (let g=0,len=list.length;g<len;g++) {
let id = list[g][1]; // list of Spreadsheet names[0] and ID numbers[1]
let csv = DriveApp.getFileById(id);
let docName = csv.getName();
let ss = SpreadsheetApp.openById(id);
let sheet = ss.getSheetByName(docName+'.csv');
/** save files as CSV to Google Drive folder */
let requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
let sheetID = sheet.getSheetId().toString();
let url = "https://docs.google.com/spreadsheets/d/"+id+"/export?gid="+sheetID+"&format=csv"
let result = UrlFetchApp.fetch(url, requestData);
let resource = {
title: docName+'.csv',
mimeType: 'application/vnd.csv',
parents: [{ id: 'downloadFolderID' }]
}
Drive.Files.insert(resource,result)
}
}
Note that for this to work you need to add Drive API (Services > Add a Service > Drive API)
To download a sheet as csv whitout any further manipulation, try this auto-download script
gs
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('M E N U')
.addItem('auto download', 'autoDownload')
.addToUi();
}
function autoDownload() {
var html = HtmlService.createHtmlOutputFromFile('download');
SpreadsheetApp.getUi().showModalDialog(html, 'CSV download interface');
}
function saveAsCSV() {
var ssid = 'your spreadsheet id';
var folderID = 'temporary folder id'
var csv = "";
var ss = SpreadsheetApp.openById(ssid)
ss.getSheets()[0].getDataRange().getValues().forEach(function (r) {
csv += r.join(",") + "\n";
});
var url = DriveApp.getFolderById(folderID)
.createFile(ss.getName() + '.csv', csv, MimeType.CSV)
.getDownloadUrl()
.replace("?e=download&gd=true", "");
return url;
}
download.html
<!DOCTYPE html>
<html>
<body>
Auto Download CSV ... please wait
</body>
<script>
function executeDownload(url) {
window.location.href = url;
}
window.onload=function() {
google.script.run
.withSuccessHandler(executeDownload)
.saveAsCSV();
window.setTimeout(function(){google.script.host.close()},9000);
}
</script>
</html>
tested with chrome
you can modify ssid, temporary folder id and setTimeout parameter to optimize

Save Gmail attachments on Google Drive

I would like to save gmail attachments(.pdf files) from a specific email in a specific Google Drive folder. I also need to rename file with a string composed by some string of the email.
I have developed a simple script using Google Apps Script with some functions.
This is the main function I have wrote:
function GmailToDrive() {
var query = '';
query = 'in:inbox from:noreply#agyo.io has:nouserlabels ';
var threads = GmailApp.search(query);
var label = getGmailLabel_(labelName);
var parentFolder;
if (threads.length > 0) {
parentFolder = getFolder_(folderName);
}
var root = DriveApp.getRootFolder();
for (var i in threads) {
var mesgs = threads[i].getMessages();
for (var j in mesgs) {
//get attachments
var attachments = mesgs[j].getAttachments();
var message_body = mesgs[j].getBody();
for (var k in attachments) {
var attachment = attachments[k];
var isDefinedType = checkIfDefinedType_(attachment);
if (!isDefinedType) continue;
var attachmentBlob = attachment.copyBlob();
var file = DriveApp.createFile(attachmentBlob);
file.setName(renameFile_(attachment, message_body))
parentFolder.addFile(file);
root.removeFile(file);
}
}
threads[i].addLabel(label);
}
}
The checkIfDefinedType_(attachment) function checks if the attachments is a .pdf file and the renameFile_(attachment, message_body) rename the attachment extracting some string from the email.
The script seems to be correctly developed but sometimes I have two or more same attachments saved in my google drive folder.
Stefano, I had the same issue, if this is the same code as adapted from here.
I removed the line for (var i in fileTypesToExtract) { which was causing duplicates for me. It was running the query for each of the file types.
// `has:pdf` searches for messages with PDF attachments
var query = 'has:pdf in:inbox from:noreply#agyo.io has:nouserlabels ';
var results = Gmail.Users.Messages.list(userId, {q: query});
results.messages.forEach(function (m) {
var msg = GmailApp.getMessageById(m.id);
msg.getAttachments().forEach(function (a) {
var fileName = a.getName();
fileName = saveAttachmentToFolder(folder, a, fileName, msg.getDate(), input.tz);
});
});
function saveAttachmentToFolder(folder, attachment, fileName, date, timezone) {
if (timezone) {
fileName = standardizeName(attachment, date, timezone);
}
Logger.log(fileName);
folder.createFile(attachment.copyBlob()).setName(fileName);
}
The code snippet above is based on a Gmail add-on that I created, specifically for saving attachments to labeled folders in Drive: https://github.com/ellaqezi/archiveByLabel/blob/main/Code.gs#L24
In the label field, you can define nested directories to create in Drive e.g. foo/bar.
In the query field, you can copy the parameters as you would use them in Gmail's search bar.

Excel file gets corrupted after I write into it using ExcelJS

I have a function where I need to write a value in an excel file at a specific row.
var Excel = require('exceljs');
setExcelData: function (sheetName, keyword, value123, callback) {
var workbook = new Excel.Workbook();
workbook.xlsx.readFile('example.xlsx').then(function () {
var worksheet = workbook.getWorksheet(sheetName);
var y = worksheet.getColumn(1).values;
for (var i = 1; i <= y.length; i++) {
var q = worksheet.getRow(i).values;
if (q[1] == keyword) {
worksheet.getRow(i).getCell(2).value = value123;
workbook.xlsx.writeFile('example.xlsx');
break;
}
}
});
callback();
},
First I read the file and find the row where the keyword is present in first column. Then I try to write "value123" in the second column of the same row. But when i execute this function, the excel file gets corrupted and I cannot open it anymore.
I faced the same issue in Ubuntu if I am modifying the file in LibreOffice. So i created a doc in google drive as suggested in
https://github.com/guyonroche/exceljs/issues/35#issuecomment-283440743. and downloaded to perform modification on excel
Below is the code worked for me.
var Excel = require('exceljs');
async function excelOp() {
let workbook = new Excel.Workbook();
workbook = await workbook.xlsx.readFile('question_50508131.xlsx'); // replace question_50508131.xls with your file
let worksheet = workbook.getWorksheet('Inventory'); // replace solution with youe sheet name
let columnValues = worksheet.getColumn(1).values;
for (let row = 1; row <= columnValues.length; row += 1) {
var rowValues = worksheet.getRow(row).values;
if (rowValues[1] == 'Laptop') { // replace Laptop with required value
worksheet.getRow(row).getCell(2).value = 350; // replace 350 with replacable value
workbook.xlsx.writeFile('question_50508131.xlsx');
break;
}
}
}
excelOp();
PreModification Excel data
PostModification Excel data

Importing an excel (xls) file into javascript

I would like to import an excel file into javascript.
I already have got a code that works (kind of).
This is my code:
function GetData(cell,row){
var excel = new ActiveXObject("Excel.Application");
var excel_file = excel.Workbooks.Open("U:\\File1.xls");
var excel_sheet = excel.Worksheets("Sheet1");
var data = excel_sheet.Cells(cell,row).Value;
return data;
}
The code only works in IE (because of ActiveX), and it is incredibly slow.
Another problem is that it can only get the data from the first 100 rows or so, after that it just loads for hours and I get an ObjectError.
Another way to import excel files, or something that works the same way, would be greatly appreciated.
Updated Code:
Opens the file just once. But now i get an Object Error inside of the try-catch, when i try to run the GetData(i,2) method.
var excel = new ActiveXObject("Excel.Application");
var excel_file = excel.Workbooks.Open("U:\\Datei.xls");
var excel_sheet = excel.Worksheets("Sheet 1");
function GetData(cell,row){
var data = excel_sheet.Cells(cell,row).Value;
return data;
}
function main(){
try{
for(var i=1; i<5000;i++){
if(text1 == GetData(i,2)){
alert(GetData(i,6));
throw "Entry found";
}
}
}
catch(e) {
alert(e)
}
}

excel file while reading it through javascript

I know this types of question doesn't belong to here but this is my last hope to get answer and solution for this. I had made a html and javascript program to read excel file through Active X, but problem is that whenever I run that page the it runs fine but when i closed it the excel file remain open and if I run this page 100 times and then close it then there will be 100 unclosed excel file which leads to slowdown my PC. And second problem is that when I try to open that excel file which is being used by that application(the application is not currently running when i tried to open excel file) it does not open without giving an error,an window of excel file open and closed with in a small part of second..I don't know what to do to resolve this. If there is any problem in my code then here it is
var xVal = 1;
var yVal = 2
function readdata(x,y) {
x = xVal;
y = yVal;
try {
var excel = new ActiveXObject("Excel.Application");
excel.Visible = false;
var excel_file = excel.Workbooks.Open("D:\\Test1.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);
xVal = xVal + 1;
}
catch (ex) {
alert(ex);
}
}
this is the code through which I am reading the excel file.
Try
data = null;
excel_sheet = null;
excel_file.Close(); // important
excel_file = null;
excel.Quit();
excel = null;
in this (reverse) order. This is (almost) equivalent to setting these values to Nothing in VBA.

Categories