excel - 从多个 CSV 文件构建 Excel 电子表格

标签 excel powershell csv

我有 1 个带有单张工作表和 3 个 csv 文件的 Excel 工作簿。工作表具有固定数量的列(带有标题)和不同数量的行。一列包含一个“ID”字段,最后三列是空白的。每个 csv 都有不同数量的列,但都有一个“ID”字段,该字段应与 Excel 工作表中的“ID”字段匹配。虽然 Excel 工作表可能有多个相同 ID 的实例,但 CSV 中没有重复的 ID。例如:

Excel文件

ID:     Name:   Color:  Location:   Age:    Siblings:
123     Bob     Red
234     Sally   Green
345     Donald  Orange
123     Bob     Black

CSV1

ID:     Name:   Place:  Animal: Location:   Car:
123     Bob     Here    Dog     Up          Ferarri
234     Sally   There   Cat     Down        Porsche
345     Donald  Nowhere Squid   Right       Yugo

CSV2

ID:     Name:   Place:  Age:    
123     Bob     Here    50      
234     Sally   There   45      
345     Donald  Nowhere 100

CSV3

ID:     Siblings:
123     Five
234     Three
345     Eight

The goal is to add the data from specific columns in the CSV files to the excel file based on matching IDs. Expected output would be the following Excel file:

ID:     Name:   Color:  Location:   Age:    Siblings:
123     Bob     Red     Up          50      Five
234     Sally   Green   Down        45      Three
345     Donald  Orange  Right       100     Eight
123     Bob     Black   Up          50      Five

I have spent quite a bit of time trying to figure the most efficient (fast) method for doing this and think I've hit a brick wall. What I have so far (in relevant part):

# Pull relevant data from csv files together #
$rtFile = $selectedDirectory + "\\" + "*RT*.csv"
$seFile = $selectedDirectory + "\\" + "*SE*.csv"
$lmFile = $selectedDirectory + "\\" + "*LM*.csv"

$rtCSV = Import-Csv $rtFile | select ID, LOCATION
$seCSV = Import-Csv $seFile | select ID, AGE
$lmCSV = Import-Csv $lmFile | select ID, SIBLINGS

$rtCSV | ForEach {$_ | Add-Member 'AGE' $null}
$rtCSV | ForEach {$_ | Add-Member 'SIBLINGS' $null}

foreach ($record in $rtCSV) {
    $record.'AGE' = $seCSV | Where {$_.ID -eq $record.ID} | Select -Expand 'AGE'
    $Record.'SIBLINGS' = $lmCSV | Where {$_.ID -eq $record.ID} | Select -Expand 'SIBLINGS'
}

# Add Data to Excel Sheet #
$WorkSheet.Activate()
$range = $WorkSheet.Range("C1").EntireColumn

foreach ($searchStr in $rtCSV.ID) {
    $search = $range.Find($searchStr)

    if ($search -ne $null) {
        $firstAdr = $search.Address(0, 0, 1, 0)

        do {
            $WorkSheet.Cells.Item($search.row,17).Value() = $rtCSV[$search.row].LOCATION
            $WorkSheet.Cells.Item($search.row,18).Value() = $rtCSV[$search.row].AGE
            $WorkSheet.Cells.Item($search.row,19).Value() = $rtCSV[$search.row].SIBLINGS

            $search = $range.FindNext($search)
        } while ($search -ne $null -and $search.Address(0, 0, 1, 0) -ne $firstAdr)
    }
}

我花了一段时间,但我终于弄清楚了为什么上面的方法不起作用。而$search.row确实返回 Excel 文档中的匹配行(因此可以很好地用于确定在哪个单元格中插入数据)它没有为 $rtCSV 中的相应值返回适当的索引(?) .那么,如何确保每次 ID 匹配时插入正确的 LOCATION、AGE 和 SIBLINGS 值?

如果在当前的结构下不可能,是否还有另一种(也许更好,更有效)的方法?一般来说,Excel 文件的行数不应超过 1,000 行。

最佳答案

如果你不介意安装额外的模块来简化你的工作,我强烈推荐 dfinke's Import Excel module .安装 if 后,实现目标的代码将很简单:

# cd C:\SO\53529676
$rtCSV = Import-Csv .\csv1.csv | select ID, LOCATION
$seCSV = Import-Csv .\csv2.csv | select ID, AGE
$lmCSV = Import-Csv .\csv3.csv | select ID, SIBLINGS
$excel = Import-Excel .\Excel1.xlsx

foreach ($record in $excel) {
  $record.'LOCATION' = ($rtCSV | Where {$_.ID -eq $record.ID}).LOCATION
  $record.'AGE' = ($seCSV | Where {$_.ID -eq $record.ID}).AGE
  $Record.'SIBLINGS' = ($lmCSV | Where {$_.ID -eq $record.ID}).SIBLINGS
}

$excel | Export-Excel .\Excel2.xlsx

关于excel - 从多个 CSV 文件构建 Excel 电子表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53529676/

相关文章:

string - VBA函数返回字符串类型不匹配错误

excel - 如何浏览保存目录?

windows - 通过 PowerShell 脚本启用 TLS 和禁用 SSL

python - 带有隐形字符的新行

excel - VBA:是什么导致传递给 ParamArray 的字符串参数更改为数字(看起来可疑地像指针)?

php - 如何在 phpspreadsheet 中添加新行?

powershell - 数据仓库管理命令行应用程序 - PowerShell 或 C# 控制台应用程序

powershell - 如何在Word.Application中设置SaveAs()对话框的参数?

c - 将 CSV 文件中的数据添加到结构中

read.csv 警告 'EOF within quoted string' 阻止完全读取文件