使用CUPS编程过滤器/后端,从任何Mac OS X应用程序“打印到PDF”

9

好的,这是我想要做的事情。我想添加一个打印选项,将用户文档打印为PDF,并在发送到设备之前添加一些页眉。

我的问题是:我如何为用户添加虚拟“打印机”驱动程序,以启动我正在开发的应用程序,以制作PDF(或制作PDF并使用新生成的PDF的引用启动我的应用程序)?我如何与CUPS接口以生成PDF?如果需要更多信息,请告诉我。

我已经通过这个使用CUPS打印的教程,并且似乎一切都设置好了,但是文件似乎从未出现在适当的临时位置。如果有人正在寻找用户端PDF打印机,这个cups-pdf-for-mac-os-x是一个可以通过安装程序工作的打印机,但是当我下载源代码并按照自述文件中的说明操作时,我遇到了相同的问题。如果有人能够使它们在Mac上通过终端工作,请告诉我你是如何一步一步做到的。


也许我误解了你的需求,但Cocoa直接支持从文档/NSView生成PDF,你不需要安装打印驱动程序。在文档中搜索“PDF”。 - CRD
这是一个具体的例子:我有一个Word文档,我想将其发送到我的设备。当我执行文件>>打印时,我希望有一个打印机选项,可以启动我的应用程序并为我提供当前Word文档的PDF的引用。(我不太关心文件何时变成PDF - 我意识到我可以在我的应用程序中完成这个过程)。我不需要在视图中显示PDF,并且我已经使用了PDFKit功能来操作文件,但从打印机选项中操作文件还没有尝试过。如果您仍然认为搜索文档就足够了,请指向更具体的参考资料?谢谢。 - Katie
正如我所想,我误解了你的需求。在查看CUPS时,你选择了一个很好的地方来寻找你想要做的事情。 - CRD
2个回答

15

操作步骤如下:

  • 使用任何喜欢的驱动程序设置打印队列,但我建议使用PostScript驱动程序/PPD。(PostScript PPD是不包含任何*cupsFilter: ...行的PPD):

  • 最初,使用名为2dir的CUPS后端(教育性质)。可以从此网站复制该后端:KDE Printing Developer Tools Wiki在复制时,请确保文件行结束符正确(类Unix)。

  • 设置初始队列的命令行:

    lpadmin \
        -p pdfqueue \
        -v 2dir:/tmp/pdfqueue \
        -E \
        -P /path/to/postscript-printer.ppd
    
    现在,2dir后端将所有输出写入目录/tmp/pdfqueue/中,并为每个作业使用唯一名称。每个结果现在应该是一个PostScript文件。(还没有你想要的修改)

  • /etc/cups/ppd/中找到该队列使用的PPD文件(它的名字应该是pdfqueue.ppd)。

  • 在PPD文件中添加以下行(最好靠近顶部):

    *cupsFilter: "application/pdf  0  -"
    (确保*从行的开头开始。) 这行告诉自动设置一个过滤链,以生成PDF,并在它通过后端发送文件之前调用名为'-'的最后一个过滤器。该'-'过滤器是特殊的:它什么也不做,它是一个直通过滤器。

  • 重新启动 CUPS 调度程序:

    sudo launchctl unload /System/Library/LaunchDaemons/org.cups.cupsd.plist
    sudo launchctl load /System/Library/LaunchDaemons/org.cups.cupsd.plist

  • 从现在开始,将打印到 pdfqueue 的每个作业都以PDF 形式保存在 /tmp/pdfqueue/*.pdf 中。

  • 研究 2dir 后端脚本。它是简单的 Bash 脚本,并且有相当不错的注释。

  • 修改 2dir 以便在将结果保存到 /tmp/pdfqueue/*.pdf 之前添加所需的 PDF 修改...


  • 更新:看起来我在上面原先指定的*cupsFilter: ... 行中忘记了 2 个引号。抱歉!


    这听起来正是我需要的!感谢您抽出时间写下所有内容。然而,请容忍我,因为我对CUPS和打印机术语不熟悉,所以我可能会问一些细微的逐步问题,而您可能已经回答过了。KDE Printing Developer Tools Wiki的链接指定2dir应该保存在/usr/lib/cups/backend/中,但是我在/usr/lib/中似乎没有cups目录。我错过了什么吗?此外,设置初始队列的最后一个标志,我假设我应该替换路径,但确切是用什么替换? - Katie
    1
    @Katie:抱歉,我在想Linux的路径。在Mac OS X上,您需要使用“/usr/libex/cups/backend/”。您可以将最后一个带有“-P”标志的路径参数替换为“/User/katie/postscript-printer.ppd”,但是当然您应该将真正的PostScript打印机PPD放在那个名称下。 - Kurt Pfeifle
    嗨@KurtPfeifle,我无法使用上述方法生成输出。我正在使用Mac OS。 - Mohammad Sadiq Shaikh
    @MohammadSadiqShaikh:你提供的信息不足以开始思考可能出了什么问题。你甚至没有告诉我们你运行的是哪个版本的OS X(你知道吗?在不同版本之间,CUPS有所改变)。 - Kurt Pfeifle
    我希望它能在Yosemite 10.10.5及以上版本上运行。 - Mohammad Sadiq Shaikh
    显示剩余5条评论

    6

    我真的希望能够接受两个答案,因为如果没有@Kurt Pfeifle提供的Mac专业知识和对打印机驱动程序和文件位置的理解,我觉得自己不可能完成这个任务。但是这就是我所做的:


    1. 从 codepoet 的 cups-pdf-for-mac-os-x 下载源代码。(对于非 Mac 用户,可以查看http://www.cups-pdf.de/) 读取自述文件详细说明,仔细阅读所有说明后,它就可以工作。但是我在获取所有部件时遇到了一些小问题,因此我将概述我所做的事情,以期能为其他人省去一些麻烦。为此,源代码所在目录称为“cups-pdfdownloaddir”。

    2. 根据自述文件中的说明编译 src 文件夹中包含的 cups-pdf.c:

      gcc -09 -s -lcups -o cups-pdf cups-pdf.c

      可能会有一个警告:ld:warning:option -s is obsolete and being ignored,但这对我没有任何影响。将二进制文件复制到 /usr/libexec/cups/backend 中。您可能需要使用 sudo 命令,这将提示您输入密码。例如:

      sudo cp /cups-pdfdownloaddir/src/cups-pdf /usr/libexec/cups/backend

      还要不忘记更改此文件的权限--它需要 root 权限(700),可以在将 cupd-pdf 移入后端目录后用以下命令更改:

      sudo chmod 700 /usr/libexec/cups/backend/cups-pdf

    3. 编辑位于 /cups-pdfdownloaddir/extra/cups-pdf.conf 中的文件。在“PDF Conversion Settings”标题下,找到一个在 GhostScript 下的行,其中读取 #GhostScript /usr/bin/gs。我没有取消注释,以防需要它,而是在其下面添加了一行 Ghostscript /usr/bin/pstopdf。(这些修改中不应有任何前置符号#)

      在 GSCall 下找到一行,其中读取 #GSCall %s -q -dCompatibilityLevel=%s -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -sOutputFile="%s" -dAutoRotatePage\ s=/PageByPage -dAutoFilterColorImages=false -dColorImageFilter=/FlateEncode -dPDFSETTINGS=/prepress -c .setpdfwrite \ -f %s 再次在此行下方添加一行 GSCall %s %s -o %s %s (同样不要取消注释)

      在 PDFVer 下找到一行,其中读取 #PDFVer 1.4 并将其更改为 PDFVer,没有空格或后续字符。

      现在,在将此文件复制到 /etc/cups 前,保存并退出编辑,采用以下命令:

      sudo cp cups-pdfdownloaddir/extra/cups-pdf.conf /etc/cups

      在文本编辑器中进行编辑时要小心,因为 UNIX 和 Mac 环境中的换行符不同,可能会破坏脚本。您可以始终使用 perl 命令删除它们,但我有点偏执,更喜欢一开始就不要处理它们。

    4. 现在,您应该能够打开一个程序(例如 Word、Excel 等)并选择文件 >> 打印,并找到一个名为 CUPS-PDF 的可用打印机。将其打印到此打印机,您应该会发现默认情况下 pdf 存储在 /var/spool/cups-pdf/yourusername/ 中。


    此外,我认为这可能会有所帮助,因为它对我很有用:如果按照这些说明出现问题并且需要重新开始/清除它,请按以下步骤删除驱动程序:(1)从/usr/libexec/cups/backend中删除cups-pdf后端(2)从/etc/cups/中删除cups-pdf.conf(3)进入“系统偏好设置”>>“打印机和扫描仪”,然后删除CUPS-PDF打印机。


    这是我成功为自己设置pdf后端/过滤器的方法,但是readme文件中包含更多详细信息和其他自定义信息。希望这能帮助其他人!


    1
    我认为你的最终目标是“将用户文档打印成PDF并在发送到设备之前添加一些页眉...”,那么你是如何解决最后一部分的问题的呢?(我的回答只涵盖了第一部分——我不知道你的问题中第二部分的详细要求。) - Kurt Pfeifle
    最终,我将标题问题与生成PDF分开处理。一旦我生成了PDF,就可以在将其发送到设备之前,在我的应用程序中通过Cocoa的PDFDocument操作数据。 - Katie
    嗨Katie,我遇到了这个错误(sampletopdf),状态为13停止。 - Mohammad Sadiq Shaikh
    从codepoet下载源代码cups-pdf-for-mac-os-x。→ 404仓库未找到 - haba713

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接