【Python+PyQt】pdf页面尺寸统计工具步骤二:获取拖入目录的所有pdf文件完整路径,存入file_path这个list中⑵

文章介绍了如何在Python中定义一个递归函数get_files_recursion_from_dir,用于获取指定目录下的所有文件(包括子目录),并在dragEnterEvent方法中应用该函数处理拖放事件,显示包含子目录的文件列表。

定义遍历指定目录下全部文件列表的函数get_files_recursion_from_dir()

def get_files_recursion_from_dir(path):
    """
    从指定的文件夹中使用递归的方式,获取全部的文件列表
    :param path: 被判断的文件夹
    :return: list,包含全部的文件,如果目录不存在或者无文件就返回一个空list
    """
    file_list = []
    if os.path.exists(path):
        for f in os.listdir(path):
            new_path = path + "/" + f
            if os.path.isdir(new_path):
                # 进入到这里,表明这个路径是文件夹不是文件
                file_list += get_files_recursion_from_dir(new_path)
            else:
                name, suf = os.path.splitext(new_path)
                if suf == '.pdf':
                    file_list.append(new_path)
    else:
        print(f"指定的目录{path},不存在")
        return []

    return file_list

 窗口对象的dragEnterEvent(self, event)中完善如下代码。

    def dragEnterEvent(self, event):
        file_path = []
        for url in event.mimeData().urls():
            str_url = str(url.toLocalFile())
            if os.path.isdir(str_url):
                list_current_all_file = get_files_recursion_from_dir(str_url)  # 获取当前目录下所有文件列表,包括子目录
                file_path.extend(list_current_all_file)
            else:
                name, suf = os.path.splitext(str_url)
                if suf == '.pdf':
                    file_path.append(str_url)

        for f in file_path:
            self.list_filelist.addItem(f)  # 将list中每一项添加到列表控件中

拖入“未知尺寸”目录,显示出其中所有文件的列表(包含子目录)。

这里是临时用了一个list控件。

本小节笔记

获取拖拽文件或目录的路径

event.mimeData().urls()返回了一个list,里面包含了所有拖入窗口的目录和文件路径。存在形式:

[PyQt5.QtCore.QUrl('file:///D:/own/pdf尺寸统计工具相关/演示/未知尺寸'), PyQt5.QtCore.QUrl('file:///D:/own/pdf尺寸统计工具相关/演示/1.jpg'), PyQt5.QtCore.QUrl('file:///D:/own/pdf尺寸统计工具相关/演示/新建文本文档.txt')]

最初找到的资料中,event.mimeData().urls()[0]太有局限性了。只给了列表中的第一项。如果每次仅拖入一个文件或一个目录,可以用。它的类型是<class 'PyQt5.QtCore.QUrl'>,用.toLocalFile()得到路径字符串。

 list的append()方法和extend()方法

如果当前路径是目录,则需遍历其中子目录得到所有文件,形成一个list_current_all_file列表,列表是常见的可迭代对象之一。在列表尾部一次增加另一个序列的多个值(用新列表扩展原列表),用extend()方法。

file_path.extend(list_current_all_file)

如果当前路径是文件,则取得其后缀名,判断后缀是否是“.pdf”,是pdf文件就将其加入到file_path列表中。追加单个元素到list尾部,用append()

file_path.append(str_url)

os.listdir(path)

返回了当前目录path下所有的文件和目录的名称列表。通过

new_path = path + "/" + f

组合成完整的路径字符串。

import sys # 操作系统模块 from PyQt5.QtGui import QColor # 导入PyQt5的QtGui模块 from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QTableWidgetItem, QTableWidget, QMessageBox # 导入PyQt5的QtWidgets模块 import os # 导入操作系统模块 import tools.common as common # 导入工具模块并设置别名为common import tools.wordtopdf as wordtopdf import tools.mergepdf as mergepdf from mainWindow import * # 导入主窗体的UI类 from pageWindow import * # 导入Word转PDF窗体的UI类 from listWindow import * # 导入统计Word文档页码窗体的UI类 from transformWindow import * # 导入提取总页码窗体的UI类 import _thread # 主窗体初始化类 class MyMainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(MyMainWindow,self).__init__() self.setupUi(self) self.setGeometry(100, 100, 1024, 600) self.setWindowTitle('Word助手') # 设置窗体的标题 # 设置窗体背景 palette = QtGui.QPalette() # 创建调色板类的对象 # 设置窗体背景自适应 palette.setBrush(self.backgroundRole(),QBrush(QPixmap("./image/bg.png").scaled(self.size(),QtCore.Qt.IgnoreAspectRatio,QtCore.Qt.SmoothTransformation))) self.setPalette(palette) self.setAutoFillBackground(True) # 设置自动填充背景 self.setFixedSize(1024,600) # 禁止显示最大化按钮及调整窗体大小 '''Word转PDF模块''' class TransformWindow(QMainWindow, Ui_TransformWindow): filelist = [] def __init__(self): super(TransformWindow,self).__init__() self.setupUi(self) self.showLoding.setText("") # 设置显示转换进度标签不显示内容 self.showLoding.setMinimumWidth(100) # 设置Label标签的最小宽度 self.multipleExecute.clicked.connect( self.multipleExecuteClick) #批量转换按钮绑定槽函数 self.singleExecute.clicked.connect(self.singleExecuteClick) # 合为一个PDF按钮绑定槽函数 self.sourcebrowseButton.clicked.connect(self.sourcebrowseClick) # 选择源文件夹按钮绑定槽函数 self.targetbrowseButton.clicked.connect(self.targetbrowseClick) # 选择目标文件夹按钮绑定槽函数 self.listpdf.itemDoubleClicked.connect(self.itemdoubleClick) # 为列表项的双击事件绑定槽函数 # 自定义打开子窗体的方法 def open(self): self.__init__() self.show() # 显示子窗体 def sourcebrowseClick(self): # 单击浏览源文件夹按钮所触发的方法 # 打开选择文件夹的对话框 dir_path = QFileDialog.getExistingDirectory(self, "请选择源文件目录", r"E:\learn\test\doc") if dir_path == "": # 处理没有选择路径的情况,这里为直接返回 return self.sourcepath.setText(dir_path) # 将获取到的文件路径添加到文本框控件中 self.listword.clear() # 清空列表 global filelist # 定义全局变量 filelist = common.getfilenames(dir_path,[],'.doc') # 获取Word文档路径 self.listword.addItems(filelist) # 将获取到的Word文件路径添加到列表控件中 def targetbrowseClick(self): # 单击浏览目标文件夹按钮所触发的方法 dir_path = QFileDialog.getExistingDirectory(self, "请选择目标文件目录", r"E:\learn\test\pdf") self.targetpath.setText(dir_path) def itemdoubleClick(self,item): # 处理双击列表项触发的方法 if os.path.exists(item.text()): os.startfile(item.text()) # 打开文件 else: QMessageBox.information(self, "温馨提示:", "不是有效的文件名!", QMessageBox.Yes) def multipleExecuteClick(self): #批量转换按钮触发的方法 # 判断是否选择了源文件,如果没有选择则弹出提示框告知 if self.listword.count() == 0: QMessageBox.information(self, "温馨提示:", "没有要转换的Word文档!", QMessageBox.Yes) return targetpath = self.targetpath.text() # 获取目标文件夹 # 判断是否选择了目标文件,如果没有选择则弹出提示框告知 if not os.path.exists(targetpath): QMessageBox.information(self, "温馨提示:", "请选择正确的目标路径!", QMessageBox.Yes) return self.listpdf.clear() # 清空结果列表 self.showLoding.setMovie(self.gif) # 设置gif图片 self.gif.start() # 启动图片,实现等待gif图片的显示 _thread.start_new_thread(self.mExecute, ()) # 开启新线程执行批量转PDF # 实现批量Word转PDF操作的方法 def mExecute(self): targetpath = self.targetpath.text() # 获取目标文件夹 valueList = wordtopdf.wordtopdf(filelist,targetpath) # 实现将Word文档批量转换为PDF if(valueList != -1): self.showLoding.clear() # 清除进度条 self.listpdf.addItems(valueList) # 将转换后的PDF路径显示在目标列表中 # 合为一个PDF按钮所触发的方法 def singleExecuteClick(self): # 判断是否选择了源文件,如果没有选择则弹出提示框告知 if self.listword.count() == 0: QMessageBox.information(self, "温馨提示:", "没有要转换的Word文档!", QMessageBox.Yes) return # 判断是否选择了目标文件夹,如果没有选择则弹出提示框告知 if not os.path.exists(self.targetpath.text()): QMessageBox.information(self, "温馨提示:", "请选择正确的目标路径!", QMessageBox.Yes) return self.listpdf.clear() # 清空结果列表 self.showLoding.setMovie(self.gif) # 设置gif图片 self.gif.start() # 启动图片,实现等待gif图片的显示 _thread.start_new_thread(self.sExecute,()) # 开启新线程执行多个Word合为一个PDF # 实现合为一个PDF文件操作的方法 def sExecute(self): targetpath = self.targetpath.text() # 获取目标路径 valueList = wordtopdf.wordtopdf(filelist, targetpath) # 将多个Word文档转换为PDF文件 if(valueList != -1): mergepdf.mergefiles(targetpath, 'merged.pdf', True) # 将多个PDF文件合并为一个PDF文件 self.showLoding.clear() # 清除进度条 temp = [os.path.join(targetpath , 'merged.pdf')] # 组合PDF文件路径 self.listpdf.addItems( temp) # 将PDF文件路径显示到结果列表中 for file in valueList: # 遍历临时生成的PDF文件列表 os.remove(file) # 删除PDF文件 '''统计Word文档页码模块''' class PageWindow(QMainWindow, Ui_PageWindow): filelist = [] # Word文件路径列表 def __init__(self): super(PageWindow,self).__init__() self.setupUi(self) self.pagetable.setColumnWidth(0,600) # 设置第一列的宽度 self.pagetable.setColumnWidth(1,100) # 设置第列的宽度 self.pagetable.setStyleSheet("background-color: lightblue" "(spread:pad,stop:0.823 rgba(255, 255, 255, 204), stop:1 rgba(255, 255, 255, 204));" "selection-background-color:lightblue;") headItem = self.pagetable.horizontalHeaderItem(0) # 获得水平方向表头的Item对象 headItem.setBackground(QColor(0, 60, 10)) # 设置单元格背景颜色 headItem.setForeground(QColor(200, 111, 30)) # 设置文字颜色 headItem = self.pagetable.horizontalHeaderItem(1) # 获得水平方向表头的Item对象 headItem.setBackground(QColor(0, 60, 10)) # 设置单元格背景颜色 headItem.setForeground(QColor(200, 111, 30)) # 设置文字颜色 self.pagetable.setEditTriggers(QTableWidget.NoEditTriggers) self.pagetable.setSelectionBehavior(QTableWidget.SelectRows) self.pagetable.setSelectionMode(QTableWidget.SingleSelection) self.pagetable.setAlternatingRowColors(True) self.totalpage.setMinimumWidth(100) # 设置Label标签的最小宽度 self.browseButton.clicked.connect(self.sourcebrowseClick) # 选择源路径 self.executeButton.clicked.connect(self.executeClick) # 开始统计按钮的事件绑定 # 自定义打开子窗体的方法 def open(self): self.__init__() self.show() # 显示子窗体 def sourcebrowseClick(self): dir_path = QFileDialog.getExistingDirectory(self, "请选择源文件目录", r"E:\learn\test\doc") if dir_path != "": # 判断已经选择了源文件目录 self.sourcepath.setText(dir_path) self.listword.clear() # 清空列表 global filelist filelist = common.getfilenames(dir_path,[],'.doc') # 获取Word文档 self.listword.addItems(filelist) def executeClick(self): #开始统计按钮的自定义事件 if self.listword.count() == 0: QMessageBox.information(self, "温馨提示:", "没有要统计页码的Word文档!", QMessageBox.Yes) return self.totalpage.setText("") self.totalpage.setMovie(self.gif) # 设置gif图片 self.label_2.setText("正在统计:") self.gif.start() # 启动图片,实现等待gif图片的显示 _thread.start_new_thread(self.execute,()) # 开启新线程执行统计页码 # 统计页码 def execute(self): valueList = [] valueList = wordtopdf.wordtopdf1(filelist) # if valueList != []: # self.totalpage.clear() # 转换完毕就将等待gif图片清理掉 totalPages = str(valueList[0]) # 总页数 self.label_2.setText("合计页码:") self.totalpage.setText(totalPages) # 显示统计出来的页码 print("行数:",len(valueList[1])) self.pagetable.setRowCount(len(valueList[1])) # 指定行数 resultList = valueList[1] # 获取统计结果 for i in range(self.pagetable.rowCount()): for j in range(self.pagetable.columnCount()): content = resultList[i][j] # 获取一个单元格的内容 newItem = QTableWidgetItem(content) # 转换为一个单元格对象 self.pagetable.setItem(i, j, newItem) # 显示在单元格中 '''提取总目录模块''' class ListWindow(QMainWindow, Ui_ListWindow): def __init__(self): super(ListWindow,self).__init__() self.setupUi(self) self.browseButton.clicked.connect(self.sourcebrowseClick) # 选择源路径 self.executeButton.clicked.connect( self.getListClick) #按钮事件绑定 self.openButton.clicked.connect(self.openButtonClick) # 为打开文件按钮绑定事件 # 自定义打开子窗体的方法 def open(self): self.__init__() self.show() # 显示子窗体 def sourcebrowseClick(self): dir_path = QFileDialog.getExistingDirectory(self, "请选择源文件目录", r"E:\learn\test\doc") if dir_path != "": # 判断已经选择了源文件目录 self.sourcepath.setText(dir_path) self.listword.clear() # 清空列表 global filelist filelist = common.getfilenames(dir_path,[],'.doc') # 获取Word文档 self.listword.addItems(filelist) def getListClick(self): #子窗体自定义事件 if self.listword.count() == 0: QMessageBox.information(self, "温馨提示:", "没有要提取目录的Word文档!", QMessageBox.Yes) return self.listfile.setText("") self.listfile.setMovie(self.gif) # 设置gif图片 self.gif.start() # 启动图片,实现等待gif图片的显示 _thread.start_new_thread(self.getList,()) # 开启新线程执行统计页码 # 提取目录 def getList(self): sourcepath = self. sourcepath.text() # 获取路径 if not os.path.exists(sourcepath): # 判断是否选择了源目录 QMessageBox.information(self,"温馨提示:","请先选择Word文档所在的文件夹!",QMessageBox.Yes) return targetpath = os.path.join(sourcepath, "pdf") # 根据源路径生成目标目录 if not os.path.exists(targetpath): # 判断目录是否存在,不存在则创建 os.makedirs(targetpath) # 创建目录 valueList = wordtopdf.wordtopdf(filelist, targetpath) if(valueList != -1): mergepdf.mergefiles(targetpath, 'merged.pdf', True) # 合并PDF temp = [os.path.join(targetpath , 'merged.pdf')] # 生成合并后的PDF文件路径 for file in valueList: # 遍历临时生成的PDF文件列表 os.remove(file) # 删除PDF文件 isList = self.checkBox.isChecked() # 指定是否带目录 resultvalue=wordtopdf.getPdfOutlines(temp[0],targetpath,isList) # 提取目录 os.remove(temp[0]) # 删除合并后的PDF文件 if valueList != []: self.listfile.clear() # 转换完毕就将等待gif图片清理掉 self.listfile.setText(resultvalue) # 将生成的目录文件路径显示到页面中 # 自定义打开子窗体的方法 def open(self): self.__init__() self.show() # 显示子窗体 # 打开文件按钮触发的事件函数 def openButtonClick(self): if self.listfile.text() == "还未提取...": QMessageBox.information(self,"温馨提示:","还没有提取目录,请先单击【开始提取】按钮!",QMessageBox.Yes) else: os.startfile(self.listfile.text()) # 打开文件 if __name__ == '__main__': app = QApplication(sys.argv) # 创建GUI对象 main = MyMainWindow() # 创建主窗体ui类对象 qmovie = QtGui.QMovie('image/loding.gif') transformWindow = TransformWindow() # 创建Word转PDF窗体对象 transformWindow.gif = qmovie # 加载gif图片 main.actionWord_PDF.triggered.connect(transformWindow.open) #为Toolbar上的Word转PDF按钮指定连接槽函数 pagewindow = PageWindow() # 创建统计Word文档页码窗体对象 pagewindow.gif = qmovie # 加载gif图片 main.action_Word.triggered.connect(pagewindow.open) #为Toolbar上的统计Word文档页码按钮指定连接槽函数 listwindow = ListWindow() # 创建提取总目录窗体对象 listwindow.gif = qmovie # 加载gif图片 main.action_list.triggered.connect(listwindow.open) #为Toolbar上的提取总目录按钮指定连接槽函数 main.show() # 显示主窗体 sys.exit(app.exec_()) # 除非退出程序关闭窗体,否则一直运行 试运行
最新发布
10-15
import os import sys import threading from datetime import datetime # ============= PyQt6 Import =============== from PyQt6.QtCore import Qt, QTimer from PyQt6.QtGui import QPixmap, QBrush, QColor from PyQt6.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QLineEdit, QToolButton, QListWidget, QFileDialog, QMessageBox, QTableWidget, QTableWidgetItem, QCheckBox, QSpacerItem, QSizePolicy ) # 初始化 COM(用于调用 Word) import pythoncom from win32com.client import Dispatch, constants, gencache from PyPDF2 import PdfFileReader, PdfFileMerger # ==================== tools/common.py ==================== def getfilenames(filepath="", filelist_out=None, file_ext='all'): if filelist_out is None: filelist_out = [] try: for filename in os.listdir(filepath): fullpath = os.path.join(filepath, filename) if os.path.isdir(fullpath): getfilenames(fullpath, filelist_out, file_ext) else: _, ext = os.path.splitext(filename) if file_ext == '.doc': if ext.lower() in ['.doc', '.docx']: filelist_out.append(fullpath) elif file_ext == 'all' or ext == file_ext: filelist_out.append(fullpath) except Exception as e: print(f"遍历出错: {e}") # 排序:按“第X章”中的数字排序 filelist_out.sort(key=lambda x: extract_chapter_number(x)) return filelist_out def extract_chapter_number(path): import re match = re.search(r"第(\d+)章", os.path.basename(path)) return int(match.group(1)) if match else float('inf') # ==================== 核心功能模块 ==================== def word_to_pdf_batch(filelist, target_dir): """批量转换Word为PDF""" result = [] os.makedirs(target_dir, exist_ok=True) try: pythoncom.CoInitialize() gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4) word = Dispatch("Word.Application") word.Visible = False for path in filelist: base_name = os.path.splitext(os.path.basename(path))[0] pdf_path = os.path.join(target_dir, f"{base_name}.pdf") try: doc = word.Documents.Open(path, ReadOnly=1) doc.ExportAsFixedFormat( pdf_path, constants.wdExportFormatPDF, Item=constants.wdExportDocumentWithMarkup, CreateBookmarks=constants.wdExportCreateHeadingBookmarks ) doc.Close() result.append(pdf_path) except Exception as e: print(f"转换失败 {path}: {e}") word.Quit() except Exception as e: print("Word COM 初始化失败:", e) return -1 return result def get_pdf_page_count(pdf_path): """获取PDF页数""" try: with open(pdf_path, "rb") as f: reader = PdfFileReader(f) return reader.getNumPages() except Exception as e: print(f"读取页数失败: {e}") return 0 def merge_pdfs(pdf_list, output_path, add_bookmarks=True): """合并多个PDF""" merger = PdfFileMerger() for pdf in pdf_list: try: with open(pdf, 'rb') as f: reader = PdfFileReader(f) if reader.isEncrypted: continue short_name = os.path.splitext(os.path.basename(pdf))[0] merger.append(reader, bookmark=short_name if add_bookmarks else None) except Exception as e: print(f"跳过文件 {pdf}: {e}") merger.write(output_path) merger.close() def extract_outline_from_pdf(pdf_path, output_docx, include_page=True): """从PDF提取大纲写入Word""" try: pythoncom.CoInitialize() gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4) word_app = Dispatch("Word.Application") word_app.Visible = True doc = word_app.Documents.Add() with open(pdf_path, "rb") as f: reader = PdfFileReader(f) outlines = reader.getOutlines() items = [] def traverse(obj): if isinstance(obj, list): for item in obj: traverse(item) elif hasattr(obj, '/Title'): title = obj['/Title'] page_num = str(obj.get('/Page', 0) + 1) if include_page else "" line = f"{title}\t\t{page_num}" if include_page else title items.append(line + "\n") for item in outlines: traverse(item) for line in items: doc.Content.InsertAfter(line) doc.SaveAs(output_docx) doc.Close() word_app.Quit() return output_docx except Exception as e: print(f"提取目录失败: {e}") return None # ==================== 主窗体 ==================== class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Word助手") self.resize(600, 400) self.setMaximumSize(600, 400) layout = QVBoxLayout() # 背景提示 tip = QLabel("欢迎使用 Word助手\n\n" "本程序会自动调用 Microsoft Word\n" "请先保存并关闭所有打开的 Word 文档") tip.setAlignment(Qt.AlignmentFlag.AlignCenter) tip.setStyleSheet("font-size: 14px; color: #333;") layout.addWidget(tip) # 按钮区 btn_layout = QHBoxLayout() self.btn_transform = QPushButton("Word转PDF") self.btn_page = QPushButton("统计页码") self.btn_list = QPushButton("提取总目录") self.btn_transform.clicked.connect(self.open_transform) self.btn_page.clicked.connect(self.open_page) self.btn_list.clicked.connect(self.open_list) btn_layout.addWidget(self.btn_transform) btn_layout.addWidget(self.btn_page) btn_layout.addWidget(self.btn_list) layout.addLayout(btn_layout) self.setLayout(layout) def open_transform(self): self.tw = TransformWindow() self.tw.show() def open_page(self): self.pw = PageWindow() self.pw.show() def open_list(self): self.lw = ListWindow() self.lw.show() # ==================== 子窗体:Word转PDF ==================== class TransformWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.init_ui() def init_ui(self): self.setWindowTitle("Word转PDF") self.resize(800, 600) layout = QVBoxLayout() # 源目录 h1 = QHBoxLayout() h1.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h1.addWidget(self.src_edit) h1.addWidget(self.src_btn) layout.addLayout(h1) self.list_word = QListWidget() layout.addWidget(QLabel("待转换文件:")) layout.addWidget(self.list_word) # 目标目录 h2 = QHBoxLayout() h2.addWidget(QLabel("PDF保存目录:")) self.dst_edit = QLineEdit() self.dst_btn = QToolButton() self.dst_btn.setText("...") self.dst_btn.clicked.connect(self.browse_target) h2.addWidget(self.dst_edit) h2.addWidget(self.dst_btn) layout.addLayout(h2) # 操作按钮 op_layout = QHBoxLayout() op_layout.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.batch_btn = QPushButton("批量转换") self.merge_btn = QPushButton("合为一个PDF") self.batch_btn.clicked.connect(self.do_batch) self.merge_btn.clicked.connect(self.do_merge) op_layout.addWidget(self.batch_btn) op_layout.addWidget(self.merge_btn) layout.addLayout(op_layout) self.result_list = QListWidget() layout.addWidget(QLabel("转换结果:")) layout.addWidget(self.result_list) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def browse_target(self): dir_ = QFileDialog.getExistingDirectory(self, "选择PDF保存目录", "") if dir_: self.dst_edit.setText(dir_) def do_batch(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择任何Word文档!") return dst = self.dst_edit.text() if not dst or not os.path.exists(dst): QMessageBox.warning(self, "警告", "请选择有效的保存路径!") return def task(): results = word_to_pdf_batch(self.filelist, dst) self.result_list.clear() if results != -1: self.result_list.addItems(results) QMessageBox.information(self, "完成", f"成功生成 {len(results)} 个PDF文件。") else: QMessageBox.critical(self, "错误", "转换过程中发生COM错误。") threading.Thread(target=task, daemon=True).start() def do_merge(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择任何Word文档!") return dst = self.dst_edit.text() if not dst or not os.path.exists(dst): QMessageBox.warning(self, "警告", "请选择有效的保存路径!") return temp_dir = os.path.join(dst, "temp_pdfs") os.makedirs(temp_dir, exist_ok=True) def task(): pdfs = word_to_pdf_batch(self.filelist, temp_dir) if pdfs == -1: return merged = os.path.join(dst, "merged.pdf") merge_pdfs(pdfs, merged) # 清理临时文件 for p in pdfs: try: os.remove(p) except: pass self.result_list.clear() self.result_list.addItem(merged) QMessageBox.information(self, "完成", "已合并为 merged.pdf") threading.Thread(target=task, daemon=True).start() # ==================== 子窗体:统计页码 ==================== class PageWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.init_ui() def init_ui(self): self.setWindowTitle("统计Word文档页码") self.resize(700, 500) layout = QVBoxLayout() h = QHBoxLayout() h.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h.addWidget(self.src_edit) h.addWidget(self.src_btn) layout.addLayout(h) self.list_word = QListWidget() layout.addWidget(QLabel("文档列表:")) layout.addWidget(self.list_word) self.table = QTableWidget(0, 2) self.table.setHorizontalHeaderLabels(["文件名", "页码"]) self.table.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.table) foot = QHBoxLayout() foot.addWidget(QLabel("合计页码:")) self.total_label = QLabel("0") foot.addWidget(self.total_label) foot.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.exec_btn = QPushButton("开始统计") self.exec_btn.clicked.connect(self.start_count) foot.addWidget(self.exec_btn) layout.addLayout(foot) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def start_count(self): if not self.filelist: QMessageBox.warning(self, "警告", "没有可统计的文档!") return def task(): total = 0 result = [] temp_dir = os.path.join(os.path.dirname(self.filelist[0]), f"temp_{int(datetime.now().timestamp())}") os.makedirs(temp_dir, exist_ok=True) for fp in self.filelist: pdf_path = os.path.join(temp_dir, os.path.splitext(os.path.basename(fp))[0] + ".pdf") if word_to_pdf_batch([fp], temp_dir) and os.path.exists(pdf_path): pages = get_pdf_page_count(pdf_path) result.append((os.path.basename(fp), str(pages))) total += pages os.remove(pdf_path) try: os.rmdir(temp_dir) except: pass self.table.setRowCount(len(result)) for i, (name, p) in enumerate(result): self.table.setItem(i, 0, QTableWidgetItem(name)) self.table.setItem(i, 1, QTableWidgetItem(p)) self.total_label.setText(str(total)) QMessageBox.information(self, "完成", "页码统计完成!") threading.Thread(target=task, daemon=True).start() # ==================== 子窗体:提取目录 ==================== class ListWindow(QWidget): def __init__(self): super().__init__() self.filelist = [] self.generated_docx = "" self.init_ui() def init_ui(self): self.setWindowTitle("提取总目录") self.resize(700, 400) layout = QVBoxLayout() h = QHBoxLayout() h.addWidget(QLabel("Word文档所在目录:")) self.src_edit = QLineEdit() self.src_btn = QToolButton() self.src_btn.setText("...") self.src_btn.clicked.connect(self.browse_source) h.addWidget(self.src_edit) h.addWidget(self.src_btn) layout.addLayout(h) self.list_word = QListWidget() layout.addWidget(QLabel("文档列表:")) layout.addWidget(self.list_word) self.chk_page = QCheckBox("包含页码") self.chk_page.setChecked(True) layout.addWidget(self.chk_page) btn_h = QHBoxLayout() btn_h.addSpacerItem(QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) self.extract_btn = QPushButton("开始提取") self.open_btn = QPushButton("打开文件") self.extract_btn.clicked.connect(self.extract) self.open_btn.clicked.connect(self.open_file) btn_h.addWidget(self.extract_btn) btn_h.addWidget(self.open_btn) layout.addLayout(btn_h) self.result_label = QLabel("还未提取...") layout.addWidget(QLabel("目录文件保存位置:")) layout.addWidget(self.result_label) self.setLayout(layout) def browse_source(self): dir_ = QFileDialog.getExistingDirectory(self, "选择Word文档目录", "") if dir_: self.src_edit.setText(dir_) self.filelist = getfilenames(dir_, [], '.doc') self.list_word.clear() self.list_word.addItems([os.path.basename(f) for f in self.filelist]) def extract(self): if not self.filelist: QMessageBox.warning(self, "警告", "未选择文档!") return src = self.src_edit.text() temp_pdf_dir = os.path.join(src, "temp_merge") os.makedirs(temp_pdf_dir, exist_ok=True) def task(): # Step 1: 转为PDF pdfs = word_to_pdf_batch(self.filelist, temp_pdf_dir) if not pdfs: return # Step 2: 合并 merged_pdf = os.path.join(temp_pdf_dir, "merged.pdf") merge_pdfs(pdfs, merged_pdf) # Step 3: 提取大纲 output_docx = os.path.join(src, f"总目录_{datetime.now().strftime('%H%M%S')}.docx") success = extract_outline_from_pdf(merged_pdf, output_docx, self.chk_page.isChecked()) # 清理 for p in pdfs: try: os.remove(p) except: pass try: os.remove(merged_pdf) os.rmdir(temp_pdf_dir) except: pass if success: self.generated_docx = success self.result_label.setText(success) QMessageBox.information(self, "完成", "目录已提取!") threading.Thread(target=task, daemon=True).start() def open_file(self): if not self.generated_docx or not os.path.exists(self.generated_docx): QMessageBox.warning(self, "警告", "尚未生成目录文件!") return os.startfile(self.generated_docx) # ==================== 主程序入口 ==================== if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) 合成一个PDF失败
10-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月春生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值