打印PDF并在打印完成后删除文件
我有一个Python应用程序,它会被反复执行。这个程序会把一个PDF文件保存下来,然后打印它。打印结束后,它会删除这个文件。
我现在的解决方案(关于打印和删除文件的部分)是这样的:
win32api.ShellExecute(0, "print", file_path, None, ".", 0)
time.sleep(10)
os.remove(self.options.dest_name)
time.sleep(10)
是一个小技巧,用来给打印过程留出时间,以便在删除文件之前完成打印。如果没有这个,Acrobat Reader会打开(反正它还是会打开),并提示找不到文件。这是因为文件已经被删除了。
我的问题是:
有没有办法不使用这个不太可靠的小技巧?最好的办法是有一个打印过程的处理程序,通过它获取打印状态的信息:我等它报告完成后再删除文件。
如果Acrobat Reader不打开那就更好了,不过这不是个大问题。
编辑:我尝试把Foxit Reader设为默认的PDF阅读器,现在它在我不想打开的时候不会打开了。;)
其他可能的解决方案:定期检查文件是否可用(没有被其他进程使用),当它再次可用时再删除它。我该如何在Python中实现呢?
4 个回答
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 文件。你可以把其中一个软件和你的程序一起打包。
与其把文件名写死在代码里并直接打印出来,不如使用 tempfile
模块来创建一个名字独一无二的临时文件。
import tempfile
file_name = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False)
如果你愿意,可以使用Windows的调度工具运行一个定期清理的脚本,来删除那些创建的文件。
最后我找到一个不错的解决方案,感谢这个回答(还有@Lennart在评论中提到的):
安装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
参考