Update 07SEPT2010: Updated script based on an excellent comment to use the Paste() method for converting CSV files into an excel workbook. Thanks Luc!
While going through the Technet Powershell Forums and Scripting Guys Forums, I came across a question by an individual who was looking for the best way to convert a .csv file into an excel file. As it stood, the individual only need to convert one csv file and that made for a fairly easy solution.
$xl = new-object -comobject excel.application$xl.visible = $true
$Workbook = $xl.workbooks.open(“$loglocation\errors_$server.csv”)
$Worksheets = $Workbooks.worksheets $Workbook.SaveAs(“$loglocation\errors_$server.xls”,1)
$Workbook.Saved = $True $xl.Quit()
Simple enough. Just open up the CSV file using a created excel com object in Powershell and then save that file as an excel spreadsheet.
This got me to thinking about what if I wanted to save multiple csv files into an excel workbook? How would that be done? And of course, can this all be automated to auto-fit the columns and provide a name to each worksheet that was relevant to each csv file that was being converted?
The short answer, is…Yes! This can be done with Powershell and accomplish all of the requirements.
Below is the script that I wrote that takes multiple csv files and adds them all into excel. It also auto-fits each column in excel so when you open it up, you already have access to all of the information without having to manually re-size each column. Plus, for each csv that you submit, a separate worksheet is created with the name of the csv file submitted, minus the extension. Depending on the size of the csv, the time it takes for the conversion will vary.
As shown in the picture below, I have two csv files that are being converted into one excel workbook and saved to whatever filename I want using the .xlsx format.
When I open up the excel file, I now see both of my CSV’s there to view.
Simple enough!
You can find this script below or at this link on the Technet Gallery:
Script Below
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.Visible = $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)
}
}









