可以做公司公章的软件(一个非常实用的加盖电子公章的工具)
可以做公司公章的软件(一个非常实用的加盖电子公章的工具)
2024-05-29 01:56:16  作者:寂寞如歌啊  网址:https://m.xinb2b.cn/life/mjt323731.html

大家好,我是野生程序员一灯。

今天分享一个python开发的小GUI项目:电子签章器。

客户的需求是这样的:

客户是一个不小的中药生产和批发企业,每天都需要为它的客户提供大量的药品质量检测纸质文件,并且需要在纸质上加盖公章。据客户说,每年都为此消耗大量的A4纸,而且需要人工处理,长期积累下来也浪费了大量的人力成本。该客户想直接为它的客户发带公章的pdf文件,这样一年能节省不少的成本。只需要一个员工,通过一个桌面软件,批量选择word文件,并且可随时选择电子公章文件(pdf格式),直接将word文件转成pdf并自动加盖公章。

这个需求有几个关键点:

1、考虑到word的格式有doc和docx,这里可以使用win32com,同时非常方便地将word转成pdf;

2、将word转成pdf后,为pdf加盖公章,本质上是加水印的行为,在代码中的逻辑是两页pdf叠加在一起;

3、使用pyqt6,为了提高使用体验,需要使用多线程,即UI线程和业务线程分开,避免在处理文件时UI界面僵死。

成品的样子

可以做公司公章的软件(一个非常实用的加盖电子公章的工具)(1)

打包后的样子

word处理部分的核心代码

from win32com.client import Dispatchimport osclass WordHandler: def __init__(self, file, only_read=True): self.file = file self.only_read = only_read self.word = Dispatch('kwps.Application') self.word.Visible = 0 self.word.DisplayAlerts = 0 self.doc = self.__open() def __open(self): doc = self.word.Documents.Open(self.file, ReadOnly=self.only_read) return doc def save_as_pdf(self): suffix = os.path.splitext(self.file)[-1] if suffix == '.doc': save_to = self.file.replace('.doc', '.pdf') elif suffix == '.docx': save_to = self.file.replace('.docx', '.pdf') self.doc.ExportAsFixedFormat(save_to, 17) return save_to def close(self): self.doc.Close() def quit(self): self.word.Quit()

啰嗦一句,在word转pdf这里,`ExportAsFixedFormat`是`Document`的方法(Open方法返回的是一个Document对象),除了这个方法,也有`SaveAs`和`SaveAs2`方法可以实现,它们是`Application`的方法,即它们是客户端提供的方法,对应着客户端 -> 文件 -> 另存为。

pdf加水印部分

这里使用`PyPDF2`,这是个声名在外的库了,无需多介绍,这里只分析加水印最基本的逻辑。

1、使用`PdfFileReader`分别打开水印pdf文件和要处理的pdf文件

2、水印文件只需要一页就ok,所以要使用PdfFileReader.getPage(0)来获取到第一页;

3、使用`PdfFileWriter`创建一个新的pdf对象,用来保存最后处理的结果

3、要处理的pdf文件在打开后,按照页数循环,逐个循环,将循环到的单页和水印单页合并,然后保存到`PdfFileWriter`所创建的对象中

至此,添加水印的工作便完成了。

pyqt的多线程部分

其实整个需求中,最耗费时间的应该是pyqt的多线程这部分了,使用多线程可以将UI线程和业务线程有效地分开,好处多多。先捋一捋最基本的流程。

可以做公司公章的软件(一个非常实用的加盖电子公章的工具)(2)

1、点击签章后,手动开启一个子线程,UI主线程需要将1和2的数据传递到子线程

2、子线程拿到数据后,就开始工作,并且每完成一个文件,还需要将信号发回到主线程,主线程可以告知用户处理的进度

3、所有文件处理完毕时,手动关闭子线程

这是子线程的核心代码

class MyDocumentThread(QObject): # 发送信号 signal_for_send = pyqtSignal(str) # 接收信号 接收一个文件列表 signal_for_accept = pyqtSignal(list) def __init__(self, parent=None): super(MyDocumentThread, self).__init__() self.lock = QMutex() def work(self, file_list): """ 文档处理逻辑 """ print('子线程接受到的数据:', file_list) # 上锁 self.lock.lock() temp_pdf_list = [] for file in file_list[0]: pdf_file = word2pdf(file) temp_pdf_list.append(pdf_file) # 发送信号给UI主线程 print('pdf处理后', temp_pdf_list) self.lock.unlock() # 将temp_pdf_list增加水印 self.lock.lock() for index, pdf in enumerate(temp_pdf_list, 1): done = add_mark(pdf, file_list[-1]) print(index, pdf) if done == 'success': self.signal_for_send.emit(f'{pdf}处理完成...') if index == len(temp_pdf_list): self.signal_for_send.emit('done') # 删除临时文件 self.lock.unlock()

注:

官方强烈推荐使用QObject来自定义自己的线程,在该线程中实现自己的业务逻辑,而非在QThread中实现执行业务逻辑。所以以上逻辑在继承QObject来实现的,并且在实例化自定义自定义线程时,需要手动实例化一个QThread,使用moveToThread将自定义线程对象交给QThread对象来处理。

关于pyqt的多线程,既有官网文档,也有各界道友的各种实现,我这里也说说自己的心得。

1、根据以上的描述,主线程和子线程需要双向通信,我们都知道,使用`pyqtSignal`可以通信,这是一个发送信号的方法,但如何实现双向通信呢?网上大部分的案例都是单向通信,即子线程将处理的结果或其他信息传回主线程。这里我们需要注意到一个关键的动作,即:`pyqtSignal().emit()`,这是发送信号的工作,如何双向通信呢?本质上,在主线程中使用`emit`,那么就是主线程向子线程发送信号,在子线程中使用`emit`就是子线程向主线程发送信号。要注意的是,需要提前定义好这两种信号,发送时可以在需要的地方执行`emit`就可以了。

可以做公司公章的软件(一个非常实用的加盖电子公章的工具)(3)

根据子线程传回的信号,向用户展示“全部处理完成”

2、如何在使用多线程

(1)以上的代码仅仅是核心代码,是实现多线程的方法,但是如何在pyqt整个流程中调用呢?这里谈谈关键点,首先要在初始化界面时,实例化咱们自定义好的线程对象。

可以做公司公章的软件(一个非常实用的加盖电子公章的工具)(4)

(2)在点击签章时,才开启线程

可以做公司公章的软件(一个非常实用的加盖电子公章的工具)(5)

有些道友在处理化界面时就启动了线程,其实要看具体需求哈,手工控制线程的启动和关闭,可以实现软件循环使用,比如处理完一批软件文档时,接着可以处理第二批,这就是手工控制的好处。如果在界面初始化自动开启线程,那么关闭后就无法再开线程了,得关闭软件才能再次开启。

好啦,今天的分享就到此为止。欢迎私信交流。

  • 邓超孙俪最新拍的电影叫什么(孙俪夫妻合拍过4部电影)
  • 2024-05-29孙俪夫妻合拍过4部电影邓超在跑男里游戏玩的好,演起电影也是很棒的,这让小编想起了一部由邓超、俞白眉导演的恶棍天使,恶棍天使于2015年12月24日在中国上映,由邓超、孙俪夫妻主演的一部爱情喜剧片,豆瓣评分4.0,但是当年票。
  • 海上繁花林向远和家人吃团圆饭(林向远陪李梦楠去见老总)
  • 2024-05-29林向远陪李梦楠去见老总剧情关键字:雷宇峥林向李梦楠Hi,大家好,最近电视剧《海上繁花》第25集正在热播,有不少网友这样评论:史上最快下线男二,我家龙龙看得我好憋屈是部爱情爽片,就是太俗太套路了,看杜晓苏和邵振嵘在一起就知道。
  • 干的刀鱼怎么做好吃(干的刀鱼做法)
  • 2024-05-29干的刀鱼做法1.把晒干的刀鱼先用热水泡一泡2.把泡好的刀鱼,用刀切开3.开始热锅起油,放入葱姜蒜4.把切好的刀鱼放入锅中开始翻炒5.继续翻炒,其中也不用放入调料,因为刀鱼本身就很咸了,否则就不能吃了。
  • 21年推理剧排行榜(一直被低估的6部冷门悬疑剧)
  • 2024-05-29一直被低估的6部冷门悬疑剧1、《舞乐传奇》剧情真的不错,比较喜欢苏决这个人物刻画,迦罗娜也不错,不愧有阿蛮这个忠诚的手下,这个将军的德行是个明主,可惜了立场原因是个反派没想到是于荣光老师的作品,一连串的反转比某些本格悬疑都好看。
  • 怎么看前十店铺排名(场均成交破千万)
  • 2024-05-29场均成交破千万天下网商丁洁编辑李丹超当品牌店播成为商家日常运营手段,如何借大促玩出新花样?针对这个问题,今年天猫618期间,聚划算给出了答案——将官方直播与品牌店播强强联合,打通站内外各大流量通道,并通过每日不间断。
  • 哈利波特怎么用邓布利多(哈利波特邓布利多是如何不靠血统继承)
  • 2024-05-29哈利波特邓布利多是如何不靠血统继承哈迷们都知道,在《哈利·波特》中,蛇佬腔是一种很神奇的能力,即,用蛇的语言去说话,与蛇交流只有继承了斯莱特林血脉的人才会说这种语言,例如冈特家族,以及伏地魔可能有朋友要问了,罗恩不是也学会了蛇佬腔吗?。
  • 为什么吃鱼的动物不吐刺(动物吃鱼为什么很少被卡住)
  • 2024-05-29动物吃鱼为什么很少被卡住鱼肉鲜美细嫩,不仅人类喜欢吃,自然界中会吃鱼的动物也很多鱼肉虽好,刺却不少,稍有不慎,就容易被鱼刺卡到喉咙,想必大家都或多或少有过被鱼刺支配的恐惧吧!我们日常所吃的鱼类当中,淡水鱼居多其实,也只有在比。
  • 电脑主机自己能组装吗?(电脑主机可以自己组装)
  • 2024-05-29电脑主机可以自己组装电脑主机可以自己组装,按如下步骤组装即可首先拿出主板,将主板上CPU插槽的拉杆打开;CPU与CPU插槽均有防呆缺口,如果CPU放置错误,是无法进行安装的,我们找到CPU的两边缺口对应主板的两边缺口,放。
  • 毒液2毒液看见蜘蛛侠为什么兴奋(毒液2中屠杀最终被毒液吃掉)
  • 2024-05-29毒液2中屠杀最终被毒液吃掉今年除了漫威电影的3部作品在引入问题上比较尴尬以外,其实对于另外一边的索尼影业的《毒液2》也是无缘内地院线,而伴随着此前《毒液2》在其他地区的上线,也是渐渐有些资源流露出来了不过,就是部分资源中声道有。
  • 芜湖低温脱硝剂研发(磷化工绿色发展)
  • 2024-05-29磷化工绿色发展  多氟多化工股份有限公司自主研发的氟硅酸制无水氢氟酸联产白炭黑生产工艺,以磷肥行业副产氟硅酸为原料制得无水氢氟酸,大幅提升氟元素利用率、降低原料成本,对于保护萤石资源,促进氟化工、磷化工行业可持续发。
  • 香蕉快要面临灭绝了吗(不可思议的香蕉)
  • 2024-05-29不可思议的香蕉香蕉只是长得比较壮的草?很多人对于这个答案都会觉得不可思议,在网络上有很多香蕉种植园的图片,从图片上看,高达三四米的粗壮香蕉植株,怎么看都具有称之为“树”的特征,怎么会仅是长得比较壮的“草”呢?无奈的。