[英]How to export a CSV to Excel using Powershell
I'm trying to export a complete CSV to Excel by using Powershell.我正在尝试使用 Powershell 将完整的 CSV 导出到 Excel。 I stuck at a point where static column names are used.
我停留在使用静态列名的地方。 But this doesn't work if my CSV has generic unknown header names.
但是,如果我的 CSV 具有通用的未知标题名称,则这不起作用。
Open your PowerShell ISE and copy & paste the following standalone code.打开您的 PowerShell ISE 并复制并粘贴以下独立代码。 Run it with F5
用F5运行它
"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell_ise.exe" “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
$processes
variable$processes
变量下name
and vm
column to Excelname
和vm
列中的所有值写入 Excelname
and vm
). name
和vm
)。 How do I address values where I don't know their header names?Import-Csv
) Import-Csv
阅读后) I just want to write an entire CSV to Excel with Powershell我只想用 Powershell 将整个 CSV 写入 Excel
Ups, I entirely forgot this question. Ups,我完全忘记了这个问题。 In the meantime I got a solution.
与此同时,我得到了一个解决方案。
This Powershell script converts a CSV to XLSX in the background此 Powershell 脚本在后台将 CSV 转换为 XLSX
=B1+B2
or 0000001
.=B1+B2
或0000001
。#Name
or anything like that.#Name
或类似的东西。 No autoformating is done.### 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()
I am using excelcnv.exe to convert csv into xlsx and that seemed to work properly.我正在使用 excelcnv.exe 将 csv 转换为 xlsx,这似乎工作正常。 You will have to change the directory to where your excelcnv is.
您必须将目录更改为 excelcnv 所在的位置。 If 32 bit, it goes to Program Files (x86)
如果是 32 位,则转到 Program Files (x86)
Start-Process -FilePath 'C:\Program Files\Microsoft Office\root\Office16\excelcnv.exe' -ArgumentList "-nme -oice ""$xlsFilePath"" ""$xlsToxlsxPath"""
Why would you bother?你为什么要打扰? Load your CSV into Excel like this:
将您的 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)
You just need to make sure that the CSV export uses the delimiter defined in your regional settings.您只需要确保 CSV 导出使用区域设置中定义的分隔符。 Override with
-Delimiter
if need be.如果需要,用
-Delimiter
覆盖。
Edit: A more general solution that should preserve the values from the CSV as plain text.编辑:一个更通用的解决方案,应该将 CSV 中的值保留为纯文本。 Code for iterating over the CSV columns taken from here .
用于迭代从此处获取的 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 | ForEach-Object {
$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)
Obviously this second approach won't perform too well, because it's processing each cell individually.显然,第二种方法不会表现得很好,因为它单独处理每个单元格。
This topic really helped me, so I'd like to share my improvements.这个话题对我很有帮助,所以我想分享我的改进。 All credits go to the nixda , this is based on his answer.
所有学分都归于 nixda ,这是基于他的回答。
For those who need to convert multiple csv's in a folder, just modify the directory.对于那些需要在一个文件夹中转换多个 csv 的人,只需修改目录即可。 Outputfilenames will be identical to input, just with another extension.
输出文件名将与输入相同,只是具有另一个扩展名。
Take care of the cleanup in the end, if you like to keep the original csv's you might not want to remove these .最后请注意清理,如果您想保留原始 csv,您可能不想删除这些 .csv 文件。
Can be easily modifed to save the xlsx in another directory.可以轻松修改以将 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
If you want to convert CSV to Excel without Excel being installed, you can use the great .NET library EPPlus (under LGPL license) to create and modify Excel Sheets and also convert CSV to Excel really fast!如果您想在不安装 Excel 的情况下将 CSV 转换为 Excel,您可以使用强大的 .NET 库EPPlus (在 LGPL 许可下)来创建和修改 Excel 表格,并将 CSV 转换为 Excel 非常快!
$HOME\\Documents\\WindowsPowerShell\\Modules\\EPPlus
)$HOME\\Documents\\WindowsPowerShell\\Modules\\EPPlus
)[Reflection.Assembly]::UnsafeLoadFrom($DLLPath) | Out-Null
[Reflection.Assembly]::UnsafeLoadFrom($DLLPath) | Out-Null
[Reflection.Assembly]::UnsafeLoadFrom($DLLPath) | Out-Null
# 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, e.g. "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"
This is a slight variation that worked better for me.这是一个对我来说效果更好的轻微变化。
$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()
I had some problem getting the other examples to work.我在让其他示例工作时遇到了一些问题。
EPPlus and other libraries produces OpenDocument Xml format, which is not the same as you get when you save from Excel as xlsx. EPPlus 和其他库生成 OpenDocument Xml 格式,这与您从 Excel 保存为 xlsx 时获得的格式不同。
macks example with open CSV and just re-saving didn't work, I never managed to get the ',' delimiter to be used correctly. macks 示例与开放的 CSV 和只是重新保存没有工作,我从来没有设法让 ',' 分隔符被正确使用。
Ansgar Wiechers example has some slight error which I found the answer for in the commencts. Ansgar Wiechers 的例子有一些小错误,我在评论中找到了答案。
Anyway, this is a complete working example.无论如何,这是一个完整的工作示例。 Save this in a File CsvToExcel.ps1
将此保存在文件 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"
Execute with:执行:
.\CsvToExcel.ps1 -inputfile "C:\Temp\X\data.csv" -outputfile "C:\Temp\X\data.xlsx"
I found this while passing and looking for answers on how to compile a set of csvs into a single excel doc with the worksheets (tabs) named after the csv files.我在通过并寻找有关如何将一组 csvs 编译成单个 excel 文档的答案时发现了这一点,其中工作表(选项卡)以 csv 文件命名。 It is a nice function.
这是一个不错的功能。 Sadly, I cannot run them on my network :( so i do not know how well it works.
遗憾的是,我无法在我的网络上运行它们 :( 所以我不知道它的效果如何。
Function Release-Ref ($ref)
{
([System.Runtime.InteropServices.Marshal]::ReleaseComObject(
[System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
Function ConvertCSV-ToExcel
{
<#
.SYNOPSIS
Converts one or more CSV files into an excel file.
.DESCRIPTION
Converts one or more CSV files into an excel file. Each CSV file is imported into its own worksheet with the name of the
file being the name of the worksheet.
.PARAMETER inputfile
Name of the CSV file being converted
.PARAMETER output
Name of the converted excel file
.EXAMPLE
Get-ChildItem *.csv | ConvertCSV-ToExcel -output ‘report.xlsx’
.EXAMPLE
ConvertCSV-ToExcel -inputfile ‘file.csv’ -output ‘report.xlsx’
.EXAMPLE
ConvertCSV-ToExcel -inputfile @(“test1.csv”,”test2.csv”) -output ‘report.xlsx’
.NOTES
Author: Boe Prox
Date Created: 01SEPT210
Last Modified:
#>
#Requires -version 2.0
[CmdletBinding(
SupportsShouldProcess = $True,
ConfirmImpact = ‘low’,
DefaultParameterSetName = ‘file’
)]
Param (
[Parameter(
ValueFromPipeline=$True,
Position=0,
Mandatory=$True,
HelpMessage=”Name of CSV/s to import”)]
[ValidateNotNullOrEmpty()]
[array]$inputfile,
[Parameter(
ValueFromPipeline=$False,
Position=1,
Mandatory=$True,
HelpMessage=”Name of excel file output”)]
[ValidateNotNullOrEmpty()]
[string]$output
)
Begin {
#Configure regular expression to match full path of each file
[regex]$regex = “^\w\:\\”
#Find the number of CSVs being imported
$count = ($inputfile.count -1)
#Create Excel Com Object
$excel = new-object -com excel.application
#Disable alerts
$excel.DisplayAlerts = $False
#Show Excel application
$excel.V isible = $False
#Add workbook
$workbook = $excel.workbooks.Add()
#Remove other worksheets
$workbook.worksheets.Item(2).delete()
#After the first worksheet is removed,the next one takes its place
$workbook.worksheets.Item(2).delete()
#Define initial worksheet number
$i = 1
}
Process {
ForEach ($input in $inputfile) {
#If more than one file, create another worksheet for each file
If ($i -gt 1) {
$workbook.worksheets.Add() | Out-Null
}
#Use the first worksheet in the workbook (also the newest created worksheet is always 1)
$worksheet = $workbook.worksheets.Item(1)
#Add name of CSV as worksheet name
$worksheet.name = “$((GCI $input).basename)”
#Open the CSV file in Excel, must be converted into complete path if no already done
If ($regex.ismatch($input)) {
$tempcsv = $excel.Workbooks.Open($input)
}
ElseIf ($regex.ismatch(“$($input.fullname)”)) {
$tempcsv = $excel.Workbooks.Open(“$($input.fullname)”)
}
Else {
$tempcsv = $excel.Workbooks.Open(“$($pwd)\$input”)
}
$tempsheet = $tempcsv.Worksheets.Item(1)
#Copy contents of the CSV file
$tempSheet.UsedRange.Copy() | Out-Null
#Paste contents of CSV into existing workbook
$worksheet.Paste()
#Close temp workbook
$tempcsv.close()
#Select all used cells
$range = $worksheet.UsedRange
#Autofit the columns
$range.EntireColumn.Autofit() | out-null
$i++
}
}
End {
#Save spreadsheet
$workbook.saveas(“$pwd\$output”)
Write-Host -Fore Green “File saved to $pwd\$output”
#Close Excel
$excel.quit()
#Release processes for Excel
$a = Release-Ref($range)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.