Powershell写入.XLSX会损坏文件

时间:2020-01-13 19:14:05

标签: powershell loops xlsx xls

我有一个Powershell脚本,该脚本可以循环访问文件夹中的.xslx文件,并且密码使用文件名来保护它们(目前)。循环访问并写入.xls没有问题,但是当我尝试打开.xls时。使用Powershell写入xlsx文件后-我收到错误消息:

Excel无法打开文件'abcd.xlsx',因为文件格式或文件 扩展名无效。确认文件未损坏 并且文件扩展名与文件格式匹配。

这是脚本:

function Release-Ref ($ref) { 
    ([System.Runtime.InteropServices.Marshal]::ReleaseComObject( 
    [System.__ComObject]$ref) -gt 0) 
    [System.GC]::Collect() 
    [System.GC]::WaitForPendingFinalizers()  
    } 

$e = $ErrorActionPreference
$ErrorActionPreference="continue"
foreach ($f in Get-ChildItem "C:"){
    try{
        $ff = $f
        $xlNormal = -4143 
        $s = [System.IO.Path]::GetFileNameWithoutExtension($f)
        $xl = new-object -comobject excel.application 
        $xl.Visible = $False
        $xl.DisplayAlerts = $False   
        $wb = $xl.Workbooks.Open($ff.FullName)
        $wb.sheets(1).columns("A:S").entirecolumn.AutoFit()
        $wb.sheets(1).columns("N").NumberFormat = "0.0%"
        $a = $wb.SaveAs("C:\Out\" + $s + ".xls",$xlNormal,$s) #works
        #$a = $wb.SaveAs("C:\Out\" + $s + ".xlsx",$xlNormal,$s) #doesn't work
        $a = $xl.Quit() 

        $a = Release-Ref($ws) 
        $a = Release-Ref($wb) 
        $a = Release-Ref($xl) 
    }
    catch {
        Write-Output "Exception"
        $ErrorActionPreference=$e;
    }
}

我搜索了其他问题,但是找不到从Powershell编写的相同问题的任何其他示例。谢谢。

2 个答案:

答案 0 :(得分:1)

使用excel处理com对象有时过于复杂。我建议使用import-excel模块。 Install-Module -Name ImportExcel

然后您可以执行以下操作。

function Release-Ref ($ref) { 
    $e = $ErrorActionPreference
    $ErrorActionPreference="continue"

foreach ($f in Get-ChildItem $file){
    try{
        $filePass = gci $f
        $path = split-path $f
        $newFile = $path + "\" + $f.BaseName + "-protected.xlsx"
        $f | Export-excel $newFile -password $filePass -NoNumberConversion * -AutoSize
    }
    catch {
        Write-Output "Exception"
        $ErrorActionPreference=$e;
    }
}
}

答案 1 :(得分:1)

由于Xls与Xlsx格式不同而导致问题。 2007版之前的旧版Excel使用二进制格式。 2007 Office引入了Xslx使用的new formats called Office Open Xml

Excel非常聪明,可以检查文件扩展名和文件格式。由于保存具有新版本扩展名的二进制文件会产生冲突,因此错误消息也暗示了这种可能性:

并且文件扩展名与文件格式匹配。

为什么Excel仍然不打开文件?我猜这是一个安全功能,可以防止意外打开Office文档。过去,Office macro viruses是许多办公室的祸根。一种主要的感染媒介是诱使用户在没有预防措施的情况下打开文件。与经典病毒不同,宏病毒感染的是应用程序数据(包括默认模板文件)而不是操作系统二进制文件,但这是另外一回事了。

无论如何,要使用正确的格式,请使用proper version value。 Xls将为-4143,Xlsx将为51。此外,Get-ChildItem返回一个FileInfo对象的集合,并且文件扩展名位于Extension属性中。像这样

# Define Xls and Xlsx versions
$typeXls = -4143
$typeXls = 51
foreach ($f in Get-ChildItem "C:"){

    try{
    $ff = $f
    ...
   # Select saveas type to match original file extension
   if($f.extension -eq '.xsl') { $fType = $typeXls }
   else if($f.extension -eq '.xslx') { $fType = $typeXlsx }

   $a = $wb.SaveAs("C:\Out\" + $s + $.extension, $fType, $s)