使用 GhostScript 打印 PDF

问题描述 投票:0回答:5

我需要您对以下问题的支持,因为它困扰了我一段时间。我们有一个小的

c#
实用程序,它使用
PDF
打印给定的
GhostScript
。按预期打印,但无法保留页面格式。但是,当我切换
Adobe Acrobat
代替
GhostScript
时,页面会按预期打印。所以我想,我在 GhostScript 的命令行参数上犯了一些明显的错误。

背景

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

  1. 字体样式和颜色不一致
  2. 一些页面具有正常字体大小,而其他页面则以超小字体打印
  3. 有些页面有建议的边距,但其他页面的边距非常小
  4. 部分页面是彩色的,其余页面是灰色的。
  5. 一些页面是横向风格,其他页面是纵向风格

简而言之,我想要打印的PDF只不过是众多具有不同字体样式、大小、边距的小尺寸pdf文档的合并(将各个pdf合并成一个大pdf)。

问题

以下逻辑使用

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

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

PDF 样本:第一部分第二部分

  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();
        }
    }
c# pdf printing ghostscript postscript
5个回答
3
投票

答案 - 更新 16/12/2013

我设法修复了它,并希望分享工作解决方案(如果有帮助的话)。特别感谢‘KenS’,他花了很多时间指导我。

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

 //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();
                   
                }
            
        }

2
投票

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

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

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

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

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

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


2
投票

您可以使用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();

            }

0
投票

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# 程序位于同一目录中。我还没有测试过这段代码。


0
投票

您可以使用免费库 PDFium 无声打印任何 PDF,任何其他非免费库都是纯粹的骗局。只需使用 NuGET 将 PDFium 免费库添加到您的项目中,这里是静态方法中的代码:

public static void PrintFileWithPDFium(string file, string printer_name, short copy_number = 1)
{
    // Create the printer settings for our printer
    PrinterSettings printerSettings = new PrinterSettings
    {
        PrinterName = printer_name,
        Copies = copy_number,
    };
    // Now print the PDF document
    using (PdfiumViewer.PdfDocument document = PdfiumViewer.PdfDocument.Load(file))
    {
        using (PrintDocument printDocument = document.CreatePrintDocument())
        {
            printDocument.PrinterSettings = printerSettings;
            //printDocument.DefaultPageSettings = pageSettings;
            printDocument.PrintController = new StandardPrintController();
            printDocument.OriginAtMargins = false;
            printDocument.Print();
        }
    }
}

有任何问题请评论这篇文章,我很高兴为您提供帮助

© www.soinside.com 2019 - 2024. All rights reserved.