<?php
/*
1、在需要的index模板里加入
···········································
<div class="btn-group">
<button type="button"class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-upload"></i> 导入 <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="javascript:;" class=" btn-import " title="导入" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false">导入Excel文件</a></li>
<li><a href="{:url('import/index', ['table' => 'user_dizhi(无fa_前缀的表名)'])}" download="">下载导入模板</a></li>
<!-- download可以自定义文件名 -->
</ul>
</div>
··········································
2、application\admin\library\traits\Backend.php 的 protected function import() 改成 public function import()
3、application\extra\upload.php 添加扩展名 ,xls,xlsx
4、保存至application\admin\controller\Import.php
此插件可免费商用或二开,但请勿修改作者、版权信息、广告以及此注释
作者:q6591163
网址:blog.dj5.cn
广告:个人承接各种网站开发、小程序。价格实惠,售后超好!欢迎建站公司业务外包和传统公司的技术外包。
*/
namespace app\admin\controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as WriterXlsx;
use app\common\controller\Backend;
use think\Db;
use think\Exception;
/**
* 表模板生成器
*
* @icon fa fa-table
* @internal
*/
class Import extends Backend
{
/**
* 全局配置 - 隐藏字段
*/
protected $globalHiddenFields = [
'id', 'deletetime', 'createtime', 'updatetime'
];
/**
* 全局配置 - 字段示例数据
*/
protected $globalFieldExamples = [
# 'title' => '示例标题',
# 'name' => '示例名称',
# 'content' => '示例内容',
# 'description' => '示例描述',
# 'keywords' => '关键词1,关键词2',
# 'author' => '作者名',
# 'source' => '来源',
# 'views' => '100',
# 'image' => '/assets/img/example.jpg',
# 'images' => '/assets/img/1.jpg,/assets/img/2.jpg',
# 'url' => 'https://example.com',
# 'email' => 'example@domain.com',
# 'phone' => '13800138000',
# 'price' => '99.99',
# 'amount' => '10',
# 'sort' => '1',
# 'flag' => '1,2,3'
];
/**
* 表个性化配置
*/
protected $tableConfigs = [
'user_dizhi' => [
// 'hidden_fields' => ['id', 'deletetime', 'createtime'],
'field_examples' => [
'switch' => '1为默认 0为非默认'
]
],
// 可以继续添加其他表的配置
];
public function _initialize()
{
parent::_initialize();
}
/**
* 生成表模板
* @param string $table 表名(不含前缀)
*/
public function index($table = '')
{
if (empty($table)) {
$this->error('请指定表名');
}
try {
// 获取带前缀的表名
$fullTableName = $this->getFullTableName($table);
// 检查表是否存在
if (!$this->tableExists($fullTableName)) {
$this->error("表 {$fullTableName} 不存在");
}
// 获取表注释
$tableComment = $this->getTableComment($fullTableName);
// 获取表字段信息
$fields = $this->getTableFields($fullTableName);
// 应用配置过滤
$fields = $this->applyConfig($fields, $table);
// 生成Excel模板
$this->generateTemplate($fields, $table, $tableComment);
} catch (Exception $e) {
$this->error('生成模板失败: ' . $e->getMessage());
}
}
/**
* 获取带前缀的完整表名
*/
protected function getFullTableName($table)
{
$prefix = config('database.prefix');
return $prefix . $table;
}
/**
* 检查表是否存在
*/
protected function tableExists($table)
{
$result = Db::query("SHOW TABLES LIKE '{$table}'");
return !empty($result);
}
/**
* 获取表字段信息
*/
protected function getTableFields($table)
{
$database = config('database.database');
$sql = "SELECT COLUMN_NAME, COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = '{$database}'
AND TABLE_NAME = '{$table}'
ORDER BY ORDINAL_POSITION";
$fields = Db::query($sql);
$result = [];
foreach ($fields as $field) {
$result[] = [
'name' => $field['COLUMN_NAME'],
'comment' => $field['COLUMN_COMMENT'] ?: $field['COLUMN_NAME'],
'example' => $this->getFieldExample($field['COLUMN_NAME'], $table)
];
}
return $result;
}
/**
* 获取字段示例数据
*/
protected function getFieldExample($fieldName, $table)
{
// 从完整表名中提取无前缀的表名
$prefix = config('database.prefix');
$tableWithoutPrefix = str_replace($prefix, '', $table);
// 优先使用表个性化配置(使用无前缀的表名)
if (isset($this->tableConfigs[$tableWithoutPrefix]['field_examples'][$fieldName])) {
return $this->tableConfigs[$tableWithoutPrefix]['field_examples'][$fieldName];
}
// 使用全局配置
if (isset($this->globalFieldExamples[$fieldName])) {
return $this->globalFieldExamples[$fieldName];
}
// 默认示例
return '';
}
/**
* 应用配置过滤字段
*/
protected function applyConfig($fields, $table)
{
$hiddenFields = $this->getHiddenFields($table);
return array_filter($fields, function($field) use ($hiddenFields) {
return !in_array($field['name'], $hiddenFields);
});
}
/**
* 获取需要隐藏的字段
*/
protected function getHiddenFields($table)
{
$hiddenFields = $this->globalHiddenFields;
// 合并表个性化隐藏字段(使用无前缀的表名)
if (isset($this->tableConfigs[$table]['hidden_fields'])) {
$hiddenFields = array_merge($hiddenFields, $this->tableConfigs[$table]['hidden_fields']);
}
return array_unique($hiddenFields);
}
/**
* 生成Excel模板
*/
protected function generateTemplate($fields, $table, $tableComment)
{
// 创建新的Spreadsheet对象
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 设置工作表标题
$sheet->setTitle('导入模板');
// 写入列标题(字段注释)
$columnIndex = 1;
foreach ($fields as $field) {
$sheet->setCellValueByColumnAndRow($columnIndex, 1, $field['comment']);
$columnIndex++;
}
// 写入示例数据
$columnIndex = 1;
foreach ($fields as $field) {
$sheet->setCellValueByColumnAndRow($columnIndex, 2, $field['example']);
$columnIndex++;
}
// 设置列宽自适应
$this->setColumnWidth($sheet, count($fields));
// 生成文件名:表注释 + 导入模板
$filename = $tableComment . '导入模板.xlsx';
// 如果表注释为空,使用表名
if (empty($tableComment) || $tableComment === $table) {
$filename = $table . '导入模板.xlsx';
}
// 设置HTTP头部
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
// 输出文件
$writer = new WriterXlsx($spreadsheet);
$writer->save('php://output');
exit;
}
/**
* 设置列宽
*/
protected function setColumnWidth($sheet, $fieldCount)
{
foreach (range('A', chr(64 + $fieldCount)) as $columnID) {
$sheet->getColumnDimension($columnID)->setAutoSize(true);
}
}
/**
* 获取可用的表列表(可选功能)
*/
public function tableList()
{
$database = config('database.database');
$prefix = config('database.prefix');
$tables = Db::query("SHOW TABLES LIKE '{$prefix}%'");
$tableList = [];
foreach ($tables as $table) {
$tableName = current($table);
$tableWithoutPrefix = str_replace($prefix, '', $tableName);
$tableComment = $this->getTableComment($tableName);
$tableList[] = [
'name' => $tableWithoutPrefix,
'full_name' => $tableName,
'comment' => $tableComment
];
}
$this->success('获取成功', null, $tableList);
}
/**
* 获取表注释
*/
protected function getTableComment($table)
{
$database = config('database.database');
$result = Db::query("SELECT TABLE_COMMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = '{$database}'
AND TABLE_NAME = '{$table}'");
return $result[0]['TABLE_COMMENT'] ?? $table;
}
}
发表评论 取消回复