当前位置:首页>Excel>Excel批量插图工具源码[python]

Excel批量插图工具源码[python]

  • 2026-04-07 12:40:15
Excel批量插图工具源码[python]

 主要功能

1. 两种匹配模式

列匹配模式:
  • 按垂直方向匹配(列对列)
  • 适合单列数据匹配场景
  • 参数:待匹配列、插入列、边距、图片文件夹
行匹配模式:
  • 按水平方向匹配(行对行)
  • 适合单行数据匹配场景
  • 参数:待匹配行、插入行、边距、图片文件夹

 2. 工作原理

  • 扫描指定的图片文件夹,提取文件名
  • 在Excel中查找与图片文件名匹配的单元格内容
  • 将匹配的图片插入到指定位置
  • 支持多种图片格式(jpg/png/webp/bmp)
    """Excel批量插图-匹配表格内容需要库:pip install xlwings PyQt6"""import osimport reimport webbrowserfrom typing import Dictimport xlwings as xwfrom PyQt6.QtWidgets import (    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,     QLabel, QPushButton, QLineEdit, QTabWidget, QTextEdit,     QFileDialog, QMessageBox, QCheckBox)from PyQt6.QtGui import QFont, QColorfrom PyQt6.QtCore import Qtclass ExcelImageMatcherPro(QMainWindow):    def __init__(self):        super().__init__()        self.setWindowTitle("Excel批量插图-匹配表格内容")        self.resize(600700)        self.col_image_map: Dict[strstr] = {}        self.row_image_map: Dict[strstr] = {}        # 创建主窗口        self.central_widget = QWidget()        self.setCentralWidget(self.central_widget)        # 主布局        self.main_layout = QVBoxLayout(self.central_widget)        self.main_layout.setContentsMargins(20202020)        self.main_layout.setSpacing(20)        # 创建标题栏        self.create_title_bar()        # 创建标签页        self.create_tab_widget()        # 创建状态栏        self.create_status_bar()        # 窗口居中        self.center_window()        # 显示帮助信息        self.show_help_guide()        # 设置窗口置顶        self.setWindowFlags(self.windowFlags() | Qt.WindowType.WindowStaysOnTopHint)    def create_title_bar(self):        """创建标题栏"""        title_frame = QWidget()        title_frame.setStyleSheet("""            QWidget {                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,                     stop:0 #4CAF50, stop:1 #45a049);                border-radius: 10px;            }        """)        title_layout = QVBoxLayout(title_frame)        title_layout.setContentsMargins(30203020)        title_label = QLabel("Excel批量插图-匹配表格内容")        title_label.setFont(QFont("Microsoft YaHei"14, QFont.Weight.Bold))        title_label.setStyleSheet("color: white;")        title_layout.addWidget(title_label)        self.main_layout.addWidget(title_frame)    def create_tab_widget(self):        """创建标签页"""        self.tab_widget = QTabWidget()        self.tab_widget.setStyleSheet("""            QTabWidget {                background: transparent;            }            QTabBar {                background: #f5f5f5;                border-radius: 8px;                margin-bottom: 10px;            }            QTabBar::tab {                background: white;                color: #666666;                padding: 12px 25px;                margin: 5px;                border-radius: 6px;                font: 10pt 'Microsoft YaHei';                font-weight: bold;            }            QTabBar::tab:selected {                background: #4CAF50;                color: white;            }            QTabBar::tab:hover:!selected {                background: #f0f0f0;            }        """)        # 创建列匹配标签页        self.create_column_tab()        # 创建行匹配标签页        self.create_row_tab()        self.main_layout.addWidget(self.tab_widget)    def create_column_tab(self):        """创建列匹配标签页"""        tab = QWidget()        self.tab_widget.addTab(tab, "列匹配模式")        tab_layout = QVBoxLayout(tab)        tab_layout.setContentsMargins(0000)        tab_layout.setSpacing(15)        # 描述        desc_label = QLabel("列匹配模式:按垂直方向匹配插入,适合单列数据匹配。")        desc_label.setStyleSheet("color: #666666; font: 9pt 'Microsoft YaHei';")        tab_layout.addWidget(desc_label)        # 参数卡片        param_card = QWidget()        param_card.setStyleSheet("""            QWidget {                background: white;                border-radius: 10px;                border: 1px solid #e0e0e0;            }        """)        param_layout = QVBoxLayout(param_card)        param_layout.setContentsMargins(20202020)        param_layout.setSpacing(15)        # 参数标题        param_title = QLabel("列匹配参数")        param_title.setFont(QFont("Microsoft YaHei"11, QFont.Weight.Bold))        param_title.setStyleSheet("color: #4CAF50;")        param_layout.addWidget(param_title)        # 参数输入        input_layout = QHBoxLayout()        input_layout.setSpacing(20)        # 待匹配列        match_col_layout = QVBoxLayout()        match_col_label = QLabel("待匹配列:")        match_col_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.col_match = QLineEdit()        self.col_match.setText("A")        self.col_match.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.col_match.setFixedWidth(80)        match_col_layout.addWidget(match_col_label)        match_col_layout.addWidget(self.col_match)        input_layout.addLayout(match_col_layout)        # 插入列        insert_col_layout = QVBoxLayout()        insert_col_label = QLabel("插入列:")        insert_col_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.col_insert = QLineEdit()        self.col_insert.setText("B")        self.col_insert.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.col_insert.setFixedWidth(80)        insert_col_layout.addWidget(insert_col_label)        insert_col_layout.addWidget(self.col_insert)        input_layout.addLayout(insert_col_layout)        # 边距        margin_layout = QVBoxLayout()        margin_label = QLabel("边距:")        margin_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.col_margin = QLineEdit()        self.col_margin.setText("2")        self.col_margin.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.col_margin.setFixedWidth(80)        margin_layout.addWidget(margin_label)        margin_layout.addWidget(self.col_margin)        input_layout.addLayout(margin_layout)        param_layout.addLayout(input_layout)        # 文件夹选择        folder_layout = QHBoxLayout()        folder_label = QLabel("图片文件夹:")        folder_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        folder_label.setFixedWidth(80)        self.col_folder_var = QLineEdit()        self.col_folder_var.setReadOnly(True)        self.col_folder_var.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;                color: #666666;            }        """)        browse_btn = QPushButton("浏览...")        browse_btn.setStyleSheet("""            QPushButton {                background: #4CAF50;                color: white;                padding: 8px 16px;                border: none;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';            }            QPushButton:hover {                background: #45a049;            }        """)        browse_btn.clicked.connect(lambdaself.select_folder("column"))        folder_layout.addWidget(folder_label)        folder_layout.addWidget(self.col_folder_var)        folder_layout.addWidget(browse_btn)        param_layout.addLayout(folder_layout)        tab_layout.addWidget(param_card)        # 执行按钮        execute_btn = QPushButton("执行列匹配插入")        execute_btn.setStyleSheet("""            QPushButton {                background: #4CAF50;                color: white;                padding: 12px;                border: none;                border-radius: 8px;                font: 10pt 'Microsoft YaHei';                font-weight: bold;            }            QPushButton:hover {                background: #45a049;            }        """)        execute_btn.clicked.connect(self.run_column_match)        tab_layout.addWidget(execute_btn)        # 日志卡片        log_card = QWidget()        log_card.setStyleSheet("""            QWidget {                background: white;                border-radius: 10px;                border: 1px solid #e0e0e0;            }        """)        log_layout = QVBoxLayout(log_card)        log_layout.setContentsMargins(20202020)        # 日志标题        log_title = QLabel("操作日志")        log_title.setFont(QFont("Microsoft YaHei"11, QFont.Weight.Bold))        log_title.setStyleSheet("color: #4CAF50;")        log_layout.addWidget(log_title)        # 日志文本框        self.col_log = QTextEdit()        self.col_log.setReadOnly(True)        self.col_log.setStyleSheet("""            QTextEdit {                background: #fafafa;                border: 1px solid #e0e0e0;                border-radius: 6px;                padding: 10px;                font: 9pt 'Microsoft YaHei';                color: #333333;            }        """)        self.col_log.setMinimumHeight(200)        log_layout.addWidget(self.col_log)        tab_layout.addWidget(log_card)    def create_row_tab(self):        """创建行匹配标签页"""        tab = QWidget()        self.tab_widget.addTab(tab, "行匹配模式")        tab_layout = QVBoxLayout(tab)        tab_layout.setContentsMargins(0000)        tab_layout.setSpacing(15)        # 描述        desc_label = QLabel("行匹配模式:按水平方向匹配插入,适合单行数据匹配。")        desc_label.setStyleSheet("color: #666666; font: 9pt 'Microsoft YaHei';")        tab_layout.addWidget(desc_label)        # 参数卡片        param_card = QWidget()        param_card.setStyleSheet("""            QWidget {                background: white;                border-radius: 10px;                border: 1px solid #e0e0e0;            }        """)        param_layout = QVBoxLayout(param_card)        param_layout.setContentsMargins(20202020)        param_layout.setSpacing(15)        # 参数标题        param_title = QLabel("行匹配参数")        param_title.setFont(QFont("Microsoft YaHei"11, QFont.Weight.Bold))        param_title.setStyleSheet("color: #4CAF50;")        param_layout.addWidget(param_title)        # 参数输入        input_layout = QHBoxLayout()        input_layout.setSpacing(20)        # 待匹配行        match_row_layout = QVBoxLayout()        match_row_label = QLabel("待匹配行:")        match_row_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.row_match = QLineEdit()        self.row_match.setText("1")        self.row_match.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.row_match.setFixedWidth(80)        match_row_layout.addWidget(match_row_label)        match_row_layout.addWidget(self.row_match)        input_layout.addLayout(match_row_layout)        # 插入行        insert_row_layout = QVBoxLayout()        insert_row_label = QLabel("插入行:")        insert_row_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.row_insert = QLineEdit()        self.row_insert.setText("2")        self.row_insert.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.row_insert.setFixedWidth(80)        insert_row_layout.addWidget(insert_row_label)        insert_row_layout.addWidget(self.row_insert)        input_layout.addLayout(insert_row_layout)        # 边距        margin_layout = QVBoxLayout()        margin_label = QLabel("边距:")        margin_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        self.row_margin = QLineEdit()        self.row_margin.setText("2")        self.row_margin.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;            }            QLineEdit:focus {                border: 1px solid #4CAF50;                background: white;            }        """)        self.row_margin.setFixedWidth(80)        margin_layout.addWidget(margin_label)        margin_layout.addWidget(self.row_margin)        input_layout.addLayout(margin_layout)        param_layout.addLayout(input_layout)        # 文件夹选择        folder_layout = QHBoxLayout()        folder_label = QLabel("图片文件夹:")        folder_label.setStyleSheet("color: #333333; font: 9pt 'Microsoft YaHei';")        folder_label.setFixedWidth(80)        self.row_folder_var = QLineEdit()        self.row_folder_var.setReadOnly(True)        self.row_folder_var.setStyleSheet("""            QLineEdit {                padding: 8px;                border: 1px solid #e0e0e0;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';                background: #fafafa;                color: #666666;            }        """)        browse_btn = QPushButton("浏览...")        browse_btn.setStyleSheet("""            QPushButton {                background: #4CAF50;                color: white;                padding: 8px 16px;                border: none;                border-radius: 6px;                font: 9pt 'Microsoft YaHei';            }            QPushButton:hover {                background: #45a049;            }        """)        browse_btn.clicked.connect(lambdaself.select_folder("row"))        folder_layout.addWidget(folder_label)        folder_layout.addWidget(self.row_folder_var)        folder_layout.addWidget(browse_btn)        param_layout.addLayout(folder_layout)        tab_layout.addWidget(param_card)        # 执行按钮        execute_btn = QPushButton("执行行匹配插入")        execute_btn.setStyleSheet("""            QPushButton {                background: #4CAF50;                color: white;                padding: 12px;                border: none;                border-radius: 8px;                font: 10pt 'Microsoft YaHei';                font-weight: bold;            }            QPushButton:hover {                background: #45a049;            }        """)        execute_btn.clicked.connect(self.run_row_match)        tab_layout.addWidget(execute_btn)        # 日志卡片        log_card = QWidget()        log_card.setStyleSheet("""            QWidget {                background: white;                border-radius: 10px;                border: 1px solid #e0e0e0;            }        """)        log_layout = QVBoxLayout(log_card)        log_layout.setContentsMargins(20202020)        # 日志标题        log_title = QLabel("操作日志")        log_title.setFont(QFont("Microsoft YaHei"11, QFont.Weight.Bold))        log_title.setStyleSheet("color: #4CAF50;")        log_layout.addWidget(log_title)        # 日志文本框        self.row_log = QTextEdit()        self.row_log.setReadOnly(True)        self.row_log.setStyleSheet("""            QTextEdit {                background: #fafafa;                border: 1px solid #e0e0e0;                border-radius: 6px;                padding: 10px;                font: 9pt 'Microsoft YaHei';                color: #333333;            }        """)        self.row_log.setMinimumHeight(200)        log_layout.addWidget(self.row_log)        tab_layout.addWidget(log_card)    def create_status_bar(self):        """创建状态栏"""        status_frame = QWidget()        status_layout = QHBoxLayout(status_frame)        status_layout.setContentsMargins(0000)        status_layout.setSpacing(20)        # 左侧按钮        left_layout = QHBoxLayout()        left_layout.setSpacing(15)        # 窗口置顶        self.topmost_check = QCheckBox("窗口置顶")        self.topmost_check.setChecked(True)        self.topmost_check.setStyleSheet("""            QCheckBox {                color: #666666;                font: 9pt 'Microsoft YaHei';            }        """)        self.topmost_check.stateChanged.connect(self.toggle_topmost)        left_layout.addWidget(self.topmost_check)        # 帮助按钮        help_btn = QPushButton("帮助")        help_btn.setStyleSheet("""            QPushButton {                background: #f0f0f0;                color: #666666;                padding: 6px 12px;                border: none;                border-radius: 4px;                font: 9pt 'Microsoft YaHei';            }            QPushButton:hover {                background: #e0e0e0;            }        """)        help_btn.clicked.connect(self.show_help_guide)        left_layout.addWidget(help_btn)        # 右侧作者信息        author_label = QLabel("By Savetime2022")        author_label.setStyleSheet("""            QLabel {                color: #999999;                font: 9pt 'Microsoft YaHei';            }            QLabel:hover {                color: #4CAF50;            }        """)        author_label.setCursor(Qt.CursorShape.PointingHandCursor)        status_layout.addLayout(left_layout)        status_layout.addStretch()        status_layout.addWidget(author_label)        self.main_layout.addWidget(status_frame)    def toggle_topmost(self, state):        """切换窗口置顶状态"""        if state == 2:  # Qt.Checked            self.setWindowFlags(self.windowFlags() | Qt.WindowType.WindowStaysOnTopHint)        else:            self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowStaysOnTopHint)        self.show()    def center_window(self):        """窗口居中"""        screen = QApplication.primaryScreen().geometry()        size = self.geometry()        self.move(            (screen.width() - size.width()) // 2,            (screen.height() - size.height()) // 2        )    def show_help_guide(self):        """显示帮助信息"""        help_text = """【新手操作指南】    1. 准备工作:        - 打开Excel文件        - 准备图片文件夹(支持jpg/png/webp/bmp格式)    2. 参数设置:        - 匹配列/行:包含名称的列或行(如A列或1行)        - 插入列/行:图片要插入的位置(如B列或2行)        - 边距:图片与单元格边界的距离(推荐2,0表示撑满)    3. 执行步骤:        (1) 选择图片文件夹        (2) 点击"执行匹配插入"按钮    ★ 注意事项:        - 图片名称需与单元格内容完全一致(不区分大小写)        - 示例:单元格"产品A" → 图片"产品A.jpg"        - 插入过程中请不要操作Excel        """        current_tab = self.tab_widget.currentIndex()        if current_tab == 0:            self.col_log.setPlainText(help_text)        else:            self.row_log.setPlainText(help_text)    def select_folder(self, mode):        """选择图片文件夹"""        folder_path = QFileDialog.getExistingDirectory(            self"选择图片文件夹""."        )        if folder_path:            if mode == "column":                self.col_folder_var.setText(folder_path)                log_widget = self.col_log                self.col_image_map = self.build_image_map_from_folder(folder_path)            else:                self.row_folder_var.setText(folder_path)                log_widget = self.row_log                self.row_image_map = self.build_image_map_from_folder(folder_path)            self.log_message("开始加载图片...", log_widget)            image_count = len(self.col_image_map if mode == "column" else self.row_image_map)            self.log_message(f"加载完成:找到 {image_count} 张支持的图片。", log_widget)            self.preview_insert_positions(mode)    def build_image_map_from_folder(self, folder_path: str) -> Dict[strstr]:        """构建图片名称到路径的映射"""        image_map: Dict[strstr] = {}        extensions = ('.jpg''.jpeg''.png''.bmp''.webp')        try:            for root, _, files in os.walk(folder_path):                for file in files:                    if file.lower().endswith(extensions):                        name_without_ext = os.path.splitext(                            file)[0].strip().lower()                        image_map[name_without_ext] = os.path.abspath(                            os.path.join(root, file))        except Exception as e:            self.log_message(f"构建图片映射出错: {e}"self.col_log)        return image_map    def validate_column_params(self) -> Dict:        """验证列模式参数有效性"""        params = {            'match_col'self.col_match.text().upper(),            'insert_col'self.col_insert.text().upper(),            'margin'self.col_margin.text()        }        if not re.match(r'^[A-Z]{1,3}$', params['match_col']):            raise ValueError("匹配列格式错误 (例如: A, B, AA)")        if not re.match(r'^[A-Z]{1,3}$', params['insert_col']):            raise ValueError("插入列格式错误 (例如: A, B, AA)")        if not params['margin'].isdigit() or int(params['margin']) < 0:            raise ValueError("边距必须是非负数字")        return {            'match_col': params['match_col'],            'insert_col': params['insert_col'],            'start_row'2,            'margin'int(params['margin'])        }    def validate_row_params(self) -> Dict:        """验证行模式参数有效性"""        params = {            'match_row'self.row_match.text(),            'insert_row'self.row_insert.text(),            'margin'self.row_margin.text()        }        if not params['match_row'].isdigit() or int(params['match_row']) < 1:            raise ValueError("匹配行必须是大于0的数字")        if not params['insert_row'].isdigit() or int(params['insert_row']) < 1:            raise ValueError("插入行必须是大于0的数字")        if not params['margin'].isdigit() or int(params['margin']) < 0:            raise ValueError("边距必须是非负数字")        return {            'match_row'int(params['match_row']),            'insert_row'int(params['insert_row']),            'margin'int(params['margin'])        }    def excel_operation(self, app):        """Excel操作上下文管理器"""        class ExcelOperation:            def __init__(self, app):                self.app = app                self.wb = None                self.ws = None            def __enter__(self):                try:                    self.wb = self.app.books.active                    if not self.wb:                        raise Exception("没有活动的Excel工作簿。")                    self.ws = self.wb.sheets.active                    if not self.ws:                        raise Exception("活动工作簿中没有活动的工作表。")                    return self.wb, self.ws                except Exception as e:                    raise Exception(f"无法访问活动工作簿或工作表: {str(e)}")            def __exit__(self, exc_type, exc_val, exc_tb):                pass        return ExcelOperation(app)    def insert_image(self, ws, image_path, cell_addr, margin, log_widget):        """插入图片到指定单元格"""        try:            # 确保使用绝对路径            abs_image_path = os.path.abspath(image_path)            if not os.path.exists(abs_image_path):                self.log_message(f"错误: 图片文件不存在 - {abs_image_path}", log_widget)                return False            # 获取目标单元格            target_cell = ws.range(cell_addr)            # 计算插入位置和大小            left = target_cell.left + margin            top = target_cell.top + margin            width = target_cell.width - 2 * margin            height = target_cell.height - 2 * margin            # 插入图片            ws.pictures.add(abs_image_path,                            left=left,                            top=top,                            width=width,                            height=height)            return True        except Exception as e:            error_msg = f"插入图片失败: {str(e)}"            self.log_message(error_msg, log_widget)            return False    def run_column_match(self):        """执行列匹配插入"""        self.log_message("开始列匹配处理..."self.col_log, clear=True)        try:            if not self.col_folder_var.text():                QMessageBox.warning(self"提示""请先选择图片文件夹!")                self.log_message("错误: 未选择图片文件夹。"self.col_log)                return            params = self.validate_column_params()            app = xw.apps.active or xw.App(visible=True)            with self.excel_operation(app) as (wb, ws):                max_row = ws.used_range.last_cell.row                success_inserts = 0                processed_excel_rows = 0                self.log_message(                    f"将在列 {params['match_col']} 中查找名称,图片插入到列 {params['insert_col']},从行 {params['start_row']} 开始。",                    self.col_log                )                for row_num_excel in range(params['start_row'], max_row + 1):                    processed_excel_rows += 1                    match_cell_addr = f"{params['match_col']}{row_num_excel}"                    cell_value = ws.range(match_cell_addr).value                    name_to_match = str(cell_value).strip(                    ) if cell_value is not None else ""                    if not name_to_match:                        continue                    insert_cell_addr = f"{params['insert_col']}{row_num_excel}"                    lower_name_to_match = name_to_match.lower()                    if lower_name_to_match in self.col_image_map:                        image_file_path = os.path.abspath(                            self.col_image_map[lower_name_to_match])                        if not os.path.exists(image_file_path):                            self.log_message(                                f"错误: 图片文件不存在 - {image_file_path}",                                self.col_log                            )                            continue                        if self.insert_image(ws, image_file_path, insert_cell_addr, params['margin'], self.col_log):                            success_inserts += 1                            self.log_message(                                f"{match_cell_addr}{name_to_match} → {insert_cell_addr}{os.path.basename(image_file_path)}",                                self.col_log                            )                    else:                        self.log_message(                            f"{match_cell_addr}{name_to_match} → 未找到匹配图片",                            self.col_log                        )                summary = f"\n共处理 {processed_excel_rows} 行数据,成功插入 {success_inserts} 张图片。"                self.log_message(summary, self.col_log)        except Exception as e:            error_msg = f"列匹配错误: {str(e)}"            self.log_message(error_msg, self.col_log)            QMessageBox.critical(self"错误", error_msg)    def run_row_match(self):        """执行行匹配插入"""        self.log_message("开始行匹配处理..."self.row_log, clear=True)        try:            if not self.row_folder_var.text():                QMessageBox.warning(self"提示""请先选择图片文件夹!")                self.log_message("错误: 未选择图片文件夹。"self.row_log)                return            params = self.validate_row_params()            app = xw.apps.active or xw.App(visible=True)            with self.excel_operation(app) as (wb, ws):                max_col = ws.used_range.last_cell.column                success_inserts = 0                processed_excel_cols = 0                self.log_message(                    f"将在行 {params['match_row']} 中查找名称,图片插入到行 {params['insert_row']}。",                    self.row_log                )                for col_num_excel in range(1, max_col + 1):                    processed_excel_cols += 1                    match_cell_addr = f"{xw.utils.col_name(col_num_excel)}{params['match_row']}"                    cell_value = ws.range(match_cell_addr).value                    name_to_match = str(cell_value).strip(                    ) if cell_value is not None else ""                    if not name_to_match:                        continue                    insert_cell_addr = f"{xw.utils.col_name(col_num_excel)}{params['insert_row']}"                    lower_name_to_match = name_to_match.lower()                    if lower_name_to_match in self.row_image_map:                        image_file_path = os.path.abspath(                            self.row_image_map[lower_name_to_match])                        if not os.path.exists(image_file_path):                            self.log_message(                                f"错误: 图片文件不存在 - {image_file_path}",                                self.row_log                            )                            continue                        if self.insert_image(ws, image_file_path, insert_cell_addr, params['margin'], self.row_log):                            success_inserts += 1                            self.log_message(                                f"{match_cell_addr}{name_to_match} → {insert_cell_addr}{os.path.basename(image_file_path)}",                                self.row_log                            )                    else:                        self.log_message(                            f"{match_cell_addr}{name_to_match} → 未找到匹配图片",                            self.row_log                        )                summary = f"\n共处理 {processed_excel_cols} 列数据,成功插入 {success_inserts} 张图片。"                self.log_message(summary, self.row_log)        except Exception as e:            error_msg = f"行匹配错误: {str(e)}"            self.log_message(error_msg, self.row_log)            QMessageBox.critical(self"错误", error_msg)    def preview_insert_positions(self, mode):        """预览插入位置"""        image_map = self.col_image_map if mode == "column" else self.row_image_map        log_widget = self.col_log if mode == "column" else self.row_log        if not image_map:            self.log_message("没有图片可供预览。请先选择图片文件夹。", log_widget)            return        self.log_message("【插入位置预览】", log_widget)        for name, path in image_map.items():            self.log_message(                f"{name} -> {os.path.basename(path)}", log_widget            )    def log_message(self, message, log_widget, clear=False):        """记录日志消息"""        if clear:            log_widget.setPlainText(message + "\n")        else:            current_text = log_widget.toPlainText()            log_widget.setPlainText(current_text + message + "\n")        log_widget.verticalScrollBar().setValue(log_widget.verticalScrollBar().maximum())if __name__ == "__main__":    import sys    app = QApplication(sys.argv)    app.setStyle("Fusion")    window = ExcelImageMatcherPro()    window.show()    sys.exit(app.exec())

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-09 05:20:28 HTTP/2.0 GET : https://h.sjds.net/a/478845.html
  2. 运行时间 : 0.246380s [ 吞吐率:4.06req/s ] 内存消耗:4,604.70kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=d0e2454ce15cb3ede32deb47a69cba3b
  1. /yingpanguazai/ssd/ssd1/www/h.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/h.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/h.sjds.net/runtime/temp/ad153693ed39fba6d1bda2fe72512cde.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001182s ] mysql:host=127.0.0.1;port=3306;dbname=h_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001985s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000738s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.002211s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001365s ]
  6. SELECT * FROM `set` [ RunTime:0.000663s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001612s ]
  8. SELECT * FROM `article` WHERE `id` = 478845 LIMIT 1 [ RunTime:0.002037s ]
  9. UPDATE `article` SET `lasttime` = 1775683229 WHERE `id` = 478845 [ RunTime:0.010419s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000679s ]
  11. SELECT * FROM `article` WHERE `id` < 478845 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001241s ]
  12. SELECT * FROM `article` WHERE `id` > 478845 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001117s ]
  13. SELECT * FROM `article` WHERE `id` < 478845 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002193s ]
  14. SELECT * FROM `article` WHERE `id` < 478845 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.012666s ]
  15. SELECT * FROM `article` WHERE `id` < 478845 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.024799s ]
0.250314s