powershell 批量转换文件夹下word/excel文档为pdf格式
本帖最后由 axelia 于 2024-11-22 12:11 编辑看论坛里也有很多使用python写的,不过因为大部分场景都是win环境,还要装python环境和库,Windows下powershell都是自带的,使用比较方便,写了一个脚本,用来将文件夹(支持子文件夹)下word、excel文件转pdf(excel多个sheet的时候,使用文件名_sheet分开转为pdf )
下面为代码:
--20241122 更新
1、注释了绝对路径,使用相对路径(将脚本放置需要转换的主目录即可,支持文件夹下子文件夹) 需要使用绝对路径的,注释掉相对路径,打开绝对路径即可
2、优化了下部分逻辑、新增了部分注释方便自行修改
3、excel 默认缩放80%,如果列超多,还是会分页导致格式异常,注释掉页面布局,打开上面的注释,使用一页显示(在pdf中显示会比较小一些)
```
#############绝对路径方式##############
# # 设置工作目录
# $directory = "C:\Users\axeli\Desktop\test"
# # 设置日志文件
# $logFile = "C:\Users\axeli\Desktop\test\conversion_log.txt"
#############相对路径方式##############
# 获取脚本所在的目录
$scriptDirectory = $PSScriptRoot
# 设置工作目录
$directory = $scriptDirectory
# 设置日志文件
$logFile = Join-Path $directory "conversion_log.txt"
# 函数:记录日志
function Log-Message {
param (
$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $logFile -Value "$timestamp - $message" -Encoding default
}
# 检查文件是否存在
function Check-FileExists {
param (
$filePath
)
if (-Not (Test-Path -Path $filePath)) {
Log-Message "File does not exist: $filePath"
return $false
}
return $true
}
# 清理 COM 对象
function Cleanup-ComObjects {
param (
]$comObjects
)
foreach ($comObject in $comObjects) {
if ($null -ne $comObject) {
try {
::ReleaseComObject($comObject) | Out-Null
}
catch {
Log-Message "Error releasing COM object: $_"
}
}
}
::Collect()
::WaitForPendingFinalizers()
}
# 处理Word文档
function Convert-WordToPDF {
param (
$filePath,
$outputPath
)
$wordApp = New-Object -ComObject Word.Application
$wordApp.DisplayAlerts = 0 # wdAlertsNone
try {
$document = $wordApp.Documents.Open($filePath)
$document.SaveAs($outputPath, 17) # 17 is wdFormatPDF
$document.Close($false) # 不保存更改
#$document.Close($false, ::Missing, ::Missing)
Log-Message "Converted $filePath to PDF successfully."
}
catch {
Log-Message "Error converting $filePath : $_"
}
# finally {
# $wordApp.Quit()
# Cleanup-ComObjects @($wordApp)
# }
finally {
if ($null -ne $document) {
try {
$document.Close($false) # 不保存更改
Log-Message "Document closed successfully."
}
catch {
Log-Message "Error closing document: $_"
}
finally {
Cleanup-ComObjects @($document)
Log-Message "Document COM object released."
}
}
if ($null -ne $wordApp) {
try {
$wordApp.Quit()
Log-Message "Word application quit successfully."
}
catch {
Log-Message "Error quitting Word application: $_"
}
finally {
Cleanup-ComObjects @($wordApp)
Log-Message "Word application COM object released."
}
}
}
}
# 处理Excel工作表
function Convert-ExcelToPDF {
param (
$filePath,
$fileBaseName,
$fileDirectory
)
$excelApp = New-Object -ComObject Excel.Application
$excelApp.DisplayAlerts = -4142 # xlNo
try {
$workbook = $excelApp.Workbooks.Open($filePath)
foreach ($worksheet in $workbook.Worksheets) {
$sheetName = $worksheet.Name
$outputPath = Join-Path $fileDirectory ($fileBaseName + "_" + $sheetName + ".pdf")
# 设置页面布局(页面内容将被缩放到一页宽和一页高,pdf文件显示会比较小)
# $worksheet.PageSetup.Zoom = $false # 关闭缩放
# $worksheet.PageSetup.FitToPagesWide = 1 #页面宽度为1
# $worksheet.PageSetup.FitToPagesTall = 1 #页面高度为1
# $worksheet.PageSetup.PaperSize = 9 # A4纸
# $worksheet.PageSetup.LeftMargin = $excelApp.InchesToPoints(0.75) # 左间距0.75英寸
# $worksheet.PageSetup.RightMargin = $excelApp.InchesToPoints(0.75) # 右间距0.75英寸
# $worksheet.PageSetup.TopMargin = $excelApp.InchesToPoints(1) #上间距1英寸
# $worksheet.PageSetup.BottomMargin = $excelApp.InchesToPoints(1) # 下间距1英寸
# $worksheet.PageSetup.Orientation = 2 # 2-横向1-竖向
# 设置页面布局(页面内容自定义缩放,适合列不是很多,需要自己修改缩放比例,如果列超长建议注释以下部分打开上面的注释使用)
$worksheet.PageSetup.Zoom = 80 #缩放80%缩放比例要针对性调整,超长的字段可能会分页需要降低缩放比例
$worksheet.PageSetup.PaperSize = 9 # A4纸
$worksheet.PageSetup.LeftMargin = $excelApp.InchesToPoints(0.75) # 左间距0.75英寸
$worksheet.PageSetup.RightMargin = $excelApp.InchesToPoints(0.75) # 右间距0.75英寸
$worksheet.PageSetup.TopMargin = $excelApp.InchesToPoints(1) # 上间距1英寸
$worksheet.PageSetup.BottomMargin = $excelApp.InchesToPoints(1) # 下间距1英寸
$worksheet.PageSetup.Orientation = 2 # 2-横向1-竖向
$worksheet.ExportAsFixedFormat(0, $outputPath) # 0 is xlTypePDF
Log-Message "Converted sheet '$sheetName' from $filePath to PDF successfully."
Cleanup-ComObjects @($worksheet)
}
# 关闭工作簿时不保存更改
$workbook.Close($false, ::Missing, ::Missing)
}
catch {
Log-Message "Error converting $filePath : $_"
}
# finally {
# $excelApp.Quit()
# Cleanup-ComObjects @($excelApp)
# }
finally {
if ($null -ne $worksheets) {
Cleanup-ComObjects @($worksheets)
}
if ($null -ne $workbook) {
try {
$workbook.Close($false, ::Missing, ::Missing)
}
catch {
Log-Message "Error closing workbook: $_"
}
Cleanup-ComObjects @($workbook)
}
if ($null -ne $excelApp) {
try {
$excelApp.Quit()
}
catch {
Log-Message "Error quitting Excel application: $_"
}
Cleanup-ComObjects @($excelApp)
}
}
}
# 遍历目录中的所有文件
Get-ChildItem -Path $directory -Recurse | Where-Object { $_.PSIsContainer -eq $false } | ForEach-Object {
# 获取文件扩展名
$extension = $_.Extension.ToLower()
# 获取文件全路径
$filePath = $_.FullName
# 获取文件的基本名称和目录
$fileBaseName = $_.BaseName
$fileDirectory = $_.Directory.FullName
# 记录文件路径
Log-Message "Processing file: $filePath"
# 定义输出路径
$outputPath = Join-Path $_.directory ($_.BaseName + ".pdf")
# 根据文件类型进行处理
switch ($extension) {
'.doc' {
if (Check-FileExists -filePath $filePath) {
Convert-WordToPDF -filePath $filePath -outputPath $outputPath
}
}
'.docx' {
if (Check-FileExists -filePath $filePath) {
Convert-WordToPDF -filePath $filePath -outputPath $outputPath
}
}
'.xls' {
if (Check-FileExists -filePath $filePath) {
Convert-ExcelToPDF -filePath $filePath -fileBaseName $fileBaseName -fileDirectory $fileDirectory
}
}
'.xlsx' {
if (Check-FileExists -filePath $filePath) {
Convert-ExcelToPDF -filePath $filePath -fileBaseName $fileBaseName -fileDirectory $fileDirectory
}
}
}
}
``` 感谢博主分享 很好,您这个就比价优秀 .docx : 设置“DisplayAlerts”时发生异常:“无法将值“False”转换为类型“Microsoft.Office.Interop.Word.WdAlertLevel”。错误:“从“System.Boolean”到“Microsoft.Office.Interop.Word.WdAlertLevel”的强制转换无效。””
这个是什么错误,大佬 HuskyHappy 发表于 2024-11-21 15:08
.docx : 设置“DisplayAlerts”时发生异常:“无法将值“False”转换为类型“Microsoft.Office.Interop.Word ...
# 禁用 Word 提示
$wordApp.DisplayAlerts = $false
这一行,你试试先关掉全部word文档,然后再试试,还报错就注释掉这一行先 一看就是相当巴适 学到了这波,超赞感谢博主分享 感谢分享{:1_927:} 这个造福大家,感谢 博主,你好,这个是直接运行就可以吗,需要装python环境之类的么