Python-pdf工具自制(合并、拆分、刪除)

pdf工具,之前寫的合并工具有點麻煩,使用PyQt5庫重寫合并拆分和刪除指定頁面的程序

實現如圖:

代碼:

import sysimport osfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QFileDialog, QListWidget, QMessageBox, QLineEdit, QHBoxLayout, QInputDialogfrom PyQt5.QtCore import Qt, QThread, pyqtSignalfrom PyPDF2 import PdfReader, PdfWriter, PdfMergerfrom PyQt5 import QtGuiclass CustomListWidget(QListWidget):def __init__(self, parent=None):super().__init__(parent)class Worker(QThread):finished = pyqtSignal(str)error = pyqtSignal(str)def __init__(self, pdf_files, range_str=None, save_path=None, operation=None):super().__init__()self.pdf_files = pdf_filesself.range_str = range_strself.save_path = save_pathself.operation = operationdef run(self):try:if self.operation == 'merge':merger = PdfMerger()for pdf in self.pdf_files:merger.append(pdf)merger.write(self.save_path)merger.close()self.finished.emit('PDF文件已成功合并。')elif self.operation == 'split':start_page, end_page = self.parse_range(self.range_str)reader = PdfReader(self.pdf_files[zxsq-anti-bbcode-0])os.makedirs(self.save_path, exist_ok=True)for page in range(start_page, end_page + 1):writer = PdfWriter()writer.add_page(reader.pages)split_save_path = os.path.join(self.save_path, f'Page_{page + 1}.pdf')writer.write(split_save_path)self.finished.emit('PDF文件已成功拆分并保存。')elif self.operation == 'delete':start_page, end_page = self.parse_range(self.range_str)reader = PdfReader(self.pdf_files[zxsq-anti-bbcode-0])writer = PdfWriter()for page_num in range(len(reader.pages)):if not (start_page <= page_num <= end_page):writer.add_page(reader.pages[zxsq-anti-bbcode-page_num])writer.write(self.save_path)self.finished.emit('指定頁面已從PDF中刪除。')except Exception as e:self.error.emit(str(e))def parse_range(self, range_str):if '-' in range_str:start_page, end_page = map(int, range_str.split('-'))else:start_page = end_page = int(range_str)return start_page - 1, end_page - 1  # Convert to 0-based indexclass PDFMergerApp(QMainWindow):def __init__(self):super().__init__()self.initUI()self.pdf_files = []def initUI(self):self.setWindowTitle('PDF 工具箱')self.setWindowIcon(QtGui.QIcon('111.ico'))self.setGeometry(100, 100, 800, 600)mainLayout = QVBoxLayout()self.addButton = QPushButton('添加 PDF', self)self.addButton.clicked.connect(self.addPDF)mainLayout.addWidget(self.addButton)self.listWidget = CustomListWidget(self)mainLayout.addWidget(self.listWidget)# 刪除按鈕的水平布局deleteLayout = QHBoxLayout()self.removeButton = QPushButton('刪除選定', self)self.removeButton.clicked.connect(self.removeSelected)deleteLayout.addWidget(self.removeButton)self.removeAllButton = QPushButton('刪除全部', self)self.removeAllButton.clicked.connect(self.removeAll)deleteLayout.addWidget(self.removeAllButton)mainLayout.addLayout(deleteLayout)self.mergeButton = QPushButton('合并 PDFs', self)self.mergeButton.clicked.connect(self.mergePDFs)mainLayout.addWidget(self.mergeButton)# 拆分和刪除頁碼的水平布局splitDeleteLayout = QHBoxLayout()self.splitInput = QLineEdit(self)self.splitInput.setPlaceholderText('輸入拆分范圍,如 1 或 1-4')splitDeleteLayout.addWidget(self.splitInput)self.splitButton = QPushButton('拆分 PDF', self)self.splitButton.clicked.connect(self.splitPDF)splitDeleteLayout.addWidget(self.splitButton)self.deleteInput = QLineEdit(self)self.deleteInput.setPlaceholderText('輸入刪除頁碼,如 1 或 1-4')splitDeleteLayout.addWidget(self.deleteInput)self.deleteButton = QPushButton('刪除頁面', self)self.deleteButton.clicked.connect(self.deletePages)splitDeleteLayout.addWidget(self.deleteButton)mainLayout.addLayout(splitDeleteLayout)container = QWidget()container.setLayout(mainLayout)self.setCentralWidget(container)def addPDF(self):files, _ = QFileDialog.getOpenFileNames(self, '打開文件', '', 'PDF files (*.pdf)')for file_path in files:self.addPDFFile(file_path)def addPDFFile(self, file_path):if file_path and file_path not in self.pdf_files:self.pdf_files.append(file_path)self.listWidget.addItem(file_path)def removeSelected(self):for item in self.listWidget.selectedItems():self.pdf_files.remove(item.text())self.listWidget.takeItem(self.listWidget.row(item))def removeAll(self):self.pdf_files.clear()self.listWidget.clear()def mergePDFs(self):save_path, _ = QFileDialog.getSaveFileName(self, '保存文件', '', 'PDF files (*.pdf)')if save_path:self.thread = Worker(self.pdf_files, save_path=save_path, operation='merge')self.thread.finished.connect(self.onFinished)self.thread.error.connect(self.onError)self.thread.start()def splitPDF(self):if len(self.pdf_files) != 1:QMessageBox.warning(self, "錯誤", "請只選擇一個PDF文件進行拆分。")returnrange_str = self.splitInput.text().strip()folder_path = self.getFolderName()if range_str and folder_path:self.thread = Worker(self.pdf_files, range_str=range_str, save_path=folder_path, operation='split')self.thread.finished.connect(self.onFinished)self.thread.error.connect(self.onError)self.thread.start()def getFolderName(self):folder_path = QFileDialog.getExistingDirectory(self, "選擇保存拆分文件的位置")if folder_path:folder_name, ok = QInputDialog.getText(self, "文件夾名稱", "輸入文件夾名稱:")if ok and folder_name:full_path = os.path.join(folder_path, folder_name)os.makedirs(full_path, exist_ok=True)return full_pathreturn Nonedef deletePages(self):if len(self.pdf_files) != 1:QMessageBox.warning(self, "錯誤", "請只選擇一個PDF文件進行刪除操作。")returnrange_str = self.deleteInput.text().strip()save_path = QFileDialog.getSaveFileName(self, '保存文件', '', 'PDF files (*.pdf)')[zxsq-anti-bbcode-0]if save_path and range_str:self.thread = Worker(self.pdf_files, range_str=range_str, save_path=save_path, operation='delete')self.thread.finished.connect(self.onFinished)self.thread.error.connect(self.onError)self.thread.start()def onFinished(self, message):self.show_message("操作完成", message)self.clear_pdf_list()def onError(self, error_message):self.show_message("操作失敗", error_message)def show_message(self, title, message):QMessageBox.information(self, title, message)def clear_pdf_list(self):self.pdf_files.clear()self.listWidget.clear()def main():app = QApplication(sys.argv)ex = PDFMergerApp()ex.show()sys.exit(app.exec_())if __name__ == '__main__':main()

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210211.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210211.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210211.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java 好碼

1【強制】不要在 foreach 循環里進行元素的 remove/add 操作。 remove 元素請使用 Iterator方式&#xff0c;如果并發操作&#xff0c;需要對 Iterator 對象加鎖。 正例&#xff1a; List<String> list new ArrayList<>(); list.add("1");list.add(…

unity 2d 入門 飛翔小鳥 Cinemachine 記錄分數(十二)

1、創建文本 右鍵->create->ui->leagcy->text 2、設置字體 3、設置默認值和數字 4、當切換分辨率&#xff0c;分數不見問題 拖拽這里調整 調整到如下圖 5、編寫得分腳本 using System.Collections; using System.Collections.Generic; using UnityEngine; …

Docker網絡架構介紹

本文主要介紹了Docker容器的單機網絡架構與集群網絡架構&#xff0c;輔以演示&#xff0c;并簡單介紹了網絡管理中的命令。 前文&#xff1a; Docker的安裝與簡單操作命令-CSDN博客 docker網絡原理介紹 與ovs類似&#xff0c;docker容器采用veth-pair linux bridge (虛擬交…

mysql語句練習

1、查詢"01"課程比"02"課程成績高的學生的信息及課程分數 SELECT student.*,s1.s_score,s2.s_score FROM student,score s1,score s2 WHERE student.s_ids1.s_id AND student.s_ids2.s_id AND s1.c_id01 AND s2.c_id02 AND s1.s_score>s2.s_score 2、…

0007Java程序設計-ssm基于微信小程序的在線考試系統

文章目錄 **摘要**目 錄系統實現開發環境 編程技術交流、源碼分享、模板分享、網課分享 企鵝&#x1f427;裙&#xff1a;776871563 摘要 網絡技術的快速發展給各行各業帶來了很大的突破&#xff0c;也給各行各業提供了一種新的管理技術&#xff0c;基于微信小程序的在線考試…

Linux下apisix離線安裝教程

Linux下apisix離線安裝教程 一、首先需要安裝etcd&#xff1a;二、通過rpm離線安裝apisix三、啟動apisix四、安裝apisix-dashboard1、安裝2、更改dashboard登錄賬號名和密碼3、運行 一、首先需要安裝etcd&#xff1a; 解壓縮etcd后執行以下命令&#xff1a; tar -xvf etcd-v3.…

C#注冊表技術及操作

目錄 一、注冊表基礎 1.Registry和RegistryKey類 &#xff08;1&#xff09;Registry類 &#xff08;2&#xff09;RegistryKey類 二、在C#中操作注冊表 1.讀取注冊表中的信息 &#xff08;1&#xff09;OpenSubKey()方法 &#xff08;2&#xff09;GetSubKeyNames()…

內外聯動——記建行江門鶴山支行營業部堵截一起新型騙局

建設銀行廣東省江門市分行&#xff08;以下簡稱“江門建行”&#xff09;認真貫徹落實黨中央、國務院決策部署&#xff0c;緊緊圍繞當地市委工作部署和上級行要求&#xff0c;扛牢國有大行責任&#xff0c;堅守金融工作的政治性、人民性&#xff0c;以深化新金融行動助力江門全…

javascript實現List列表數據結構

書籍推薦 有幸拜讀《數據結構與算法Javascript描述》這本書&#xff0c;先強烈安利一波&#xff01;非常感謝作者大大給我們前端領域帶來這本書。 全書從javascript的角度出發&#xff0c;簡單明了的分析了數據結構在javascript領域的實現過程與實際的應用案例&#xff0c;且…

postgres 登錄及常用命令

登陸 輸入以下命令&#xff0c;嘗試登錄psql: psql -U postgres 報告以下錯誤&#xff1a; psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "postgres" 換成下面…

Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.

報錯&#xff1a; OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performan…

差異計算基礎知識 - 了解期末業務操作、WIP 和差異

原文地址&#xff1a;Basics of variance calculation-Understanding Period End activities, WIP and Variances | SAP Blogs 大家好&#xff0c; 這是我在成本核算方面的第六份文件&#xff0c;旨在解釋期末的差異計算和相關活動。 我將引導您完成期末活動和差異計算。在本文…

MySQL char 尾隨空格丟失與右側空格填充

今天看《高性能MySQL(第四版)》,講char,varchar時說“當存儲CHAR值時&#xff0c;MySQL刪除所有尾隨空格。如果需要進行比較&#xff0c;值會用空格填充。”感覺這兩句話有沖突啊&#xff0c;便研究了下。 對于具體的問題&#xff0c;當然官方文檔是最好的&#xff0c;The CHAR…

【性能測試】Jmeter 配置元件(一):計數器

Jmeter 配置元件&#xff08;一&#xff09;&#xff1a;計數器 在 Jmeter 中&#xff0c;通過函數 ${__counter(,)} 可以實現每次加 1 1 1 的計數效果。但如果步長不為 1 1 1&#xff0c;則要利用到我們的計數器。 函數作用${__counter(,)}計數器&#xff0c;每次加 1${__d…

vue父子組件傳值

父組件向子組件傳值 1.在父組件中調用子組件時&#xff0c;定義要傳遞的參數 //使用子組件&#xff0c;并傳遞value作為prop<childComponent :childValue"parentValue"></childComponent>// 父組件的data中定義傳遞的參數data() {return {parentValue: &…

論文導讀|10月MSOM文章精選:智慧醫療

編者按 在“10月MSOM文章精選&#xff1a;智慧醫療”中&#xff0c;我們有主題、有針對性地選擇了MSOM期刊雜志中一些有關智慧醫療領域的有趣文章&#xff0c;不但對文章的內容進行了概括與點評&#xff0c;而且也對文章的結構進行了梳理&#xff0c;旨在激發廣大讀者的閱讀興趣…

c++--面向對象特性

1.面向對象指的是繼承&#xff0c;封裝&#xff0c;多態。 繼承主要關注類的構造&#xff0c;賦值&#xff0c;析構。 以下對多態&#xff0c;封裝進行補充說明。 2、多態 2.1.定義 a.賦值 派生類的指針&#xff0c;可以賦值給基類的指針。 派送類的對象&#xff0c;可以賦值給…

教師需要什么技能?

作為一名老師&#xff0c;需要掌握許多技能&#xff0c;以便能夠成功地教育和指導學生。以下是一些關鍵技能&#xff1a; 1.教學技能&#xff1a;老師需要有深入的學科知識和教學經驗&#xff0c;以便能夠有效地傳授知識。教師應該了解如何設計和執行教學計劃&#xff0c;制定課…

【Java基礎篇 | 面向對象】—— 聊聊什么是接口(下篇)

個人主頁&#xff1a;兜里有顆棉花糖 歡迎 點贊&#x1f44d; 收藏? 留言? 加關注&#x1f493;本文由 兜里有顆棉花糖 原創 收錄于專欄【JavaSE_primary】 本專欄旨在分享學習JavaSE的一點學習心得&#xff0c;歡迎大家在評論區交流討論&#x1f48c; 上篇&#xff08;【Ja…

SpringBoot 自動裝配原理詳解

什么是 SpringBoot 自動裝配&#xff1f; 我們現在提到自動裝配的時候&#xff0c;一般會和 Spring Boot 聯系在一起。但是&#xff0c;實際上 Spring Framework 早就實現了這個功能。Spring Boot 只是在其基礎上&#xff0c;通過 SPI 的方式&#xff0c;做了進一步優化。 Spr…