打印PDF并在打印完成后删除文件

3 投票
4 回答
6571 浏览
提问于 2025-04-16 08:40

我有一个Python应用程序,它会被反复执行。这个程序会把一个PDF文件保存下来,然后打印它。打印结束后,它会删除这个文件。

我现在的解决方案(关于打印和删除文件的部分)是这样的:

win32api.ShellExecute(0, "print", file_path, None,  ".",  0)
time.sleep(10)
os.remove(self.options.dest_name)

time.sleep(10) 是一个小技巧,用来给打印过程留出时间,以便在删除文件之前完成打印。如果没有这个,Acrobat Reader会打开(反正它还是会打开),并提示找不到文件。这是因为文件已经被删除了。

我的问题是:

  1. 有没有办法不使用这个不太可靠的小技巧?最好的办法是有一个打印过程的处理程序,通过它获取打印状态的信息:我等它报告完成后再删除文件。

  2. 如果Acrobat Reader不打开那就更好了,不过这不是个大问题。

编辑:我尝试把Foxit Reader设为默认的PDF阅读器,现在它在我不想打开的时候不会打开了。;)

其他可能的解决方案:定期检查文件是否可用(没有被其他进程使用),当它再次可用时再删除它。我该如何在Python中实现呢?

4 个回答

1

Adobe Acrobat 有一个参数 "/t",这个参数可以让它打开文件、打印文件,然后自动退出。使用这个参数,你可以调用 Acrobat Reader,等它完成后再删除文件。

以下是未经测试的代码:

>>> import subprocess
# You will have to figure out where your Acrobate reader is located, can be found in the registry:
>>> acrobatexe = "C:\Program Files\Adobe\Acrobat 4.0\Reader\AcroRd32.exe"  
>>> subprocess.call([acrobatexe, "/t", tempfilename, "My Windows Printer Name"])
>>> os.unlink(tempfilename)

大概就是这样的。

如果你不想让 Acrobat 打开,还有一些开源软件可以通过命令行打印 PDF 文件。你可以把其中一个软件和你的程序一起打包。

2

与其把文件名写死在代码里并直接打印出来,不如使用 tempfile 模块来创建一个名字独一无二的临时文件。

import tempfile
file_name = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False)

如果你愿意,可以使用Windows的调度工具运行一个定期清理的脚本,来删除那些创建的文件。

4

最后我找到一个不错的解决方案,感谢这个回答(还有@Lennart在评论中提到的):

安装Ghostscript

安装GSview(里面包含了gsprint.exe

写下这段代码:

file_path = "C:\\temp\\test.pdf"
p = subprocess.Popen(["C:\\Ghostgum\\gsview\\gsprint.exe", "-printer", printer_name, "-colour",  file_path],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate() # waits for the gs process to end
os.remove(file_path) # now the file can be removed

这样就不会弹出Acrobat窗口,也不会在打印前删除文件……唯一麻烦的是安装GS。

另请查看:gsprint 参考

撰写回答