I am successfully using the example from sheetJS's website, like so:
/* create new workbook */
var workbook = XLSX.utils.book_new();
/* convert table 'table1' to worksheet named "Sheet1" */
var ws1 = XLSX.utils.table_to_sheet(document.getElementById('table1'));
XLSX.utils.book_append_sheet(workbook, ws1, "Sheet1");
/* convert table 'table2' to worksheet named "Sheet2" */
var ws2 = XLSX.utils.table_to_sheet(document.getElementById('table2'));
XLSX.utils.book_append_sheet(workbook, ws2, "Sheet2");
/* workbook now has 2 worksheets */
Is it possible to append multiple html tables to a single sheet? They have the same structure. I imagine it could be something, like so:
/* convert 'table1', 'table2', 'table3' to single sheet named "Sheet1" */
var ws1 = XLSX.utils.table_to_sheet(document.getElementById('table1'));
var ws2 = XLSX.utils.table_to_sheet(document.getElementById('table2'));
var ws3 = XLSX.utils.table_to_sheet(document.getElementById('table3'));
XLSX.utils.book_append_sheet(workbook, {ws1, ws2, ws3}, "Sheet1");
I found the answer from this following link:
https://codepen.io/anon/pen/EebyzQ?editors=0010
What it does is it appends the worksheets into one, skips the header of the first one, and then exports it as an excel sheet:
function convert(){
let tbl1 = document.getElementsByTagName("table")[0]
let tbl2 = document.getElementsByTagName("table")[1]
let worksheet_tmp1 = XLSX.utils.table_to_sheet(tbl1);
let worksheet_tmp2 = XLSX.utils.table_to_sheet(tbl2);
let a = XLSX.utils.sheet_to_json(worksheet_tmp1, { header: 1 })
let b = XLSX.utils.sheet_to_json(worksheet_tmp2, { header: 1 })
a = a.concat(['']).concat(b)
let worksheet = XLSX.utils.json_to_sheet(a, { skipHeader: true })
const new_workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(new_workbook, worksheet, "worksheet")
XLSX.writeFile(new_workbook, 'tmp_file.xls')
}
Here is a working code for three tables based on #md Moazzem answer
function convert(section){
var elt = document.getElementById('tbl_exporttable_to_xls');
var elt2 = document.getElementById('tbl_exporttable_to_xls2');
var elt3 = document.getElementById('tbl_exporttable_to_xls3');
let worksheet_tmp1 = XLSX.utils.table_to_sheet(elt);
let worksheet_tmp2 = XLSX.utils.table_to_sheet(elt2);
let worksheet_tmp3 = XLSX.utils.table_to_sheet(elt3);
let a = XLSX.utils.sheet_to_json(worksheet_tmp1, { header: 1 })
let b = XLSX.utils.sheet_to_json(worksheet_tmp2, { header: 1 })
let c = XLSX.utils.sheet_to_json(worksheet_tmp3, { header: 1 })
a = a.concat(['']).concat(b)
a = a.concat(['']).concat(c)
let worksheet = XLSX.utils.json_to_sheet(a, { skipHeader: true })
const new_workbook = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(new_workbook, worksheet, "worksheet")
XLSX.writeFile(new_workbook, (section+'-Marks.xlsx'))
}
Related
I have read all the previous posts and I have a similiar subjetc that I can't solve. I have to copy/paste a Google Sheets (two sheets, 'GENERAL', 'VALEUR') document.
I have won to write a code to copy/paste : 1 document (source) ==to==> 1 document (destination)
function expCalc(){
copypaste_GENERAL();
copypaste_VALEUR();
}
function copypaste_GENERAL() {
var source_G = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1xTBgfI-yy30GHm-LpsUWWoLRACNk5rdc81DPKGyS9fw/edit#gid=0');
var sourceSheet_G = source_G.getSheetByName('GENERAL');
var sourceRange_G = sourceSheet_G.getDataRange();
var sourceValues_G = sourceRange_G.getValues();
var tempSheet_G = source_G.getSheetByName('TEMP_GENERAL');
var tempRange_G = tempSheet_G.getRange('A1:DU11');
var destination_G = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1kFKaNOc8JbRM63tb24QB3_fJms5vnQbZj2lOYsoh0CA/edit#gid=1580219321');
var destSheet_G = destination_G.getSheetByName('GENERAL');
sourceRange_G.copyTo(tempRange_G); // paste all formats?, broken references
tempRange_G.offset(0, 0, sourceValues_G.length, sourceValues_G[0].length)
.setValues(sourceValues_G); // paste all values (over broken refs)
copydSheet = tempSheet_G.copyTo(destination_G); // now copy temp sheet to another ss
copydSheet.getDataRange().copyTo(destSheet_G.getDataRange());
destination_G.deleteSheet(copydSheet); //delete copydSheet
}
function copypaste_VALEUR() {
var source_V = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1xTBgfI-yy30GHm-LpsUWWoLRACNk5rdc81DPKGyS9fw/edit#gid=0');
var sourceSheet_V = source_V.getSheetByName('VALEUR');
var sourceRange_V = sourceSheet_V.getDataRange();
var sourceValues_V = sourceRange_V.getValues();
var tempSheet_V = source_V.getSheetByName('TEMP_VALEUR');
var tempRange_V = tempSheet_V.getRange('A1:I255');
var destination_V = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1kFKaNOc8JbRM63tb24QB3_fJms5vnQbZj2lOYsoh0CA/edit#gid=1580219321');
var destSheet_V = destination_V.getSheetByName('VALEUR');
sourceRange_V.copyTo(tempRange_V); // paste all formats?, broken references
tempRange_V.offset(0, 0, sourceValues_V.length, sourceValues_V[0].length)
.setValues(sourceValues_V); // paste all values (over broken refs)
copydSheet = tempSheet_V.copyTo(destination_V); // now copy temp sheet to another ss
copydSheet.getDataRange().copyTo(destSheet_V.getDataRange());
destination_V.deleteSheet(copydSheet); //delete copydSheet
}
but I can't write a code to copy/paste : 1 document (source) ==to==> MANY (more than 1) documents (destination) according to a list of URLs (here, example only on 2 URLs)
Here is my test code (using only t'GENERAL' sheet for this present test)
function copypaste_GENERAL() {
var source = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1xTBgfI-yy30GHm-LpsUWWoLRACNk5rdc81DPKGyS9fw/edit#gid=0');
var sourceSheet = source.getSheetByName('GENERAL');
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var tempSheet = source.getSheetByName('TEMP_GENERAL');
var tempRange = tempSheet.getRange('A1:DU11');
var destSpreadUrl = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1kFKaNOc8JbRM63tb24QB3_fJms5vnQbZj2lOYsoh0CA/edit#gid=1580219321');
var destSheetUrl = destSpreadUrl.getSheetByName('URLTST');
var destSheet_G = destSpreadUrl.getSheetByName('GENERAL');
var urlessai = destSheetUrl.getRange("D2:D3").getValues();
for (var row = 1; row = 3; row++) {
if (urlessai[row] != '') {
sourceRange.copyTo(tempRange); // paste all formats?, broken references
tempRange.offset(0, 0, sourceValues.length, sourceValues[0].length)
.setValues(sourceValues); // paste all values (over broken refs)
copydSheet = tempSheet.copyTo(destSpreadUrl); // now copy temp sheet to another ss
copydSheet.getDataRange().copyTo(destSheet_G.getDataRange());
destSpreadUrl.deleteSheet(copydSheet); //delete copydSheet
};
};
};
Please, can you help me to find a solution to write this copy/paste loop on a list of URLs (for x users) ?
Thanks in advance !
Philippe
This is probably not exactly what you want but I think it's close and I'm willing to tweak it.
function copySrcDes() {
const ss = SpreadsheetApp.getActive();
const locs = [{srcid:"1xTBgfI-yy30GHm-LpsUWWoLRACNk5rdc81DPKGyS9fw",desid:"1kFKaNOc8JbRM63tb24QB3_fJms5vnQbZj2lOYsoh0CA",shts:["GENERAL"]},{srcid:"1xTBgfI-yy30GHm-LpsUWWoLRACNk5rdc81DPKGyS9fw",desid:"1kFKaNOc8JbRM63tb24QB3_fJms5vnQbZj2lOYsoh0CA",shts:["VALEUR"]}];
locs.forEach(obj => {
let sss = SpreadsheetApp.openById(obj.srcid);
let dss = SpreadsheetApp.openById(obj.desid);
obj.shts.forEach(n => {
let ssh = sss.getSheetByName(n);
let dsh = dss.getSheetByName(n);
let vs = ssh.getDataRange().getValues();
dsh.getRange(1,1,vs.length,vs[0].length).setValues(vs);
});
});
}
I have found so many scripts to copy values only from one spreadhseet to another. However, all of them is to copy the whole spreasheet.
I am very new with google script and cannot find a way to copy values only from specific tabs to another spreasheet adding these new tabs to it.
function temp() {
var sss = SpreadsheetApp.openById('XYZ'); // sss = source spreadsheet
//var ss = sss.getSheets()[4]; // ss = source sheet
var ss = sss.getSheets(); // ss = source sheet
var id=4; //default number
for(var i in ss)
{
var sheet = ss[i];
if(sheet.getName()== "ABC")
{ id=i;
break;
}
}
console.log(id);
ss=sss.getSheets()[id];
//Get full range of data
var SRange = ss.getDataRange();
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
SpreadsheetApp.flush();
var tss = SpreadsheetApp.getActiveSpreadsheet(); // tss = target spreadsheet
var ts = tss.getSheetByName('ABC'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
Thanks a lot in advance.
Issue:
You can to copy the values from a specific set of sheets to a new spreadsheet.
I assume that you don't want to copy the sheet itself, but only the values from the source sheet.
Modifications:
Use filter to get an array of your desired sheets (based on sheet name).
If the target spreadsheet doesn't have a sheet with that name, create it with Spreadsheet.insertSheet.
Code sample:
function temp() {
var sheetNames = ["ABC", "DEF"]; // Change accordingly
var sss = SpreadsheetApp.openById('XYZ');
var sheetsToCopy = sss.getSheets().filter(s => sheetNames.includes(s.getSheetName()));
sheetsToCopy.forEach(ss => {
var sourceSheetName = ss.getSheetName();
var SRange = ss.getDataRange();
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var tss = SpreadsheetApp.getActiveSpreadsheet();
var ts = tss.getSheetByName(sourceSheetName);
if (!ts) ts = tss.insertSheet(sourceSheetName);
ts.getRange(A1Range).setValues(SData);
});
}
Copy these sheets to another spreadsheet
function copythese() {
const ss = SpreadsheetApp.getActive();
const these = ['Sheet0','Sheet1'];//Put your sheetnames here
const another = SpreadsheetApp.openById("another id");//put the other spreadsheet id here
ss.getSheets().filter(sh => ~these.indexOf(sh.getName())).forEach(sh => {
sh.copyTo(another);
});
}
Append These Values to another spreadsheet
function appendthesevalues() {
const ss = SpreadsheetApp.getActive();
const these = ['Sheet0','Sheet1'];
const another = SpreadsheetApp.openById("another id");
ss.getSheets().filter(sh => ~these.indexOf(sh.getName())).forEach(sh => {
let vs = sh.getDataRange().getValues();
let nsh = another.getSheetByName(sh.getName());
if(!nsh) {
nsh = another.insertSheet(sh.getName());
SpreadsheetApp.flush();
}
if(nsh) {
nsh.getRange(nsh.getLastRow() + 1, 1 ,vs.length, vs[0].length).setValues(vs);
}
});
}
I have the following code that works great when the header row is row 1
readerData(rawFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "array" });
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
const header = this.getHeaderRow(worksheet);
const results = XLSX.utils.sheet_to_json(worksheet,{ header: 0, range: 0, defval: ""});
this.generateData({ header, results });
this.loading = false;
resolve();
};
reader.readAsArrayBuffer(rawFile);
});
},
generateData({ header, results }) {
this.excelData.header = header;
this.excelData.results = results;
this.excelData.original_results = [...results];
this.onSuccess && this.onSuccess(this.excelData);
var grid = this.$refs.membersGrid.ej2Instances;
grid.dataSource = this.excelData.results;
grid.refresh();
},
getHeaderRow(sheet) {
const headers = [];
const range = XLSX.utils.decode_range(sheet["!ref"]);
let C;
const R = range.s.r;
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) {
/* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })];
/* find the cell in the first row */
let hdr = "UNKNOWN " + C; // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
headers.push(hdr);
}
return headers;
},
It works great and put all of the Header values into the excelData.header and it put all of the named array data into the excelData.results. My problem is it all goes to a mess when the first row or first two rows are blank or I need to skip them. I've tried
https://github.com/SheetJS/sheetjs/issues/463
but I'm using "xlsx": "^0.17.1" . When I used
range.s.r = 1;
I was able to change my range to A2 but I could not get my named array of data. Any help is appreciated .
After a few days of digging and a lot of trial and error code I got my solution that I will post for others to use if they have the same problem. I used the same code up to this point.
readerData(rawFile) {
let fileName = rawFile.name;
this.showLoading();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
var data = e.target.result;
var workbook = XLSX.read(data, { type: "array" });
var firstSheetName = workbook.SheetNames[0];
var worksheet = workbook.Sheets[firstSheetName];
var range = XLSX.utils.decode_range(worksheet['!ref']);
var header = this.getHeaderRow(worksheet,range);
The reason for this is that it gives me the file name, the first sheets name and the value in the first row. From there I can determine where my header row is and where the data row starts. The data row does not have to be the row after the header so my next line of code could be:
range.s.r = 1; // <-- zero-indexed, so setting to 1 will skip row 0
worksheet['!ref'] = XLSX.utils.encode_range(range);
header = this.getHeaderRow(worksheet,range);
range.s.r = 2;
var results = XLSX.utils.sheet_to_json(worksheet,{ header: header, range: range, defval: ""});
The results are based upon the values header and range that have been adjusted using the:
range.s.r = 1 or 2 or whatever number you need
I can now read all of the Excel sheets and make a clean named array for data processing. Hope this helps someone.
rather than my original 0's
I'm trying to set checkboxes in a range. The firebase_id array must match column B in the range. If matching? Set row to TRUE. But i'm get some randomly checked checboxxes..
What am I doing wrong..?
function setCheckboxIfValueKinguinIdExist() {
const AS = SpreadsheetApp.getActiveSpreadsheet();
const SHEET_TESTING = AS.getSheetByName("Testing");
let get_firebase_items = getSelectedIdsFromFirebase();
let firebase_ids = get_firebase_items.map(function(item){return item.kinguinId}); // [ '17','2962','9798']
let last_row = SHEET_TESTING.getLastRow();
let values = SHEET_TESTING.getRange("A2:B"+last_row).getValues();
let row = 1;
for(let a in values) {
let item = values[a][1];
if(firebase_ids.includes(item) === true){
SHEET_TESTING.getRange(row,1).setValue("TRUE");
}
row++;
}
}
Try this:
function setCheckboxIfValueKinguinIdExist() {
const AS = SpreadsheetApp.getActiveSpreadsheet();
const SHEET_TESTING = AS.getSheetByName("Testing");
let get_firebase_items = getSelectedIdsFromFirebase();
let firebase_ids = get_firebase_items.map(function(item){return item.kinguinId}); // [ '17','2962','9798']
var last_row = SHEET_TESTING.getLastRow();
var values = SHEET_TESTING.getRange("A2:B"+last_row).getValues();
var row = 1;
values.forEach((r,i)=>{
if(firebase_ids.includes(r[1])) {
SHEET_TESTING.getRange(i+2,1).setValue("TRUE");
}
});
}
I'm relatively new to coding, so thanks in advance for any assistance here.
I have a script that runs two functions on the same sheet.
Button2 contains a function (email_button2) that runs a SQL query and pulls info into columns A to D
Button1 also contains a function (email_button1) that runs a separate query and I want to pull this info in columns G to AA (21 columns)
Right now, when I click Button1, I get the following error: Incorrect range width, was 1 but should be 21
Any idea what I should change or add to my script?
function data_button() {
// Logger.log(e)
var thisDoc = SpreadsheetApp.getActiveSpreadsheet();
var helpers = thisDoc.getSheetByName("helper");
query =
helpers.getRange(3,2).getValue().split(String.fromCharCode(13)).join(" ").split(String.fromCharCode(10)).join(" ")
// lastrow = helpers.getRange("lastrow").getValue()
do_query(query,"data")
}
function email_button1() {
// Logger.log(e)
var thisDoc = SpreadsheetApp.getActiveSpreadsheet();
var helpers = thisDoc.getSheetByName("helper");
query =
helpers.getRange(4,2).getValue().split(String.fromCharCode(13)).join("
").split(String.fromCharCode(10)).join(" ")
// lastrow = helpers.getRange("lastrow").getValue()
do_query(query,"emails",11,7)
}
function email_button2() {
// Logger.log(e)
var thisDoc = SpreadsheetApp.getActiveSpreadsheet();
var helpers = thisDoc.getSheetByName("helper");
query =
helpers.getRange(5,2).getValue().split(String.fromCharCode(13)).join("
").split(String.fromCharCode(10)).join(" ")
// lastrow = helpers.getRange("lastrow").getValue()
do_query(query,"emails",11,1)
}
function do_query(query,sheetname,startRow,startCol){
//List of lists?
var url= "xxxxxxxxxxxxxx"
var q = {"query":query}
var options = {
'method' : 'post',
'payload' : q,
'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, options); // get feed
var response2 = response.getContentText()
var rows = response2.split(";;;")
var columnCount = rows[0].length
var data = [];
for(var i = 0; i < rows.length; i++){
var row = rows[i].split('|||');
data.push(row);
}
Logger.log(data)
var a = data[1]
var thisDoc = SpreadsheetApp.getActiveSpreadsheet();
var sheet2 = thisDoc.getSheetByName(sheetname);
sheet2.getRange(startRow,startCol,200,4).clear()
sheet2.getRange(startRow,startCol, data.length,
data[0].length).setValues(data);
//this line above designates column headers
//sheet2.getRange(12, 1, data[1].length, data[1] .
[0].length).setValues(data[1]);
//Logger.log(data[0].length)
//Logger.log(data[0][0].length)
//Logger.log(data[0])
// thisDoc.getSheetByName("helper").getRange("lastrow").setValue(data.length)
}