Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从多个CSV文件构建Excel电子表格_Excel_Powershell_Csv - Fatal编程技术网

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

从多个CSV文件构建Excel电子表格,excel,powershell,csv,Excel,Powershell,Csv,我有一个Excel工作簿,其中有一张工作表和3个csv文件。工作表有固定数量的列(带标题)和不同数量的行。一列包含“ID”字段,最后三列为空。每个csv都有不同数量的列,但都有一个“ID”字段,该字段应与Excel工作表中的“ID”字段相匹配。虽然Excel工作表可能有多个相同ID的实例,但CSV中没有重复的ID。例如: Excel文件 ID: Name: Color: Location: Age: Siblings: 123 Bob Red 234

我有一个Excel工作簿,其中有一张工作表和3个csv文件。工作表有固定数量的列(带标题)和不同数量的行。一列包含“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 我花了一段时间,但我终于明白了为什么上面的方法不起作用。虽然
$search.row
会返回Excel文档中匹配的行(因此可以用来确定在哪个单元格中插入数据),但它不会返回
$rtCSV
中相应值的适当索引(?)。那么,如何确保在每次ID匹配时为位置、年龄和兄弟姐妹插入正确的值呢


如果在目前的建设中不可能,还有其他(可能更好、更有效)的方法吗?一般来说,Excel文件的行数不应超过1000行。

如果您不介意安装其他模块以简化工作,我强烈建议您。安装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

如果你主要关心的是性能,考虑2件事:

将“lookup tables”(csv1、csv2、csv3)转换为哈希表,以便快速查找(这有点类似于数据库中的索引)

将所有数据保存在平面文件(csv)中,以避免依赖关系,并使脚本简单高效。然后,您可以将数据链接到电子表格,作为要应用的视图 根据需要设置格式(您可以在MS Access中从csv创建链接表和视图,然后将其馈送到Excel中的数据表)

下面是一个示例(为了简单起见,使用其他一些伪文件)。您也可以在主循环中使用工作表对象(只需循环行索引和更新单元格对象)


我想你可以在将文件导入excel之前通过使用此<代码>在PowerShell中合并数据–杂乱无章的Cookie怪物-http://ramblingcookiemonster.github.io/Join-Object/脚本。您可能需要合并前两个,然后合并第三个,但看起来它可以满足您的需要。 ID: Name: Place: Age: 123 Bob Here 50 234 Sally There 45 345 Donald Nowhere 100 ID: Siblings: 123 Five 234 Three 345 Eight 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
# 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)
    }
}
# 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
# generate hashtables
$person = @{}
$location = @{}
Import-Csv location.csv | foreach {$location.Add($_.id, @{zip=$_.zip; city=$_.city})}
Import-Csv person.csv | foreach {$person.Add($_.id, @{name=$_.name; age=$_.age})}

# loop through the main file
Import-Csv main.csv | foreach {
    $id = $_.id
    $_.name = $person[$id].name
    $_.age = $person[$id].age
    $_.city = $location[$id].city
    $_.zip = $location[$id].zip
    Write-Output $_ } | Convertto-Csv | Out-File mainOut.csv