说实话,打印这事儿听起来挺简单的——选中文件,右键,打印。但当你要一次性处理几十上百个PDF或者图片时,鼠标点击就会变成一场噩梦。我见过太多人为了赶工,盯着打印机一个一个“吐”纸,最后眼睛花、手指酸。其实,Windows 早就给我们留了一扇后门,那就是命令行。今天咱们不聊虚的,直接上手,教你如何用几行脚本,让电脑自己帮你把活干了。

为什么要学这个?先看看那些让人抓狂的场景

想象一下这个场景:你是个小工作室的会计,月底了,客户发来200份PDF合同需要盖章打印。如果手动操作,哪怕每份只花10秒钟,你也得盯着屏幕近一个小时。而且中途如果卡纸了、出错了,你还得重新来过。

或者你是设计师,需要把一批高清图片批量打印到不同的相纸尺寸上。手动调整每个文件的打印属性?那简直是时间黑洞。

再比如,你是个运维人员,服务器日志每天产生几十个文本文件,你需要定期归档打印。这时候如果还是靠人去点,不仅效率低,还容易漏掉某些文件。

这些场景的共同点就是:重复、枯燥、量大。而这正是批处理命令最擅长的领域。Windows 内置的 print 命令和 PowerShell 脚本,配合一些简单的逻辑,就能让你从“打印苦力”变成“自动化老板”。

基础篇:那个被忽视的 print 命令

很多人不知道,Windows 的 cmd(命令提示符)里自带一个 print 命令。别被它的名字骗了,它可不是用来“打印文字”的,而是用来调用系统默认打印机打印文件的。

最简单的用法,你在任何位置打开 CMD,输入:

print C:\Users\YourName\Documents\report.pdf

敲回车,系统就会调用默认打印机,把这个 PDF 发过去。听起来很简单对吧?但这里有个坑,我必须先告诉你。

坑点一:文件路径有空格 如果你的文件夹名字是“我的文档”,上面这条命令会报错,因为空格会被系统误解为参数分隔符。解决办法是用双引号把路径包起来:

print "C:\Users\YourName\我的文档\report.pdf"

坑点二:文件格式支持 print 命令并不是万能钥匙。它对图片(JPG, PNG)和文本文件(TXT)支持得很好,但对 PDF 的支持取决于你安装的 PDF 阅读器。如果你用的是 Adobe Acrobat Reader,通常没问题;但如果你用的是某些轻量级阅读器,可能就不响应了。

坑点三:后台静默打印 默认情况下,print 命令执行时会弹出一个进度窗口,而且必须等打印任务提交完成才会返回命令行。这意味着如果你在脚本里用它,脚本会卡住。对于批量任务,我们更需要的是“提交即走”。这时候我们需要加 /P 参数来指定打印机,或者配合其他工具实现更高级的控制。

进阶篇:构建第一个批量打印脚本

光会单文件打印没意思,咱们得让脚本自己动起来。假设你现在有一个文件夹 C:\PrintJobs,里面有100个 PDF 文件,你想全部打印到默认的激光打印机上。

我们可以写一个简单的 .bat 文件。新建一个文本文件,命名为 batch_print.bat,然后用记事本打开,输入以下内容:

@echo off
setlocal enabledelayedexpansion

REM 设置源文件夹路径,请根据实际情况修改
set "SourceFolder=C:\PrintJobs"

REM 设置目标打印机名称,如果留空则使用默认打印机
set "PrinterName="

echo 开始批量打印任务...
echo 源文件夹:%SourceFolder%

REM 遍历文件夹中的所有 PDF 文件
for %%F in ("%SourceFolder%\*.pdf") do (
    echo 正在打印: %%~nxF
    if defined PrinterName (
        print /D:"%PrinterName%" "%%F"
    ) else (
        print "%%F"
    )
)

echo 全部任务已提交!
pause

看懂了吗?我逐行给你拆解一下:

  • @echo off:这行很重要,它让命令行在执行时隐藏掉每行命令本身,只显示我们 echo 出来的内容,界面更清爽。
  • setlocal enabledelayedexpansion:这是为了处理变量延迟展开,虽然在这个简单例子里不是必须的,但养这个好习惯能防止以后遇到复杂逻辑时出bug。
  • for %%F in (...):这是核心。它告诉电脑,“去这个文件夹里找所有 .pdf 后缀的文件,把每个文件临时命名为 %%F”。
  • %%~nxF:这是变量的一个小技巧。%F 是完整路径加文件名,~n 是纯文件名,~x 是扩展名。组合起来 %%~nxF 就是像 合同001.pdf 这样的显示名称,方便我们在屏幕上看到正在处理哪个文件。
  • print /D:"%PrinterName%":如果你指定了打印机,就用 /D 参数指定目标打印机。注意,打印机名称必须和“设备和打印机”里显示的名称完全一致,包括空格。

把这个脚本放到 C:\PrintJobs 旁边,双击运行。你会看到屏幕上逐行滚动文件名,然后打印机开始工作。你可以去喝杯咖啡了。

高级篇:解决“排队拥堵”和“复杂属性”问题

刚才那个脚本有个大问题:它只是把文件“扔”给打印机队列。如果文件很大(比如几十页的高清PDF),而打印机很慢,脚本可能会堆积大量任务,甚至导致打印机缓冲区溢出,或者在打印过程中因为队列堵塞而失败。

更麻烦的是,有时候你需要改变打印属性:比如双面打印、黑白打印、或者指定纸张大小。Windows 自带的 print 命令完全不支持这些参数。

这时候,我们需要引入两个更强的工具:PowerShellAdobe Acrobat 的命令行工具(或者通用的 AcroRd32.exe)。

方案一:使用 PowerShell 进行更稳健的控制

PowerShell 比 CMD 强大得多,它可以直接操作 COM 对象,甚至调用 .NET 类库。我们可以写一个 PowerShell 脚本来替代上面的 bat 文件,实现更精细的控制。

新建一个 print.ps1 文件:

$SourceFolder = "C:\PrintJobs"
$PrinterName = "" # 留空表示默认打印机
$WaitTime = 2 # 每个文件打印后等待几秒,防止队列拥堵

Get-ChildItem -Path $SourceFolder -Filter *.pdf | ForEach-Object {
    $FileName = $_.Name
    Write-Host "正在打印: $FileName" -ForegroundColor Cyan
    
    # 调用系统默认打印机
    if ($PrinterName) {
        # 如果有指定打印机,使用 Start-Process 指定打印机
        Start-Process -FilePath $_.FullName -Verb Print -PrinterName $PrinterName
    } else {
        Start-Process -FilePath $_.FullName -Verb Print
    }
    
    Write-Host "  -> 已发送至打印队列" -ForegroundColor Green
    Start-Sleep -Seconds $WaitTime
}

Write-Host "所有任务已提交完毕!" -ForegroundColor Yellow

这个脚本里,Start-Process-Verb Print 参数非常关键。它比 print 命令更底层,兼容性更好。而且 Start-Sleep 让我们可以在每个文件之间插入等待时间,避免瞬间发送过多任务压垮打印机驱动。

但是! 你发现没有?这个脚本还是无法控制“双面打印”或“黑白模式”。因为 -Verb Print 只是触发“打印”这个动作,具体参数得看文件的关联程序(比如 Adobe Reader)怎么处理。

方案二:调用 Adobe Acrobat 命令行实现高级控制

如果你公司里大家用的是 Adobe Acrobat Pro/DC,那我们就有了杀手锏。Adobe 提供了一个命令行工具 AcroRd32.exe,它支持大量参数,包括打印机设置。

不过,直接调用 AcroRd32.exe 比较复杂,因为它的参数语法很古董。更现代、更可靠的方案是使用 Adobe Acrobat 的 JavaScript 环境,或者使用第三方开源工具如 PDFtkGhostscript 先处理再打印。

但对于大多数普通用户,其实有一个更简单的中间方案:利用 Windows 的“打印”对话框的预置配置文件

我们可以利用 PowerShell 的 PrintDocument 类,但这通常只针对文本或图像。对于 PDF,最稳妥的“高级打印”方案其实是:先通过脚本将 PDF 转换为适合打印的格式(如图片),再批量打印图片,或者使用专门的打印管理软件如 QuickMillPDF24 的命令行接口。

鉴于通用性,我再给你一个针对 文本和图片 的超实用 PowerShell 脚本,这个场景在实际办公中极高频:批量打印文件夹里所有的 JPG 照片,并设置相纸尺寸。

# 批量打印图片并设置特定打印机和纸张
$ImageFolder = "C:\Photos"
$TargetPrinter = "EPSON Photo 1500" # 请替换为你的打印机名称

Get-ChildItem -Path $ImageFolder -Include *.jpg,*.png,*.jpeg | ForEach-Object {
    $Image = [System.Drawing.Image]::FromFile($_.FullName)
    
    # 创建打印文档对象
    $Doc = New-Object System.Drawing.Printing.PrintDocument
    $Doc.PrinterSettings.PrinterName = $TargetPrinter
    $Doc.PrinterSettings.DefaultPageSettings.PaperSize = $Doc.PrinterSettings.PaperSizes | Where-Object { $_.PaperName -like "*4x6*" } | Select-Object -First 1
    
    # 处理打印事件,绘制图片
    $Doc.Add_PrintPage({
        param($sender, $e)
        $e.Graphics.DrawImage($Image, 0, 0, $e.MarginBounds.Width, $e.MarginBounds.Height)
    })
    
    try {
        $Doc.Print()
        Write-Host "成功打印: $($_.Name)" -ForegroundColor Green
    } catch {
        Write-Host "打印失败: $($_.Name) - 错误: $($_.Exception.Message)" -ForegroundColor Red
    } finally {
        $Image.Dispose()
        $Doc.Dispose()
    }
}

这段代码看起来有点长,但它展示了真正的“专家级”控制:

  1. 它指定了特定的打印机(不再是默认的)。
  2. 它尝试自动寻找 “4x6” 的相纸尺寸。
  3. 它使用 try-catch-finally 结构,确保即使打印失败,内存中的图片对象也会被正确释放,不会导致内存泄漏。
  4. 它在屏幕上实时反馈成功或失败的信息。

实战中的几个“血泪”教训

作为一个经常帮人解决打印自动化问题的“老手”,我得给你几个避坑指南,这些都是真金白银换来的经验。

第一,打印机名称必须精确。 在“控制面板” -> “设备和打印机”里,右键点击你的打印机,选择“属性”,你会看到“端口”或者“常规”标签页下的完整名称。有时候名称里带括号,比如 HP LaserJet Pro (USB001),你脚本里写的 HP LaserJet Pro 就会找不到打印机,导致打印失败或者回退到默认打印机。

第二,注意文件的独占锁。 如果你在批量打印过程中,打开了某个正在被打印的文件(比如在 Adobe Reader 里预览),Windows 可能会锁定该文件,导致 print 命令失败,报错“文件被占用”。所以,批量打印前,关掉所有打开的相关文档

第三,网络打印机的延迟。 如果你的打印机是网络打印机,在发送大量任务时,可能会出现“队头阻塞”。比如第一个文件卡住了,后面所有文件都会等着。建议在脚本中加入检查打印机状态的功能,或者使用更稳定的打印队列管理工具。

第四,PDF 版本兼容性。 有些老旧的 PDF 文件使用了特殊的加密或字体嵌入,print 命令可能无法正确解析。如果遇到个别文件打印出来是空白的,试着手动打印一次看看,如果手动也不行,那就是文件本身的问题,需要从源头解决。

总结:让技术为你省时间

从最简单的 print 命令,到 PowerShell 的精细控制,再到针对图片的专业绘制打印,这一路走来,你会发现:自动化不是为了炫技,而是为了把人类从重复劳动中解放出来。

你不需要成为编程专家,只需要掌握这几个核心的思路:

  1. 批量操作:用 for 循环遍历文件。
  2. 路径处理:用引号包裹含空格的路径,用 %%~nxF 提取文件名。
  3. 错误处理:用 try-catch 捕获异常,保证脚本不会因一个文件失败而崩溃。
  4. 资源释放:在操作图像等大对象时,记得 Dispose(),保持系统清爽。

下次当你面对那一堆需要打印的文件时,别急着拿起鼠标。打开记事本,写几行脚本,点一下运行,然后安心地去做点更有价值的事情。这才是现代办公该有的样子。

如果你在实际操作中还遇到什么奇怪的问题,比如“为什么我的脚本运行后打印机没反应?”或者“怎么打印指定页码?”,欢迎随时再来探讨。打印的世界,比你想的要有意思得多。