Create Excel file from command line - excel

Is there any way to create a new Excel file from command line?

If the Excel files you need to create are always the same, you can create a template manually, then create new files at will with something like...
copy template.xlsx myNewSpreadsheet.xlsx
If you need to create files with content that varies, I suggest starting with the powershell solution proposed by David.

You can do this using PowerShell:
PS> $excel = New-Object -ComObject "Excel.Application"
PS> $wb = $excel.Workbooks.Add()
PS> $ws = $wb.ActiveSheet
PS> $excel.Visible = $True
< do some work >
PS> $wb.SaveAs("xltest.xlsx")
PS> $wb.Close()
PS> $excel.Quit()

Related

PowerShell opens excel while running script and crashes

I have made some code to run a Macro on 560 Excel files.
There is a small issue with the code, it seems it doesn't save excel file, and opens every excel file, cause excel to crash.
is there a way to have the macro be ran on these 560 files in the backround, and to automatically save once macro is ran, rather than saving it manually?
Thanks
Here is my Code:
# start excel
$excel = New-Object -comobject Excel.Application
# get files
$files = Get-ChildItem 'C:\Users\ME\Desktop\TEST'
# loop through all files in the directory
ForEach ($file in $files){
# open the file
$workbook = $excel.Workbooks.Open($file.FullName)
# make file visible
$excel.Visible = $true
# run macro
$app = $excel.Application
$app.run("PERSONAL.xlsb!Module6.MyMacro")
}
By setting $excel.Visible = $true, the code will become much slower because of all the screen updates involved.
Also, you do not save the workbook after running the code, and because you never quit Excel and remove the COM objects from memory, eventually it will crash because of running out of resources.
Try:
# start excel
$excel = New-Object -comobject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
# get files and loop through the list
# the usual extension for macro-enabled Excel files is `*.xlsm`.
# if your files have this extension, add -Filter '*.xlsm' to the
# Get-ChildItem command below.
Get-ChildItem -Path 'C:\Users\ME\Desktop\TEST' -File | ForEach-Object {
# open the file
$workbook = $excel.Workbooks.Open($_.FullName)
# run macro
$app = $excel.Application
$app.run("PERSONAL.xlsb!Module6.MyMacro")
$workbook.Close($true) # $true --> save changes
}
$excel.Quit()
# cleanup COM objects
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

Powershell - Excel SaveAs csv with specified delimiter

Afternoon all,
Is it possible to save a CSV file using Powershell with a different delimiter, in my case "§". I am using the following script to open and change items in an XLSX file and then wish to save as a "§" delimited CSV. The find and replace method does not work in my case ( (Get-Content -Path $CSVfile).Replace(',','§') | Set-Content -Path $CSVfile2)
$Path = "C:\ScriptRepository\CQC\DataToLoad\"
$FileName = (Get-ChildItem $path).FullName
$FileName2 = (Get-ChildItem $path).Name
$CSVFile = "$Path\$Filename2.csv"
$Excel = New-Object -ComObject Excel.Application -Property #{Visible =
$false}
$Excel.displayalerts=$False
$Workbook = $Excel.Workbooks.Open($FileName)
$WorkSheet = $WorkBook.Sheets.Item(2)
$Worksheet.Activate()
$worksheet.columns.item('G').NumberFormat ="m/d/yyyy"
$Worksheet.Cells.Item(1,3).Value = "Site ID"
$Worksheet.Cells.Item(1,4).Value = "Site Name"
$Worksheet.SaveAs($CSVFile,
[Microsoft.Office.Interop.Excel.XlFileFormat]::xlCSVWindows)
$workbook.Save()
$workbook.Close()
$Excel.Quit()
Running the following command, will let you save the CSV file using the delimiter §
Import-CSV filename.csv | ConvertTo-CSV -NoTypeInformation -Delimiter "§" | Out-File output_filename.csv
You should check out ImportExcel - PowerShell module to import/export Excel spreadsheets, without Excel. It makes working with excel files easier using powershell.
I know this is an older post but here is an option I recently came across:
Just update the e:\projects\dss\pse&g.xlsxwith the source location and file as well as the file.csv with the location and file name. Lastly your Worksheet if it is named differently [Sheet1$].
$oleDbConn = New-Object System.Data.OleDb.OleDbConnection
$oleDbCmd = New-Object System.Data.OleDb.OleDbCommand
$oleDbAdapter = New-Object System.Data.OleDb.OleDbDataAdapter
$dataTable = New-Object System.Data.DataTable
$oleDbConn.ConnectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=e:\projects\dss\pse&g.xlsx;Extended Properties=Excel 12.0;Persist Security Info=False"
$oleDbConn.Open()
$oleDbCmd.Connection = $OleDbConn
$oleDbCmd.commandtext = “Select * from [Sheet1$]”
$oleDbAdapter.SelectCommand = $OleDbCmd
$ret=$oleDbAdapter.Fill($dataTable)
Write-Host "Rows returned:$ret" -ForegroundColor green
$dataTable | Export-Csv file.csv -Delimiter ';'
$oleDbConn.Close()
Source
I was using SaveAs(file.csv,6) but couldn't change the delimiter. Also Ishan's resolution works but I wanted something more OOB as this is going to be used within an SSIS package for myself across different systems and this just works. =)

How to use powershell to run personal macro with different paths

I am trying to create automatically a report out of an excel file. I already analyzed one specific file and the report is saved local.
Now I want to use this macro to run it on other files. Therefore I have to change the path in the powershell.
Now I want to run the macro automatically (let`s say at 1am) with powershell.
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open("C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
$FilePath = "C:\Users\fami\Desktop\example.xls"
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run("PERSONAL.XLSB!run")
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
Only the $FilePath needs to be variable.
You just need to use a Parameter for the $FilePath variable instead of hard coding it. Like this:
param([string]$FilePath)
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open("C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB")
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run("PERSONAL.XLSB!run")
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
Then you would schedule the script and specify the -FilePath paramater like so:
powershell.exe -file C:\folder\yourscript.ps1 -FilePath "C:\Users\fami\Desktop\example.xls"
EDIT: To read a list of files from a text file (with one file on each line) would be this.
param(
[string]$FileList,
[string]$PersonalXLSB="C:\Users\fami\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB",
[string]$RunMacro="PERSONAL.XLSB!run"
)
$Files = Get-Content $FileList
foreach ($FilePath in $Files) {
$excel = New-Object -comobject Excel.Application
$wbPersonalXLSB = $excel.workbooks.open($PersonalXLSB)
$workbook = $excel.Workbooks.Open($FilePath)
$excel.Visible = $false
$worksheet = $workbook.worksheets.item(1)
$excel.Run($RunMacro)
$wbPersonalXLSB.Close()
$workbook.save()
$workbook.close()
$excel.quit()
}
I've also moved the PersonalXLSB and Macro to Params, as they have a value set this will be used as default if you don't specify anything else. It's most basic form is like this:
powershell.exe -file C:\folder\yourscript.ps1 -FileList "C:\folder\name.text"
You can change the other params like this:
powershell.exe -file C:\folder\yourscript.ps1 -FileList "C:\folder\name.text" -RunMacro="PERSONAL.XLSB!macroname"

PowerShell + Excel - $workbook.save() hangs up on me

I started messing around with Excel on PowerShell, specially because I had to go through 138 files changing every instance of $B$1 to TEXT($B$1,"0000") and I didn't want to do that manually.
Found a couple of resources online and changed the formula but when I try .Save(), PowerShell seems to just sit there, waiting for something I have no idea what.
PS C:\> $excel = New-Object -com Excel.Application
PS C:\> Get-ChildItem '\\UNC\Path\to\folder' <Common file string>*.xls -Recurse | Select-Object -First 1 | % {
>> $workbook = $excel.Workbooks.Open($_.Fullname)
>> $workbook.Save()
>> }
Any ideas on what could be the problem?
When Excel hangs in this regard I would suspect it is waiting for you to do something. The easiest was to confirm this is setting the visibility to True.
$excel.Visible = $true
That would just show you the dialog that was hidden from you previously. As discussed in comments it appears you got a message from the Compatibly Checker. Once you know what it is and are willing to suppress it then just have the following
$excel.Visible = $false
$excel.displayAlerts = $false

Calling Excel macros from PowerShell with arguments

Using Powershell it's rather easy to call Excel macro's from a script, for example with a script like this:
$excel = new-object -comobject excel.application
$excelFiles = Get-ChildItem -Path C:\fso -Include *.xls, *.xlsm -Recurse
Foreach($file in $excelFiles)
{
$workbook = $excel.workbooks.open($file.fullname)
$worksheet = $workbook.worksheets.item(1)
$excel.Run("CreateChart")
$workbook.save()
$workbook.close()
}
$excel.quit()
However, I didn't manage to call a macro with some arguments. Is this possible or is the best way to write a config file that the macro will read when called?
You can run a macro with arguments like this:
$excel.Run('CreateChart', 'arg1', 'arg2', ...)

Resources