【问题标题】:.xlsm to csv using Powershell.xlsm 到 csv 使用 Powershell
【发布时间】:2018-12-04 11:19:30
【问题描述】:

我想将文件夹中的多个文件从 .xlsm 转换为 csv。 Excel 文件包含多张工作表。 因为我对Powershell的了解非常有限,当时我在网上搜索了一个脚本并在Extract and convert all Excel worksheets into CSV files using PowerShell找到了一个

问题是,有几次我设法使这些脚本工作(一个脚本调用另一个脚本),但我还没有弄清楚它何时或如何发生。 我正在从 Powershell ISE 运行脚本并收到以下错误消息:

使用“1”参数调用“Open”的异常:“抱歉,我们找不到 C:\Docs。它可能被移动、重命名或删除了吗?” 在 C:\Docs\xlstocsv.ps1:9 char:5 + $wb = $E.Workbooks.Open($excelFile) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ComMethodTargetInvocation

因为我已经成功运行了几次这些脚本,所以假设这些脚本是正确的并且我的 Powershell(?) 设置有问题是正确的吗? 我的想法已经用完了。

PS 我希望这里允许粘贴到其他网页的链接。

编辑 添加了代码。

脚本一(我从 Powershell ISE 开始的那个):

$ens = Get-ChildItem "C:\Docs\" -filter *.xlsm
foreach($e in $ens)
{   [threading.thread]::CurrentThread.CurrentCulture = 'en-US'
    ExportWSToCSV -excelFileName $e.BaseName -csvLoc "C:\Docs\Final\"
}

脚本二

Function ExportWSToCSV ($excelFileName, $csvLoc)

{   [threading.thread]::CurrentThread.CurrentCulture = 'en-US'
    $excelFile = "C:\Docs\"
    $E = New-Object -ComObject Excel.Application
    $E.Visible = $false
    $E.DisplayAlerts = $false
    $wb = $E.Workbooks.Open($excelFile)
    foreach ($ws in $wb.Worksheets)
    {
        $n = $excelFileName + "_" + $ws.Name
        $ws.SaveAs($csvLoc + $n + '.csv', 6)
    }
    $E.Quit()
}
ExportWSToCSV -excelFileName "file" -csvLoc "C:\Docs\Final\"     

我添加了“[threading.thread]::CurrentThread.CurrentCulture = 'en-US'” 部分,我能够成功运行这些脚本,但只能运行一次。所以这基本上似乎我可以从代码中丢弃这一行。

【问题讨论】:

  • 发布您的代码。
  • "假设脚本是正确的并且我的 Powershell(?) 设置有问题是正确的吗?"不,那将是极其罕见的。您的代码很可能存在基于您处理文件、调用方法或调用命令的方式的错误。您的算法是正确的,但是您假设您的数据文件总是正确或永远不会正确,并且该假设是不正确的。没有代码就不能多说。
  • @TheIncorrigible1 代码现已添加。
  • @BaconBits 有道理。添加代码。
  • $excelFile 是一个文件夹。 $E.Workbooks.Open($excelFile) 告诉 Excel 尝试将该文件夹作为工作簿打开,这显然会失败。在将该操作的结果传递给Open() 方法之前,您可能希望Join-Path $excelFile $excelFileName

标签: excel powershell export-to-csv


【解决方案1】:

如果您的唯一目标是将文件从 .xlsm 转换为 .csv,您可以这样做(使用示例 sn-ps):

function Convert-XlsmToCsv {
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [Alias('FullName')]
        [string] $Path
    )
    begin {
        $excel = New-Object -ComObject Excel.Application -Property @{
            Visible       = $false
            DisplayAlerts = $false
        }
    }
    process {
        $root = Split-Path -Path $Path
        $filename = [System.IO.Path]::GetFileNameWithoutExtension($Path)
        $workbook = $excel.Workbooks.Open($Path)
        foreach ($worksheet in $workbook.Worksheets) {
            $name = Join-Path -Path $root -ChildPath "${filename}_$($worksheet.Name).csv"
            try {
                $worksheet.SaveAs($name, 6)
            } catch {
                Write-Error -Message "Failed to save csv! Path: '$name'. $PSItem"
            }
        }
    }
    end {
        $excel.Quit()
        $null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)
    }
}

使用中:

Get-ChildItem -Path C:\Docs -Filter *.xlsm |
    Convert-XlsmToCsv

这做了一些假设,但很容易编辑。

【讨论】:

  • 我根据您的代码创建了两个 .ps1 文件,然后在 Powershell ISE 中运行包含“Get-ChildItem -Path C:\Docs -Filter *.xlsm | Convert-XlsmToCsv”的文件。不幸的是,它返回了以下错误:“Convert-XlsmToCsv:术语'Convert-XlsmToCsv'不被识别为cmdlet、函数、脚本文件或可运行程序的名称。检查...”等等。所以我用包含函数的.ps1文件的完整路径替换了“Convert-XlsmToCsv”,但仍然无法让它工作......也许这个脚本没问题,但我只是犯了一些菜鸟错误......
  • 函数必须存在于内存中才能调用它。将函数的代码放在一个文件中。在同一个文件的下方,您可以编写代码来调用该函数。然后执行那个文件。
  • 经过一些研究和测试,我终于得到了这个工作!我将以上所有内容保存到一个 ps1 文件中,并在“begin {”之后添加了“[threading.thread]::CurrentThread.CurrentCulture = 'en-US'”(不带双引号)。然后我从 Powershell ISE 内部运行它。
猜你喜欢
  • 1970-01-01
  • 2020-02-03
  • 2017-12-19
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多