我有一个受密码保护的Excel文件(Office 2019,xlsx文件)。我想创建一个Powershell脚本以使用密码打开文件,然后将其另存为csv,而不使用密码在新目录中。我试图回答问题here,但这对我没有用。我没有使用Powershell的丰富经验,感谢您提供任何见识。
我想在这里为正在寻找类似解决方案的任何人更新此解决方案。我很惊讶,在任何地方都找不到一个简单的方法。
对我的原始帖子的批评者来说-如果您过去曾经写过类似的东西,答案将是您可能使用过的现有脚本的简单复制和粘贴。我本人拥有大量此类脚本的存储库,并经常与同事和社区共享它们,因此我一直在寻找可能具有相似共享之处的人员。您显然没有,所以您的回应毫无意义。
$filepath = "C:\MyDailyFile\Blah.xlsx"
$password = "omgpassword"
try {
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$excel.DisplayAlerts = $true
## Open target password protected workbook
## [Type}::Missing are placeholders for positional parameters. See the Workbook class for more detail.
$wb = $excel.Workbooks.Open($filepath, [Type]::Missing, [Type]::Missing, [Type]::Missing, $password)
$sheet = $wb.ActiveSheet
## Save the open workbook in a new directory without a password
## and change the file type to CSV
$wb.SaveAs("C:\MyDailyFile\BlahCommaDelim",6,"")
## The second property of the SaveAs class (6) corresponds to a type "csv". The above results in the following SaveAs path:
## C:\MyDailyFile\BlahCommaDelim.csv
## More information on XlFileFormat parameters https://docs.microsoft.com/en-us/office/vba/api/Excel.XlFileFormat
$excel.Quit()
} finally {
$sheet, $wb, $excel | ForEach-Object {
if ($_ -ne $null) {
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($_)
}
}
}
答案 0 :(得分:0)
始终一次浏览一个代码块,以确保您获得了期望的结果。
我正在利用穷人的调试用例。 variable squeezing是指将结果分配给变量,同时自动输出到屏幕。您会注意到这一切都按预期进行,并且Lee询问您遇到的错误是谨慎的询问。
您的声明:
我试图在这里关注这个问题,但这对我不起作用。
...并不是真正的说明。
($XlsFiles = Get-ChildItem -Path 'D:\Temp' -Filter 'File*.xl*')
<#
# Results
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 28-Apr-20 15:49 9811 FileData.xlsx
-a---- 28-Apr-20 15:50 16384 FileDataProtected.xlsx
#>
($XlsFiles = Get-ChildItem -Path 'D:\Temp' -Filter 'File*.csv')
<#
# Results
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06-Apr-20 00:54 260 FileData.csv
#>
($filepath = 'D:\Temp\FileDataProtected.xlsx')
($password = 'omgpassword')
<#
# Results
D:\Temp\FileDataProtected.xlsx
omgpassword
#>
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$excel.DisplayAlerts = $true
为什么在这里打字?确实没有必要。
# ($wb = $excel.Workbooks.Open($filepath, [Type]::Missing, [Type]::Missing, [Type]::Missing, $password))
<#
# Results
Application : Microsoft.Office.Interop.Excel.ApplicationClass
Creator : 1480803660
Parent : Microsoft.Office.Interop.Excel.ApplicationClass
AcceptLabelsInFormulas : False
ActiveChart :
ActiveSheet : System.__ComObject
Author :
AutoUpdateFrequency : 0
AutoUpdateSaveChanges :
ChangeHistoryDuration : 0
BuiltinDocumentProperties : System.__ComObject
Charts : System.__ComObject
CodeName :
_CodeName :
CommandBars :
Comments :
ConflictResolution : 1
Container :
CreateBackup : False
CustomDocumentProperties : System.__ComObject
Date1904 : False
DialogSheets : System.__ComObject
DisplayDrawingObjects : -4104
FileFormat : 51
FullName : D:\Temp\FileDataProtected.xlsx
...
#>
($wb = $excel.Workbooks.Open($filepath,0,0,5,$password))
<#
# Results
Application : Microsoft.Office.Interop.Excel.ApplicationClass
Creator : 1480803660
Parent : Microsoft.Office.Interop.Excel.ApplicationClass
AcceptLabelsInFormulas : False
ActiveChart :
ActiveSheet : System.__ComObject
Author :
AutoUpdateFrequency : 0
AutoUpdateSaveChanges :
ChangeHistoryDuration : 0
BuiltinDocumentProperties : System.__ComObject
Charts : System.__ComObject
CodeName :
_CodeName :
CommandBars :
Comments :
ConflictResolution : 1
Container :
CreateBackup : False
CustomDocumentProperties : System.__ComObject
Date1904 : False
DialogSheets : System.__ComObject
DisplayDrawingObjects : -4104
FileFormat : 51
FullName : D:\Temp\FileDataProtected.xlsx
...
#>
您在发布的任何地方都没有使用它,所以,为什么呢? 对于未使用的内容,也需要很长时间才能完成。
#>
($sheet = $wb.ActiveSheet)
<#
# Results
Application : Microsoft.Office.Interop.Excel.ApplicationClass
Creator : 1480803660
Parent : System.__ComObject
CodeName :
_CodeName :
Index : 1
Name : FileData
...
#>
$wb.SaveAs('D:\Temp\FileDataUnProtected.csv',6,'')
<#
# Results
当您这样做时,Excel会通过从Xlsx切换为CSV向您大喊数据丢失。
# Clean-up
$excel.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
<#
# Results
6
#>
($XlsFiles = Get-ChildItem -Path 'D:\Temp' -Filter 'File*.csv')
<#
# Results
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06-Apr-20 00:54 260 FileData.csv
-a---- 28-Apr-20 16:21 129 FileDataUnProtected.csv
#>
Get-Content -Path 'D:\Temp\FileDataUnProtected.csv'
<#
# Results
0 minutes
0 minutes
1 day and 19 hours
1 day and 2 hours
1 day and 20 hours
1 day and 23 hours
13 hours
2 days
20 hours
#>
Import-Csv -Path 'D:\Temp\FileDataUnProtected.csv'
<#
# Results
0 minutes
1 day and 19 hours
1 day and 2 hours
1 day and 20 hours
1 day and 23 hours
13 hours
2 days
20 hours
#>
最后,这没有什么意义,因为您只有一个要处理的COM对象,其他对象只是变量,应使用Remove-Variable cmdlet进行清理
finally {
$sheet, $wb, $excel | ForEach-Object {
if ($_ -ne $null) {
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($_)
}
}