I've created a code to copy-paste the values from the most recent uploaded Gsheet file to another. The code is supposed to copy-paste only values that fulfil a cell condition.
The problem is, this code takes to long to run and doesn't finish to copy all values before having a run-time error.
The file has about 300.000 cells and the final amounts to be pasted on the 2nd file have about 90.000 cells.
Does anyone have a recommendation on how to proceed?
Thank you so much for your kind support.
function Master_Run_DB() {
Copy_EUDB();
}
function Copy_EUDB() {
var myLink = extractLink_EUDB();
sendData_EUDB(myLink);
}
function extractLink_EUDB() {
var newData = new Date().toLocaleString();
var drive = DriveApp.getFolderById("link to file");
var file = drive.getFilesByType(MimeType.GOOGLE_SHEETS);
var link = file.next().getUrl();
var ss = SpreadsheetApp.getActiveSpreadsheet();
return link
}
function sendData_EUDB(link) {
var mainSS = SpreadsheetApp.openById("link to file");
var lastRow = mainSS.getSheetByName("Database").getLastRow();
mainSS.getSheetByName("Database").getRange("A2" + ":R" + lastRow).clearContent();
var baseSS = SpreadsheetApp.openByUrl(link);
Logger.log(SpreadsheetApp.getActiveSpreadsheet().getUrl());
var lRow = baseSS.getSheetByName("Sheet1").getLastRow();
for (var i = 2; i <= lRow; i++) {
var cell = baseSS.getRange("G" + i);
var val = cell.getValue();
if (val == "EU") {
var sourceData = baseSS.getSheetByName("Sheet1").getRange("A" + i + ":R" + i).getValues();
var to = mainSS.getSheetByName("Database").getRange("A" + i + ":R" + i).setValues(sourceData);
}
}
};
Hello again,
Now that the new code is working, I was trying to add an IF AND clause to the copy-paste. The objective would be to copy only values that fulfil the following condition:
Column 7 = "EU"
Column 11 <> "CCCC"
But I'm getting a Syntax Error. Any advice?
Thank you in advance for your kind support
function Master_Run_EU() {
var drive = DriveApp.getFolderById("link to file");
var file = drive.getFilesByType(MimeType.GOOGLE_SHEETS);
var link = file.next().getUrl();
var ss = SpreadsheetApp.openById("link to file");
const sh=ss.getSheetByName('Database');
sh.getRange(2,1,sh.getLastRow(),22).clearContent();
var dbss = SpreadsheetApp.openByUrl(link);
const dbsh=dbss.getSheetByName('Sheet1');
var oA=[];
var vs=dbsh.getRange(2,1,dbsh.getLastRow()-1,22).getValues();
vs.forEach(function(r,i){
if(r[7]=="EU" && r[11]<>"CCCC") {
oA.push(r);
}
});
sh.getRange(2,1,oA.length,oA[0].length).setValues(oA);
}
Try this:
function Master_Run_DB() {
var drive = DriveApp.getFolderById("1ViOyzIkGOI6G6SMrtmPv4vjL-2-2duHC");
var file = drive.getFilesByType(MimeType.GOOGLE_SHEETS);
var link = file.next().getUrl();
var ss = SpreadsheetApp.openById("13CchyoqiWyvGTnYuG5TWA4cggBS-FsoDkW8XGesDkiY");
const sh=ss.getSheetByName('Database');
sh.getRange(2,1,sh.getLastRow(),18).clearContent();
var dbss = SpreadsheetApp.openByUrl(link);
const dbsh=dbss.getSheetByName('Sheet1');
var vs=dbsh.getRange(2,1,dbsh.getLastRow()-1,18).getValues();
vs.forEach(function(r,i){
if(r[6]=="EU") {
sh.getRange(i+2,1,1,18).setValues([r]);
}
});
}
It would be faster to do it this way:
function Master_Run_DB() {
var drive = DriveApp.getFolderById("1ViOyzIkGOI6G6SMrtmPv4vjL-2-2duHC");
var file = drive.getFilesByType(MimeType.GOOGLE_SHEETS);
var link = file.next().getUrl();
var ss = SpreadsheetApp.openById("13CchyoqiWyvGTnYuG5TWA4cggBS-FsoDkW8XGesDkiY");
const sh=ss.getSheetByName('Database');
sh.getRange(2,1,sh.getLastRow(),18).clearContent();
var dbss = SpreadsheetApp.openByUrl(link);
const dbsh=dbss.getSheetByName('Sheet1');
var oA=[];
var vs=dbsh.getRange(2,1,dbsh.getLastRow()-1,18).getValues();
vs.forEach(function(r,i){
if(r[6]=="EU") {
oA.push(r);
}
});
sh.getRange(2,1,oA.length,oA[0].length).setValues(oA);
}
I want to, when i click on button (separate for both CSV and PDF), it automatically download in CSV and PDF file with correct Formatting.
this CSV code i want to add PDF inside code
$scope.downloadData = function() {
var datasets = $scope.datasets.reverse();
var file_name = $scope.m_id+ '.csv';
var dataUrl = 'data:text/csv;charset=utf-8,';
var json = [];
if(datasets !== null) {
for(idx = 0; idx < datasets.length; idx++) {
var dataset = datasets[idx].data;
var time = datasets[idx].timestamp;
time = $filter('date')(time, "dd/MMMM/yyyy-hh:mm a");
dataset.time = time;
json.push(dataset);
}
var fields = Object.keys(json[0]);
var csv = json.map(
function(row) {
return fields.map(
function(fieldName) {
return '"' + (row[fieldName] || '') + '"';
}
);
}
);
csv.unshift(fields);
var csv_str = csv.join('%0A');
var downloadURL = dataUrl + csv_str;
var saveAs = function(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
document.body.appendChild(link); // Firefox requires the link to be in the body
link.download = filename;
link.href = uri;
link.target = "_blank";
link.click();
document.body.removeChild(link); // remove the link when done
} else {
location.replace(uri);
}
};
saveAs(downloadURL, file_name);
} else {
$scope.err_msg = 'Failed to get data. Try reloading the page.';
}
};
I try some of script i found on internet, but it is not working, some have formatting issue and save have downloading.
In Advance Thanks.
You should use this awesome library for pdf/csv or whatever else formats.. File Saver
Here's is code example, service created using FileSaver
function download(api, file, contentType) {
var d = $q.defer();
$http({
method: 'GET',
url: api,
responseType: 'arraybuffer',
headers: {
'Content-type': contentType
}
}).success(function(response) {
var data = new Blob([response], {
type: contentType+ ';charset=utf-8'
});
FileSaver.saveAs(data, file);
d.resolve(response);
}).error(function(response) {
d.reject(response);
});
return d.promise;
}
file input is name of file, you can use same service and pass the types and file names direct from controller.
Let;s you service name is homeService
for pdf call
homeservice.download('/api/download/whaever', 'export.pdf', 'application/pdf')
Method: PUT
Endpoint :
/application1/file/{filetype}/transactionType {
"accountNumber":"344224433344333"
}
API will return file of type CSV/pdf/xls
Question:
How to open in new tab or download suing angularJs 1.5
I have tried few solution but it doesnot works in IE
https://codepen.io/waghanil87/pen/vZBozE
Thanks in advance!
you need to convert the base64 string to blob type and then donload/print it
function b64toBlob(b64Data,callback) {
var contentType = 'application/pdf'; // put your file type here
var sliceSize = 512;
b64Data = b64Data.replace(/^[^,]+,/, '');
b64Data = b64Data.replace(/\s/g, '');
var byteCharacters = window.atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
blob = new Blob(byteArrays, {
type: contentType
});
callback(blob)
}
function downloadData(fileName,blob) {
var a = document.createElement("a");
var url = window.URL.createObjectURL(blob);
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
// call it like this
b64toBlob(base64string,function(data){
function downloadData('sample.pdf',data)
})
My code is working fine when I zip 3 files around 300kb each and send it to client. Used following links for help:
Dynamically create and stream zip to client
how to convert multiple files to compressed zip file using node js
But as soon as I try to zip 4th file I get "download - Failed Network error" in chrome.
Following is my code:
var express = require('express');
var app = express();
var fileSystem = require('fs');
var Archiver = require('archiver');
var util = require('util');
var AdmZip = require('adm-zip');
var config = require('./config');
var log_file = fileSystem.createWriteStream(__dirname + '/debug.log', {flags : 'a'});
logError = function(d) { //
log_file.write('[' + new Date().toUTCString() + '] ' + util.format(d) + '\n');
};
app.get('/zip', function(req, res, next) {
try {
res = setHeaderOfRes(res);
sendZip(req, res);
}catch (err) {
logError(err.message);
next(err); // This will call the error middleware for 500 error
}
});
var setHeaderOfRes = function (res){
res.setHeader("Access-Control-Allow-Origin", "*"); //Remove this when this is on production
res.setHeader("Content-Type", "application/zip");
res.setHeader("Content-disposition", "attachment;");
return res;
};
var sendZip = function (req, res) {
var filesNotFound = [];
zip.pipe(res);
if (req.query.leapIds) {
var leapIdsArray = req.query.leapIds.split(',');
var i, lengthi;
for (i = 0, lengthi = leapIdsArray.length; i < lengthi; i++) {
try {
var t = config.web.sharedFilePath + leapIdsArray[i] + '.vsdx';
if (fileSystem.statSync(t).isFile()) {
zip.append(new fileSystem.createReadStream(t), {
name: leapIdsArray[i] + '.vsdx'
});
};
} catch (err) {
filesNotFound.push(leapIdsArray[i] + '.vsdx');
}
}
var k, lengthk;
var str = '';
for (k = 0, lengthk = filesNotFound.length; k < lengthk; k++) {
str += filesNotFound[k] +',';
}
if(filesNotFound.length > 0){
zip.append('These file/files does not exist on server - ' + str , { name: 'logFile.log' });
}
zip.finalize();
}
};
I tried zip.file instead of zip.append that didn't work.
I want to zip minimum 10 files of 300kb each and send it to the client. Can anyone please let me know the approach.
Thanks
/********************* Update ****************************************
I was only looking at server.js created in node. Actually the data is sent correctly to client. Angularjs client code seems to be not working for large files.
$http.get(env.nodeJsServerUrl + "zip?leapIds=" + nodeDetails, { responseType: "arraybuffer" }
).then(function (response) {
nodesDetails = response.data;
var base64String = _arrayBufferToBase64(nodesDetails);
function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:application/zip;base64,' + base64String,
target: '_blank',
download: $scope.main.routeParams.sectorId + "-ProcessFiles.zip"
})[0].click();
});
This part href: 'data:application/zip;base64,' + base64String, seems to be failing for large data received from server. For small files it is working. Large files it is failing.
Found out.
The problem was not in nodejs zipping logic. That worked perfect.
Issue was in the way I was handling the received response data.
If the data that is received is too large then following code fails
anchor.attr({
href: 'data:application/zip;base64,' + base64String,
target: '_blank',
download: $scope.main.routeParams.sectorId + "-ProcessFiles.zip"
})[0].click();
so the work around is to use blob:
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
var contentType = 'application/zip'
var blob = b64toBlob(base64String, contentType);
saveAs(blob, "hello world.zip");
This link helped me out: How to save binary data of zip file in Javascript?
already answered here: https://stackoverflow.com/a/62639710/8612027
Sending a zip file as binary data with expressjs and node-zip:
app.get("/multipleinzip", (req, res) => {
var zip = new require('node-zip')();
var csv1 = "a,b,c,d,e,f,g,h\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8";
zip.file('test1.file', csv1);
var csv2 = "z,w,x,d,e,f,g,h\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8";
zip.file('test2.file', csv2);
var csv3 = "q,w,e,d,e,f,g,h\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8";
zip.file('test3.file', csv3);
var csv4 = "t,y,u,d,e,f,g,h\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8\n1,2,3,4,5,6,7,8";
zip.file('test4.file', csv4);
var data = zip.generate({base64:false,compression:'DEFLATE'});
console.log(data); // ugly data
res.type("zip")
res.send(new Buffer(data, 'binary'));
})
Creating a download link for the zip file. Fetch data and convert the response to an arraybuffer with ->
//get the response from fetch as arrayBuffer...
var data = response.arrayBuffer();
const blob = new Blob([data]);
const fileName = `${filename}.${extension}`;
if (navigator.msSaveBlob) {
// IE 10+
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
// Browsers that support HTML5 download attribute
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}