You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA宏打印PDF需求:自定义选择打印机并调出打印对话框

实现PDF打印时选择打印机并调出打印对话框

下面提供两种可行方案,根据你的环境选择:

方案1:依赖Adobe Acrobat(推荐)

如果系统安装了Adobe Acrobat完整版(非Reader),可以利用其VBA对象模型直接调出打印对话框,支持选择打印机和设置参数:

Sub GetBOM()
    Dim strPth As String, strFile As String
    Dim acroPDDoc As Object
    
    strPth = "C:\"
    strFile = "X.pdf"
    
    Set acroPDDoc = CreateObject("AcroExch.PDDoc")
    
    If acroPDDoc.Open(strPth & strFile) Then
        ' 弹出打印对话框,用户可选择打印机、调整设置
        If Not acroPDDoc.PrintPagesSilent(0, acroPDDoc.GetNumPages - 1, 0, False) Then
            MsgBox "打印失败"
        End If
        acroPDDoc.Close
    Else
        MsgBox "无法打开指定PDF文件"
    End If
    
    Set acroPDDoc = Nothing
End Sub
  • PrintPagesSilent的第四个参数设为False时触发打印对话框;设为True则静默用默认打印机打印。
  • 未安装Acrobat完整版时此方法不可用,可改用方案2。

方案2:无第三方依赖(系统API实现)

通过Windows API调用打印对话框获取用户选择的打印机,再执行打印:

' 32位Excel声明,64位需添加PtrSafe关键字
Public Declare Function PrintDlg Lib "comdlg32.dll" Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
    ByVal Destination As String, ByVal Source As Long, ByVal Length As Long)

' 打印对话框结构体定义
Type PRINTDLG_TYPE
    lStructSize As Long
    hwndOwner As Long
    hDevMode As Long
    hDevNames As Long
    hDC As Long
    Flags As Long
    nFromPage As Integer
    nToPage As Integer
    nMinPage As Integer
    nMaxPage As Integer
    nCopies As Integer
    hInstance As Long
    lCustData As Long
    lpfnPrintHook As Long
    lpfnSetupHook As Long
    lpPrintTemplateName As String
    lpSetupTemplateName As String
    hPrintTemplate As Long
    hSetupTemplate As Long
End Type

Sub GetBOM()
    Dim strPth As String, strFile As String
    Dim pd As PRINTDLG_TYPE
    Dim result As Long
    
    strPth = "C:\"
    strFile = "X.pdf"
    
    ' 初始化对话框参数
    pd.lStructSize = Len(pd)
    pd.hwndOwner = 0
    pd.Flags = &H4 ' PD_RETURNDC:获取选中打印机的设备上下文
    
    ' 调出打印对话框
    result = PrintDlg(pd)
    
    If result = 1 Then ' 用户确认打印
        If Not PrintPDFWithPrinter(0, strPth & strFile, pd.hDevNames) Then
            MsgBox "打印失败"
        End If
    Else
        MsgBox "已取消打印"
    End If
End Sub

Public Function PrintPDFWithPrinter(xlHwnd As Long, FileName As String, hDevNames As Long) As Boolean
    Dim X As Long
    Dim printerName As String
    Dim devNamesData As String
    Dim offset As Integer
    
    ' 从hDevNames中提取打印机名称
    devNamesData = Space$(256)
    CopyMemory ByVal devNamesData, ByVal hDevNames, 256
    offset = Asc(Mid$(devNamesData, 5, 1)) + Asc(Mid$(devNamesData, 6, 1)) * 256 + 7
    printerName = Mid$(devNamesData, offset)
    
    ' 指定打印机执行打印
    X = ShellExecute(xlHwnd, "PrintTo", FileName, Chr$(34) & printerName & Chr$(34), 0&, 3)
    
    PrintPDFWithPrinter = (X > 32)
End Function

64位Excel适配说明

将所有API声明前添加PtrSafe关键字,例如:

Public Declare PtrSafe Function PrintDlg Lib "comdlg32.dll" Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long

注意事项

  • 确保PDF文件路径正确,避免因路径错误导致操作失败。
  • 方案1功能更完善,支持更多打印设置;方案2无需额外软件依赖,兼容性更广。

内容的提问来源于stack exchange,提问作者Vigna 65ST

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:33:09