Save Array Values Column wise to CSV file using Javascript - javascript

Trying to save my Array values to CSV file column wise using javascript. Right now my code saves the array values row wise.
Current Output -
country1,country2,country3,country4
capital1,capital2,capital3,capital4,
currency1,currency2,currency3,currency4
Required Output -
country1,capital1,currency1
country2,capital2,currency2
country3,capital3,currency3
country4,capital4,currency4
My code so far -
<form>
<input id="download" type="button" value="Download">
</form>
function downloadableCSV(rows) {
var content = "data:text/csv;charset=utf-8,";
rows.forEach(function(column, index) {
content = content + column.join(",") + "\n";
});
return encodeURI(content);
}
var country = ["England","Australia","Mexico","Brazil","Spain","Portugal","Italy","Thailand","Japan"];
var capital = ["London","Canberra","Mexico City","Brasilia","Madrid","Lisbon","Rome","Bangkok","Tokyo"];
var currency = ["Pound","Dollar","peso","Brazilian real","Euro","Euro","Euro","Thai baht","Japanese yen"];
var continent = ["Europe","Australia","NorthAmerica","SouthAmerica","Europe","Europe","Europe","Asia","Asia"];
var language = ["English","English","Spanish","Portuguese","Spainish","Portuguese","Italian","Thailand","Japanese"];
var heading = ["Country","Capital","currency","continent","language"];
var rows = [[heading],[country],[capital],[currency],[continent],[language]];
$("#download").click(function() {
window.open(downloadableCSV(rows));
});
I tried using various functions before but was unsuccessful.Is there a way to implement the required output. Any help would be greatly appreciated.

To group your data you can use zip from lodash (https://lodash.com/docs/4.17.4#zip)
Here is working js code (https://jsbin.com/ditodosime/edit?html,js,output):
function downloadableCSV(heading, rows) {
var content = "data:text/csv;charset=utf-8,";
var dataRows = rows.map(function(columnValues, index) {
return columnValues.join(",");
});
content += heading + "\n" + dataRows.join("\n");
return encodeURI(content);
}
var country = ["England","Australia","Mexico","Brazil","Spain","Portugal","Italy","Thailand","Japan"];
var capital = ["London","Canberra","Mexico City","Brasilia","Madrid","Lisbon","Rome","Bangkok","Tokyo"];
var currency = ["Pound","Dollar","peso","Brazilian real","Euro","Euro","Euro","Thai baht","Japanese yen"];
var continent = ["Europe","Australia","NorthAmerica","SouthAmerica","Europe","Europe","Europe","Asia","Asia"];
var language = ["English","English","Spanish","Portuguese","Spainish","Portuguese","Italian","Thailand","Japanese"];
var heading = ["Country","Capital","currency","continent","language"];
var rows = _.zip(country,capital,currency,continent,language);
window.open(downloadableCSV(heading, rows));

Related

JavaScript Extracting lines from csv file

Please help me, I have the below code, I need to extract the start time from row 1 Col 2, and the end time Last row Col2.
Thanks
async function getData() {
let fileName = document.getElementById("myFile").files[0].name;
alert('The file "' + fileName + '" has been selected.');
const response = await fetch("./csv/" + fileName); //fetch csv files from ./csv/folder
const data = await response.text(); // waiting for the filename to be fetched.
const table = data.split("\n").slice(1); // take out the headers
table.forEach((row) => {
const columns = row.split(","); //parse the comma separator
const test_date = columns[1]; //select date column
const test_time = columns[2]; //select time column
const date_time = test_date + test_time; //concatinate date and time column
xlabels.push(date_time); //join and display date and time in one column
const pressure = columns[3]; //select pressure column
yPressure.push(pressure); // display pressure column
const temp = columns[4]; //select temp column
yTemp.push(temp); // display temp column
console.log(test_date, test_time, pressure, temp);
});
}
There are packages available for parsing csv files... Are you doing this server or client side? If you are using nodejs on the backend I've used convert-excel-to-json in the past.. I havent done it on the frontend before but a quick google search found me this guy
converting the excel file to json means its a simple matter of finding your data in the object tree :D
I used this code to print the items in a csv as inputs in HTML. Does this help you get your values? You can use the second js function function createForm(csv) to print the value you want.
document.getElementById("upload").addEventListener("change", upload, false);
var out = "";
function upload(e) {
document.getElementById('csvForm').innerHTML = "";
var data = null;
var file = e.target.files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(event) {
var csvData = event.target.result;
var parsedCSV = d3.csv.parseRows(csvData);
parsedCSV.forEach(function(d, i) {
if (i == 0) return true; // skip the header
if (d.constructor === Array) {
createForm(d);
}
});
}
}
function createForm(csv) {
out += '<input value="' + csv[0] + '">'; // first item in the csv
out += '<input value="' + csv[2] + '">'; // third item in the csv
document.getElementById('csvForm').innerHTML = out;
out += '<br>';
}
<script src="https://d3js.org/d3.v3.js"></script>
<input id="upload" type="file">
<form id="csvForm"></form>

JavaScript multiple checkboxes - delimited list - store and parse

I was wondering if anybody can help
I'm new and don't know any  Javascript.
I need help for my caspio app.
The code below works I just need to get the second part
I got the first part of storing the values of checked checkboxes in a database field as a comma de-limited list.
Now I need to read the comma de-limited list from the database and update the checkboxes accordingly.
<SCRIPT LANGUAGE="JavaScript">
function concatenate()
{
var Resultfieldname = "CheckboxChoices";
var firstVirtual = 1;
var lastVirtual = 3;
var ResultString = "";
var virtualFieldName = "";
for (i=firstVirtual ;i<=lastVirtual; i++)
{
virtualFieldName = "cbParamVirtual"+i;
if (document.getElementById(virtualFieldName).checked) ResultString = ResultString + "," + document.getElementById(virtualFieldName).value;
}
Resultfieldname = "EditRecord"+Resultfieldname;
if (ResultString.length>0) ResultString = ResultString.substr(1);
document.getElementById(Resultfieldname ).value = ResultString;
}
document.getElementById("caspioform").onsubmit=concatenate;
</SCRIPT>

Use RegEx to replace tags in document with column data from spreadsheet

I've been searching for the answer to this question but have so far been unable to piece together the answer. Please explain any answer you have in really simple terms as I'm fairly new to GAS and RegEx. I've got most of the syntax down but the execution of it in GAS is giving me a hard time.
Basically, I want to write a script that, when the spreadsheet is edited, checks which rows have yet to be merged. Then, on those rows, creates a copy of a template Google Doc and names the document based on the spreadsheet data. From there (this is the hard part), I need it to replace merge tags in the template with the data from the spreadsheet.
The tags in the templates I'll be using look like this: <<mergeTag>>
My idea was to match the whole tag, and replace it with data from the spreadsheet that exists in the column with the same name as what's inside the "<<>>". Ex: <<FooBar>> would be replaced with the data from the column named FooBar. It would obviously be from the current row that needs the merging.
After that, all that's left is to send an email (a few more row-specific personalization) with that document attached (sometimes as a PDF) with the body of the message coming from an HTML file elsewhere in the project.
This is the whole thing I have so far (notice the placeholders here and there that I can personalize for each spreadsheet I use this for):
function onEdit() {
//SPREADSHEET GLOBAL VARIABLES
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get only the merge sheet
var sheet = ss.getSheetByName("Merge Data");
//get all values for later reference
var range = sheet.getActiveRange();
var values = range.getValues();
var lastRow = range.getLastRow();
var lastColumn = range.getLastColumn();
//get merge checker ranges
var urlColumn = range.getLastColumn();
var checkColumn = (urlColumn - 1);
var checkRow = range.getLastRow();
var checkRange = sheet.getRange(2, checkColumn, checkRow);
var check = checkRange.getBackgrounds();
//get template determination range (unique to each project)
var tempConditionRange = sheet.getRange(row, column);
var tempConditionCheck = tempConditionRange.getValues();
//set color variables for status cell
var red = "#FF0000";
var yellow = "#FFCC00";
var green = "#33CC33";
//////////////////////////////////////////////////////////
//DOC GLOBAL VARIABLES
var docTemplate1 = DriveApp.getFileById(id);
var docTemplate2 = DriveApp.getFileById(id);
var docTemplate3 = DriveApp.getFileById(id);
var folderDestination = DriveApp.getFolderById(id);
//////////////////////////////////////////////////////////
//EMAIL GLOBAL VARIABLES
var emailTag = ss.getRangeByName("Merge Data!EmailTag");
var personalizers = "";
var subject = "" + personalizers;
var emailBody = HtmlService.createHtmlOutputFromFile("Email Template");
//////////////////////////////////////////////////////////
// MERGE CODE
for (i = 0; i < check.length; i++) {
//for rows with data, check if they have already been merged
if (check[i] == green) {
continue;
} else {
var statusCell = sheet.getRange((i+2), checkColumn, 1, 1);
var urlCell = sheet.getRange((i+2), urlColumn, 1, 1);
var dataRow = sheet.getRange((i+2), 1, lastRow, (lastColumn - 2))
statusCell.setBackground(red);
//for rows with data, but not yet merged, perform the merge code
//////////////////////////////////////////////////////////
//DOC CREATION
//Determine which template to use
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate1;
}
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate2;
}
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate3;
}
//Create a copy of the template
//Rename the document using data from specific columns, at specific rows
//Move the doc to the correct folder
var docName = "";
var docCopy = docToUse.makeCopy(docName, folderDestination);
var docId = docCopy.getId();
var docURL = docCopy.getUrl();
var docToSend = DriveApp.getFileById(docId);
var docBody = DocumentApp.openById(docId).getBody();
Here's where I need the help
//Locate the Merge Tags
//Match Merge Tags to the column headers of the same name
//Replace the Merge Tags with the data from the matched column, from the correct row
function tagReplace() {
var tagMatch = "/(<{2}(\w+)>{2})/g";
}
statusCell.setBackground(yellow);
urlCell.setValue(docURL);
The rest is just finishing up the process
//////////////////////////////////////////////////////////
//EMAIL CREATION
//Create an email using an HTML template
//Use Merge Tags to personalize email
//Attach the doc we created to the email
//Send email to recipients based on data in the sheet
MailApp.sendEmail(emailTag, subject, emailBody, {
name: "Person McPerson",
attachments: [docToSend], //[docToSend.getAs(MIME.PDF)],
html: emailBody,
});
//////////////////////////////////////////////////////////
//CHECK ROW UPDATE
statusCell.setBackground(green);
}
}
}
My sheets all have a frozen first row that acts as the header row. All my columns will be consistently named the exact same thing as the tags (minus the <<>>).
How do I match the tags to the data?
EDIT
```````````````````
The solution did not work as described when I inserted it into my code as follows:
function formMerge() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Merge Data");
var urlColumn = sheet.getMaxColumns();
var checkColumn = urlColumn - 1;
var lastRow = ss.getSheetByName("Form Responses").getLastRow();
var values = sheet.getDataRange().getValues();
var headers = values[0];
var urlRange = sheet.getRange(2, urlColumn, lastRow);
var checkRange = sheet.getRange(2, checkColumn, lastRow);
var check = checkRange.getBackgrounds();
var red = "#ff0404";
var yellow = "#ffec0a";
var green = "#3bec3b";
var docTemplate = DriveApp.getFileById(id);
var folderDestination = DriveApp.getFolderById(id);
// MERGE CODE
for (i = 0; i < check.length; i++) {
if (check[i] == green) {
continue;
} else {
var statusCell = sheet.getRange((i+2), checkColumn, 1, 1);
var urlCell = sheet.getRange((i+2), urlColumn, 1, 1);
var dataRow = sheet.getRange((i+2), 1, 1, (urlColumn - 2)).getValues();
var clientNameRange = sheet.getRange((i+2), 3);
var clientName = clientNameRange.getValue();
var dateRange = sheet.getRange((i+2), 2);
var datePreFormat = dateRange.getValue();
var timeZone = CalendarApp.getTimeZone();
var date = Utilities.formatDate(new Date(datePreFormat), timeZone, "MM/dd/yyyy");
statusCell.setBackground(red);
//EMAIL VARIABLES
var personalizers = clientName;
var subject = "Post Intake Report for " + personalizers;
var emailBody = "Please see the attached Google Doc for the Post Intake Report for " + clientName + ". The intake was performed on " + date + ".";
var emailTagRange = sheet.getRange((i+2), 24);
var emailTagValue = emailTagRange.getValue();
var emailTag = emailTagValue.split(", ");
//DOC CREATION
var docToUse = docTemplate;
var docName = "Post Intake Report - " + clientName + " [" + date + "]";
var docCopy = docToUse.makeCopy(docName, folderDestination);
var docId = docCopy.getId();
var docURL = docCopy.getUrl();
var docBody = DocumentApp.openById(docId).getBody().editAsText();
for (var j=0; j<headers.length; j++) {
var re = new RegExp("(<<"+headers[j]+">>)","g");
docBody.replaceText(re, dataRow[j]);
}
statusCell.setBackground(yellow);
urlCell.setValue(docURL);
//EMAIL CREATION
MailApp.sendEmail(emailTag, subject, emailBody, {
name: "Christopher Anderson",
attachments: [docCopy],
html: emailBody
});
statusCell.setBackground(green);
}
}
}
Build the RegExp for each tag on the fly, using the header values from your spreadsheet.
Use Body.replaceText() to perform the replacements.
var values = sheet.getDataRange().getValues();
var headers = values[0];
...
// Loop over all columns. Use header names to search for tags.
for (var col=0; col<headers.length; col++) {
// Build RegExp using column header
var re = new RegExp("(<{2}"+headers[col]+">{2})","g");
// Replace tags with data from this column in dataRow
body.replaceText(re, dataRow[col]);
}
This snippet will operate on a single row; the first couple of declarations should appear outside of your row loop. The column looping is then done after you've created and opened the new document, and obtained the body object.
It loops over all the columns in the spreadsheet, using the header names to find the tags you've defined, and replaces them with the corresponding cell contents for the current row.

extract javascript variable from a function

this is my first post. Hope I've observed all the rules properly.
I'm a JS beginner and I've been watching tutorials on thenewboston.com and w3schools and some others on Youtube but can't find the answer to my question.
I have a form that uses JS to dynamically add input rows and that works fine. However the last part I just can't get to work. It is the bit that is supposed to collate all the data entered by the user.
This is what I have so far:
//get all the row data
function getData(TechRiskTable){
try {
var table = document.getElementById(TechRiskTable);
var rowCount = table.rows.length;
var jsonArray = new Array();
for(var index=0; index < rowCount; index++) {
var mapObj = {};
var row = table.rows[index];
var name1 = row.cells[0].childNodes[0];
var name2 = row.cells[1].childNodes[0];
var name3 = row.cells[2].childNodes[0];
var name4 = row.cells[3].childNodes[0];
var name5 = row.cells[4].childNodes[0];
mapObj['name1'] = name1.value;
mapObj['name2'] = name2.value;
mapObj['name3'] = name3.value;
mapObj['name4'] = name4.value;
mapObj['name5'] = name5.value;
// document.write("Value in jsonArray " + name1.value + "<br />");
}
}catch(e) {
alert(e);
}
}
Ok, so I'm running this on a classic ASP page and the "onclick" does this:
response.write input type=submit onclick='getData(TechRiskTable);' value='Send to Reviewer'><input type=reset value='Start Again'>
My question is this: How can I extract the values the user entered into the added rows in the table "TechRiskTable" so I can insert them into a database. I don't need help with getting it into the dbase, I can do that myself. I'm just having trouble extracting the actual values. That "document.write" bit does actually display the correct values on the page when I have it uncommented, but that is still within the function. I can't find a way to access the entered data from OUTSIDE the function. I've tried using request.querystring but that doesn't return any data either.
I assume that I need to get them out of jsonArray() but I can't find anywhere I can get this to work.
Any clarification required please let me know. I didn't include all the code as this post would then be too long but if you need more just ask.
Cheers
function getData(TechRiskTable){
try {
var table = document.getElementById(TechRiskTable);
var rowCount = table.rows.length;
var jsonArray = new Array();
for(var index=0; index < rowCount; index++) {
var mapObj = {};
var row = table.rows[index];
var name1 = row.cells[0].childNodes[0];
var name2 = row.cells[1].childNodes[0];
var name3 = row.cells[2].childNodes[0];
var name4 = row.cells[3].childNodes[0];
var name5 = row.cells[4].childNodes[0];
mapObj['name1'] = name1.value;
mapObj['name2'] = name2.value;
mapObj['name3'] = name3.value;
mapObj['name4'] = name4.value;
mapObj['name5'] = name5.value;
// document.write("Value in jsonArray " + name1.value + "<br />");
return mapObj;
}
}catch(e) {
alert(e);
}
return null;
I am assuming you are calling this method from somewhere else,
var mapObj = getData(TechRiskTable);
if(mapObj!=null)
{
alert("name1 is "+mapObj.name1+" and name2 is "+mapObj.name2);
}

How to get specific property from Google Spreadsheet JSON feed

I am reading JSON from a Google Spreadsheet and need help getting to the text within entry.content.$t. The text is a column named "description" in the spreadsheet. The feed for the spreadsheet is (removed)
So far, my script is
function listChapters(root) {
var feed = root.feed;
var entries = feed.entry || [];
var html = ['<ul>'];
for (var i = 0; i < entries.length; ++i) {
var chlist = entries[i];
var title = (chlist.title.type == 'html') ? chlist.title.$t : escape(chlist.title.$t);
var chapters = chlist.content.$t;
html.push('<li>', chapters, '</li>');
}
html.push('</ul>');
document.getElementById("chapterlist").innerHTML = html.join("");
}
The question is - How do I read "description" from $t to place in the var chapters?
The text within chlist.content.$t is almost, but not quite, properly formatted JSON. Since it's not properly formatted, you cannot use JSON.parse() to create an object that you could then get a description property from.
Here's a brute-force approach that will extract the description, used in place of the original html.push('<li>', chapters, '</li>');:
// Get the text between 'description: ' and 'Chapter website:'
var descStart = chapters.indexOf('description:')+13; //+length of 'description: '
var descEnd = chapters.indexOf('Chapter website:');
var description = chapters.substring(descStart,descEnd);
html.push('<li>', description, '</li>');
Tested with this, checking results in debugger:
function test() {
var url = '---URL---';
var result = UrlFetchApp.fetch(url);
var text = result.getContentText();
var bodytext = Xml.parse(text,true).html.body.getText();
var root = JSON.parse(bodytext);
listChapters(root);
}

Categories