使用 GhostScript 打印 PDF

Posted

技术标签:

【中文标题】使用 GhostScript 打印 PDF【英文标题】:Print PDF using GhostScript 【发布时间】:2013-12-11 16:16:18 【问题描述】:

在以下问题上,我需要您的支持,因为它让我有一段时间了。我们有一个小的c# 实用程序,它使用GhostScript 打印给定PDF。此打印按预期打印,但未能保留页面格式。但是,当我切换Adobe Acrobat 代替GhostScript 时,页面会按预期打印。所以我想,我在 GhostScript 的命令行参数上犯了一些明显的错误。

背景

以下是核心 c# 逻辑,它在每个页面上打印具有不同样式的给定 PDF 文件。给定的 PDF 文件有页面;

    字体样式和颜色不一致 有些页面的字体大小正常,而其他页面的字体则超小 一些页面有推荐的边距,但其他页面的边距非常小 部分页面为彩色,其余为灰色。 有些页面是横向的,而另一些是纵向的

简而言之,我尝试打印的 PDF 只不过是众多具有不同字体样式、大小和边距的小型 pdf 文档的合并(将单个 pdf 合并为一个大 pdf)。

问题

以下逻辑使用GhostScript(v9.02) 打印PDF 文件。尽管以下逻辑打印任何给定的 PDF,但它无法保留页面格式,包括 页眉、页脚、字体大小、边距、方向(我的 pdf 文件有横向和纵向页面)。

有趣的是,如果我使用 acrobat reader 打印相同的 PDF,那么它将按预期与所有页面级格式一起打印。

PDF 样本:First section、Second section

  void PrintDocument()
    
         var psInfo = new ProcessStartInfo();
                psInfo.Arguments =
                    String.Format(
                        " -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=1 -sDEVICE=ljet4 -sOutputFile=\"\\\\spool\\0\" \"1\"",
                        GetDefaultPrinter(), @"C:\PDFOutput\test.pdf");
                psInfo.FileName = @"C:\Program Files\gs\gs9.10\bin\gswin64c.exe";
                psInfo.UseShellExecute = false;

        using (var process= Process.Start(psInfo))
        
            process.WaitForExit();
        
    

【问题讨论】:

只是为了确保我理解您的问题:您的问题是否与合并 PDF 文件(而不是实际创建或真正打印 PDF)有关? @elgonzo,问题在于打印而不是合并。 现在我很困惑...如果只是关于打印而不是合并 PDF,您为什么要谈论 Acrobat 以及将单个 PDF 合并到一个更大的 PDF 中? 从我们项目的经验来看,GhostScript/GhostPDL (PCL)/GhostXPS 实际上与字体支持非常不一致,除非是面向ghost的DTP核心,否则都不应该在生产周期中使用。 也许您应该报告问题,以便解决问题。据我所知,Ghostscript 完全支持所有字体类型。当然,如果您不嵌入或不提供字体,那么您将获得替代品,但这不是应用程序的错。 【参考方案1】:

我想你之前问过这个问题,从你的代码示例中也很清楚你使用的是 GSView,而不是 Ghostscript

现在,虽然 GSView 确实使用 Ghostscript 来完成繁重的工作,但令人担心的是您无法区分这两个应用程序。

尽管您现在至少设法引用了 Ghostscript 版本,但您仍然没有提供可供查看的示例 PDF 文件,也没有提供命令行。您还需要提供一个命令行(不,我不准备通过阅读您的代码来组装它)并且您应该从命令行尝试这个,而不是在您自己的应用程序中,以表明它不是您的应用程序制作错误。

您应该考虑将 Ghostscript 升级到当前版本。

请注意,快速阅读您的代码表明您正在指定一些命令行选项(例如 -dPDFSETTINGS),这些选项仅适用于将文件转换为 PDF,不适用于任何其他目的(例如打印)。

所以正如我之前所说,提供一个样本文件来重现问题,以及一个导致问题的命令行(最好是 Ghostscript 命令行)。知道您使用的是哪台打印机可能也很有用,尽管我不太可能有一个副本来测试。

【讨论】:

感谢您的回复。 (1) 看了之后,我的印象是GsView是用GhostScript来打印PDF的。我想我需要回顾一下我的理解。 (2) 你能帮助我或指导我如何在没有 GSView 的情况下使用 GhostScript 打印 PDF 吗? (3) 关于示例 PDF,我可以向您保证一件事,该文档包含 NDA 和财务信息,因此我无法共享它。对于那个很抱歉。但肯定的是,我会寻找一些过时/旧的 PDF 文件(4)你是绝对正确的,由于缺乏知识,我正在尝试使用随机命令行选项。 根据您的建议,我修改了我的初始帖子和我的应用程序,它取代了 GSView 的使用,现在它完全依赖于 GhostScript。不过,这个问题继续持有良好。有什么帮助吗?? GSView确实使用了Ghostscript,但是命令行参数不一样。如果您无法共享导致问题的文档,我将无能为力。也许您可以创建一个可以共享的。要使用 Ghostscript 打印文件(在 Windows 下),您需要使用 mswinpr2 设备。 我附上了文件样本。实际上,我们在打印之前加入这些文件(一个接一个)。但是这个加入过程是由第三方完成的,因此我无法控制它。但是,这些单独的文档足以重现该问题。另外,正如您所建议的,我愿意使用 GhostScript 或 GS​​View 和 GhostScript 来打印文档。 app1.pdf 坏了,它包含 2 个 %%EOF 和 2 个 startxref 指令(应该只有 1 个)。 Ghostscript 在读取文件时会修复此问题。主要问题是这两个文件都使用了它们不提供的字体。每当发生这种情况时,您获得字体替换,即使使用 Acrobat 也是如此。 Acrobat 行为不同的原因是,在安装时,它会将 Windows 字体文件夹中的字体添加到它可以使用的字体中。您也可以通过添加 -sFONTPATH= 并可能通过修改 fontmap.gs 文件(这将需要您下载 GS 源)来为 Ghostscript 执行此操作【参考方案2】:

答案 - 2013 年 16 月 12 日更新

我设法修复了它,如果它可以帮助其他人,我想附上工作解决方案。特别感谢“KenS”,因为他花了很多时间指导我。

总而言之,我最终决定使用 GSView 和 GhostScript 来打印 PDF 以绕过 Adob​​e。核心逻辑如下;

 //PrintParamter is a custom data structure to capture file related info
private void PrintDocument(PrintParamter fs, string printerName = null)
        
            if (!File.Exists(fs.FullyQualifiedName)) return;

            var filename = fs.FullyQualifiedName ?? string.Empty;
            printerName = printerName ?? GetDefaultPrinter(); //get your printer here

            var processArgs = string.Format("-dAutoRotatePages=/All -dNOPAUSE -dBATCH -sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage -dEmbedAllFonts=true -dSubsetFonts=true -dPDFSETTINGS=/prepress -dNOPLATFONTS -sFONTPATH=\"C:\\Program Files\\gs\\gs9.10\\fonts\" -noquery -dNumCopies=1 -all -colour -printer \"0\" \"1\"", printerName, filename);
            try
            

                var gsProcessInfo = new ProcessStartInfo
                                        
                                            WindowStyle = ProcessWindowStyle.Hidden,
                                            FileName = gsViewEXEInstallationLocation,
                                            Arguments = processArgs
                                        ;
                using (var gsProcess = Process.Start(gsProcessInfo))
                

                    gsProcess.WaitForExit();

                

        

【讨论】:

【参考方案3】:

你可以使用GSPRINT。

我已经设法通过仅将 gsprint.exe/gswin64c.exe/gsdll64.dll 复制到一个目录中并从那里启动它来使其工作。

示例代码:

    // This uses gsprint (mind the paths)
    private const string gsPrintExecutable = @"C:\gs\gsprint.exe";
    private const string gsExecutable = @"C:\gs\gswin64c.exe";

    string pdfPath = @"C:\myShinyPDF.PDF"
    string printerName = "MY PRINTER";


    string processArgs = string.Format("-ghostscript \"0\" -copies=1 -all -printer \"1\" \"2\"", gsExecutable, printerName, pdfPath );

            var gsProcessInfo = new ProcessStartInfo
                                    
                                        WindowStyle = ProcessWindowStyle.Hidden,
                                        FileName = gsPrintExecutable ,
                                        Arguments = processArgs
                                    ;
            using (var gsProcess = Process.Start(gsProcessInfo))
            

                gsProcess.WaitForExit();

            

【讨论】:

【参考方案4】:

Process.Start() 中尝试以下命令:

gswin32c.exe -sDEVICE=mswinpr2 -dBATCH -dNOPAUSE -dNOPROMPT -dNoCancel -dPDFFitPage -sOutputFile="%printer%\\[printer_servername]\[printername]" "[filepath_to_pdf]"

在 C# 中应该是这样的:

string strCmdText = "gswin32c.exe -sDEVICE=mswinpr2 -dBATCH -dNOPAUSE -dNOPROMPT -dNoCancel -dPDFFitPage -sOutputFile=\"%printer%\\\\[printer_servername]\\[printername]\" \"[filepath_to_pdf]\"";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);

这会将指定的 PDF 文件放入打印队列。

注意- gswin32c.exe 必须与 C# 程序位于同一目录中。我没有测试过这段代码。

【讨论】:

以上是关于使用 GhostScript 打印 PDF的主要内容,如果未能解决你的问题,请参考以下文章

Ghostscript.NET 无法使用选定的打印机名称进行打印

打印时出现 GhostScript 图像质量问题

使用 Ghostscript.NET 包装器打印 PDF - 空白页

直接打印时 GhostScript 挂起

Ghostscript.net 打印 pdf 页面方向

使用 Ghostscript 打印时页面裁剪和旋转不正确