XiaoYu121 发表于 2023-11-23 15:45

pdf工具自制(合并、拆分、删除)

本帖最后由 苏紫方璇 于 2023-11-26 14:07 编辑

pdf工具,之前写的合并工具有点麻烦,使用PyQt5库重写合并拆分和删除指定页面的程序





```
import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QFileDialog, QListWidget, QMessageBox, QLineEdit, QHBoxLayout, QInputDialog
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyPDF2 import PdfReader, PdfWriter, PdfMerger
from PyQt5 import QtGui

class 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_files
      self.range_str = range_str
      self.save_path = save_path
      self.operation = operation

    def 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)
                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)
                writer = PdfWriter()
                for page_num in range(len(reader.pages)):
                  if not (start_page <= page_num <= end_page):
                        writer.add_page(reader.pages)
                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 index

class 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文件进行拆分。")
            return

      range_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_path
      return None

    def deletePages(self):
      if len(self.pdf_files) != 1:
            QMessageBox.warning(self, "错误", "请只选择一个PDF文件进行删除操作。")
            return

      range_str = self.deleteInput.text().strip()
      save_path = QFileDialog.getSaveFileName(self, '保存文件', '', 'PDF files (*.pdf)')
      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()
```


打包文件下载:https://lxiaoyu.lanzouj.com/ircjV1fqb38f 密码:97wy

火焰加鲁鲁 发表于 2023-11-23 18:43

感谢分享,占一楼

Agri6789 发表于 2023-11-23 19:01

感谢分享,占二楼

吖力锅 发表于 2023-11-23 21:25

这个不错,收藏了

wo396765325ok 发表于 2023-11-24 07:35

软件很好在哪下载?

XiaoYu121 发表于 2023-11-24 07:55

wo396765325ok 发表于 2023-11-24 07:35
软件很好在哪下载?

文章最后

yu520 发表于 2023-11-24 09:03

好用,感谢分享

mokson 发表于 2023-11-24 11:17

bzgl666 发表于 2023-11-24 12:26

感谢分享,

Heisenber9 发表于 2023-11-24 23:07

感谢分享,软件简单但够用
页: [1] 2
查看完整版本: pdf工具自制(合并、拆分、删除)