<?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;
    }
}


点赞(1)

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部