流程
1.先说下大体流程,本文只实现了简单的导出效果,不涉及业务,对于本文中有错误和其他问题,请指出留言给我,谢谢!
表格形式
1.表格可以为静态页或动态加载而成,本文中用的是easyuiDatagrid生成的表格,导出过程用到了一些bootstrap的东西
**需要注意: datagrid或其他方法生成表格页面后,表格的内部结构会发生变化,以页面编译后的数据结构为准 **
可以看到生成后的表格和正常表格结构大相径庭,其中包含一些我们不需要的结构,在后面选择输出内容时要注意
5.导出界面代码 应用了easyui中的组件和data-table:
选择导出格式
Save as CSV
Save as TXT
Save as SQL
Save as JSON
Save as XML
Export to Excel
Export to Word
6.需要导入的包和脚本,另外还有主要涉及的3个js页下面会说,稍后我会挂到附件,需要可以下载
导出
主要涉及的三个js页分别是main.js,table-export.js,tableExport.js 首先是main.js,基本不用改什么Down下来根据需要自己看下就可以用了, 然后是table-export.js,里面是一些监听和逻辑,下面说 最后是tableExport.js,里面是具体的一些实现
1.以下拿导出excel举例,其他格式大体相同,只有写入相应格式时不一样 table-export.js中绑定的监听事件:
- 调用tableExport:
$(exportTable).tableExport({
type: 'excel',
escape: 'false',
ignoreColumn: '['+ignoreColumn+']'
});
2.其中的tableExport在tableExport.js里面,tableExport.js里面东西比较多,我只说能实现功能的部分
-
绑定的tableExport一些属性,重点是下面那两个selector,其他根据需要,可以不修改:
var defaults = { consoleLog: false, csvEnclosure: '"', csvSeparator: ',', csvUseBOM: true, displayTableName: false, escape: false, excelstyles: ['border-bottom', 'border-top', 'border-left', 'border-right'], fileName: 'tableExport', htmlContent: false, ignoreColumn: [], ignoreRow: [], jspdf: { orientation: 'p', unit: 'pt', format: 'a4', margins: { left: 20, right: 10, top: 10, bottom: 10 }, autotable: { padding: 2, lineHeight: 12, fontSize: 8, tableExport: { onAfterAutotable: null, onBeforeAutotable: null, onTable: null } } }, numbers: { html: { decimalMark: '.', thousandsSeparator: ',' }, output: { decimalMark: '.', thousandsSeparator: ',' } }, onCellData: null, outputMode: 'file', // file|string|base64 tbodySelector: 'tr', //用来后面选择导出表主体 theadSelector: 'tr', //同理这个用来导出表头 tableName: 'myTableName', //table名 type: 'csv', worksheetName: '项目统计' //sheetName };
还有些其他的属性可以Down下来自己看下
4.上面三步中介绍了监听和默认属性,接下来我们看下和excel匹配的方法: 下面贴出的是完整方法,可以不看直接往下翻,从判断类型开始看
else if (defaults.type == 'excel' || defaults.type == 'doc') {
rowIndex = 0;
var excelData = "";
// Header excel
$(".datagrid-htable tbody").last().find(defaults.theadSelector).each(function () {
trData = "";
ForEachVisibleCell(this, 'td', rowIndex,function (cell, row, col) {
if (cell != null) {
if (parseString(cell, row, col)!="") {
trData += "" + parseString(cell, row, col) + " ";
}
}
}
});
if (trData.length > 0)
excelData += "" + trData + ' ';
rowIndex++;
});
// Row Vs Column excel
$(".datagrid-btable tbody").last().find(defaults.tbodySelector).each(function () {
trData = "";
ForEachVisibleCell(this, 'td', rowIndex,function (cell, row, col) {
if (cell != null) {
if (parseString(cell, row, col)!="") {
trData += "" + parseString(cell, row, col) + " ";
}
}
});
if (trData.length > 0)
excelData += "" + trData + ' ';
rowIndex++;
});
if (defaults.displayTableName)
excelData += "" + parseString($('' + defaults.tableName + '
')) + " ";
excelData += '
';
if (defaults.consoleLog === true)
console.log(excelData);
var excelFile = "";
excelFile += '';
excelFile += '';
excelFile += "";
if (defaults.type === 'excel') {
excelFile += "";
}
excelFile += "";
excelFile += "";
excelFile += excelData;
excelFile += "";
excelFile += "";
if (defaults.outputMode == 'string')
return excelFile;
var base64data = base64encode(excelFile);
if (defaults.outputMode === 'base64')
return base64data;
var extension = (defaults.type === 'excel') ? 'xls' : 'doc';
try {
var blob = new Blob([excelFile], { type: 'application/vnd.ms-' + defaults.type });
saveAs(blob, defaults.fileName + '.' + extension);
}
catch (e) {
downloadFile(defaults.fileName + '.' + extension, 'data:application/vnd.ms-' + defaults.type + ';base64,' + base64data);
}
}
判断类型:
} else if (defaults.type == 'excel' || defaults.type == 'doc') {
5.选择要到导出的范围和数据,注意导出的数据格式
上图中选中的蓝色部分,从$一直到each之前,通过选择器选择要到处的数据,看下数据的格式:
正确选择想要导出的东西,不然表格的内容会出现一些你看起来莫名其妙的问题, 选择时可以参照我最上面的表格结构来对比看 很多时候表格都是后生成的,我们写选择器的时候要按照生成之后的结构来确定
6.拿到数据后.each来循环写入每行内容:
- 其中的foreach用来写单元格边框,用的时候可以debugger看下,是一段html,因为excel文件用记事本打开其实也是一段html:
for (var styles in defaults.excelstyles) {
if (defaults.excelstyles.hasOwnProperty(styles)) {
trData += defaults.excelstyles[styles] + ": " + $(cell).css(defaults.excelstyles[styles]) + ";";
}
}
- 其中parseString(cell, row, col)方法返回的是你要写入表格单元格中的数据:
if (parseString(cell, row, col) != "") {
trData += "'>" + parseString(cell, row, col) + "";
}
-
判断不是空,就把它写在excel中的单元格里,是空则不写,但单元格还是存在,所以如果想要去掉空的单元格,上面写单元格边框时先判断是否有内容
-
下面是parseString方法,可以看下,也可以吧tableExport.jsDown下来,里面有:
function parseString(cell, rowIndex, colIndex) {
var result = '';
if (cell != null) {
var $cell = $(cell);
//在定义Export时默认给了false
if (defaults.htmlContent === true) {
result = $cell.html().trim();
}
else {
//拿到每个td中的值
result = $cell.text().trim().replace(/\u00AD/g, ""); // remove soft hyphens 删除软连接
//decimalMark为'.' thousandsSeparator为','
if (defaults.numbers.html.decimalMark != defaults.numbers.output.decimalMark ||
defaults.numbers.html.thousandsSeparator != defaults.numbers.output.thousandsSeparator) {
var number = parseNumber(result);
if (number !== false) {
var frac = ("" + number).split('.');
if (frac.length == 1)
frac[1] = "";
var mod = frac[0].length > 3 ? frac[0].length % 3 : 0;
result = (number < 0 ? "-" : "") +
(defaults.numbers.output.thousandsSeparator ? ((mod ? frac[0].substr(0, mod) + defaults.numbers.output.thousandsSeparator : "") + frac[0].substr(mod).replace(/(\d{3})(?=\d)/g, "$1" + defaults.numbers.output.thousandsSeparator)) : frac[0]) +
(frac[1].length ? defaults.numbers.output.decimalMark + frac[1] : "");
}
}
}
if (defaults.escape === true) {
result = escape(result);
}
if (typeof defaults.onCellData === 'function') {
result = defaults.onCellData($cell, rowIndex, colIndex, result);
}
}
return result;
}
7.each后还会有一些结尾标签的写入,默认不用更改即可 例如:
if (defaults.type === 'excel') {
excelFile += "";
}
excelFile += "";
excelFile += "";
excelFile += excelData;
excelFile += "";
excelFile += "