为打印预览对话框 PrintPreviewDialog 添加保存到 PDF 文件按钮源代码详解

为打印预览对话框 PrintPreviewDialog 添加保存到 PDF 文件按钮源代码详解

前言

以 Windows 平台 Visual Studio 2017 C# 为开发工具,Windows Forms(.Net FrameWork 4.0)为框架,创建创建自定义打印预览对话框,并添加自定义按钮,以将打印文档内容保存到 PDF 文件。

1、创建自定义打印预览对话框 CustomPrintPreviewDialog

在项目中添加类,命名为 CustomPrintPreviewDialog : PrintPreviewDialog

csharp 复制代码
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace 命名空间
{
    public partial class CustomPrintPreviewDialog : PrintPreviewDialog//以原始打印预览为基类
    {
    }
}    

2、自定义打印预览对话框内部按钮和事件

2.1、自定义打印预览对话框内部按钮和事件

csharp 复制代码
using static 命名空间.PublicStaticClass;

namespace 命名空间
{
    public partial class CustomPrintPreviewDialog : PrintPreviewDialog
    {
        /// <summary>页面设置</summary>
        private PageSetupDialog pageSetupDialog = new PageSetupDialog();
        /// <summary>当前打印文档</summary>
        private PrintDocument CurrentDocument;
        /// <summary>获取和设置当前打印文档</summary>
        public new PrintDocument Document
        {
            get => CurrentDocument;
            set
            {
                CurrentDocument = value;
                base.Document = value;
            }
        }
       
        /// <summary>自定义打印预览对话框</summary>
        public CustomPrintPreviewDialog()
        {
            // 获取打印预览对话框原生工具栏
            if (!(this.Controls["toolStrip1"] is ToolStrip toolStrip)) return;

            //初始化页面设置
            pageSetupDialog = new PageSetupDialog
            {
                EnableMetric = true//打开毫米为单位,否则为1/100英寸
            };
            
            // 添加页面设置按钮,和内部单击事件
            ToolStripButton PrintSettingsButton = new ToolStripButton("页面设置", null, (s, e) => PrintSettingsButton_Click())
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,// 显示样式
                Image = Properties.Resources.PageSetup,//自定义按钮图标图像
                ImageScaling = ToolStripItemImageScaling.SizeToFit,
                Size = new Size(120, 40),// 设置按钮大小
                Margin = new Padding(20, 2, 5, 2),// 设置边距控制位置
                Alignment = ToolStripItemAlignment.Left,//.Right// 设置对齐方式
            };
            toolStrip.Items.Insert(0, PrintSettingsButton);//插入到PrintPreviewDialog工具栏最前面

            // 添加保存为PDF文件按钮,和内部单击事件
            ToolStripButton SavePDFButton = new ToolStripButton("保存为 PDF", null, (s, e) => PrintToPDF())
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
                Image = Properties.Resources.PDFFile,
                ImageScaling = ToolStripItemImageScaling.SizeToFit,
                ToolTipText = "保存为 PDF 文件"
            };
            toolStrip.Items.Insert(10, SavePDFButton);//插入第10个图标位置
        }
        
        /// <summary>打印设置按钮单击</summary>
        private void PrintSettingsButton_Click()
        {
            pageSetupDialog.Document = this.PrintPreviewControl.Document;
            pageSetupDialog.PageSettings = this.PrintPreviewControl.Document.DefaultPageSettings;

            if (pageSetupDialog.ShowDialog() == DialogResult.OK)
            {
                this.Document.DefaultPageSettings = pageSetupDialog.PageSettings;
                this.PrintPreviewControl.InvalidatePreview();//刷新预览
            }
        }

        /// <summary>打印到PDF文件</summary>
        private void PrintToPDF()
        {
            if (CurrentDocument == null)
            {
                MessageBox.Show("没有可打印的文档", "提示",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            string PDFFilePath = string.Empty;
            switch (printResultTableType)
            {
                case PrintResultTableType.AdcpDischargeMeasureResults:
                    PDFFilePath = SiteMeasureResultsFile.Replace(".SRF", "_ADCP流量测验记载表.PDF");
                    break;
                case PrintResultTableType.AdcpVelocityDirectionResults:
                    PDFFilePath = SiteMeasureResultsFile.Replace(".SRF", "_ADCP流速流向成果表.PDF");
                    break;
                case PrintResultTableType.PrintPreviewFormGraphics:
                    if (string.IsNullOrEmpty(ProjectDirectory))
                    {
                        PDFFilePath = Application.StartupPath + $"\\{ActiveFormName}窗体图形.PDF";
                    }
                    else
                    {
                        PDFFilePath = ProjectDirectory + $"\\{ActiveFormName}窗体图形.PDF";
                    }
                    break;
                case PrintResultTableType.PrintPreviewGraphics:
                    if (string.IsNullOrEmpty(ProjectDirectory))
                    {
                        PDFFilePath = Application.StartupPath + $"\\{ActiveFormName}图形.PDF";
                    }
                    else
                    {
                        PDFFilePath = ProjectDirectory + $"\\{ActiveFormName}图形.PDF";
                    }
                    break;
            }
            string PrinterString = string.Empty;
            if (CheckPdfPrinterExists(out PrinterString))
            {
                using (PrintDialog printDialog = new PrintDialog())
                {
                    // 配置打印设置
                    PrinterSettings printerSettings = new PrinterSettings
                    {
                        PrinterName = PrinterString,//PDF 虚拟打印机名称
                        PrintToFile = true,//打开打印到文件
                        PrintFileName = PDFFilePath//打印的PDF文件路径名称
                    };

                    printDialog.Document = CurrentDocument;
                    printDialog.PrinterSettings = printerSettings;
                   // printDialog.UseEXDialog = true;

                    // 执行打印
                    CurrentDocument.PrinterSettings = printerSettings;
                    CurrentDocument.Print();

                    MessageBox.Show($"PDF文件已成功保存到:\r\n\r\n{PDFFilePath}", "导出成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("未找到 Adobe 或微软 PDF 打印机","提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            }
        }


        /// <summary>检查 PDF虚拟打印机</summary>
        /// <param name="PrinterString">输出 PDF 打印机名称</param>
        /// <returns>返回是否存在 PDF 虚拟打印机</returns>
        private bool CheckPdfPrinterExists(out string PrinterString)
        {
            foreach (string printer in PrinterSettings.InstalledPrinters)
            {
                if (printer.Contains("Microsoft Print to PDF") || printer.Contains("Adobe PDF") || printer.Contains("Acrobat Distiller"))
                {
                    PrinterString = printer;
                    return true;
                }
            }
            PrinterString = string.Empty;
            return false;
        }
    }
}    

2.2、公共静态类和打印预览分类枚举

csharp 复制代码
namespace 命名空间
{
    /// <summary>公共静态类</summary>
    public static class PublicStaticClass
    {
        /// <summary>打印表类型</summary>
        public static PrintResultTableType printResultTableType;
        ///<summary>活动窗体名称</summary>
        public static string ActiveFormName = string.Empty;
    }
    /// <summary>打印成果表类型</summary>
    public enum PrintResultTableType
    {
        /// <summary>打印预览ADCP流量测验成果表</summary>
        AdcpDischargeMeasureResults = 0,
        /// <summary>打印预览ADCP流速流向成果表</summary>
        AdcpVelocityDirectionResults = 1,
        /// <summary>打印预览图形</summary>
        PrintPreviewGraphics = 2,
        /// <summary>打印预览窗体图形</summary>
        PrintPreviewFormGraphics = 3,
    }
}    

2.3、主窗调用自定义打印预览对话框

主窗体为MDI,以打印子窗体图像为例。

csharp 复制代码
using static 命名空间.PublicStaticClass;
namespace 命名空间
{
   public partial class AdcpProcesMainForm : Form
   {
        /// <summary>打印文档</summary>
        private PrintDocument PrintDocument = null;

        public AdcpProcesMainForm()
        {
            InitializeComponent();
            this.MdiChildActivate += OnMdiChildActivated;
        }
        
        /// <summary>当前活动子窗口</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnMdiChildActivated(object sender, EventArgs e)
        {
            var activeChild = this.ActiveMdiChild;
            if (activeChild != null)
            {
                ActiveFormName =activeChild.Text;
            }
        }
        
        private void PrintPreviewFormGraphicsMenu_Click(object sender, EventArgs e)
        {
            var activeChild = this.ActiveMdiChild;
            if (this.ActiveMdiChild != null)
            {
                printResultTableType = PrintResultTableType.PrintPreviewFormGraphics;
                
                //this.Hide();//隐藏主窗,配合Preview.FormClosed。

                PrintDocument = new PrintDocument();
                // 自定义打印预览
                CustomPrintPreviewDialog Preview = new CustomPrintPreviewDialog
                {
                    // ShowIcon = false,
                    StartPosition = FormStartPosition.CenterScreen,
                    WindowState = FormWindowState.Maximized,
                    Icon = Properties.Resources.AdcpTable, // 设置自定义打印预览图标
                    Text = "窗体打印预览",            // 设置窗口标题
                    Height = Screen.PrimaryScreen.Bounds.Height,
                    Width = Screen.PrimaryScreen.Bounds.Width,
                    FormBorderStyle = FormBorderStyle.FixedDialog,
                };

                // 捕获子窗体的图形区域
                Bitmap FormImage = new Bitmap(activeChild.Width, activeChild.Height);

                activeChild.DrawToBitmap(FormImage, new Rectangle(0, 0, FormImage.Width, FormImage.Height));

                PrintDocument.PrintPage += (s, args) =>
                {
                    // 计算居中打印位置
                    Rectangle printArea = args.MarginBounds;
                    if (FormImage.Width > printArea.Width || FormImage.Height > printArea.Height)
                    {
                        // 按比例缩放
                        Size newSize = FitSize(FormImage.Size, printArea.Size);
                        int x = printArea.X + (printArea.Width - newSize.Width) / 2;
                        int y = printArea.Y + (printArea.Height - newSize.Height) / 2;

                        args.Graphics.DrawImage(FormImage,
                            new Rectangle(x, y, newSize.Width, newSize.Height));
                    }
                    else
                    {
                        // 居中打印
                        int x = printArea.X + (printArea.Width - FormImage.Width) / 2;
                        int y = printArea.Y + (printArea.Height - FormImage.Height) / 2;
                        args.Graphics.DrawImage(FormImage, x, y);
                    }
                };

                /// <summary>打印预览窗体关闭后,恢复主窗显示</summary>
                //Preview.FormClosed += (s, args) =>
                // {
                //     this.Show(); // 预览关闭时重新显示主窗体
                //     this.Activate(); // 激活主窗体获得焦点
                // };

                Preview.Document = PrintDocument;

                if (FormImage.Width > FormImage.Height)
                {
                    Preview.Document.DefaultPageSettings.Landscape = true;
                    Preview.Landscape = true;
                }
                else
                {
                    Preview.Document.DefaultPageSettings.Landscape = false;
                    Preview.Landscape = false;
                }

                Preview.ShowDialog(this);
            }
        }
    }    
}

3、自定义打印预览对话框外部按钮

3.1、自定义打印预览对话框外部按钮

csharp 复制代码
namespace 命名空间
{
    public partial class CustomPrintPreviewDialog : PrintPreviewDialog
    {
        /// <summary>页面设置</summary>
        private PageSetupDialog pageSetupDialog = new PageSetupDialog();
        /// <summary>保存到PDF按钮事件</summary>
        public event EventHandler SavePDFButtonClick;
        
        /// <summary>自定义打印预览对话框</summary>
        public CustomPrintPreviewDialog()
        {
            // 获取打印预览对话框原生工具栏
            if (!(this.Controls["toolStrip1"] is ToolStrip toolStrip)) return;

            //初始化页面设置
            pageSetupDialog = new PageSetupDialog
            {
                EnableMetric = true//打开毫米为单位,否则为1/100英寸
            };
            
            // 添加页面设置按钮,和内部单击事件
            ToolStripButton PrintSettingsButton = new ToolStripButton("页面设置", null, (s, e) => PrintSettingsButton_Click())
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,// 显示样式
                Image = Properties.Resources.PageSetup,//自定义按钮图标图像
                ImageScaling = ToolStripItemImageScaling.SizeToFit,
                Size = new Size(120, 40),// 设置按钮大小
                Margin = new Padding(20, 2, 5, 2),// 设置边距控制位置
                Alignment = ToolStripItemAlignment.Left,//.Right// 设置对齐方式
            };
            toolStrip.Items.Insert(0, PrintSettingsButton);//插入到PrintPreviewDialog工具栏最前面

            // 添加保存为PDF文件按钮,和外部单击事件
            ToolStripButton SavePDFButton = new ToolStripButton("保存为 PDF", null, (s, e) => SavePDFButtonClick?.Invoke(this, e))
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
                Image = Properties.Resources.PDFFile,
                ImageScaling = ToolStripItemImageScaling.SizeToFit,
                ToolTipText = "保存为 PDF 文件"
            };
            toolStrip.Items.Insert(10, SavePDFButton);//插入第10个图标位置
        }
        
        /// <summary>打印设置按钮单击</summary>
        private void PrintSettingsButton_Click()
        {
            pageSetupDialog.Document = this.PrintPreviewControl.Document;
            pageSetupDialog.PageSettings = this.PrintPreviewControl.Document.DefaultPageSettings;

            if (pageSetupDialog.ShowDialog() == DialogResult.OK)
            {
                this.Document.DefaultPageSettings = pageSetupDialog.PageSettings;
                this.PrintPreviewControl.InvalidatePreview();//刷新预览
            }
        }
    }
}    

3.2、公共静态类和打印预览分类枚举

csharp 复制代码
namespace 命名空间
{
    /// <summary>公共静态类</summary>
    public static class PublicStaticClass
    {
        /// <summary>打印表类型</summary>
        public static PrintResultTableType printResultTableType;
        ///<summary>活动窗体名称</summary>
        public static string ActiveFormName = string.Empty;
    }
    /// <summary>打印成果表类型</summary>
    public enum PrintResultTableType
    {
        /// <summary>打印预览ADCP流量测验成果表</summary>
        AdcpDischargeMeasureResults = 0,
        /// <summary>打印预览ADCP流速流向成果表</summary>
        AdcpVelocityDirectionResults = 1,
        /// <summary>打印预览图形</summary>
        PrintPreviewGraphics = 2,
        /// <summary>打印预览窗体图形</summary>
        PrintPreviewFormGraphics = 3,
    }
}    

3.3、主窗调用自定义打印预览对话框

csharp 复制代码
namespace 命名空间
{
   public partial class AdcpProcesMainForm : Form
   {
        /// <summary>打印文档</summary>
        private PrintDocument PrintDocument = null;
        
        public AdcpProcesMainForm()
        {
            InitializeComponent();
            this.MdiChildActivate += OnMdiChildActivated;
        }
        /// <summary>当前活动子窗口</summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnMdiChildActivated(object sender, EventArgs e)
        {
            var activeChild = this.ActiveMdiChild;
            if (activeChild != null)
            {
                ActiveFormName =activeChild.Text;
            }
        }

  private void PrintPreviewFormGraphicsMenu_Click(object sender, EventArgs e)
        {
            var activeChild = this.ActiveMdiChild;
            if (this.ActiveMdiChild != null)
            {
                printResultTableType = PrintResultTableType.PrintPreviewFormGraphics;
                //this.Hide();

                PrintDocument = new PrintDocument();
                // 打印预览
                CustomPrintPreviewDialog Preview = new CustomPrintPreviewDialog
                {
                    // ShowIcon = false,
                    StartPosition = FormStartPosition.CenterScreen,
                    WindowState = FormWindowState.Maximized,
                    Icon = Properties.Resources.AdcpTable, // 设置系统信息图标
                    Text = "窗体打印预览",            // 设置窗口标题
                    Height = Screen.PrimaryScreen.Bounds.Height,
                    Width = Screen.PrimaryScreen.Bounds.Width,
                    FormBorderStyle = FormBorderStyle.FixedDialog,
                };

                // 捕获子窗体的图形区域
                Bitmap FormImage = new Bitmap(activeChild.Width, activeChild.Height);
                //Bitmap FormImage = new Bitmap(activeChild.ClientSize.Width, activeChild.ClientSize.Height );

                activeChild.DrawToBitmap(FormImage, new Rectangle(0, 0, FormImage.Width, FormImage.Height));

                PrintDocument.PrintPage += (s, args) =>
                {

                    // 计算居中打印位置
                    Rectangle printArea = args.MarginBounds;
                    if (FormImage.Width > printArea.Width || FormImage.Height > printArea.Height)
                    {
                        // 按比例缩放
                        Size newSize = FitSize(FormImage.Size, printArea.Size);
                        int x = printArea.X + (printArea.Width - newSize.Width) / 2;
                        int y = printArea.Y + (printArea.Height - newSize.Height) / 2;

                        args.Graphics.DrawImage(FormImage,
                            new Rectangle(x, y, newSize.Width, newSize.Height));
                    }
                    else
                    {
                        // 居中打印
                        int x = printArea.X + (printArea.Width - FormImage.Width) / 2;
                        int y = printArea.Y + (printArea.Height - FormImage.Height) / 2;
                        args.Graphics.DrawImage(FormImage, x, y);
                    }
                };

                //Preview.FormClosed += (s, args) =>
                // {
                //     this.Show(); // 预览关闭时重新显示主窗体
                //     this.Activate(); // 激活主窗体获得焦点
                // };

                Preview.Document = PrintDocument;

                if (FormImage.Width > FormImage.Height)
                {
                    Preview.Document.DefaultPageSettings.Landscape = true;
                    Preview.Landscape = true;
                }
                else
                {
                    Preview.Document.DefaultPageSettings.Landscape = false;
                    Preview.Landscape = false;
                }

                Preview.SavePDFButtonClick += SavePDFButton_Click;//按钮事件
                Preview.ShowDialog(this);//
            }
        }

        /// <summary>保存为PDF文件</summary>
        /// <param name="sender"></param>
        /// <param name="e">事件基类</param>
        private void SavePDFButton_Click(object sender, EventArgs e)
        {
            string PrinterString = string.Empty;
            if (CheckPdfPrinterExists(out PrinterString))//检查和获取PDF虚拟打印机名称
            {
                string PDFFilePath = string.Empty;

                switch (printResultTableType)
                {
                    case PrintResultTableType.AdcpDischargeMeasureResults:
                        PDFFilePath = SiteMeasureResultsFile.Replace(".SRF", "_ADCP流量测验记载表.PDF");
                        break;
                    case PrintResultTableType.AdcpVelocityDirectionResults:
                        PDFFilePath = SiteMeasureResultsFile.Replace(".SRF", "_ADCP流速流向成果表.PDF");
                        break;
                    case PrintResultTableType.PrintPreviewFormGraphics:
                        if (string.IsNullOrEmpty(ProjectDirectory))
                        {
                            PDFFilePath = Application.StartupPath + $"\\{ActiveFormName}窗体图形.PDF";
                        }
                        else
                        {
                            PDFFilePath = ProjectDirectory + $"\\{ActiveFormName}窗体图形.PDF";
                        }
                        break;
                    case PrintResultTableType.PrintPreviewGraphics:
                        if (string.IsNullOrEmpty(ProjectDirectory))
                        {
                            PDFFilePath = Application.StartupPath + $"\\{ActiveFormName}图形.PDF";
                        }
                        else
                        {
                            PDFFilePath = ProjectDirectory + $"\\{ActiveFormName}图形.PDF";
                        }
                        break;
                }

                if (PrintDocument != null)
                {
                    using (PrintDialog printDialog = new PrintDialog())
                    {
                        // 配置打印设置
                        PrinterSettings printerSettings = new PrinterSettings
                        {
                            PrinterName = PrinterString,//PDF 虚拟打印机名称
                            PrintToFile = true,//打开打印到文件
                            PrintFileName = PDFFilePath//打印的PDF文件路径名称
                        };

                        printDialog.Document = PrintDocument;
                        printDialog.PrinterSettings = printerSettings;
                        // printDialog.UseEXDialog = true;

                        // 执行打印
                        PrintDocument.PrinterSettings = printerSettings;
                        PrintDocument.Print();

                        MessageBox.Show($"PDF文件已成功保存到:\r\n\r\n{PDFFilePath}", "导出成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            else
            {
                //throw new Exception("未找到 Adobe 或微软 PDF 打印机");
                MessageBox.Show("未找到 Adobe 或微软 PDF 打印机", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>检查 PDF虚拟打印机</summary>
        /// <param name="PrinterString">输出 PDF 打印机名称</param>
        /// <returns>返回是否存在 PDF 虚拟打印机</returns>
        private bool CheckPdfPrinterExists(out string PrinterString)
        {
            foreach (string printer in PrinterSettings.InstalledPrinters)
            {
                if (printer.Contains("Microsoft Print to PDF") || printer.Contains("Adobe PDF") || printer.Contains("Acrobat Distiller"))
                {
                    PrinterString = printer;
                    return true;
                }
            }
            PrinterString = string.Empty;
            return false;
        }
     }   
}

4、Adobe PDF 与 Microsoft Print to PDF 的转换特点

4.1、Microsoft Print to PDF 转换 PDF

采用 Microsoft Print to PDF 虚拟打印机转换 PDF 文件,如果是窗体或图像,像素没有 Adobe PDF 虚拟打印机转换 PDF 清晰。

Microsoft Print to PDF 虚拟打印设置,可以设置 PrintToFile = true 直接指定文件输出:

csharp 复制代码
         PrinterSettings printerSettings = new PrinterSettings
         {
             PrinterName = PrinterString,//PDF 虚拟打印机名称
             PrintToFile = true,//打开打印到文件
             PrintFileName = PDFFilePath//打印的PDF文件路径名称
         };

4.2、Adobe PDF 转换 PDF

采用 Adobe PDF 虚拟打印机转换 PDF 文件,图像像素明显清晰。设置 PrintToFile = true 直接指定文件输出,输出的文件类型为 PostScript,文件扩展名为 PS,需要再转换为 PDF 文件,原创说明网络上很难搜索到这方面的详细描叙。设置 PrintToFile = false 直接可以输出 PDF 文件,默认输出到系统文档目录 Document\document.pdf 输出,不能直接定义文件名和目录。

需要指定输出 PDF 文件可以采用输出先输出 *.PS,再转换为 *.PDF。

转换关键,计算机必须安装有 Adobo Acrobat Pro ,在项目中引用 COM 类库 Acrobat Distiller 或 Acrobat。

引用 COM 类库 Acrobat Distiller 后声明:

复制代码
using ACRODISTXLib;
csharp 复制代码
         String PSFile = PDFFilePath.Replace(".PDF", ".PS");
         PrinterSettings printerSettings = new PrinterSettings
         {
             PrinterName = PrinterString,//PDF 虚拟打印机名称
             PrintToFile = true,//打开打印到文件
             PrintFileName = PSFilePath//打印的PS文件路径名称
         };
         CurrentPrintDocument.PrintController = new StandardPrintController();

         CurrentPrintDocument.PrinterSettings = printerSettings;
         CurrentPrintDocument.DefaultPageSettings.Landscape = Landscape;

         CurrentPrintDocument.Print();

         System.Threading.Thread.Sleep(200);
         
         if (File.Exists(PSFilePath))
         {
             PdfDistiller PdfDistiller = new PdfDistiller();
             PdfDistiller.FileToPDF(PSFile, PDFFilePath, "Standard");

             if (File.Exists(PDFFilePath))
             {
                String LOGFile = PDFFilePath.Replace(".PDF", ".LOG");
                File.Delete(PSFile);//删除转换过程文件
                File.Delete(LOGFile);//删除转换日志文件
                MessageBox.Show($"PDF文件已成功保存到:\r\n\r\n{PDFFilePath}", "导出成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
             }

             Marshal.ReleaseComObject(PdfDistiller);//卸载 Distiller 进程
             PdfDistiller = null;
        }     

转换结果:

其它转换中解决的问题:

1、首先提示,上述代码中没有处理错误消息!

2、使用 PrintToFile = true 打印到 PS 文件,必须取消勾选仅依靠系统字体;不使用文档字体,否则程序弹出错误。

通过程序修改注册表可以取消勾选仅依靠系统字体;不使用文档字体

信息位置:\HKEY_CURRENT_USER\Printers\DevModePerUser\Adobe PDF

主键:HKEY_CURRENT_USER

子健:Printers\DevModePerUser

键名:Adobe PDF

键值:二进制 Binary 第 1164 个数设置为 0

复制代码
      SubKey = "Printers\\DevModePerUser\\";
      object AdobePDFobject = null;
      PdfRegKey(RegDomain.CurrentUser, SubKey, "Adobe PDF", ref AdobePDFobject, RegValueKind.Binary);//读注册表

      byte[] AdobePDFArray = (byte[])AdobePDFobject;
      AdobePDFArray[1164] = 0;
      AdobePDFobject = AdobePDFArray;

      PdfRegKey(RegDomain.CurrentUser, SubKey, "Adobe PDF", ref AdobePDFobject, RegValueKind.Binary,true );//写注册表

该设置值写入了很多地方:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\Adobe PDF\PrinterDriverData\DistillerHostFontHasMostFonts

  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Print\Printers\Adobe PDF\PrinterDriverData\DistillerHostFontHasMostFonts

  • HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Printers\Adobe PDF\PrinterDriverData\DistillerHostFontHasMostFonts

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\Adobe PDF\PrinterDriverData\DistillerHostFontHasMostFonts

  • HKEY_CURRENT_USER\Printers\DevModePerUser\Adobe PDF

  • HKEY_CURRENT_USER\Printers\DevModes2\Adobe PDF

只有使用用户权限修改 HKEY_CURRENT_USER\Printers\DevModePerUser\Adobe PDF 即可。

3、PS 转换为 PDF 默认弹出安全性确定

可以运行 Acrobat Distiller 勾选信任通过所有文件:

通过程序修改注册表可以勾选信任通过所有文件:

复制代码
  SubKey = "Software\\Adobe\\Acrobat Distiller\\DC\\Preferences\\";  //通过所有输入文件的安全性,不弹出安全性对话框
  object bTrustAllFiles =new byte[] {0};
  PdfRegKey(RegDomain.CurrentUser, SubKey, "bTrustAllFiles", ref bTrustAllFiles, RegValueKind.Binary, true);

以上针对 Adobo Acrobat Pro 2023 版本。