I have imported a comma seperated csv file using powershell.
I gets imported and looks as it should. The problem is, the cells contain formulas.
Like =20+50+70. It doesn't get calculated unless i click enter i the top field.
Another problem is, that some of the cells contains numbers like =50,2+70,5. These cells excel doesn't understand at all. It can't caltulate them, unless i remove the , or replace it with a dot (.). But this is not a possibility.
How to i fix this?
The csv file is imported with powershell using this:
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
$wbpath=Join-Path "$psscriptroot" 'file.xlsx'
$importcsv=Join-Path "$psscriptroot" 'file.csv'
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $false
$xl.Workbooks.OpenText($importcsv)
$xl.DisplayAlerts = $false
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
$xl.ActiveWorkbook.SaveAs($wbpath,51)
$xl.Quit()
while([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)){'released'}
The
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
is necessary or i will get errors because my system locale is not us.
Thank you.
CSV Sample:
name1.name1.name1,"=20","=7,65","=20,01"
name2.name2.name2,"=20+10","=4,96+0,65","=20,01+10"
name3.name3.name3,"=20","=4,96+0,88","=21,01+11"
Sounds like you need to
a) Force the worksheet to calculate
b) If you're going to stick with en-US locale then you need to replace those commas with decimal points. That's the GB/US standard and how Excel will interpret decimals. I'd strongly advise however that you stick to the locale that your data is set up in.
(untested as I'm currently on a Mac)
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
$wbpath=Join-Path "$psscriptroot" 'file.xlsx'
$importcsv=Join-Path "$psscriptroot" 'file.csv'
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $false
$wb = $xl.Workbooks.OpenText($importcsv)
$xl.DisplayAlerts = $false
[threading.thread]::CurrentThread.CurrentCulture = 'en-US'
$sh = $wb.Sheets.Item(1)
# loop through the used range and replace any commas with decimals
foreach ($cell in $sh.usedRange)
{
[string]$formula = $cell.formula
$formula -replace ',','.'
$cell.formula = $formula
}
# force the sheet to calculate
$sh.Calculate()
$xl.ActiveWorkbook.SaveAs($wbpath,51)
$xl.Quit()
while([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)){'released'}
As with the previous answer, you have to account for locale; not all .csv files are the same formatting based on what country locale they were encoded in. While UTF is standard, in some respects CSV is a "legacy format", even if it's the most lightweight, simple way to transfer data using plaintext.
Sam already answered the majority of the difficult stuff, so I'll just add a few things. If you are making an automated solution and work with multiple countries, there's a few ways you can determine how it's encoded. You can go the more technically proficient route and implement a custom function similar to this one https://gist.github.com/jpoehls/2406504 or, because it's a CSV, you can make a decent guess since the most common encoding formats use different delimiters; I believe the one you are mentioning uses tabs as encoding.
I'll focus on the ones within Excel importing because those weren't mentioned. There's a fairly neat function in the Data tab that allows you to customize your import based on what delimiters it uses. In the third step when you press Advanced, it allows you to tell it which separator (comma or decimal) that the source data is using, and once you select that and press Finish, it will convert the result to whatever your locale is set to for Excel and properly evaluate functions. Example picture So, the workflow for this would be open a new Excel book, select Data > From Text and proceed from there. It will convert the text from the locale you choose (in your case 1252 is likely) into whatever decimal format you specify.
Related
I want to open the CSV file using powershell Excel.Application.
my code is like this:
$csv = "csv name"
$xlsx = "output excel name"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$wb = $excel.Workbook.Open($csv)
$wb.SaveAs($xlsx,51)
$excel.Quit()
But Turns out that the data in the csv "004" will loaded as 4
Anyone can think of a way to do this?
Noted that there are many special case in my csv:
there are data like "004", "01234678" in the csv and I would like to import all of them as text.
there are comma within the data like "FlatA, 7/F"
there are newline character within the data like
"abcdef
def
ghi"
you can also give your own solution that can load the csv to excel using powershell which can fulfill all the above cases.
Thanks a lot. You will save my life if you able to do this.
I have this CSV file I generate using Export-CSV. Everything is fine with it but it display like this when opening in Excel because the cells are not formatted as TEXT:
I want to force open the CSV with the cells all set to TEXT like you can do manually with the interface.
Is there a way to automate that with PowerShell, opening the CSV in Excel with cells formatted as text?
There is a little trick you can use - convert your data to html, and save with "xls" extention. For example:
Get-Process | convertto-html | Out-File csv2.xls
You'll see a warning when opening it, just click OK.
You can suppress that warning message by adding extra key in registry:
open regedit
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Excel\Security
Create a new DWORD with name ExtensionHardening and value 0
Found a very good way to make it happen!
After generating your CSV file, here is how to automatically load it into Excel with AutoFit column width and TEXT format for cells :) :
$Fichier = "PATH_TO_CSV.csv"
$objExcel = New-Object -ComObject Excel.Application
$WorkBook = $objExcel.Workbooks.Open($Fichier)
$WorkSheet = $WorkBook.worksheets.item(1)
$objExcel.Visible = $true
$Range = $worksheet.UsedRange.Cells
$range.NumberFormat = "#"
$WorkSheet.Columns("A:B").AutoFit()
Powershell script is as follows:
$E = New-Object -ComObject Excel.Application
$E.Visible = $false
$E.DisplayAlerts = $false
$wb = $E.Workbooks.Open($args[0])
$wb_name = fix-wbname($wb.Name)
foreach ($ws in $wb.Worksheets)
{
$n = $wb.Name + "_" + $ws.Name + ".csv"
$n = Join-Path -Path $args[1] -ChildPath $n
$ws.SaveAs($n, 6)
}
It works, but Excel does silly things to the text formatting. Dates in the YYYY-MM-DD format are changed to M/D/YYYY. The number 18446744073709500000 is changed to "1.84467E+19"
Is there any way I can do this and have Excel just export the values as they are?
In general, no. Dates in excel are not stored internally in the same format that you see them on the screen. They are stored in some sort of binary numberger format that is almost undoubtedly the same format used internally in Windows. I haven't researched this. You are going to have to find out what default conversion takes place when the conversion to csv happens. This could be culture dependent.
Culture dependencies can be controlled by settings inside of excel. If the conversions to csv are being done by Powershell, you may be able to control culture dependecies by specifying optional parameters.
Sorry this is so vague.
I have an Excel file that I receive and want to process it to a CSV using Powershell.
I have to alter it quite specifically so it can be a reliable input for a program that will process the csv info.
I don't know the exact headers, but i know there can be duplicates.
What I do is open the xlsx file with excel and save it as CSV:
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $True
$objExcel.DisplayAlerts = $True
$Workbook = $objExcel.Workbooks.open($xlsx1)
$WorkSheet = $WorkBook.sheets.item($sheet)
$xlCSV = 6
$Workbook = $objExcel.Workbooks.open($xlsx2)
$WorkSheet = $WorkBook.sheets.item($sheet)
$WorkBook.SaveAs($csv2,$xlCSV)
Now, the XLSX file will have comma's, so first I want to change them to dots.
I tried this, but it's not working:
$objRange = $worksheet.UsedRange
$objRange.Replace ",", "."
It errors out saying: Unexpected token '", "'.
Then when saving I want to set the Delimiter to comma, as it uses ";" standard.
With something like:
$WorkBook.SaveAs($csv2,$xlCSV) -delimiter ","
The last problem is the duplicate headers; this prevents PS to use Import-CSV. Here I tried, when file is separated with a comma it works:
Get-Content $downloads\BBKS_DIR_AUTO_COMMA.csv -totalcount 1 >$downloads\Headers.txt
But then I need to rename de duplicate names like I can have Regio, Regio, Regio.
I want to change this to Regio, Regio2, Regio3
My plan was to lookup the data of the txt, search for duplicates, and then ad an incremental nummer.
In the end I need to add a column with incremental numbers, but always with four numbers, like; 0001, 0002, 0010, 0020, 0200, 1500, I wont exceed 9999. How can this be done?
If you can help me, if only partially I'm very happy.
Further, I'm running Windows 7 x64, Powershell 3.0, Excel 2016 (if relevant)
If easier, its fine to go back to Command prompt for some tasks.
Personally, I wouldn't try and work with Excel sheets via Excel itself and COM - I'd use the excellent module https://github.com/dfinke/ImportExcel
Then you can import from the sheet straight to a native Powershell object array, and re-export with Export-Csv -Delimiter.
Edit: To answer follow ups :
Once you've loaded the module you can do "Get-Module ImportExcel | Select-Object -ExpandProperty ExportedCommands" to see what it makes available.
To import your Excel in the first place, do something like :
$WorkBook = Import-Excel
And if you need to take care of duplicate column names, you can do :
$WorkBook = Import-Excel -Header #("Regio1", "Regio2", "Regio")
Where the array you pass to -Header needs to include every column you want from the workbook.
I am doing data output to csv file via powershell. Generally things goes well.
I have exported the data to csv file. It contains about 10 columns. When I open it with MS Excel it's all contained in first column. I want to split it by several columns programmatically via powershell(same GUI version offers). I could make looping and stuff to split the every row and then put values to appropriate cell but then it would take way too much time.
I believe there should be an elegant solution to make one column split to multiple. Is there a way to make it in one simple step without looping?
This is what I came up with so far:
PS, The CSV file is 100% FINE. The delimiter is ','
Get-Service | Export-Csv -NoTypeInformation c:\1.csv -Encoding UTF8
$xl = New-Object -comobject Excel.Application
$xl.Visible = $true
$xl.DisplayAlerts = $False
$wb = $xl.Workbooks.Open('c:\1.csv')
$ws = $wb.Sheets|?{$_.name -eq '1'}
$ws.Activate()
$col = $ws.Cells.Item(1,1).EntireColumn
This will get you the desired functionality; add to your code. Check out the MSDN page for more information on TextToColumns.
# Select column
$columnA = $ws.Range("A1").EntireColumn
# Enumerations
$xlDelimited = 1
$xlTextQualifier = 1
# Convert Text To Columns
$columnA.texttocolumns($ws.Range("A1"),$xlDelimited,$xlTextQualifier,$true,$false,$false,$true,$false)
$ws.columns.autofit()
I had to create a CSV which had "","" as delimiter to test this out. The file with "," was fine in excel.
# Opens with all fields in column A, used to test TextToColumns works
"Name,""field1"",""field2"",""field3"""
"Test,""field1"",""field.2[]"",""field3"""
# Opens fine in Excel
Name,"field1","field2","field3"
Test,"field1","field.2[]","field3"
Disclaimer: Tested with $ws = $wb.Worksheets.item(1)