Un script para simplificar la creación de una tabla SO
¿Cómo crear una tabla de rebajas a partir de hojas de Google?
Aceptado
Este código le permite copiar datos de su hoja de cálculo, redactarlos, alinear cada columna de forma independiente y luego publicarlos en SO con la reducción adecuada para crear una tabla atractiva.
El código:
redactar.gs:
function onOpen() {
menu();
}
function menu() {
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Authenticate','authenticate')
.addItem('Redactable Table','showRedactTableDialog')
.addToUi();
}
function authenticate() {
//no nothing
}
function getCSVDataRange() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const rg=sh.getActiveRange();
const cols=rg.getWidth();
const datarange=rg.getA1Notation();
return {datarange:datarange,columns:cols};
}
function getRedactRangeList() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const rgA=sh.getActiveRangeList().getRanges();
const redactrange=rgA.map(function(rg,i){return rg.getA1Notation();}).join(',');
return {redactrange:redactrange};
}
function showRedactTableDialog() {
var userInterface=HtmlService.createHtmlOutputFromFile('redacttable').setWidth(400).setHeight(200);
const h=userInterface.getHeight();
const w=userInterface.getWidth();
const title='Redactable Data Table';
userInterface.append(Utilities.formatString('<div id="dim">w:%s,h:%s</div>',w,h));
SpreadsheetApp.getUi().showModelessDialog(userInterface, title);
}
function getPresets() {
return {datarange:'',redactrange:'',delimiter:',',redactstring:'Redacted'};
}
function getTablePresets() {
return {datarange:'',redactrange:'',align:'c',redactstring:'Redacted',aligntext:""};
}
function testrdtable() {
redactableDataTable({"redactrange":"","cols":"3","col":"3","align":"l","aligntext":"rrr","datarange":"A1:C4","redactstring":"Redacted"})
}
function redactableDataTable(obj) {
Logger.log(JSON.stringify(obj));
const {datarange,redactrange,redactstring,align,aligntext}=obj;
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const drg=sh.getRange(datarange);
const vA=drg.getValues();
//new parameters
const dlm='|';
const dlmrow={l:':---',c:':---:',r:'---:'};
const aline=(aligntext.length>0)?aligntext:align;
if(redactrange) {
const rgA1=redactrange.split(',');
//Logger.log(rgA1);
const rgA=rgA1.map(function(A1,i){
return sh.getRange(A1);
});
const rowStart=drg.getRow();
const colStart=drg.getColumn();
//const rowEnd=drg.getRow()+drg.getHeight()-1;
//const colEnd=drg.getColumn()+drg.getWidth()-1;
rgA.forEach(function(rg,k){
var v=rg.getDisplayValues();
let row=rg.getRow();
let col=rg.getColumn();
v.forEach(function(r,i){
r.forEach(function(c,j){
vA[row-rowStart+i][col-colStart+j]=redactstring;//redact string
});
});
});
}
var tsv='';
var hdr=[vA.shift()];
//header row
hdr.forEach(function(r,i){tsv+=dlm;r.forEach(function(c,j){if(j>0)tsv+=dlm;tsv+=c;});tsv+=dlm;});
tsv+='\r\n';
//delimiter row
hdr.forEach(function(r,i){tsv+=dlm;r.forEach(function(c,j){if(j>0)tsv+=dlm;tsv+=dlmrow[aline[j%aline.length]];});tsv+=dlm;});
tsv+='\r\n';
//data table
vA.forEach(function(r,i){if(i>0){tsv+='\r\n';}tsv+=dlm;r.forEach(function(c,j){if(j>0){tsv+=dlm;}tsv+=c;});tsv+=dlm;});
let s=`Data:${datarange} - Redact:${redactrange}`;
var html=Utilities.formatString('<body><input type="button" value="Exit" onClick="google.script.host.close();" /><br /><textarea rows="1" cols="150" id="rngs">%s</textarea><br /><textarea rows="30" cols="150" id="tsv">%s</textarea></body>',s,tsv);
html+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" />';
console.log(html);
var ui=HtmlService.createHtmlOutput(html).setWidth(1200);
SpreadsheetApp.getUi().showModelessDialog(ui, 'Table Markdown');
}
código HTML:
redactar tabla.hmtl:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
select,
input {
margin: 2px 5px 2px 0;
font-size: 12px;
}
#cols {
margin: 2px 5px 2px 5px;
font-size: 12px;
}
.bold {
font-weight: "bold";
}
</style>
</head>
<body>
<form name="form">
<br /><input type="text" id="dtrg" name="datarange" placeholder="Select Data Range" size="20" readonly /><input type="button" value="Data" onClick="getDataRange();" title="Select Data Range." /><input type="text" id="cols" name="cols" size="2" readonly />Cols
<br /><input type="text" id="rdrg" name="redactrange" placeholder="Select Redact Ranges" size="20" readonly /><input type="button" value="Redact" onClick="getRedactRangelist();" title="Select Redact Rangelist." />
<br /><span class="bold">Alignment</span>
<br /><select name="align"><option value="l">left</option><option value="c">center</option><option value="r">right</option></select>
<input type="text" id="alntxt" name="aligntext" placeholder="Align all columns with r,c,or l only" size="25" oninput="getLength();" /><input type="text" name="col" id="col" size="2" readonly />
<br /><input type="text" id="rs" name="redactstring" size="15" />Redact String
<br /><input type="button" value="Submit" onClick="processForm(this.parentNode);" />
</form>
<script>
$(function(){
google.script.run
.withSuccessHandler(function(obj){
if(obj.datarange) {$('#dtrg').val(obj.datarange);}
if(obj.redactrange) {$('#rdrg').val(obj.redactrange);}
if(obj.align) {$('#aln').val(obj.align);}
if(obj.redactstring) {$('#rs').val(obj.redactstring);}
if(obj.aligntext){$('$alntxt').val(obj.aligntext);}
})
.getTablePresets();
});
function getLength() {
let s=$('#alntxt').val();
let all='rlc';
if(!all.includes(s[s.length-1])){
$('#alntxt').val(s.slice(0,-1));
}
$('#col').val($('#alntxt').val().length);
}
function getDataRange() {
google.script.run
.withSuccessHandler(function(obj){
$('#dtrg').val(obj.datarange);
$('#cols').val(obj.columns);
})
.getCSVDataRange();
}
function getRedactRangelist() {
google.script.run
.withSuccessHandler(function(obj){
$('#rdrg').val(obj.redactrange);
})
.getRedactRangeList();
}
function processForm(form) {
google.script.run.redactableDataTable(form);
}
console.log('My Code');
</script>
</body>
</html>
tablaMarkdown.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>';
</head>
<body>
<input type="button" value="Exit" onClick="google.script.host.close();" /><br />
<textarea rows="1" cols="150" id="rngs"></textarea><br /><textarea rows="30" cols="150" id="tsv"></textarea>
<br /><input type="button" value="Exit" onClick="google.script.host.close();" />
<script>
$(function(){
google.script.run
.withSuccessHandler((robj)=>{
$("#tsv").val(robj.tsv);
$("#rngs").val(robj.rngs);
}).redactableDataTable(obj);
});
</script>
</body>
</html>
Este script también está disponible aquí: https://sites.google.com/view/googappsscript/table-utility
Manifestación:
Versión 2
Esta versión genera automáticamente letras de columna y números de fila que considero útiles en situaciones en las que no hay encabezados en los datos porque ayudan a proporcionar un marco para comprender dónde se encuentra la tabla. De todos modos juega con eso. No es difícil de entender.
GS:
function showRedactTableDialog() {
var userInterface = HtmlService.createHtmlOutputFromFile('redacttable').setWidth(400).setHeight(250);
const h = userInterface.getHeight();
const w = userInterface.getWidth();
const title = 'Redactable Data Table';
userInterface.append(Utilities.formatString('<div id="dim">w:%s,h:%s</div>', w, h));
SpreadsheetApp.getUi().showModelessDialog(userInterface, title);
}
function redactableDataTable(obj) {
Logger.log(JSON.stringify(obj));
const { datarange, redactrange, headers, rows, redactstring, align, aligntext } = obj;
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
const drg = sh.getRange(datarange);
const vA = drg.getDisplayValues().map((r => {
r.forEach(c => {
c.replace(/\r\n/, ' ')
});
return r;
}));
//new parameters
const dlm = '|';
const dlmrow = { l: ':---', c: ':---:', r: '---:' };
const aline = (aligntext.length > 0) ? aligntext : align;
if (redactrange) {
const rgA1 = redactrange.split(',');
//Logger.log(rgA1);
const rgA = rgA1.map(function (A1, i) {
return sh.getRange(A1);
});
const rowStart = drg.getRow();
const colStart = drg.getColumn();
//const rowEnd=drg.getRow()+drg.getHeight()-1;
//const colEnd=drg.getColumn()+drg.getWidth()-1;
rgA.forEach(function (rg, k) {
var v = rg.getDisplayValues();
let row = rg.getRow();
let col = rg.getColumn();
v.forEach(function (r, i) {
r.forEach(function (c, j) {
vA[row - rowStart + i][col - colStart + j] = redactstring;//redact string
});
});
});
}
Logger.log(headers);
if (headers && headers.length > 0) {
vA.unshift(headers.split(','));
}
var tsv = '';
var hdr = [vA.shift()];
//header row
hdr.forEach(function (r, i) { tsv += dlm; r.forEach(function (c, j) { if (j > 0) tsv += dlm; tsv += c; }); tsv += dlm; });
tsv += '\r\n';
if(rows && rows.length > 0) {
tsv = dlm + tsv + dlm + ':---:';
}
//delimiter row
hdr.forEach(function (r, i) { tsv += dlm; r.forEach(function (c, j) { if (j > 0) tsv += dlm; tsv += dlmrow[aline[j % aline.length]]; }); tsv += dlm; });
tsv += '\r\n';
//data table
if(rows && rows.length > 0) {
let rA = rows.split(",");
vA.forEach(function (r, i) { if (i > 0) { tsv += '\r\n'; } tsv += dlm + rA[i] + dlm; r.forEach(function (c, j) { if (j > 0) { tsv += dlm; } tsv += c; }); tsv += dlm; });
} else {
vA.forEach(function (r, i) { if (i > 0) { tsv += '\r\n'; } tsv += dlm; r.forEach(function (c, j) { if (j > 0) { tsv += dlm; } tsv += c; }); tsv += dlm; });
}
let s = `Data:${datarange} - Redact:${redactrange}`;
var html = Utilities.formatString('<body><input type="button" value="Exit" onClick="google.script.host.close();" /><br /><textarea rows="1" cols="150" id="rngs">%s</textarea><br /><textarea rows="30" cols="150" id="tsv">%s</textarea></body>', s, tsv);
html += '<br /><input type="button" value="Exit" onClick="google.script.host.close();" />';
console.log(html);
var ui = HtmlService.createHtmlOutput(html).setWidth(800);
SpreadsheetApp.getUi().showModelessDialog(ui, 'Table Markdown');
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
select,
input {
margin: 2px 5px 2px 0;
font-size: 12px;
}
#cols {
margin: 2px 5px 2px 5px;
font-size: 12px;
}
.bold {
font-weight: "bold";
}
</style>
</head>
<body>
<form name="form">
<br /><input type="text" id="dtrg" name="datarange" placeholder="Select Data Range" size="20" readonly /><input type="button" value="Data" onClick="getDataRange();" title="Select Data Range." /><input type="text" id="cols" name="cols" size="2" readonly />Cols
<br /><input type="text" id="rdrg" name="redactrange" placeholder="Select Redact Ranges" size="20" readonly /><input type="button" value="Redact" onClick="getRedactRangelist();" title="Select Redact Rangelist." />
<br /><input type="text" id= "hdrs" name="headers" placeholder="Enter Column Header Separated by Comma" size="30" /><input type="button" id="autocol" value="auto" onClick="autoCols();" />
<br /><input type="text" id= "rows" name="rows" placeholder="Enter Row Numbers Separated by Comma" size="30" /><input type="button" id="autorow" value="auto" onClick="autoRows();" />
<br /><span class="bold">Alignment</span>
<br /><select name="align"><option value="l">left</option><option value="c">center</option><option value="r">right</option></select>
<input type="text" id="alntxt" name="aligntext" placeholder="Align all columns with r,c,or l only" size="25" oninput="getLength();" /><input type="text" name="col" id="col" size="2" readonly />
<br /><input type="text" id="rs" name="redactstring" size="15" />Redact String
<br /><input type="button" value="Submit" onClick="processForm(this.parentNode);" />
</form>
<script>
$(function(){
google.script.run
.withSuccessHandler(function(obj){
if(obj.datarange) {$('#dtrg').val(obj.datarange);}
if(obj.redactrange) {$('#rdrg').val(obj.redactrange);}
if(obj.align) {$('#aln').val(obj.align);}
if(obj.redactstring) {$('#rs').val(obj.redactstring);}
if(obj.aligntext){$('$alntxt').val(obj.aligntext);}
})
.getTablePresets();
});
function getLength() {
let s=$('#alntxt').val();
let all='rlc';
if(!all.includes(s[s.length-1])){
$('#alntxt').val(s.slice(0,-1));
}
$('#col').val($('#alntxt').val().length);
}
function getDataRange() {
google.script.run
.withSuccessHandler(function(obj){
$('#dtrg').val(obj.datarange);
$('#cols').val(obj.columns);
})
.getCSVDataRange();
}
function getRedactRangelist() {
google.script.run
.withSuccessHandler(function(obj){
$('#rdrg').val(obj.redactrange);
})
.getRedactRangeList();
}
function processForm(form) {
google.script.run.redactableDataTable(form);
}
function autoCols() {
let s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
google.script.run
.withSuccessHandler((obj) => {
console.log(JSON.stringify(obj));
let hs = s.slice(obj.col - 1,obj.col + obj.width -1);
document.getElementById("hdrs").value = hs.split("").join(',');
})
.getUpperLeft();
}
function autoRows() {
google.script.run
.withSuccessHandler((obj) => {
let rs = obj.row;
document.getElementById("rows").value = Array.from(new Array(obj.height).keys(),x => x + rs).join(",");
})
.getUpperLeft();
}
console.log('My Code');
</script>
</body>
</html>