chore: 添加支持导入Excel的依赖
This commit is contained in:
@@ -350,6 +350,100 @@ class Project extends Base {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导入Excel文件
|
||||
* @return json
|
||||
*/
|
||||
public function import_excel()
|
||||
{
|
||||
if (IS_POST) {
|
||||
$file = request()->file('excel_file');
|
||||
if (!$file) {
|
||||
$this->error('请选择要导入的文件');
|
||||
}
|
||||
|
||||
// 验证文件类型
|
||||
$ext = strtolower(pathinfo($file->getInfo('name'), PATHINFO_EXTENSION));
|
||||
if (!in_array($ext, ['xls', 'xlsx'])) {
|
||||
$this->error('只支持Excel格式文件(.xls, .xlsx)');
|
||||
}
|
||||
|
||||
// 移动文件到临时目录
|
||||
$info = $file->move(ROOT_PATH . 'data' . DS . 'runtime', '');
|
||||
if (!$info) {
|
||||
$this->error('文件上传失败: ' . $file->getError());
|
||||
}
|
||||
|
||||
$filename = ROOT_PATH . 'data' . DS . 'runtime' . DS . $info->getSaveName();
|
||||
|
||||
// 解析Excel文件
|
||||
$data = [];
|
||||
try {
|
||||
// 引入PHPExcel库
|
||||
vendor('phpoffice.phpexcel.Classes.PHPExcel');
|
||||
|
||||
// 判断文件类型
|
||||
if ($ext == 'xls') {
|
||||
$objReader = \PHPExcel_IOFactory::createReader('Excel5');
|
||||
} else {
|
||||
$objReader = \PHPExcel_IOFactory::createReader('Excel2007');
|
||||
}
|
||||
|
||||
$objPHPExcel = $objReader->load($filename);
|
||||
$sheet = $objPHPExcel->getSheet(0);
|
||||
$highestRow = $sheet->getHighestRow();
|
||||
$highestColumn = $sheet->getHighestColumn();
|
||||
|
||||
// 跳过第一行标题
|
||||
for ($row = 2; $row <= $highestRow; $row++) {
|
||||
// 获取一行数据
|
||||
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE)[0];
|
||||
|
||||
// 确保行数据完整
|
||||
if (count($rowData) >= 6) {
|
||||
// 验证必要字段不为空
|
||||
if (empty(trim($rowData[0])) || empty(trim($rowData[1]))) {
|
||||
continue; // 跳过必填字段为空的行
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
'name' => trim($rowData[0]),
|
||||
'pwd' => trim($rowData[1]),
|
||||
'enterprise' => trim($rowData[2]),
|
||||
'filing' => trim($rowData[3]),
|
||||
'sid' => trim($rowData[4]),
|
||||
'limitationdate' => trim($rowData[5]),
|
||||
'createtime' => getTime()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 删除临时文件
|
||||
unlink($filename);
|
||||
|
||||
// 批量插入数据
|
||||
if (!empty($data)) {
|
||||
$result = Db::name('project')->insertAll($data);
|
||||
if ($result) {
|
||||
$this->success('成功导入 ' . count($data) . ' 条记录');
|
||||
} else {
|
||||
$this->error('导入失败');
|
||||
}
|
||||
} else {
|
||||
$this->error('文件中没有有效数据');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// 删除临时文件
|
||||
if (file_exists($filename)) {
|
||||
unlink($filename);
|
||||
}
|
||||
$this->error('文件解析失败: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$this->error('非法请求');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试
|
||||
* @return string
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="member-nav-group">
|
||||
{eq name="'Project@users_index'|is_check_access" value="1"}
|
||||
<label class="member-nav-item">
|
||||
<input type="button" class="btn {if condition="!in_array($Request.action, ['users_index','users_add','users_edit'])"}current{else/}selected{/if}" value="应用登记管理" onclick="window.location.href='{:url("Project/users_index")}';">
|
||||
<input type="button" class="btn {if condition="!in_array($Request.action, ['users_index','users_add','users_edit'])"}current{else/}selected{/if}" value="应用管理" onclick="window.location.href='{:url("Project/users_index")}';">
|
||||
</label>
|
||||
{/eq}
|
||||
{eq name="'Project@level_index'|is_check_access" value="1"}
|
||||
@@ -42,6 +42,13 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="fbutton">
|
||||
<a href="javascript:void(0);" onclick="importExcel();">
|
||||
<div class="add">
|
||||
<span><i class="fa fa-upload"></i>导入Excel</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hDiv">
|
||||
@@ -170,6 +177,155 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 删除
|
||||
function usersdel(obj){
|
||||
var admin_id = $(obj).data('admin_id');
|
||||
if (0 < admin_id) {
|
||||
var title = "系统管理员前台ID,删除不可恢复?";
|
||||
} else {
|
||||
var title = "此操作不可恢复,确认彻底删除?";
|
||||
}
|
||||
layer.confirm(title, {
|
||||
title: false,//$(obj).attr('data-username'),
|
||||
btn: ['确定','取消'] //按钮
|
||||
}, function(){
|
||||
layer_loading('正在处理');
|
||||
// 确定
|
||||
$.ajax({
|
||||
type : 'post',
|
||||
url : $(obj).attr('data-url'),
|
||||
data : {del_id:$(obj).attr('data-id'), _ajax:1},
|
||||
dataType : 'json',
|
||||
success : function(data){
|
||||
layer.closeAll();
|
||||
if(data.code == 1){
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
window.location.reload();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2, title:false});
|
||||
}
|
||||
}
|
||||
})
|
||||
}, function(index){
|
||||
layer.close(index);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 批量删除提交
|
||||
function batch_del(obj, name) {
|
||||
var a = [];
|
||||
$('input[name^='+name+']').each(function(i,o){
|
||||
if($(o).is(':checked')){
|
||||
a.push($(o).val());
|
||||
}
|
||||
})
|
||||
if(a.length == 0){
|
||||
layer.alert('请至少选择一项', {icon: 2, title:false});
|
||||
return;
|
||||
}
|
||||
// 删除按钮
|
||||
layer.confirm('此操作不可恢复,确认批量彻底删除?', {
|
||||
title: false,
|
||||
btn: ['确定', '取消'] //按钮
|
||||
}, function () {
|
||||
layer_loading('正在处理');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: $(obj).attr('data-url'),
|
||||
data: {del_id:a, _ajax:1},
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
layer.closeAll();
|
||||
if(data.code == 1){
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
window.location.reload();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2, title:false});
|
||||
}
|
||||
},
|
||||
error:function(){
|
||||
layer.closeAll();
|
||||
layer.alert(ey_unknown_error, {icon: 2, title:false});
|
||||
}
|
||||
});
|
||||
}, function (index) {
|
||||
layer.closeAll(index);
|
||||
});
|
||||
}
|
||||
|
||||
// 导入Excel
|
||||
function importExcel() {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '导入Excel数据',
|
||||
area: ['500px', '300px'],
|
||||
content: '<div style="padding: 20px;">' +
|
||||
'<form id="importForm" enctype="multipart/form-data">' +
|
||||
'<div class="layui-form-item">' +
|
||||
'<label class="layui-form-label">选择文件:</label>' +
|
||||
'<div class="layui-input-block">' +
|
||||
'<input type="file" name="excel_file" accept=".xls,.xlsx" class="layui-input" style="height: 38px;" required>' +
|
||||
'<div class="layui-form-mid layui-word-aux">只支持Excel文件(.xls, .xlsx)</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="layui-form-item" style="margin-top: 20px;">' +
|
||||
'<div class="layui-input-block">' +
|
||||
'<button type="button" class="layui-btn" onclick="submitImport()">上传并导入</button>' +
|
||||
'<button type="button" class="layui-btn layui-btn-primary" onclick="layer.closeAll()">取消</button>' +
|
||||
'<a href="../../../data/project_template.xlsx" style="margin-left: 10px;" download="project_template.xlsx">下载模板</a>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</form>' +
|
||||
'<div style="margin-top: 20px; color: #999; font-size: 12px;">' +
|
||||
'<p><strong>Excel文件格式要求:</strong></p>' +
|
||||
'<p>1. 第一行为列标题(会被自动忽略)</p>' +
|
||||
'<p>2. 列顺序必须为:名称、密码、个人/企业、备案号、证件号码、有效期</p>' +
|
||||
'<p>3. 名称和密码为必填项</p>' +
|
||||
'<p>4. 支持.xls和.xlsx格式</p>' +
|
||||
'<p>5. 日期格式:YYYY-MM-DD</p>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
success: function(layero, index) {
|
||||
// 初始化layui表单
|
||||
layui.use('form', function(){
|
||||
var form = layui.form;
|
||||
form.render();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
function submitImport() {
|
||||
var formData = new FormData($('#importForm')[0]);
|
||||
|
||||
layer_loading('正在导入数据...');
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("Project/import_excel")}',
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
layer.closeAll();
|
||||
if(res.code == 1) {
|
||||
layer.msg(res.msg, {icon: 1}, function(){
|
||||
window.location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.alert(res.msg, {icon: 2, title: false});
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
layer.closeAll();
|
||||
layer.alert('导入失败,请重试', {icon: 2, title: false});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function(){
|
||||
$('input[name*=ids]').click(function(){
|
||||
if ($('input[name*=ids]').length == $('input[name*=ids]:checked').length) {
|
||||
@@ -182,6 +338,7 @@
|
||||
$('input[type=checkbox]').prop('checked',this.checked);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
// 表格行点击选中切换
|
||||
$('#flexigrid > table>tbody >tr').click(function(){
|
||||
@@ -223,88 +380,9 @@
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 删除
|
||||
function usersdel(obj){
|
||||
var admin_id = $(obj).data('admin_id');
|
||||
if (0 < admin_id) {
|
||||
var title = "系统管理员前台ID,删除不可恢复?";
|
||||
} else {
|
||||
var title = "此操作不可恢复,确认彻底删除?";
|
||||
}
|
||||
layer.confirm(title, {
|
||||
title: false,//$(obj).attr('data-username'),
|
||||
btn: ['确定','取消'] //按钮
|
||||
}, function(){
|
||||
layer_loading('正在处理');
|
||||
// 确定
|
||||
$.ajax({
|
||||
type : 'post',
|
||||
url : $(obj).attr('data-url'),
|
||||
data : {del_id:$(obj).attr('data-id'), _ajax:1},
|
||||
dataType : 'json',
|
||||
success : function(data){
|
||||
layer.closeAll();
|
||||
if(data.code == 1){
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
window.location.reload();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2, title:false});
|
||||
}
|
||||
}
|
||||
})
|
||||
}, function(index){
|
||||
layer.close(index);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除提交
|
||||
*/
|
||||
function batch_del(obj, name) {
|
||||
var a = [];
|
||||
$('input[name^='+name+']').each(function(i,o){
|
||||
if($(o).is(':checked')){
|
||||
a.push($(o).val());
|
||||
}
|
||||
})
|
||||
if(a.length == 0){
|
||||
layer.alert('请至少选择一项', {icon: 2, title:false});
|
||||
return;
|
||||
}
|
||||
// 删除按钮
|
||||
layer.confirm('此操作不可恢复,确认批量彻底删除?', {
|
||||
title: false,
|
||||
btn: ['确定', '取消'] //按钮
|
||||
}, function () {
|
||||
layer_loading('正在处理');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: $(obj).attr('data-url'),
|
||||
data: {del_id:a, _ajax:1},
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
layer.closeAll();
|
||||
if(data.code == 1){
|
||||
layer.msg(data.msg, {icon: 1});
|
||||
window.location.reload();
|
||||
}else{
|
||||
layer.alert(data.msg, {icon: 2, title:false});
|
||||
}
|
||||
},
|
||||
error:function(){
|
||||
layer.closeAll();
|
||||
layer.alert(ey_unknown_error, {icon: 2, title:false});
|
||||
}
|
||||
});
|
||||
}, function (index) {
|
||||
layer.closeAll(index);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
{include file="public/footer" /}
|
||||
Reference in New Issue
Block a user