axelia 发表于 2024-11-21 14:37

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
            }
      }
    }
}

```

anbanke 发表于 2024-11-21 15:30

感谢博主分享

那年夏天52 发表于 2024-11-21 15:01

很好,您这个就比价优秀

HuskyHappy 发表于 2024-11-21 15:08

.docx : 设置“DisplayAlerts”时发生异常:“无法将值“False”转换为类型“Microsoft.Office.Interop.Word.WdAlertLevel”。错误:“从“System.Boolean”到“Microsoft.Office.Interop.Word.WdAlertLevel”的强制转换无效。””

这个是什么错误,大佬

axelia 发表于 2024-11-21 15:11

HuskyHappy 发表于 2024-11-21 15:08
.docx : 设置“DisplayAlerts”时发生异常:“无法将值“False”转换为类型“Microsoft.Office.Interop.Word ...

       # 禁用 Word 提示
      $wordApp.DisplayAlerts = $false


这一行,你试试先关掉全部word文档,然后再试试,还报错就注释掉这一行先

wj阿斗 发表于 2024-11-21 15:12

一看就是相当巴适

爱学习的小妖精 发表于 2024-11-21 15:15

学到了这波,超赞感谢博主分享

markChenZhiWei 发表于 2024-11-21 15:58

感谢分享{:1_927:}

稻海香 发表于 2024-11-21 16:04

这个造福大家,感谢

xiaotuyun 发表于 2024-11-21 16:05

博主,你好,这个是直接运行就可以吗,需要装python环境之类的么
页: [1] 2 3
查看完整版本: powershell 批量转换文件夹下word/excel文档为pdf格式