试试ai吧,很强大。
BAT 自身没有读取 Excel 工作簿的命令。对于 .xlsx、.xlsm 等文件,不能直接用 findstr,因为 .xlsx 实际上是压缩后的 XML 文件。
在电脑已经安装 Microsoft Excel 的情况下,较可靠的方法是:
BAT 调用 PowerShell,再通过 Excel COM 接口搜索。
下面是一个完整的单文件 BAT,不会长期生成额外的 .ps1 文件。
可以把多个关键词用英文竖线 | 分隔,例如:
合同|**|付款
下面这个版本会逐个搜索关键词,只要单元格中包含其中任意一个关键词就输出,结果中还会增加“匹配关键词”一列。
代码保持为utf-8的bat文件。
- @echo off
- chcp 65001 >nul
- setlocal
- rem 搜索目录:BAT 所在目录
- set "SEARCH_DIR=%~dp0"
- set /p "SEARCH_KEYWORDS=请输入关键词,多个关键词用英文竖线 | 分隔:"
- if not defined SEARCH_KEYWORDS (
- echo 没有输入关键词。
- pause
- exit /b 1
- )
- set "BAT_SELF=%~f0"
- powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
- "$text=[IO.File]::ReadAllText($env:BAT_SELF);" ^
- "$mark=':'+'__POWERSHELL__';" ^
- "$pos=$text.IndexOf($mark);" ^
- "$code=$text.Substring($pos+$mark.Length);" ^
- "& ([ScriptBlock]::Create($code))"
- echo.
- pause
- exit /b
- :__POWERSHELL__
- $ErrorActionPreference = 'Stop'
- $folder = $env:SEARCH_DIR
- $output = Join-Path $folder 'Excel搜索结果.csv'
- $keywords = $env:SEARCH_KEYWORDS -split '\|' |
- ForEach-Object { $_.Trim() } |
- Where-Object { $_ -ne '' } |
- Select-Object -Unique
- if (-not $keywords) {
- Write-Host '没有有效关键词。'
- return
- }
- $results = [System.Collections.Generic.List[object]]::new()
- $excel = $null
- try {
- $excel = New-Object -ComObject Excel.Application
- $excel.Visible = $false
- $excel.DisplayAlerts = $false
- $files = Get-ChildItem -LiteralPath $folder -Recurse -File |
- Where-Object {
- $_.Extension.ToLower() -in '.xls', '.xlsx', '.xlsm', '.xlsb' -and
- $_.Name -notlike '~$*'
- }
- if (-not $files) {
- Write-Host '没有找到 Excel 文件。'
- return
- }
- foreach ($file in $files) {
- $workbook = $null
- Write-Host "正在搜索:$($file.FullName)"
- try {
- $workbook = $excel.Workbooks.Open(
- $file.FullName,
- 0,
- $true
- )
- foreach ($sheet in @($workbook.Worksheets)) {
- $range = $null
- try {
- $range = $sheet.UsedRange
- foreach ($keyword in $keywords) {
- $cell = $null
- try {
- # -4163:按单元格显示值搜索
- # 2:部分匹配,即包含关键词
- # 1:按行搜索
- $cell = $range.Find(
- $keyword,
- [Type]::Missing,
- -4163,
- 2,
- 1,
- 1,
- $false,
- $false,
- $false
- )
- if ($null -ne $cell) {
- $seen = [System.Collections.Generic.HashSet[string]]::new()
- while ($null -ne $cell) {
- $address = $cell.Address()
- if (-not $seen.Add($address)) {
- break
- }
- $results.Add([PSCustomObject]@{
- 匹配关键词 = $keyword
- 文件 = $file.FullName
- 工作表 = $sheet.Name
- 行号 = $cell.Row
- 列号 = $cell.Column
- 单元格 = $cell.Address($false, $false)
- 内容 = [string]$cell.Value2
- })
- $nextCell = $range.FindNext($cell)
- if ($null -ne $cell) {
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($cell)
- }
- $cell = $nextCell
- }
- }
- }
- finally {
- if ($null -ne $cell) {
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($cell)
- }
- }
- }
- }
- finally {
- if ($null -ne $range) {
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($range)
- }
- if ($null -ne $sheet) {
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($sheet)
- }
- }
- }
- }
- catch {
- Write-Warning "无法搜索文件:$($file.FullName)"
- Write-Warning $_.Exception.Message
- }
- finally {
- if ($null -ne $workbook) {
- $workbook.Close($false)
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($workbook)
- }
- }
- }
- if ($results.Count -gt 0) {
- $results |
- Sort-Object 文件, 工作表, 行号, 列号, 匹配关键词 |
- Export-Csv -LiteralPath $output `
- -NoTypeInformation `
- -Encoding UTF8
- Write-Host ''
- Write-Host "搜索完成,共找到 $($results.Count) 条匹配结果。"
- Write-Host "结果文件:$output"
- }
- else {
- if (Test-Path -LiteralPath $output) {
- Remove-Item -LiteralPath $output -Force
- }
- Write-Host ''
- Write-Host '没有找到匹配内容。'
- }
- }
- finally {
- if ($null -ne $excel) {
- $excel.Quit()
- [void][Runtime.InteropServices.Marshal]::ReleaseComObject($excel)
- }
- [GC]::Collect()
- [GC]::WaitForPendingFinalizers()
- }
复制代码 |