如何使用PowerShell将多个xls文件转换为csv?

时间:2011-05-19 14:05:50

标签: excel powershell csv xls

我正在尝试使用以下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组,并在自己的运行中处理每个组。这样做有点不方便。

提前致谢

4 个答案:

答案 0 :(得分:4)

尝试移动代码以启动并退出excel INSIDE你的循环。

是的,它的速度较慢,但​​它会鼓励Excel在每次操作之间清理临时文件。

它不会像你想象的那么慢,因为即使在你退出几秒钟之后,Windows和COM也足够聪明地将Excel保留在内存中,以便下次创建Excel对象时它会快速发生,完全适合这种情况。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

$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)