[英]Excel VBA, “Print” secured pdf to another pdf file using Shell
[英]Print one page of pdf document from VBA using shell
我有 PDF 文檔,這些文檔大多是多頁的,但我只想從每個文檔中打印第 1 頁。 下面打印整個 pdf 文檔。 我已經看到對參數 page=1 的引用,但似乎沒有將其放入以下正確的位置:-
Shell ("""" & "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" & """/p /h """ & strPathAndFilename & """")
有人可以告訴我如何獲得上述 shell 命令來打印文檔的第 1 頁。 非常感謝。
使用這種方法,理論上應該是不可能的,歇斯底里/歷史上 Adobe 支持在這條線上采取的做法是。 不清楚它是否違反 EULA 對 Reader 用戶的可編程幫助。
...也有免費的閱讀器。 命令行在 1992 年左右被微軟宣布過時......
因此不支持 Adobe 方法(只是 Acrobat Reader 的流行濫用,包括 MS 商業印刷)。 有解決方法。
因此,要直接回答您的問題,您只需將第 1 頁拆分為僅將其發送到 Acrobat Reader 以盲打印onepage.pdf
Acrobat API 通過 vba 有不同的方法來指定只轉換一頁。 但那是使用昂貴的方法來完成這樣一個“簡單”的任務。
因此,您的解決方案有 3 條更常見的途徑
wscript "pdf_print_sendkeys.vbs" "C:\Users\WDAGUtilityAccount\Desktop\SandBox\apps\PDF\Adobe\Reader\AcroRd32.exe" "C:\test.pdf" "1"
對於更簡單的前 2 個選項,有許多好的解決方案
免責聲明我支持 SumatraPDF,它只使用一個便攜式 exe(保留為二進制文件是 FOSS)可以輕松地在命令行打印第 1 頁,但是它只會打印為圖像,如果可以接受的話應該會很好地為您服務。
謝謝您的答復。 我可以使用 Acrobat Pro 來做到這一點,但只接受 /p 參數並讓用戶將打印的 output 限制在第一頁。
請嘗試下一個方法。 它啟動 Adobe Acrobat Reader DC 打印 window 然后找到它的控制必要的處理程序並根據打印需要更改/按下它們。 SendKeys
確實意味着一種可靠的方法,如果您移動鼠標並將焦點從 window 更改它應該起作用的位置:
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwnd1 As LongPtr, _
ByVal hwnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, _
ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
Private Declare PtrSafe Function GetNextWindow Lib "user32.dll" Alias "GetWindow" (ByVal hwnd As LongPtr, _
ByVal wFlag As Long) As LongPtr
然后復制同一模塊中的下一個代碼:
Sub PrintPdfSpecificPage()
Dim strPathAndFilename As String, strPages As String
strPathAndFilename = "your pdf file full name" 'use here the real full name
strPages = "2" 'the page to be printed number
'it may be "1,2" or "2-4"...
'launch the Adobe Acrobat DC printing window:
Shell ("""" & "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" & """/p """ & strPathAndFilename & """")
'wait for the window to expose its handle and continue the process of the necessary controls identification (their handles):
Dim prHwnd As LongPtr, grBoxHw1 As LongPtr, grNext4 As LongPtr, grNext20 As LongPtr
Dim pgHwnd As LongPtr, pgNHwnd As LongPtr, printHwnd As LongPtr, nrPag As String
Const BM_CLICK = &HF5, WM_SETTEXT = &HC
Const WM_LBUTTON_DOWN = &H201, WM_LBUTTON_UP = &H202
Do While prHwnd = 0
prHwnd = FindWindow("#32770", "Print")
DoEvents
Loop
Application.Wait Now + TimeValue("00:00:02") 'wait two seconds for the whole window to expose its controls handles
grBoxHw1 = FindWindowEx(prHwnd, 0, "GroupBox", vbNullString) 'the first child GroupBox window
grNext4 = getNextChildX(grBoxHw1, 3, "GroupBox"): Hex (grNext4) 'find the fourth control handle
pgHwnd = FindWindowEx(grNext4, 0, "Button", "Pa&ges") 'find the radio button accepting pages interval handler
SendMessage pgHwnd, WM_LBUTTON_DOWN, 0&, 0&
SendMessage pgHwnd, BM_CLICK, 0&, ByVal 0& 'check the radio button
pgNHwnd = FindWindowEx(grNext4, 0, "RICHEDIT50W", vbNullString) 'find the window where the page number to be dropped
SendMessage pgNHwnd, WM_LBUTTON_DOWN, ByVal 0&, 0& 'without this lines, the page number is changed, but the changing event is not triggered...
SendMessage pgNHwnd, WM_LBUTTON_UP, ByVal 0&, 0&
SendMessage pgNHwnd, WM_SETTEXT, 0&, ByVal strPages 'place the page to be printed number
SendMessage pgNHwnd, WM_LBUTTON_DOWN, ByVal 0&, 0&
SendMessage pgNHwnd, WM_LBUTTON_UP, ByVal 0&, 0&
grNext20 = getNextChildX(grBoxHw1, 19, "GroupBox"): Debug.Print 'find the GroupBox where the Print button exists
printHwnd = FindWindowEx(grNext20, 0&, "Button", "Print") 'find the Print button handle
SendMessage printHwnd, BM_CLICK, 0&, ByVal 0& 'press/click the Print button:
'close the Acrobat main Window:
Dim acrobatHwnd As LongPtr
Const WM_SYSCOMMAND = &H112, SC_CLOSE = &HF060
'wait for the printing Window to be closed, to let Acrobat expose its main window handle:
Do While acrobatHwnd = 0
acrobatHwnd = FindWindow("AcrobatSDIWindow", "Adobe Acrobat Reader DC (32-bit)")
DoEvents
Loop
SendMessage acrobatHwnd, &H10, 0&, 0& 'close the main Acrobat Reader window
End Sub
Function getNextChildX(parentHwnd As LongPtr, x As Long, strClass As String) As LongPtr
Dim nextChild As LongPtr, i As Long
nextChild = FindWindowEx(parentHwnd, 0&, strClass, vbNullString)
For i = 1 To x
nextChild = GetNextWindow(nextChild, 2)
Next i
getNextChildX = nextChild
End Function
它比我想象的要復雜一些,但在我的環境中工作......
請測試它並發送一些反饋
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.