PowerShell使用Compare-Object对比两个XLSX文件仅输出差异内容
PowerShell实现XLSX文件差异比对方案
可行性说明
Compare-Object可实现基础的对象差异识别,但原生逻辑无法直接满足「仅输出变更字段、区分新增/修改场景」的定制化要求,需要在基础比对能力上增加逐字段校验、条目匹配的二次开发逻辑。
现有脚本问题
当前使用的脚本如下:
#IMPORT PS EXCEL MODULE import-module psexcel #FILE TO BE COMPARED VARIABLES $file1 = Import-XLSX C:\CurrentFile.xlsx $file2 = Import-XLSX C:\PreviousFile.xlsx #FILTER TO GET DATA ONLY FROM THE REFERENCE FILE ONLY filter leftside{ param( [Parameter(Position=0, Mandatory=$true,ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [PSCustomObject] $obj ) $obj|?{$_.sideindicator -eq '<='} } #PROPERTY VARIABLE $property = "Name" , "UserPrincipalName" , "NickName" , "Age" , "Sex" #COMPARISON PROPER $Comparison = Compare-Object -referenceobject $file1 -differenceobject $file2 -SyncWindow ($file1.Length / 2) -property $property | leftside
该脚本存在3个核心问题:
- 直接将全属性传入
Compare-Object做整体匹配,只要任意属性存在差异就返回整行对象,无法定位具体变更字段 - 仅筛选参考对象侧的差异条目,没有区分「新增条目」和「字段修改条目」两类差异场景
- 没有逐字段比对逻辑,无法实现无变更字段留空的输出要求
明确输出规则
- 以
Name作为行唯一标识符,所有输出行必须保留该字段值 - 仅输出存在差异的行,两文件中完全匹配的行不输出
- 差异行中仅展示存在变更的字段内容,无变更的字段留空,新增条目展示全部字段内容
- 覆盖字段值修改、条目新增等所有差异场景
可直接运行的实现脚本
# 导入Excel处理模块 Import-Module psexcel # 基础配置 $oldFile = "C:\PreviousFile.xlsx" $newFile = "C:\CurrentFile.xlsx" $primaryKey = "Name" $compareFields = @("UserPrincipalName", "NickName", "Age", "Sex") # 读取两个文件的内容 $oldRows = Import-XLSX $oldFile $newRows = Import-XLSX $newFile # 将旧文件数据转为哈希表,以主键为索引提升匹配效率 $oldRowMap = @{} foreach ($row in $oldRows) { $oldRowMap[$row.$primaryKey] = $row } $finalDiff = @() # 遍历新文件逐行校验差异 foreach ($currentRow in $newRows) { $keyVal = $currentRow.$primaryKey # 初始化输出对象,默认所有对比字段为空 $output = [PSCustomObject]@{ $primaryKey = $keyVal } foreach ($field in $compareFields) { $output | Add-Member -NotePropertyName $field -NotePropertyValue $null } # 判定为新增条目:填充所有字段值 if (-not $oldRowMap.ContainsKey($keyVal)) { foreach ($field in $compareFields) { $output.$field = $currentRow.$field } $finalDiff += $output continue } # 判定为存量条目:逐字段对比,仅填充变更字段 $matchOldRow = $oldRowMap[$keyVal] $hasChange = $false foreach ($field in $compareFields) { if ($currentRow.$field -ne $matchOldRow.$field) { $output.$field = $currentRow.$field $hasChange = $true } } # 存在字段变更才加入结果集 if ($hasChange) { $finalDiff += $output } } # 输出最终差异结果,可按需导出为XLSX/CSV格式 $finalDiff
脚本逻辑说明
- 以
Name作为唯一匹配键,先做条目级匹配,自动区分新增、修改两类差异场景 - 存量条目逐字段对比新旧值,仅当值不一致时才填充对应字段内容,无变更字段保持为空
- 完全无差异的存量行不会进入最终结果集
- 新增条目自动填充所有字段内容,符合输出要求
内容的提问来源于stack exchange,提问作者bujom
相关产品推荐
相关产品推荐

