【问题标题】:How to convert multiple xls files to csv using powershell?如何使用powershell将多个xls文件转换为csv?
【发布时间】:2011-08-28 22:21:42
【问题描述】:

我正在尝试使用以下 powershell 脚本将多个 Excel 文件 (xls) 转换为 csv:

$excel = new-object -ComObject "Excel.Application"
$excel.DisplayAlerts=$True
$excel.Visible =$false
foreach ($file in get-childitem $src_dir) {
    $wb = $excel.Workbooks.Open($file.FullName)
    $wb.SaveAs($dst_dir + $file.Name + ".csv", 6)# 6 -> csv
    $wb.Close($True)
}
$excel.Quit()
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)

原则上这是可行的,例如我得到 csv 文件。但是,对于一些文件(每次运行不同)我得到一个例外:

Exception calling "SaveAs" with "2" argument(s): "Microsoft Office Excel cannot access the file 'C:\Users\...\AppData\Local\Temp'. ...

此外,我收到一个消息框,询问我是否要将更改保存到源 xls。

一旦我调用 SaveAs,$wb 就会引用新文件。那么如何保存或放弃对源文件的更改呢?为什么这只发生在少数文件上?这个脚本还有其他问题吗?

更新

我将输入文件(约 200 个)任意(即不知道组的大小)分成 10 组,并在自己的运行中处理每个组。这行得通,所以有点不方便。

提前致谢

【问题讨论】:

  • 你看看错误中显示的临时文件,看看是否没有剩余文件。我在 PDF 转换脚本中遇到了类似的问题,遗留的旧临时文件是问题的根源。
  • 不幸的是,错误消息只命名了 Temp 目录。我在运行期间监视了目录,并且出现并消失了两个具有随机名称的文件(可能是每个转换后的 xls)。

标签: excel powershell csv xls


【解决方案1】:

尝试移动代码以在循环内启动和退出 excel。

是的,这样会比较慢,但它会鼓励 Excel 在每次操作之间清理其临时文件。

它不会像你想象的那么慢,因为 Windows 和 COM 足够聪明,即使在你退出几秒钟后,它也可以将 Excel 大部分留在内存中,这样下次你创建一个 Excel 对象时它会很快发生,正好适合这种情况。

【讨论】:

    【解决方案2】:

    也许您可以实现一个计时器来等待一段时间?或者您在脚本运行时查看目录内部,然后在每个循环后删除临时文件(一个 xls 文件转换)。

    【讨论】:

      【解决方案3】:

      我相信您可以通过使用$wb.Close($False) 而不是$wb.Close($True) 来避免询问您是否要保存的消息框。这是我正常使用的,我没有收到任何消息框。

      【讨论】:

        【解决方案4】:

        我更新的带有计时器的脚本 - 可能不是准确的答案,但会帮助寻找脚本的人:

        $excel = new-object -ComObject "Excel.Application"
        $excel.DisplayAlerts=$True
        $excel.Visible =$false
        $src_dir='D:\folderwithxlsx\'
        $dst_dir='D:\folderwithcsv\'
        Get-ChildItem $src_dir -Filter *.xlsx |
        Foreach-Object{
          'processing '+$_.FullName
          $wb = $excel.Workbooks.Open($_.FullName)
          $dst_file=$dst_dir + $_.BaseName + ".csv"
          $wb.SaveAs($dst_file, 6)# 6 -> csv
          'saved '+$dst_file
          $wb.Close($True)
          Start-Sleep -Seconds 2
         }
        $excel.Quit()
        [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
        

        【讨论】:

          猜你喜欢
          • 2015-02-02
          • 2020-12-30
          • 1970-01-01
          • 2015-11-11
          • 2014-03-13
          • 1970-01-01
          • 1970-01-01
          • 2014-07-10
          • 1970-01-01
          相关资源
          最近更新 更多