使用Powershell打开受密码保护的Excel xlsx文件,然后将其另存为csv,而不输入密码

时间:2020-04-28 15:49:51

标签: excel powershell

我有一个受密码保护的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($_)
        }
    }
}

1 个答案:

答案 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($_)
    }
}