mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-04-05 05:52:43 +08:00
219 lines
11 KiB
PHP
219 lines
11 KiB
PHP
// +----------------------------------------------------------------------
|
||
// | Static Plugin for ThinkAdmin
|
||
// +----------------------------------------------------------------------
|
||
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
|
||
// +----------------------------------------------------------------------
|
||
// | 官方网站: https://thinkadmin.top
|
||
// +----------------------------------------------------------------------
|
||
// | 开源协议 ( https://mit-license.org )
|
||
// | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||
// +----------------------------------------------------------------------
|
||
// | gitee 代码仓库:https://gitee.com/zoujingli/think-plugs-static
|
||
// | github 代码仓库:https://github.com/zoujingli/think-plugs-static
|
||
// +----------------------------------------------------------------------
|
||
|
||
define(function () {
|
||
|
||
/*! 定义构造函数 */
|
||
function Excel(data, name) {
|
||
if (data && name) this.export(data, name);
|
||
}
|
||
|
||
/*! 默认导出配置 */
|
||
Excel.prototype.options = {writeOpt: {bookSST: false}};
|
||
|
||
/*! 导出 Excel 文件 */
|
||
Excel.prototype.export = function (data, name, options) {
|
||
name = name || '数据导出_' + layui.util.toDateString(Date.now(), '_yyyyMMdd_HHmmss');
|
||
if (name.substring(0, -5).toLowerCase() !== '.xlsx') name += '.xlsx';
|
||
layui.excel.exportExcel(data, name, 'xlsx', $.extend(options || {}, this.options));
|
||
};
|
||
|
||
/*! 绑定导出的事件 */
|
||
// <a data-form-export>通用导出</a>
|
||
// <a data-form-export="URL链接">指定链接导出</a>
|
||
// <!-- 自定义导出 Excel 文件 -->
|
||
// <a id="EXPORT1" data-excel="URL链接">自定义导出1</a>
|
||
// <a id="EXPORT2" data-excel="URL链接">自定义导出2</a>
|
||
// <script>
|
||
// Excel.bind(DONE1,FILENAME1,'#EXPORT1')
|
||
// Excel.bind(DONE2,FILENAME2,'#EXPORT2')
|
||
// </script>
|
||
Excel.prototype.bind = function (done, filename, selector, options) {
|
||
let that = this;
|
||
this.options = $.extend(this.options, options || {});
|
||
this.bindLoadDone(function (data, button) {
|
||
that.export(done.call(that, data, []), button.dataset.filename || filename);
|
||
}, selector);
|
||
};
|
||
|
||
/*! 加载所有数据 */
|
||
Excel.prototype.bindLoadDone = function (done, selector) {
|
||
let that = this;
|
||
$('body').off('click', selector || '[data-form-export]').on('click', selector || '[data-form-export]', function () {
|
||
let button = this, form = $(this).parents('form');
|
||
let method = this.dataset.method || form.attr('method') || 'get';
|
||
let location = this.dataset.excel || this.dataset.formExport || form.attr('action') || '';
|
||
let sortType = $(this).attr('data-sort-type') || '', sortField = $(this).attr('data-sort-field') || '';
|
||
if (sortField.length > 0 && sortType.length > 0) {
|
||
location += (location.indexOf('?') > -1 ? '&' : '?') + '_order_=' + sortType + '&_field_=' + sortField;
|
||
}
|
||
that.load(location, form.serialize(), method).then((data) => done.call(that, data, button)).fail(function (ret) {
|
||
$.msg.tips(ret || '数据加载失败');
|
||
});
|
||
});
|
||
}
|
||
|
||
/*! 加载导出的文档 */
|
||
Excel.prototype.load = function (url, data, method) {
|
||
return (function (defer, lists, loaded) {
|
||
loaded = $.msg.loading('正在加载 <span data-upload-count>0.00</span>%');
|
||
return (lists = []), LoadNextPage(1, 1), defer;
|
||
|
||
function LoadNextPage(curPage, maxPage, urlParams) {
|
||
let proc = (curPage / maxPage * 100).toFixed(2);
|
||
$('[data-upload-count]').html(proc > 100 ? '100.00' : proc);
|
||
if (curPage > maxPage) return $.msg.close(loaded), defer.resolve(lists);
|
||
urlParams = (url.indexOf('?') > -1 ? '&' : '?') + 'output=json¬_cache_limit=1&limit=100&page=' + curPage;
|
||
$.form.load(url + urlParams, data, method, function (ret) {
|
||
if (ret.code) {
|
||
lists = lists.concat(ret.data.list);
|
||
if (ret.data.page) LoadNextPage((ret.data.page.current || 1) + 1, ret.data.page.pages || 1);
|
||
} else {
|
||
defer.reject('数据加载异常');
|
||
}
|
||
return false;
|
||
}, false);
|
||
}
|
||
})($.Deferred());
|
||
};
|
||
|
||
/*! 设置表格导出样式 */
|
||
// this.withStyle(data, {A: 60, B: 80, C: 99, E: 120, G: 120}, 99, 28)
|
||
Excel.prototype.withStyle = function (data, colsWidth, defaultWidth, defaultHeight) {
|
||
// 自动计算列序
|
||
let idx, colN = 0, defaC = {}, lastCol;
|
||
for (idx in data[0]) defaC[lastCol = layui.excel.numToTitle(++colN)] = defaultWidth || 99;
|
||
defaC[lastCol] = 160;
|
||
|
||
// 设置表头样式
|
||
layui.excel.setExportCellStyle(data, 'A1:' + lastCol + '1', {
|
||
s: {
|
||
font: {sz: 12, bold: true, color: {rgb: "FFFFFF"}, name: '微软雅黑', shadow: true},
|
||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: '5FB878'}},
|
||
alignment: {vertical: 'center', horizontal: 'center'}
|
||
}
|
||
});
|
||
|
||
// 设置内容样式
|
||
(function (style1, style2) {
|
||
layui.excel.setExportCellStyle(data, 'A2:' + lastCol + data.length, {s: style1}, function (rawCell, newCell, row, config, curRow) {
|
||
typeof rawCell !== 'object' && (rawCell = {v: rawCell});
|
||
rawCell.s = Object.assign({}, style2, rawCell.s || {});
|
||
return (curRow % 2 === 0) ? newCell : rawCell;
|
||
});
|
||
})({
|
||
font: {sz: 10, shadow: true, name: '微软雅黑'},
|
||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "EAEAEA"}},
|
||
alignment: {vertical: 'center', horizontal: 'center'}
|
||
}, {
|
||
font: {sz: 10, shadow: true, name: '微软雅黑'},
|
||
fill: {bgColor: {indexed: 64}, fgColor: {rgb: "FFFFFF"}},
|
||
alignment: {vertical: 'center', horizontal: 'center'}
|
||
});
|
||
|
||
// 设置表格行宽高,需要设置最后的行或列宽高,否则部分不生效 ???
|
||
let rowsC = {1: 33}, colsC = Object.assign({}, defaC, {A: 60}, colsWidth || {});
|
||
rowsC[data.length] = defaultHeight || 28, this.options.extend = Object.assign({}, {
|
||
'!cols': layui.excel.makeColConfig(colsC, defaultWidth || 99),
|
||
'!rows': layui.excel.makeRowConfig(rowsC, defaultHeight || 28),
|
||
}, this.options.extend || {});
|
||
return data;
|
||
}
|
||
|
||
/*! 直接推送表格内容 */
|
||
// url: 记录推送地址
|
||
// sheet: 表格 Sheet 名称
|
||
// cols: { _: 1, 表头名1: 字段名1, 表头名2: 字段名2 },其中字段 _ 配置起始行
|
||
// filter: 数据过滤处理,如果返回 false 不上传记录
|
||
// Excel.push(ACTION, '用户信息', {_:1, username: "用户名称", phone: "联系手机"})
|
||
Excel.prototype.push = function (url, sheet, cols, filter) {
|
||
let loaded, $input;
|
||
$input = $('<input class="layui-hide" type="file" accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">');
|
||
$input.appendTo($('body')).click().on('change', function (event) {
|
||
if (!event.target.files || event.target.files.length < 1) return $.msg.tips('没有可操作文件');
|
||
loaded = $.msg.loading('<span data-load-name>读取</span> <span data-load-count>0.00%</span>');
|
||
try {
|
||
// 导入Excel数据,并逐行上传处理
|
||
layui.excel.importExcel(event.target.files, {}, function (data) {
|
||
if (!data[0][sheet]) return $.msg.tips('未读取到表[' + sheet + ']的数据');
|
||
let _cols = {}, _data = data[0][sheet], items = [], row, col, key, item;
|
||
for (row in _data) if (parseInt(row) + 1 === parseInt(cols._ || '1')) {
|
||
for (col in _data[row]) for (key in cols) if (_data[row][col] === cols[key]) _cols[key] = col;
|
||
} else if (parseInt(row) + 1 > cols._ || 1) {
|
||
item = {};
|
||
for (key in _cols) item[key] = CellToValue(_data[row][_cols[key]]);
|
||
items.push(item);
|
||
}
|
||
PushQueue(items, items.length, 0, 0, 1);
|
||
});
|
||
} catch (e) {
|
||
$.msg.error('读取 Excel 文件失败!')
|
||
}
|
||
});
|
||
|
||
/*! 单项推送数据 */
|
||
function PushQueue(items, total, ers, oks, idx) {
|
||
if ((total = items.length) < 1) return CleanAll(), $.msg.tips('未读取到有效数据');
|
||
return (ers = 0, oks = 0, idx = 0), $('[data-load-name]').html('更新'), DoPostItem(idx, items[idx]);
|
||
|
||
/*! 执行导入的数据 */
|
||
function DoPostItem(idx, item, data) {
|
||
if (idx >= total) {
|
||
return CleanAll(), $.msg.success('共处理' + total + '条记录( 成功 ' + oks + ' 条, 失败 ' + ers + ' 条 )', 3, function () {
|
||
$.form.reload();
|
||
});
|
||
} else {
|
||
let proc = (idx * 100 / total).toFixed(2);
|
||
$('[data-load-count]').html((proc > 100 ? '100.00' : proc) + '%( 成功 ' + oks + ' 条, 失败 ' + ers + ' 条 )');
|
||
/*! 单元数据过滤 */
|
||
data = item;
|
||
if (filter && (data = filter(item)) === false) {
|
||
return (ers++), DoPostItem(idx + 1, items[idx + 1]);
|
||
}
|
||
/*! 提交单个数据 */
|
||
DoUpdate(url, data).then(function (ret) {
|
||
(ret.code ? oks++ : ers++), DoPostItem(idx + 1, items[idx + 1]);
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
/*! 清理文件选择器 */
|
||
function CleanAll() {
|
||
$input.remove();
|
||
if (loaded) $.msg.close(loaded);
|
||
}
|
||
|
||
/*! 表格单元内容转换 */
|
||
function CellToValue(v) {
|
||
if (typeof v !== 'undefined' && /^\d+\.\d{12}$/.test(v)) {
|
||
return LAY_EXCEL.dateCodeFormat(v, 'YYYY-MM-DD HH:ii:ss');
|
||
} else {
|
||
return typeof v !== 'undefined' ? v : '';
|
||
}
|
||
}
|
||
|
||
/*! 队列方式上传数据 */
|
||
function DoUpdate(url, item) {
|
||
return (function (defer) {
|
||
return $.form.load(url, item, 'post', function (ret) {
|
||
return defer.resolve(ret), false;
|
||
}, false), defer.promise();
|
||
})($.Deferred());
|
||
}
|
||
}
|
||
|
||
/*! 返回对象实例 */
|
||
return new Excel;
|
||
}); |