import os
import time
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QScreen,QIcon,QPixmap
from PyQt5.QtCore import QThread, pyqtSignal,QTimer,QDir,Qt
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from win32com.client import constants,gencache
from pdf2docx import Converter
from PIL import Image,ImageFile
from docxcompose.composer import Composer
from PyPDF2 import PdfReader, PdfWriter
import fitz
import docx
# from image import log_rc
# 防止字符串乱码
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
#按钮的样式
#UI界面
class MainWindow(QWidget):
itemChecked = pyqtSignal( str )
start_signal = pyqtSignal(str)
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# # 窗体标题和尺寸
self.font = QtGui.QFont()
# self.font.setFamily("宋体") # 括号里可以设置成自己想要的其它字体
self.font.setPointSize(10) # 括号里的数字可以设置成自己想要的字体大小
self.setFont(self.font)
self.setWindowTitle('Format conversion')
# self.setWindowIcon(QIcon(QtGui.QPixmap(":image/logo.png")))
# 窗体的尺寸
self.resize(900, 500)
# 窗体位置居中
qr=self.frameGeometry()
center = QScreen.availableGeometry(QApplication.primaryScreen()).center()
qr.moveCenter(center)
#垂直方向的布局,创建布局
layout = QVBoxLayout()
self.layout=layout
self.layout_2 = QHBoxLayout()
self.layout.addLayout(self.layout_2)
self.header_layout = QHBoxLayout()
self.layout_4 = QVBoxLayout()
self.layout.addLayout(self.layout_4 )
self.middle_layout = QHBoxLayout()
self.layout_3 = QHBoxLayout()
self.layout.addLayout(self.layout_3)
self.footer_layout = QHBoxLayout()
layout.addLayout(self.init_header())
layout.addLayout(self.init_middle())
layout.addLayout(self.init_footer())
#给窗体设置元素的排列方式
self.setLayout(layout) #设置整体的布局
self.path=None
timer=QTimer()
self.timer=timer
def init_header(self):
# 创建按钮
self.btn_choice_file = QPushButton('选择文件')
self.btn_choice_file.clicked.connect(self.choose_file)
self.header_layout.addWidget(self.btn_choice_file)
self.layout_2.addLayout(self.header_layout)
self.layout_2.addStretch()# 弹簧,把按钮弹到最左边
#标签
header_layout2=QHBoxLayout()
label=QLabel()
label.setText('路径:')
header_layout2.addWidget(label)
# 输入框
txt_asin=QLineEdit()
self.txt_asin=txt_asin
header_layout2.addWidget(txt_asin)
self.layout_2.addLayout(header_layout2)
return self.header_layout
def init_middle(self):
# 文本框
plainTextEdit_2 = QPlainTextEdit()
self.plainTextEdit_2 = plainTextEdit_2
self.middle_layout.addWidget(plainTextEdit_2)
self.layout_4.addLayout(self.middle_layout)
return self.middle_layout
def init_footer(self) :
#底部菜单
lab = QLabel()
lab.setText('请选择转换模式:')
self.footer_layout.addWidget(lab)
self.layout_3.addLayout(self.footer_layout)
texts = ['文档转PDF', '图片转PDF', 'PDF转图片', 'PDF转文档', '文档合并','PDF分割']
self.cmbox = QComboBox(self)
self.cmbox.setFixedSize(120,25)
listwgt = QListWidget()
self.cmbox.setView(listwgt)
self.cmbox.setModel(listwgt.model())
self.lineEdit = QLineEdit(self.cmbox)
self.lineEdit.setReadOnly(True)
self.cmbox.setLineEdit(self.lineEdit)
self.itemChecked.connect(self.printa)
self.ButtonGroup = QButtonGroup() #定义按键组,实现单选功能
for text in texts:
self.check = QCheckBox(text)
self.check.stateChanged.connect(self.on_state_changed)
item = QListWidgetItem(listwgt)
listwgt.setItemWidget(item, self.check)
self.ButtonGroup.addButton(self.check)
self.footer_layout.addWidget(self.cmbox)
self.layout_3.addLayout(self.footer_layout)
self.footer_layout.addStretch()
# 开始按钮
btn_1 =QPushButton('开始')
btn_1.clicked.connect(self.start_btn)
self.layout_3.addWidget(btn_1)
btn_2 = QPushButton('结束')
btn_2.clicked.connect(self.stop_btn)
self.layout_3.addWidget(btn_2)
return self.footer_layout
def start_btn(self):
name = self.lineEdit.text()
text = self.txt_asin.text()
if len(name)==0 and len(text) ==0:
QMessageBox.warning(self, '错误', '请先选择文件,再选择转换的模式')
elif len(name) == 0 and len(text) > 0:
QMessageBox.warning(self, '错误', '请选择转换的模式')
elif len(name) > 0 and len(text) == 0:
QMessageBox.warning(self, '错误', '请选择文件')
elif len(name) > 0 and len(text) > 0:
if name == '文档转PDF':
from utils.scheduler import SCHEDULER
SCHEDULER.start1(self,self.path,self.Word_to_Pdf,self.log_view)
elif name == 'PDF转文档':
from utils.scheduler import SCHEDULER
SCHEDULER.start2(self, self.path, self.Pdf_to_Word, self.log_view)
elif name == '图片转PDF':
from utils.scheduler import SCHEDULER
SCHEDULER.start3(self, self.path, self.pic_to_pdf, self.log_view)
elif name == 'PDF转图片':
from utils.scheduler import SCHEDULER
SCHEDULER.start4(self, self.path, self.pdf_to_pic, self.log_view)
elif name == '文档合并':
from utils.scheduler import SCHEDULER
SCHEDULER.start5(self, self.path, self.merge_to_word, self.log_view)
elif name == 'PDF分割':
from utils.scheduler import SCHEDULER
SCHEDULER.start6(self, self.path, self.split_pdf, self.log_view)
def stop_btn(self):
from utils.scheduler import SCHEDULER
SCHEDULER.stop(self)
def on_state_changed(self):
if self.sender().checkState() == Qt.Checked:
sel_data = self.sender().text()
self.itemChecked.emit(sel_data)
def printa(self,data):
self.lineEdit.setText(data)
def choose_file(self):
self.dlg = QFileDialog()
self.dlg.setWindowTitle('打开文件')
self.dlg.setLabelText(QFileDialog.LookIn, "路径:")
self.dlg.setLabelText(QFileDialog.FileName, "文件名:")
self.dlg.setLabelText(QFileDialog.FileType, "文件类型:")
self.dlg.setLabelText(QFileDialog.Accept, "打开")
self.dlg.setLabelText(QFileDialog.Reject, "取消")
# self.setWindowIcon(QIcon(QtGui.QPixmap(":image/logo.png")))
self.dlg.resize(800, 400)
self.dlg.setDirectory(r'C:\Users\Administrator.DESKTOP-HN63D5M\Desktop')
self.dlg.setViewMode(QFileDialog.Detail)
self.dlg.setOption(QFileDialog.DontUseNativeDialog, True)
self.dlg.setFilter(QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot)
listView = self.dlg.findChild(QListView, "listView")
if listView:
listView.setSelectionMode(QAbstractItemView.ExtendedSelection)
treeView = self.dlg.findChild(QTreeView, "treeView")
if treeView:
treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.buttonBox = self.dlg.findChild(QDialogButtonBox, "buttonBox")
self.buttonBox.accepted.connect(self.slot_accept)
self.dlg.exec_()
def slot_accept(self):
path_list = self.dlg.selectedFiles()
self.path = path_list
self.file_name(self.path)
def file_name(self,dir) :
print(self.path)
file_list=[]
for i in dir :
if not os.path.isdir( i ) :
file_list.append( i )
if len( file_list ) == 0 :
QMessageBox.warning( self, '错误', '你选中的是文件夹,请重新选择文件' )
else :
current_path=os.path.dirname( file_list[0] )
self.txt_asin.setText( current_path )
def get_path(self) :
name=self.txt_asin.text()
return name
def Word_to_Pdf(self, Word_path, Pdf_path) :
word = gencache.EnsureDispatch('Word.Application')
doc = word.Documents.Open(Word_path, ReadOnly=1)
doc.ExportAsFixedFormat(Pdf_path, constants.wdExportFormatPDF)
word.Quit()
def Pdf_to_Word(self, pdf_path, word_path) :
cv= Converter( pdf_path )
cv.convert( word_path, start=0, end=None )
cv.close()
def pic_to_pdf(self, img_path, pdf_path) :
im1=Image.open( img_path )
if img_path.endswith('.png'):
im1 = im1.convert("RGB")
else:
im1 = im1.convert("RGBA")
im1.save(pdf_path)
def pdf_to_pic(self,pdf_path):
pdf_dir = os.path.dirname(pdf_path) + '/'
res_list = pdf_path.split('/')
name = res_list[len(res_list) - 1].replace('.pdf', '')
doc = fitz.open(pdf_path)
pg_list = []
for pg in range(doc.page_count):
page = doc[pg]
rotate = int(0)
# 每个尺寸的缩放系数为1.5,这将为我们生成分辨率提高三倍多的图像。如果转换出来图片是横排的话(即方向改变的话),请把下面的数值改小点
zoom_x = 2.111
zoom_y = 2.111
trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
pm = page.get_pixmap(matrix=trans, alpha=False)
pg_path = pdf_dir + name + f'{pg}.png'
# 注意记住不能直接填充路径,要分段,不然会多创建一个空文件加
pm.save(pdf_dir + name + f'{pg}.png')
pg_list.append(pg_path)
if len(pg_list) > 0:
img_path = pdf_dir + name + '.png'
self.merge_img(pg_list, img_path)
for i in pg_list:
if os.path.exists(i):
os.remove(i)
# 合并图片
def merge_img(self, img_list, img_path):
img_name = img_list[0]
color_mod = 'RGBA' if img_name.endswith('.png') else 'RGB' # jpeg格式不支持RGBA
first_img = Image.open(img_list[0])
height_size = first_img.size[1]
total_width = first_img.size[0]
total_height = height_size * len(img_list)
left = 0
right = height_size
target = Image.new(color_mod, (total_width, total_height)) # 最终拼接的图像的大小
for img in img_list:
target.paste(Image.open(img), (0, left, total_width, right))
left += height_size
right += height_size
target.save(img_path, quality=100)
#合并word
def merge_to_word(self,files_list,save_path):
doc = docx.Document(files_list[0])
top = doc.sections[0].top_margin
bottom = doc.sections[0].bottom_margin
left = doc.sections[0].left_margin
right = doc.sections[0].right_margin
height = doc.sections[0].page_height
width = doc.sections[0].page_width
master = docx.Document()
master.sections[0].top_margin = top
master.sections[0].bottom_margin = bottom
master.sections[0].left_margin = left
master.sections[0].right_margin = right
master.sections[0].page_height = height
master.sections[0].page_width = width
composer = Composer(master)
for i in range(0, len(files_list)):
doc_temp = docx.Document((files_list[i]))
if i < len(files_list) - 1:
doc_temp.add_page_break()
composer.append(doc_temp)
composer.save(save_path)
#PDF分割
def split_pdf(self,path):
pdf = PdfReader(path)
pdf_writer = PdfWriter()
for page in range(len(pdf.pages)):
pdf_writer.add_page(pdf.pages[page])
out_file_name = path.split('.pdf')[0] + '_' + str(page + 1) + '.pdf'
with open(out_file_name, 'wb') as f:
pdf_writer.write(f)
def log_view(self, text) :
cursor=self.plainTextEdit_2.textCursor()
cursor.movePosition( QtGui.QTextCursor.End )
cursor.insertText( text + "\n" )
self.plainTextEdit_2.setTextCursor( cursor )
self.plainTextEdit_2.ensureCursorVisible()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
仅提供部分源码,做参考之用