chore: 添加支持导入Excel的依赖

This commit is contained in:
2025-12-17 17:33:24 +08:00
parent 7e0ca0a8e7
commit c7e186a1a9
1035 changed files with 283359 additions and 201 deletions

View File

@@ -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

View File

@@ -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" /}