跳到主要内容

在自定义代码视图加载第三方js模块

Redash有些功能原生不能很好的支持。在这种情况下我们我们可以在自定义视图中通过appendchild在innerHTML中加载第三方插件实现我们需要一些功能。 以下举例通过第三方js插件实现多层表头表格的导出

  1. 表格的生成
    • 通过table标签将我们需要的表头建立起来。
    • 使用python数据源处理我们的原始数据以符合我们表头。
    • 在视图的通用界面,将要展示的字段绑定到我们y轴上,方便我们在自定义视图中用ys对象调用。
    • 处理第一步生成的表格,将表格的数据通过遍历ys对象的方法加上td标签,并合并表头生成我们需要的表格视图。
  2. 引入第三方模块,并通过appendchild导入。
    • 在rowhtml中加入需要导入的script库。
    • 获取rowhtml中所有的script对象
    • 按顺序导入script对象。
  3. 使用第三方模块,对导出样式做一些处理。 以下是整体的使用代码,可以直接参考使用:
//通过 appendChild 把所有的 <script> 标签对象直接塞进页面以加载外部script
function runScript(script){
return new Promise((reslove, rejected) => {
const newScript = document.createElement('script');
newScript.innerHTML = script.innerHTML;
const src = script.getAttribute('src');
if (src) newScript.setAttribute('src', src);
newScript.onload = () => reslove();
newScript.onerror = err => rejected();
document.head.appendChild(newScript);
document.head.removeChild(newScript);
if (!src) {
reslove();
}
})
}

//获取html中所有的script标签的对象
function setHTMLWithScript(container, rawHTML){
container.innerHTML = rawHTML;
const scripts = container.querySelectorAll('script');
return Array.prototype.slice.apply(scripts).reduce((chain, script) => {
return chain.then(() => runScript(script));
}, Promise.resolve());
}

//设置导出的样式
function setHTMLAttribute(container,tagname,key,value){
const all_tagname_object=container.getElementsByTagName(tagname)
for (let tagname_object of all_tagname_object){
tagname_object.setAttribute(key, value);}

}

//组合表格所有的数据行
var table_rows="";
//for (var i=0;i<ys.id.length;i++)
//{
// table_rows=table_rows + '<tr><td>'+ys.id[i]+'</td><td>'+ys.name[i]+'</td><td>'+ys.url[i]+'</td><td>'+ys.alexa[i]+'</td><td>'+ys.country[i]+'</td></tr>';
//}

//需要加载的外部html,包含需要展现的表格和需要导入js模块
rawHTML=`
<script type="text/javascript" src="https://preview.dazdata.com/dazdatafiles/jscdn/tableToExcel.js"></script>
<script>
function exportTables () {
TableToExcel.convert(document.getElementById("table1"),{"name":"test1.xlsx"});
}
</script>
<button onclick="exportTables()">导出excel</button>
<style type="text/css">
.pure-table {
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
border: 1px solid #cbcbcb;
width: 100%
}
.pure-table caption {
color: #000;
font: italic 85%/1 arial,sans-serif;
padding: 1em 0;
text-align: center;
}
.pure-table td{
border-left: 1px solid #cbcbcb;
border-width: 0 0 0 1px;
font-size: inherit;
margin: 0;
overflow: visible;
padding: .5em 1em;
text-align: center;
}
.pure-table th{
border: 1px solid #cbcbcb;
border-width: 1 1 1 1px;
font-size: inherit;
margin: 0;
overflow: visible;
padding: .5em 1em;
text-align: center;
data-f-bold: true;
}
.pure-table tr {
background-color: transparent;
}
.pure-table tr:nth-child(2n+3) {
background-color: #f2f2f2;
}
.pure-table tr:nth-child(2),.pure-table tr:nth-child(1) {
background-color: #338FCC20;
}
</style>

<table class="pure-table" id="table1">
<tr>
<th rowspan="2" >id</th>
<th colspan="2" >infomation</th>
<th colspan="2" >rank</th>
</tr>
<tr>
<th >name</th>
<th >url</th>
<th >alexa</th>
<th >country</th>
</tr>`+ table_rows +`
</table>
`
//调用
setHTMLWithScript(element,rawHTML);

//设置导出的样式
setHTMLAttribute(element,'th','data-f-bold',true)
setHTMLAttribute(element,'th','data-a-h','center')
element.style.overflow="auto";