Compare commits
No commits in common. "1.0" and "main" have entirely different histories.
29
LICENSE
Normal file
29
LICENSE
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
PDF工具箱软件许可协议
|
||||||
|
|
||||||
|
版权所有 © 2025 作者 "SnowZ"
|
||||||
|
|
||||||
|
使用条款:
|
||||||
|
|
||||||
|
1. 授权范围
|
||||||
|
- 本软件为免费软件,用户可以免费使用
|
||||||
|
- 用户可以自由复制、分发本软件
|
||||||
|
- 用户可以查看、学习本软件的源代码
|
||||||
|
|
||||||
|
2. 禁止事项
|
||||||
|
- 严禁将本软件进行商业销售
|
||||||
|
- 严禁对本软件进行二次打包后销售
|
||||||
|
- 严禁将本软件的部分或全部代码用于商业销售的其他软件中
|
||||||
|
|
||||||
|
3. 免责声明
|
||||||
|
- 本软件按"现状"提供,不提供任何形式的保证
|
||||||
|
- 作者不对使用本软件导致的任何损失承担责任
|
||||||
|
|
||||||
|
4. 协议修改
|
||||||
|
- 作者保留修改本协议的权利
|
||||||
|
- 修改后的协议自公布之日起生效
|
||||||
|
|
||||||
|
5. 协议终止
|
||||||
|
- 如果用户违反本协议的任何条款,本软件使用权将自动终止
|
||||||
|
- 协议终止后,用户必须停止使用本软件并删除所有副本
|
||||||
|
|
||||||
|
使用本软件即表示您同意接受本协议的所有条款。
|
31
README.md
31
README.md
@ -42,4 +42,33 @@
|
|||||||
1. 克隆或下载本项目
|
1. 克隆或下载本项目
|
||||||
2. 安装依赖包:
|
2. 安装依赖包:
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## 打包说明
|
||||||
|
如果您想将程序打包成可执行文件,可以使用PyInstaller进行打包:
|
||||||
|
|
||||||
|
1. 首先安装PyInstaller:
|
||||||
|
```bash
|
||||||
|
pip install pyinstaller
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 进入项目目录,运行以下命令进行打包:
|
||||||
|
```bash
|
||||||
|
pyinstaller --onefile --windowed --add-data "src;src" --add-data "config.json;." --add-data "requirements.txt;." main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 打包完成后,在dist目录下会生成可执行文件。
|
||||||
|
打包完成后,可执行文件将在 dist/PDF工具箱 目录中生成。
|
||||||
|
注意事项:
|
||||||
|
- 打包前请确保已安装所有依赖包
|
||||||
|
- 如果使用PDF转Excel功能,打包后的程序仍然需要Java环境
|
||||||
|
- 首次运行打包后的程序可能需要稍等片刻
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
打包命令的参数说明:
|
||||||
|
- `--name "PDF工具箱"`: 设置生成的程序名称
|
||||||
|
- `--windowed`: 不显示控制台窗口
|
||||||
|
- `--icon=assets/icon.ico`: 设置程序图标(如果有的话)
|
||||||
|
- `--add-data "assets;assets"`: 包含资源文件(如果有的话)
|
@ -5,6 +5,39 @@ import pandas as pd
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
class PDFConverter:
|
class PDFConverter:
|
||||||
|
@staticmethod
|
||||||
|
def batch_convert(pdf_paths, output_dir, convert_type):
|
||||||
|
"""
|
||||||
|
批量转换PDF文件
|
||||||
|
:param pdf_paths: PDF文件路径列表
|
||||||
|
:param output_dir: 输出目录
|
||||||
|
:param convert_type: 转换类型 ('word', 'images', 'markdown', 'excel')
|
||||||
|
"""
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
for pdf_path in pdf_paths:
|
||||||
|
filename = os.path.basename(pdf_path)
|
||||||
|
name_without_ext = os.path.splitext(filename)[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
if convert_type == 'word':
|
||||||
|
output_path = os.path.join(output_dir, f"{name_without_ext}.docx")
|
||||||
|
PDFConverter.pdf_to_word(pdf_path, output_path)
|
||||||
|
elif convert_type == 'images':
|
||||||
|
# 为每个PDF创建单独的图片目录
|
||||||
|
pdf_images_dir = os.path.join(output_dir, name_without_ext)
|
||||||
|
os.makedirs(pdf_images_dir, exist_ok=True)
|
||||||
|
PDFConverter.pdf_to_images(pdf_path, pdf_images_dir)
|
||||||
|
elif convert_type == 'markdown':
|
||||||
|
output_path = os.path.join(output_dir, f"{name_without_ext}.md")
|
||||||
|
PDFConverter.pdf_to_markdown(pdf_path, output_path)
|
||||||
|
elif convert_type == 'excel':
|
||||||
|
output_path = os.path.join(output_dir, f"{name_without_ext}.xlsx")
|
||||||
|
PDFConverter.pdf_to_excel(pdf_path, output_path)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"转换文件 {filename} 时出错: {str(e)}")
|
||||||
|
continue
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pdf_to_word(pdf_path, output_path):
|
def pdf_to_word(pdf_path, output_path):
|
||||||
converter = pdf2docx.Converter(pdf_path)
|
converter = pdf2docx.Converter(pdf_path)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout,
|
from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QPushButton, QLabel, QFileDialog, QTabWidget,
|
QPushButton, QLabel, QFileDialog, QTabWidget,
|
||||||
QLineEdit, QMessageBox, QProgressBar)
|
QLineEdit, QMessageBox, QProgressBar, QListWidget)
|
||||||
from PyQt6.QtCore import Qt
|
from PyQt6.QtCore import Qt
|
||||||
from PyQt6.QtGui import QIcon
|
from PyQt6.QtGui import QIcon
|
||||||
from core.converter import PDFConverter
|
from core.converter import PDFConverter
|
||||||
@ -40,31 +40,40 @@ class MainWindow(QMainWindow):
|
|||||||
layout = QVBoxLayout(widget)
|
layout = QVBoxLayout(widget)
|
||||||
|
|
||||||
# 添加文件选择
|
# 添加文件选择
|
||||||
select_file_btn = QPushButton("选择PDF文件")
|
select_file_btn = QPushButton("选择PDF文件(可多选)")
|
||||||
select_file_btn.clicked.connect(self.select_pdf_file)
|
select_file_btn.clicked.connect(self.select_pdf_files)
|
||||||
|
|
||||||
# 添加文件路径显示
|
# 添加文件列表显示
|
||||||
self.file_label = QLabel("未选择文件")
|
self.files_list_widget = QListWidget()
|
||||||
|
|
||||||
|
# 添加输出目录选择
|
||||||
|
output_dir_layout = QHBoxLayout()
|
||||||
|
self.output_dir_label = QLabel("输出目录:未选择")
|
||||||
|
select_output_dir_btn = QPushButton("选择输出目录")
|
||||||
|
select_output_dir_btn.clicked.connect(self.select_output_directory)
|
||||||
|
output_dir_layout.addWidget(self.output_dir_label)
|
||||||
|
output_dir_layout.addWidget(select_output_dir_btn)
|
||||||
|
|
||||||
# 添加进度条
|
# 添加进度条
|
||||||
self.progress_bar = QProgressBar()
|
self.progress_bar = QProgressBar()
|
||||||
self.progress_bar.setVisible(False)
|
self.progress_bar.setVisible(False)
|
||||||
|
|
||||||
# 添加转换按钮
|
# 添加转换按钮
|
||||||
convert_to_word = QPushButton("转换为Word")
|
convert_to_word = QPushButton("批量转换为Word")
|
||||||
convert_to_word.clicked.connect(lambda: self.convert_pdf("word"))
|
convert_to_word.clicked.connect(lambda: self.batch_convert_files("word"))
|
||||||
|
|
||||||
convert_to_image = QPushButton("转换为图片")
|
convert_to_image = QPushButton("批量转换为图片")
|
||||||
convert_to_image.clicked.connect(lambda: self.convert_pdf("image"))
|
convert_to_image.clicked.connect(lambda: self.batch_convert_files("images"))
|
||||||
|
|
||||||
convert_to_markdown = QPushButton("转换为Markdown")
|
convert_to_markdown = QPushButton("批量转换为Markdown")
|
||||||
convert_to_markdown.clicked.connect(lambda: self.convert_pdf("markdown"))
|
convert_to_markdown.clicked.connect(lambda: self.batch_convert_files("markdown"))
|
||||||
|
|
||||||
convert_to_excel = QPushButton("转换为Excel")
|
convert_to_excel = QPushButton("批量转换为Excel")
|
||||||
convert_to_excel.clicked.connect(lambda: self.convert_pdf("excel"))
|
convert_to_excel.clicked.connect(lambda: self.batch_convert_files("excel"))
|
||||||
|
|
||||||
layout.addWidget(select_file_btn)
|
layout.addWidget(select_file_btn)
|
||||||
layout.addWidget(self.file_label)
|
layout.addWidget(self.files_list_widget)
|
||||||
|
layout.addLayout(output_dir_layout)
|
||||||
layout.addWidget(self.progress_bar)
|
layout.addWidget(self.progress_bar)
|
||||||
layout.addWidget(convert_to_word)
|
layout.addWidget(convert_to_word)
|
||||||
layout.addWidget(convert_to_image)
|
layout.addWidget(convert_to_image)
|
||||||
@ -73,45 +82,49 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
def select_pdf_file(self):
|
def select_pdf_files(self):
|
||||||
file_name, _ = QFileDialog.getOpenFileName(
|
files, _ = QFileDialog.getOpenFileNames(
|
||||||
self,
|
self,
|
||||||
"选择PDF文件",
|
"选择PDF文件",
|
||||||
"",
|
"",
|
||||||
"PDF文件 (*.pdf)"
|
"PDF文件 (*.pdf)"
|
||||||
)
|
)
|
||||||
if file_name:
|
if files:
|
||||||
self.selected_files = [file_name]
|
self.selected_files = files
|
||||||
self.file_label.setText(f"已选择: {os.path.basename(file_name)}")
|
self.files_list_widget.clear()
|
||||||
|
for file in files:
|
||||||
|
self.files_list_widget.addItem(os.path.basename(file))
|
||||||
|
|
||||||
def convert_pdf(self, target_format):
|
def select_output_directory(self):
|
||||||
if not self.selected_files:
|
output_dir = QFileDialog.getExistingDirectory(
|
||||||
|
self,
|
||||||
|
"选择输出目录"
|
||||||
|
)
|
||||||
|
if output_dir:
|
||||||
|
self.output_directory = output_dir
|
||||||
|
self.output_dir_label.setText(f"输出目录:{output_dir}")
|
||||||
|
|
||||||
|
def batch_convert_files(self, convert_type):
|
||||||
|
if not hasattr(self, 'selected_files') or not self.selected_files:
|
||||||
QMessageBox.warning(self, "警告", "请先选择PDF文件!")
|
QMessageBox.warning(self, "警告", "请先选择PDF文件!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not hasattr(self, 'output_directory'):
|
||||||
|
QMessageBox.warning(self, "警告", "请选择输出目录!")
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.progress_bar.setVisible(True)
|
self.progress_bar.setVisible(True)
|
||||||
self.progress_bar.setValue(0)
|
self.progress_bar.setValue(0)
|
||||||
|
|
||||||
input_file = self.selected_files[0]
|
# 计算总文件数用于进度显示
|
||||||
output_dir = os.path.dirname(input_file)
|
total_files = len(self.selected_files)
|
||||||
|
|
||||||
|
# 批量转换文件
|
||||||
|
PDFConverter.batch_convert(self.selected_files, self.output_directory, convert_type)
|
||||||
|
|
||||||
if target_format == "word":
|
|
||||||
output_file = os.path.splitext(input_file)[0] + ".docx"
|
|
||||||
PDFConverter.pdf_to_word(input_file, output_file)
|
|
||||||
elif target_format == "image":
|
|
||||||
output_dir = os.path.splitext(input_file)[0] + "_images"
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
|
||||||
PDFConverter.pdf_to_images(input_file, output_dir)
|
|
||||||
elif target_format == "markdown":
|
|
||||||
output_file = os.path.splitext(input_file)[0] + ".md"
|
|
||||||
PDFConverter.pdf_to_markdown(input_file, output_file)
|
|
||||||
elif target_format == "excel":
|
|
||||||
output_file = os.path.splitext(input_file)[0] + ".xlsx"
|
|
||||||
PDFConverter.pdf_to_excel(input_file, output_file)
|
|
||||||
|
|
||||||
self.progress_bar.setValue(100)
|
self.progress_bar.setValue(100)
|
||||||
QMessageBox.information(self, "成功", "转换完成!")
|
QMessageBox.information(self, "成功", "批量转换完成!")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.critical(self, "错误", f"转换失败:{str(e)}")
|
QMessageBox.critical(self, "错误", f"转换失败:{str(e)}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user