多个csv文件到xlsx文件但使用powershell的不同表

时间:2018-03-16 15:41:19

标签: excel powershell

我有20个csv文件。每个都是无关的。如何将它们组合成一个20张的xlsx文件,每个文件以csv文件命名。

$root = "C:\Users\abc\Desktop\testcsv"
$CSVfiles = Get-ChildItem -Path $root -Filter *.csv

$xlsx = "C:\Users\abc\Desktop\testxl.xlsx" #output location
$delimiter = "," #delimiter

#Create a excel
$xl=New-Object -ComObject Excel.Application
$xl.Visible=$true
#add a workbook
$wb=$xl.WorkBooks.add(1)

ForEach ($csv in $CSVfiles){

    #name  the worksheet
    $ws=$wb.WorkSheets.item(1)
    $ws.Name = [io.path]::GetFileNameWithoutExtension($csv)

    $TxtConnector = ("TEXT;" + $csv)
    $Connector = $ws.QueryTables.add($TxtConnector,$ws.Range("A1"))
    $query = $ws.QueryTables.item($Connector.name)
    $query.TextFileOtherDelimiter = $delimiter
    $query.TextFileParseType  = 1
    $query.TextFileColumnDataTypes = ,1 * $ws.Cells.Columns.Count
    $query.AdjustColumnWidth = 1

    # Execute & delete the import query
    $query.Refresh()
    $query.Delete()
    $wb.SaveAs($xlsx,51)
}
# Save & close the Workbook as XLSX.
$xl.Quit()

4 个答案:

答案 0 :(得分:2)

https://stackoverflow.com/a/51094040/5995160的答案在处理大量数据的csv时太慢了,我修改了此解决方案以使用https://github.com/dfinke/ImportExcel。至少对我而言,这极大地提高了此任务的性能。

Install-Module ImportExcel -scope CurrentUser
$csvs = Get-ChildItem .\* -Include *.csv
$csvCount = $csvs.Count
Write-Host "Detected the following CSV files: ($csvCount)"
foreach ($csv in $csvs) {
    Write-Host " -"$csv.Name
}

$excelFileName = $(get-date -f yyyyMMdd) + "_" + $env:USERNAME + "_combined-data.xlsx"
Write-Host "Creating: $excelFileName"

foreach ($csv in $csvs) {
    $csvPath = ".\" + $csv.Name
    $worksheetName = $csv.Name.Replace(".csv","")
    Write-Host " - Adding $worksheetName to $excelFileName"
    Import-Csv -Path $csvPath | Export-Excel -Path $excelFileName -WorkSheetname $worksheetName
}

此解决方案假定用户已将目录更改为所有csv所在的目录。

答案 1 :(得分:0)

请参阅下文,了解使用OpenText方法的解决方案。

至少有两点需要注意:

  • 我假设您的工作簿默认创建一个工作表。如果创建的内容不止于此,则需要修改脚本,以便从最终结果中删除这些附加工作表。

  • 您指定TextFileColumnDataTypes的方式非常聪明。您需要修改它并将数组提供给下面的FieldInfo参数。请参阅上面链接的文档,了解它所期望的数组类型。

$CSVfiles = Get-ChildItem -Path $root -Filter *.csv

$xlsx = "C:\Users\abc\Desktop\testxl.xlsx" #output location

#Create a excel
$xl = New-Object -ComObject Excel.Application

$xl.Visible=$true

#add a workbook
$wb = $xl.WorkBooks.add(1)

# how many worksheets do you have in your original workbook? Assuming one:
$ws = $wb.Worksheets.Item(1)

ForEach ($csv in $CSVfiles){

    # OpenText method does not work well with csv files
    Copy-Item -Path $csv.FullName -Destination ($csv.FullName).Replace(".csv",".txt") -Force

    # Use OpenText method. FieldInfo will need to be amended to suit your needs
    $xl.WorkBooks.OpenText(`
                    ($file.FullName).Replace(".csv",".txt"),    # Filename
                    2,                 # Origin
                    1,                 # StartRow
                    1,                 # DataType
                    1,                 # TextQualifier
                    $false,            # ConsecutiveDelimiter
                    $false,            # Tab
                    $false,            # Semicolon
                    $true,             # Comma
                    $false,            # Space
                    $false,            # Other
                    $false,            # OtherChar
                    @()                # FieldInfo
    )

    $tempBook   = $xl.ActiveWorkbook

    $tempBook.worksheets.Item(1).Range("A1").Select()         | Out-Null
    $tempBook.worksheets.Item(1).Move($wb.Worksheets.Item(1)) | Out-Null

    # name  the worksheet
    $xl.ActiveSheet.Name = $csv.BaseName

    Remove-Item -Path ($csv.FullName).Replace(".csv",".txt")  -Force

}

$ws.Delete()

# Save & close the Workbook as XLSX.
$wb.SaveAs($xlsx,51)
$wb.Close()

$xl.Quit()

答案 2 :(得分:0)

This way,将第一行更改为存储这20个CSV文件的文件夹,然后

$path="c:\path\to\folder" #target folder
cd $path;

$csvs = Get-ChildItem .\* -Include *.csv
$y=$csvs.Count
Write-Host "Detected the following CSV files: ($y)"
foreach ($csv in $csvs)
{
Write-Host " "$csv.Name
}
$outputfilename = $(get-date -f yyyyMMdd) + "_" + $env:USERNAME + "_combined-data.xlsx" #creates file name with date/username
Write-Host Creating: $outputfilename
$excelapp = new-object -comobject Excel.Application
$excelapp.sheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
$sheet=1

foreach ($csv in $csvs)
{
$row=1
$column=1
$worksheet = $xlsx.Worksheets.Item($sheet)
$worksheet.Name = $csv.Name
$file = (Get-Content $csv)
foreach($line in $file)
{
$linecontents=$line -split ',(?!\s*\w+")'
foreach($cell in $linecontents)
{
$worksheet.Cells.Item($row,$column) = $cell
$column++
}
$column=1
$row++
}
$sheet++
}
$output = $path + "\" + $outputfilename
$xlsx.SaveAs($output)
$excelapp.quit()
cd \ #returns to drive root

答案 3 :(得分:-2)

您可以在powershell上使用VBScript来执行此操作。 你可以在这里读更多关于它的内容: http://www.robvanderwoude.com/vbstech_databases_excel.php

另请阅读"使用VBS打开CSV","使用VBS复制/移动工作表"和#34;保存工作簿"。

我认为StackOverflow的研究员不会为你赢得代码,但是如果你进行搜索,那就试试错误,你可能会回答更加扎实的问题。