Creating XLSX (Excel) spreadsheet (or Zip files) in Javacript Server Side - javascript

I'm looking for some guidance or ideas on how to create a proper formatted Excel (XLSX) spreadsheet using Javascript Serverside.
I've found multiple sites/libraries (such as SheetJS) which can create the file, but depend on web functions (ie. blobs and the like).
Alternatively a JS library which similarly can create a zip file without using blobs/web functions (ie. i can create the XML files structured within the XLSX file/zip but cannot compress server side.
The reason for this is the need to export these files on Server Side scripts within NetSuite/SuiteScript... so far I've come up empty.

You may be able to get what you are looking for using the 'N/file' SuiteScript module. Create a file using file.Type.EXCEL

Here's a scheduled script code sample that will take saved search results and create an excel file that is saved to the file cabinet. You can reference Suite Answer Id 93557. Also the "file.Type" enum does allow for the type Zip, reference Suite Answer Id 43530
define(['N/search','N/file'], function(search, file) {
function execute(scriptContext){
//Load saved search
var mySearch = search.load({id: '47'});
//Run saved search
var mySearchResultSet = mySearch.run();
//Headers of CSV File separated by commas and ends with a new line (\r\n)
var csvFile = 'Internal ID,Item Name,Average Cost\r\n';
//Iterate through each result
mySearchResultSet.each(iterator);
function iterator(resultObject){
//get values
var internalid = resultObject.getValue(mySearch.columns[0])
var itemid = resultObject.getValue(mySearch.columns[1])
var formulacolumn = resultObject.getValue(mySearch.columns[2])
//Add each result as a new line on CSV
csvFile += internalid+','+itemid+','+formulacolumn+'\r\n'
return true;
}
//Variable for datetime
var date = new Date();
//Creation of file
var fileObj = file.create({
name: 'Saved Search Result - ' + date.toLocaleDateString() +'.xlsx',
fileType: file.Type.EXCEL,
contents: csvFile,
description: 'This is a CSV file.',
encoding: file.Encoding.UTF8,
folder: 123
});
//Save the CSV file
var fileId = fileObj.save();
}
return {
execute: execute
};
});

Related

How to get producer of a PDF in google app script

I am trying to write a gmail add-on where I iterate over all emails and create a report based on their producers. Iterating over emails is the easiest part and I have done that, however I can't find any way to get producer line of each PDFs.
So far I tried
analyzing the blob, however this is something like writing a PDF library to parse all syntax. producer tag is not clearly present
adding pdf.js, which is a third party open source tool to extract such information. However, I couldn't add it due to ES3 - ES6 support issue.
What's the best way to get the producer line of a PDF in google app script?
Thank you
You want to retrieve the value of Producer from PDF file.
I could understand like above. If my understanding is correct, how about this sample script? In this sample script, from your shared PDF files, the value of Producer is retrieved by 2 regular expressions from the file content. Please think of this as one of several answers.
Sample script:
When you use this script, please set the folder ID of folder that PDF files are put. This script retrieves the value from all PDF files in a folder.
var folderId = "### folderId ###";
var files = DriveApp.getFolderById(folderId).getFilesByType(MimeType.PDF);
var regex = [/Producer\((\w.+)\)/i, /<pdf:Producer>(\w.+)<\/pdf:Producer>/i];
var result = [];
while (files.hasNext()) {
var file = files.next();
var content = file.getBlob().getDataAsString();
var r = regex.reduce(function(s, e) {
var m = content.match(e);
if (Array.isArray(m)) s = m[1];
return s;
}, "");
result.push({
fileName: file.getName(),
fileId: file.getId(),
vaueOfProducer: r,
});
}
Logger.log(result); // Result
Result:
This sample result was retrieved from a folder (my Google Drive) that the shared 3 PDF files were put.
[
{
"fileName": "2348706469653861032.pdf",
"fileId": "###",
"vaueOfProducer": "iText� 7.1.5 �2000-2019 iText Group NV \(iText; licensed version\)"
},
{
"fileName": "Getting started with OneDrive.pdf",
"fileId": "###",
"vaueOfProducer": "Adobe PDF library 15.00"
},
{
"fileName": "DITO-Salesflow-040419-1359-46.pdf",
"fileId": "###",
"vaueOfProducer": "iText 2.1.7 by 1T3XT"
}
]
Note:
About the file of 2348706469653861032.pdf, the characters which cannot be displayed are included in the value of Producer.
This is a sample script. So please modify this for your situation.

Read a file with dynamic file name in JavaScript

Is it possible to read a file with file name as Sometext_ddmmyy.xls in JavaScript?
The file name changes daily but date ddmmyy are random date in that week or previous.
But the path of the file never changes.
Can you help to code in JavaScript to read the file?
Code:
var filename = /^path\\sometext_.*.xls$/;
....
var neobjectexcel = new ActiveXObject("Excel.Application");
var sheet = neojectexcel.Workbooks.Open(filename).ActiveSheet;
...
I used Regex but I am getting "Sorry, we couldn't find /^path\sometext_.*.xls$/ Is it possible it was moved, renamed or deleted?" Error!
Even the regex /^path\\sometext_\d\d\d\d\d\d.xls$/ is giving the same error.
Also tried \d+ instead of \d\d\d\d\d\d does not works.
Please help!
Update: The file will be in a folder on a server along with other files of similar names like sometext_ddmmyy.xls randomtext_ddmmyy.xls randomothertext_ddmmyy.xls and will be accessed with script on the same server.
With FileSystemObject you can filter a filename with a RegExp and find the latest filtered file added to a folder like so:
function getLatestFile (path, filter) {
var fileIO = new ActiveXObject('Scripting.FileSystemObject'),
folder = fileIO.GetFolder(path), // Get a folder object
files = new Enumerator(folder.files), // Create files collection
latest = 0,
file, date, isTargetFile, temp, target;
while (!files.atEnd()) { // Iterate files collection
file = files.item(); // Get a file from the collection
temp = new String(file); // Convert a file object to string
isTargetFile = filter.test(temp); // Filter the filename
date = new Date(file.DateCreated).getTime(); // Get the creation date of the file
if (isTargetFile && date > latest) { // Check if this file passed the filter and is newer than the previous filter-passed file
target = temp;
latest = date;
}
files.moveNext(); // Continue iteration
}
return target;
}
An example call for your case would be:
var filename = getLatestFile(path_to_folder, /sometext_\d{6}\.xls$/);
Arguments: path = the path to the folder where to search files. filter = a RegExp object (literal or constructed) to filter the filename. When creating the RegExp, note that the converted file object (temp) uses a backslash as a folder separator, though the RegExp can be created to filter the filename only. If the function returns undefined, none of the filenames has matched the RegExp.

Get spreadsheet id or url from the spreadsheets name

I have multiple named spreadsheets in a folder on google drive. How would I get their id or url by passing one of the names to a function?
I can get the file using DriveApp, but I dont know how to get the id from that.
function getFile(name)
{
var folder = DriveApp.getFolderById('id');
var file = folder.getFilesByName(name);
//get file id
}
Is there a way to get the id or url using DriveApp or SpreadsheetApp?
The command folder.getFilesByName(name);potentially retrieve more than one file (has it's name say it- getFiles) so it give you a file iterator that you need to parse with a while loop.
If you are absolutely sure that there is at least one file with that has the name, you can avoid the loop with a little dirty code like this:
var file = folder.getFilesByName(name).next();
and then retrieve the id with:
var id = file.getId()
-- EDIT:
If you are not sure to retrieve a file (You don't know if it exist or has the right name....) you'll need to check the result of the file iterator.
Instead of writing :
var file = folder.getFilesByName(name);
prefer to write:
var files = folder.getFilesByName(name); // you could have zero or more than one file
And then you can do a while loop if you believe there is more than one file with that name:
var out = [];
while(files.hasNext()) {
var file = files.next();
out.push(file.getId());
Logger.log(file.getId());
}
return out;
or if there is only one or zero file a simple if will do the job:
if (files.hasNext()) {
var file = files.next();
Logger.log(file.getId());
return file.getIt(); // eventually
}
else {
Logger.log("there is no file with that name");
return "no id"; // eventually
}

How to properly download a .zip file using Node Js, Archiver and Express

I am attempting to zip the contents of two directories and download the resulting .zip file. One directory contains .txt files and the other .jpg. I am using archiver to zip the files and running the express framework on node js. I am inclined to think that the problem exists in the download step, as the resulting zipped file that is created in the project root expands as expected, however when the file is downloaded, I get an "Error 2 - No such file or directory."
app.get('/download',function(req, res){
zipFile = new Date() + "-Backup.zip";
var output = fs.createWriteStream(__dirname +"/backups/"+ zipFile);
var archive = archiver('zip');
output.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
archive.on('error', function(err) {
throw err;
});
archive.pipe(output);
var files1 = fs.readdirSync(__dirname+'/posts');
var files2 = fs.readdirSync(__dirname+'/uploads');
for(var i = 0; i< files1.length; i++){
archive.append(fs.createReadStream(__dirname+"/posts/"+files1[i]), { name: files1[i] });
}
for(var i = 0; i< files2.length; i++){
archive.append(fs.createReadStream(__dirname+"/uploads/"+files2[i]), { name: files2[i] });
}
archive.finalize();
res.download(__dirname + "/backups/" + zipFile, zipFile);
});
zipFile is a global variable.
The on 'close' logs fire properly and no errors occur, but the file will not open after being downloaded. Is there an issue with response headers or something else I am unaware of?
Thanks for the help.
I solved my own problem using node-zip as the archive utility.
var zip = require('node-zip')(); // require the node-zip utility
var fs = require('fs'); // I use fs to read the directories for their contents
var zipName = "someArbitraryName.zip"; // This just creates a variable to store the name of the zip file that you want to create
var someDir = fs.readdirSync(__dirname+"/nameOfDirectoryToZip"); // read the directory that you would like to zip
var newZipFolder = zip.folder('nameOfDirectoryToZip'); // declare a folder with the same name as the directory you would like to zip (we'll later put the read contents into this folder)
//append each file in the directory to the declared folder
for(var i = 0; i < someDir.length,i++){
newZipFolder.file(someDir[i], fs.readFileSync(__dirname+"/nameOfDirectoryToZip/"+someDir[i]),{base64:true});
}
var data = zip.generate({base64:false,compression:'DEFLATE'}); //generate the zip file data
//write the data to file
fs.writeFile(__dirname +"/"+ zipName, data, 'binary', function(err){
if(err){
console.log(err);
}
// do something with the new zipped file
}
Essentially, what is happening can broken down into 3 steps:
Use fs to read the contents of a directory that you would like to zip.
Use zip.folder to declare the folder, then use zip.file to append files to that directory. I just used a for loop to iteratively add each file in the directory that was read in step 1.
Use zip.generate to create the .zip file data, and write it to file using fs.
The resulting file can be downloaded or whatever you would like to do with it. I have seen no issues using this method.
If you want to zip more than one directory, just repeat steps 1 and 2 before you zip.generate, creating a new zip.folder for each directory.
Just use
archive.on("finish",function(){
res.download(__dirname + "/backups/" + zipFile);
})

unable to edit the json file at client side

i want to edit an json file using javascript. the file is "client.json" and is at the local system and is modified at local system only. I am using form for creating the new client details and i want that those details to be appended to the json file as the object.
{"clients":[
{
"name":"xxxx",
"team":"yyy",
"location": {
"city":"beijing",
"country":"china"
},
"wdays":{"start":"Monday","end":"friday"},
"whours":{"start":"9 A.M","end":"6 P.M" }
},
{
"name":"xxxx",
"team":"yyy",
"location": {
"city":"new york",
"country":"usa"
},
"wdays":{"start":"Monday","end":"friday"},
"whours":{"start":"9 A.M","end":"6 P.M" }
}
]}
the following the javascript code is about reading data from form and appending that data as the json object.........`
</script>
<script type="text/javascript">
function addtojson()
{
var client_name=(document.getElementById("cname")).value;
var country=document.getElementById("country").value;
var city=document.getElementById("city").value;
var wtimeto=document.getElementById("wtimeto").value;
var wtimefrom=document.getElementById("wtimefrom").value;
var wdayto=document.getElementById("wdayto").value;
var wdayfrom=document.getElementById("wdayfrom").value;
jQuery.getJSON('client.json')
.done(function(data) {
var cobj=new Object();
cobj.name=client_name;
cobj.team="YYY";
cobj.location=new Object();
cobj.location.city=city;
cobj.location.country=country;
cobj.wdays=new Object();
cobj.wdays.start=wdayto;
cobj.wdays.end=wdayfrom;
cobj.whours=new Object();
cobj.whours.start=wtimeto;
cobj.whours.end=wtimefrom;
var myString = JSON.stringify(cobj);
alert('I am working');
alert(myString);
data.clients.push(cobj);
alert(JSON.stringify(data.clients[0]));//it gives previous first array object
alert(JSON.stringify(data.clients[1]));//it gives previous second array object
alert(JSON.stringify(data.clients[2]));//it gives the new appended array object
});
return true;
}
</script>`
though the data is being modified locally in the program the json file is not getting updated????????
JavaScript in a browser is generally not permitted to write to the local disk. Regardless, after you load the JSON file, you're editing the loaded document in memory, which has no impact on the file on the disk until you write the changes to disk. This is where you will run into the problem of not being allowed to write to disk from a script.
You might be able to get something going using dynamically-generated data: URI's to trigger a download prompt to download the new version of the file and save it to disk. See http://en.wikipedia.org/wiki/Data_URI_scheme for more info.

Categories

Resources