如何使用Powershell将CSV导出到Excel
我正尝试使用Powershell将完整的CSV导出到Excel。 我坚持使用静态列名称的一点。 但是,如果我的CSV具有通用的未知标题名称,则这不起作用。
重现步骤
打开PowerShell ISE并复制并粘贴以下独立代码。 用F5运行它
“C:\ WINDOWS \ SYSTEM32 \ WindowsPowerShell \ V1.0 \ powershell_ise.exe”
Get-Process | Export-Csv -Path $env:temp\process.csv -NoTypeInformation $processes = Import-Csv -Path $env:temp\process.csv $Excel = New-Object -ComObject excel.application $workbook = $Excel.workbooks.add() $i = 1 foreach($process in $processes) { $excel.cells.item($i,1) = $process.name $excel.cells.item($i,2) = $process.vm $i++ } Remove-Item $env:temp\process.csv $Excel.visible = $true
它能做什么
- 该脚本会将所有活动进程的列表以CSV格式导出到您的临时文件夹。 这个文件只用于我们的例子。 它可以是任何数据的CSV
- 它读入新创build的CSV并将其保存在
$processes
variables下 - 它创build一个新的空的Excel工作簿,我们可以写数据
- 它遍历所有行(?),并将
name
和vm
列中的所有值写入Excel
我的问题
- 如果我不知道列标题怎么办? (在我们的例子
name
和vm
)。 如何处理我不知道标题名称的值? - 我如何计算一个CSV有多less列? (在用
Import-Csv
阅读之后)
我只想用Powershell写一个完整的CSV到Excel
Ups,我完全忘了这个问题。 在此期间,我得到了一个解决scheme。
此Powershell脚本在后台将CSV转换为XLSX
噱头是
- 保留所有CSV值为纯文本,如
=B1+B2
或0000001
。
你没有看到#Name
或类似的东西。 没有autoformating完成。 - 根据您的区域设置自动select正确的分隔符(逗号或分号)
- 自动调整列
PowerShell代码
### Set input and output path $inputCSV = "C:\somefolder\input.csv" $outputXLSX = "C:\somefolder\output.xlsx" ### Create a new Excel Workbook with one empty sheet $excel = New-Object -ComObject excel.application $workbook = $excel.Workbooks.Add(1) $worksheet = $workbook.worksheets.Item(1) ### Build the QueryTables.Add command ### QueryTables does the same as when clicking "Data » From Text" in Excel $TxtConnector = ("TEXT;" + $inputCSV) $Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1")) $query = $worksheet.QueryTables.item($Connector.name) ### Set the delimiter (, or ;) according to your regional settings $query.TextFileOtherDelimiter = $Excel.Application.International(5) ### Set the format to delimited and text for every column ### A trick to create an array of 2s is used with the preceding comma $query.TextFileParseType = 1 $query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count $query.AdjustColumnWidth = 1 ### Execute & delete the import query $query.Refresh() $query.Delete() ### Save & close the Workbook as XLSX. Change the output extension for Excel 2003 $Workbook.SaveAs($outputXLSX,51) $excel.Quit()
你为什么打扰? 像这样将你的CSV加载到Excel中:
$csv = Join-Path $env:TEMP "process.csv" $xls = Join-Path $env:TEMP "process.xlsx" $xl = New-Object -COM "Excel.Application" $xl.Visible = $true $wb = $xl.Workbooks.OpenText($csv) $wb.SaveAs($xls, 51)
您只需确保CSV导出使用区域设置中定义的分隔符。 如果需要,用-Delimiter
覆盖。
编辑:一个更一般的解决scheme,应该保持CSV作为纯文本的值。 迭代从这里取得的CSV列的代码。
$csv = Join-Path $env:TEMP "input.csv" $xls = Join-Path $env:TEMP "output.xlsx" $xl = New-Object -COM "Excel.Application" $xl.Visible = $true $wb = $xl.Workbooks.Add() $ws = $wb.Sheets.Item(1) $ws.Cells.NumberFormat = "@" $i = 1 Import-Csv $csv | % { $j = 1 foreach ($prop in $_.PSObject.Properties) { if ($i -eq 1) { $ws.Cells.Item($i, $j++).Value = $prop.Name } else { $ws.Cells.Item($i, $j++).Value = $prop.Value } } $i++ } $wb.SaveAs($xls, 51) $wb.Close() $xl.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)
这个话题真的帮了我很大的忙,所以我想分享一下我的改进。 所有学分都去nixda ,这是基于他的答案。
对于需要在文件夹中转换多个csv的用户,只需修改目录即可。 输出文件名将与input相同,只是另一个扩展名。
最后照顾清理,如果你想保留原来的csv的,你可能不想删除这些 。
可以很容易地修改将xlsx保存在另一个目录中。
$workingdir = "C:\data\*.csv" $csv = dir -path $workingdir foreach($inputCSV in $csv){ $outputXLSX = $inputCSV.DirectoryName + "\" + $inputCSV.Basename + ".xlsx" ### Create a new Excel Workbook with one empty sheet $excel = New-Object -ComObject excel.application $excel.DisplayAlerts = $False $workbook = $excel.Workbooks.Add(1) $worksheet = $workbook.worksheets.Item(1) ### Build the QueryTables.Add command ### QueryTables does the same as when clicking "Data » From Text" in Excel $TxtConnector = ("TEXT;" + $inputCSV) $Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1")) $query = $worksheet.QueryTables.item($Connector.name) ### Set the delimiter (, or ;) according to your regional settings ### $Excel.Application.International(3) = , ### $Excel.Application.International(5) = ; $query.TextFileOtherDelimiter = $Excel.Application.International(5) ### Set the format to delimited and text for every column ### A trick to create an array of 2s is used with the preceding comma $query.TextFileParseType = 1 $query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count $query.AdjustColumnWidth = 1 ### Execute & delete the import query $query.Refresh() $query.Delete() ### Save & close the Workbook as XLSX. Change the output extension for Excel 2003 $Workbook.SaveAs($outputXLSX,51) $excel.Quit() } ## To exclude an item, use the '-exclude' parameter (wildcards if needed) remove-item -path $workingdir -exclude *Crab4dq.csv
如果您想要在没有安装Excel的情况下将CSV转换为Excel,您可以使用伟大的.NET库EPPlus (在LGPL许可证下)创build和修改Excel表格,并将CSV转换成Excel真的很快!
制备
- 下载最新的稳定EPPlus版本
- 将EPPlus提取到您的首选位置(例如,到
$HOME\Documents\WindowsPowerShell\Modules\EPPlus
) - 右键单击EPPlus.dll,select“属性”,然后在“常规”选项卡的底部单击“取消阻止”以允许加载此dll。 如果您没有权限执行此操作,请尝试
[Reflection.Assembly]::UnsafeLoadFrom($DLLPath) | Out-Null
[Reflection.Assembly]::UnsafeLoadFrom($DLLPath) | Out-Null
详细的Powershell命令将CSV导入到Excel
# Create temporary CSV and Excel file names $FileNameCSV = "$HOME\Downloads\test.csv" $FileNameExcel = "$HOME\Downloads\test.xlsx" # Create CSV File (with first line containing type information and empty last line) Get-Process | Export-Csv -Delimiter ';' -Encoding UTF8 -Path $FileNameCSV # Load EPPlus $DLLPath = "$HOME\Documents\WindowsPowerShell\Modules\EPPlus\EPPlus.dll" [Reflection.Assembly]::LoadFile($DLLPath) | Out-Null # Set CSV Format $Format = New-object -TypeName OfficeOpenXml.ExcelTextFormat $Format.Delimiter = ";" # use Text Qualifier if your CSV entries are quoted, eg "Cell1","Cell2" $Format.TextQualifier = '"' $Format.Encoding = [System.Text.Encoding]::UTF8 $Format.SkipLinesBeginning = '1' $Format.SkipLinesEnd = '1' # Set Preferred Table Style $TableStyle = [OfficeOpenXml.Table.TableStyles]::Medium1 # Create Excel File $ExcelPackage = New-Object OfficeOpenXml.ExcelPackage $Worksheet = $ExcelPackage.Workbook.Worksheets.Add("FromCSV") # Load CSV File with first row as heads using a table style $null=$Worksheet.Cells.LoadFromText((Get-Item $FileNameCSV),$Format,$TableStyle,$true) # Load CSV File without table style #$null=$Worksheet.Cells.LoadFromText($file,$format) # Fit Column Size to Size of Content $Worksheet.Cells[$Worksheet.Dimension.Address].AutoFitColumns() # Save Excel File $ExcelPackage.SaveAs($FileNameExcel) Write-Host "CSV File $FileNameCSV converted to Excel file $FileNameExcel"
这是一个稍微的变化 ,对我来说效果更好。
$csv = Join-Path $env:TEMP "input.csv" $xls = Join-Path $env:TEMP "output.xlsx" $xl = new-object -comobject excel.application $xl.visible = $false $Workbook = $xl.workbooks.open($CSV) $Worksheets = $Workbooks.worksheets $Workbook.SaveAs($XLS,1) $Workbook.Saved = $True $xl.Quit()
我有一些问题让其他例子工作。
EPPlus和其他库生成OpenDocument Xml格式,这与从Excel以xlsx保存时所得到的格式不同。
马克斯与开放CSV的例子,只是重新保存没有工作,我从来没有设法得到','分隔符正确使用。
Ansgar Wiechers的例子有一些轻微的错误,我在评论中find了答案。
无论如何,这是一个完整的工作例子。 将其保存在文件CsvToExcel.ps1中
param ( [Parameter(Mandatory=$true)][string]$inputfile, [Parameter(Mandatory=$true)][string]$outputfile ) $excel = New-Object -ComObject Excel.Application $excel.Visible = $false $wb = $excel.Workbooks.Add() $ws = $wb.Sheets.Item(1) $ws.Cells.NumberFormat = "@" write-output "Opening $inputfile" $i = 1 Import-Csv $inputfile | Foreach-Object { $j = 1 foreach ($prop in $_.PSObject.Properties) { if ($i -eq 1) { $ws.Cells.Item($i, $j) = $prop.Name } else { $ws.Cells.Item($i, $j) = $prop.Value } $j++ } $i++ } $wb.SaveAs($outputfile,51) $wb.Close() $excel.Quit() write-output "Success"
执行:
.\CsvToExcel.ps1 -inputfile "C:\Temp\X\data.csv" -outputfile "C:\Temp\X\data.xlsx"