嘿,朋友!如果你现在正盯着屏幕上堆积如山的PDF、Word文档叹气,手动一个个点击“打印”,那咱们得好好聊聊了。我是 Agnes,在这个领域摸爬滚打多年,见过太多人把时间浪费在重复劳动上。今天,我不给你整那些枯燥的教科书定义,咱们直接上手,用 Windows 最强大的“隐藏技能”——批处理(Batch)和 PowerShell,把你的打印工作流自动化。
别被“代码”两个字吓跑,我保证,这里的每一个字符都有它存在的意义,而且学会了,你下午就能提前下班。
为什么你要学这个?先看看那些头疼的场景
想象一下:法务部发来一份100页的合同,你需要打印其中第10、20、35页;或者,销售团队有50份报价单分散在不同的文件夹里,明天就要开会,你却还在纠结怎么全选打印?
手动操作?太慢了,而且容易出错。
批处理的核心思想很简单:让电脑帮你跑腿,你只管喝茶。 我们利用 Windows 自带的 rundll32、printui.dll 以及 PowerShell 的 COM 对象,来实现无需打开文档即可后台打印、指定范围打印、自动选择打印机等功能。
基础篇:一行命令搞定简单打印
首先,我们要打破一个误区:批处理打印,不需要你安装额外的软件,Windows 本身就有足够强大的工具。
1. 使用 rundll32 进行静默打印
这是最经典、兼容性最好的方法。rundll32.exe 是 Windows 的一个系统组件,它可以调用 DLL 中的函数。对于打印,我们利用的是 shell32.dll 中的 ShellExecuteEx 或者更直接的打印接口。
但其实,对于大多数普通文档(如 .txt, .pdf),最简单的方式是直接调用系统的关联程序,并传递 /p 参数(在 Windows 中,/p 通常代表“打印”)。
示例:打印单个 PDF 文件
假设你有一个文件 report.pdf,你想直接打印,而不打开 PDF 阅读器。
@echo off
:: 关闭回显,让屏幕清爽一点
set "FilePath=C:\Users\YourName\Documents\report.pdf"
set "PrinterName=Microsoft Print to PDF" :: 或者你的默认打印机名称
:: 方法一:使用 rundll32 调用 shell 执行打印
:: 注意:这种方法依赖于文件关联。如果 .pdf 关联的是 Adobe Reader,它会尝试打开并打印。
:: 更推荐的方法二,使用 PowerShell 调用 COM 对象,更稳定。
echo 正在打印 %FilePath% ...
start "" /wait "%FilePath%" /p
:: /p 参数的意思是“打印后退出程序”(适用于支持该参数的应用,如 Word, PowerPoint)
:: 如果应用不支持 /p,我们可以使用下面的 PowerShell 方案。
这里有个坑:start /p 并不是对所有程序都有效。Adobe Acrobat 支持 /p,但很多其他软件可能不支持。所以,我们需要更“底层”且通用的方法——PowerShell。
2. PowerShell:打印 PDF 的“黑科技”
PowerShell 是 Windows 10⁄11 的标配,它可以通过 COM 对象直接控制 Adobe Acrobat 或其他 PDF 阅读器。这是目前最可靠的批量打印 PDF 的方法。
示例:使用 PowerShell 打印 PDF
# 保存为 print_pdf.ps1
param(
[string]$FilePath = "C:\Users\YourName\Documents\report.pdf",
[string]$PrinterName = "" # 留空则使用默认打印机
)
# 检查文件是否存在
if (-not (Test-Path $FilePath)) {
Write-Error "文件不存在: $FilePath"
exit 1
}
# 创建 AcroExch.App 对象(需要 Adobe Acrobat 安装)
$acroApp = New-Object -ComObject AcroExch.App
$acroDoc = $acroApp.Open($FilePath, "")
if ($null -eq $acroDoc) {
Write-Error "无法打开文档: $FilePath"
exit 1
}
# 指定打印机(可选)
if ($PrinterName -ne "") {
$acroDoc.PrintPages(0, $acroDoc.GetNumPages() - 1, $true, $PrinterName)
} else {
# 使用默认打印机打印所有页面
$acroDoc.PrintPages(0, $acroDoc.GetNumPages() - 1, $true)
}
# 关闭文档,释放对象
$acroDoc.Close($true)
$acroApp.Exit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroDoc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroApp) | Out-Null
Write-Host "打印任务已发送至: $PrinterName 或 默认打印机"
如何运行?
右键点击 .ps1 文件,选择“使用 PowerShell 运行”。或者在命令行中执行:
powershell -ExecutionPolicy Bypass -File print_pdf.ps1
为什么这样更好? 因为它不依赖文件关联,直接控制 Adobe 核心,稳定、快速,而且可以精确控制打印页数。
进阶篇:批量打印多个文件,并按页码范围过滤
现在,假设你有 10 个 PDF 文件,你只想打印每个文件的第 5 到 10 页,并且全部发送到同一台打印机。这用纯批处理会很复杂,但用 PowerShell 脚本结合循环,就非常简单。
场景:批量打印指定文件夹下的所有 PDF,每份只打印前 5 页
完整脚本示例:batch_print.ps1
# 定义配置
$SourceFolder = "C:\Users\YourName\Documents\Invoices"
$OutputPrinter = "HP LaserJet Pro" # 替换为你的实际打印机名称
$PagesStart = 1
$PagesEnd = 5
# 获取所有 PDF 文件
$Files = Get-ChildItem -Path $SourceFolder -Filter "*.pdf" | Where-Object { -not $_.PSIsContainer }
if ($Files.Count -eq 0) {
Write-Host "在 $SourceFolder 下未找到 PDF 文件。"
exit 0
}
Write-Host "找到 $($Files.Count) 个 PDF 文件,开始批量打印..."
# 创建 Acrobat 应用对象(只创建一次,提高效率)
$acroApp = New-Object -ComObject AcroExch.App
$acroApp.Hide() # 隐藏窗口,避免屏幕闪烁
foreach ($File in $Files) {
Write-Host "正在处理: $($File.Name)"
$acroDoc = $acroApp.Open($File.FullName, "")
if ($null -ne $acroDoc) {
$totalPages = $acroDoc.GetNumPages()
# 检查是否需要限制页数
$endPage = if ($PagesEnd -gt $totalPages) { $totalPages } else { $PagesEnd }
try {
# 打印指定页码范围
$acroDoc.PrintPages($PagesStart - 1, $endPage - 1, $true, $OutputPrinter)
Write-Host " -> 已发送 $($File.Name) 的第 $PagesStart 到 $endPage 页到 $OutputPrinter"
}
catch {
Write-Host " -> 打印失败: $($File.Name) - $($_.Exception.Message)"
}
finally {
$acroDoc.Close($false) # 关闭文档但不保存
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroDoc) | Out-Null
}
} else {
Write-Host " -> 无法打开文档: $($File.Name)"
}
}
$acroApp.Exit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroApp) | Out-Null
Write-Host "所有任务完成!"
这段代码的精妙之处:
- 对象复用:
AcroExch.App只创建一次,遍历过程中复用,避免频繁启动/关闭 Adobe 进程,速度提升巨大。 - 错误处理:
try-catch-finally确保即使某个文件打印失败,也不会中断整个流程。 - 进度反馈:
Write-Host让你实时看到哪个文件正在处理,心里有底。
高级篇:与 Task Scheduler 结合,实现真正的自动化
学会写脚本只是第一步。真正的“自动化办公”意味着你不需要手动运行脚本。你可以让它在特定时间、或当文件放入特定文件夹时自动执行。
1. 创建 Windows 任务计划
假设你希望每天早上 9 点,自动打印 C:\Inbox\Pending 文件夹下所有的新 PDF 文件。
步骤:
- 打开“任务计划程序”(Taskschd.msc)。
- 点击“创建基本任务”。
- 名称:
AutoPrintPDF,触发器:每天 9:00。 - 操作:启动程序,程序脚本填
powershell.exe,添加参数填:-ExecutionPolicy Bypass -File "C:\Scripts\batch_print.ps1" - 完成。
这样,你每天早上 9 点都不用碰电脑,打印机就会自动开始工作。
2. 使用 Folder Redirection 或 PowerShell 监视文件夹
更高级的做法是:当有新文件放入文件夹时,立即触发打印。这需要用到 PowerShell 的 FileSystemWatcher。
示例:实时监视文件夹并打印
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Inbox\Pending"
$watcher.Filter = "*.pdf"
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
$action = {
$file = $event.SourceEventArgs.FullPath
Write-Host "$(Get-Date): 检测到新文件 $file,开始打印..."
# 调用上面的打印逻辑
$acroApp = New-Object -ComObject AcroExch.App
$acroDoc = $acroApp.Open($file, "")
if ($null -ne $acroDoc) {
$acroDoc.PrintPages(0, $acroDoc.GetNumPages() - 1, $true, "HP LaserJet Pro")
$acroDoc.Close($false)
}
$acroApp.Exit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroDoc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($acroApp) | Out-Null
}
Register-ObjectEvent $watcher "Created" -Action $action
Write-Host "正在监视文件夹: C:\Inbox\Pending,按 Ctrl+C 退出..."
while ($true) { Start-Sleep -Seconds 1 }
把这个脚本做成一个 Windows 服务,或者用 schtasks 设置它开机自启,你就拥有了一个“永不停歇的打印机器人”。
常见陷阱与解决方案
1. 打印机名称不对
问题:脚本报错“打印机未找到”。
解决:在命令行运行 wmic printer get name 查看准确的打印机名称,注意空格和大小写。
2. Adobe Acrobat 未安装或版本不兼容
问题:AcroExch.App 对象创建失败。
解决:确保安装了 Adobe Acrobat(不仅是 Reader,最好是完整版 Acrobat,因为 COM 接口在 Reader 中可能受限)。如果必须用 Adobe Reader,可以尝试调用 ShellExecute 并传入“print”操作,但稳定性不如 COM 对象。
3. 64位 vs 32位进程
问题:脚本在 64 位 PowerShell 中运行,但 Adobe 是 32 位的,导致 COM 对象无法创建。 解决:使用 32 位 PowerShell 运行脚本:
%WINDIR%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File your_script.ps1
4. 打印顺序混乱
问题:多个文件同时打印,顺序错乱。
解决:在脚本中加入 Start-Sleep,每个文件打印后等待几秒,给打印机缓冲时间。
总结:从“打工”到“管理”
朋友,今天咱们聊的不仅是打印,更是一种思维:如何让机器服务于你,而不是你服务于机器。
批处理和 PowerShell 不是程序员专属,它们是现代办公者的“超能力”。当你能够用几行代码解决重复一天的工作,你就把时间还给了自己——去读书、去陪伴家人、去提升核心技能。
下一步行动建议:
- 先别急着写复杂脚本,先从最简单的
powershell -Command "Start-Process -FilePath 'report.pdf' -Verb Print"开始体验。 - 逐步替换你日常重复的打印任务。
- 把常用脚本保存在固定位置,配上快捷键,形成你的“自动化工作流”。
记住,自动化不是为了偷懒,而是为了更高效地创造价值。祝你打印自由,下班快乐!
