【问题标题】:PowerShell - Import multiple CSV files to Excel file in multiple worksheetsPowerShell - 将多个 CSV 文件导入多个工作表中的 Excel 文件
【发布时间】:2021-01-27 14:30:17
【问题描述】:

我有以下代码(来自 SO 的其他地方),它将 20 个奇怪的 CSV 文件导入到一个 Excel 文件中的不同选项卡中。我需要将 XLSX 选项卡称为 CSV 文件名。

代码运行,但每次运行时至少没有导入一个 CSV 文件。所有选项卡都存在,但数据未通过。它也是每次运行都会丢失的不同 CSV 文件。

有没有办法确保所有 CSV 文件和数据都导入 XLSX?我想如果我在每次运行时暂停脚本,它会给代码一个重置的机会,但“Start-Sleep -s 1”没有帮助。

错误包括:

“Microsoft Excel 一次只能转换一列。范围可以是多行高,但不超过一列宽。仅选择一列中的单元格再试一次。”

“无法获取 Range 类的 PasteSpecial 属性”

如果其中一个 CSV 文件中没有数据,此脚本是否还有一种方法可以忽略 CSV 导入?

# import multiple CSV files into separate Excel worksheets
$inputfolder='C:\somefolder’
$mergedwb='C:\somefolder\importtemplate.xlsx'

$xl = New-Object -ComObject Excel.Application
$xl.Visible=$true

$wb = $xl.WorkBooks.add()

Get-ChildItem $inputfolder\*.csv |
    ForEach-Object{
        Try{
            Write-Host "Moving $_" -ForegroundColor green
            $sheet = $wb.Sheets.Add()
            $sheet.Name = $_.BaseName
            $data = Get-Content $_ -Raw
            Set-Clipboard $data
            $sheet.UsedRange.PasteSpecial(
                [Microsoft.Office.Interop.Excel.XlPasteType]::xlPasteAll,
                [Microsoft.Office.Interop.Excel.XlPasteSpecialOperation]::xlPasteSpecialOperationAdd
            )
            $sheet.UsedRange.TextToColumns(
                $sheet.UsedRange,
                [Microsoft.Office.Interop.Excel.XlTextParsingType]::xlDelimited,
                [Microsoft.Office.Interop.Excel.XlTextQualifier]::xlTextQualifierDoubleQuote,
                $false, $false, $false, $true
            )
        }
        Catch{
            Write-Host $_ -ForegroundColor Red
        } Start-Sleep -s 1
    }
$wb.Sheets.Item('sheet1').Delete()
$wb.Sheets.Item('sheet2').Delete()

$wb.SaveAs($mergedwb)
$wb.Close()
$xl.Quit()

【问题讨论】:

  • 检查失败的 CSV 文件。他们是否使用与成功的分隔符不同的分隔符?此外,如果您添加指向您在 在 SO 中的其他地方 找到的原始代码的链接,那就太好了
  • CSV 文件都使用相同的分隔符。正如我所说的,这很奇怪,因为每次运行都是一个不同的文件,无法加载到 XLSX 中。无法加载的随机错误出现 - '无法获取 Range 类的 PasteSpecial 属性'。 CSV 中只有 2 列,没有公式。你认为我应该使用 Paste 而不是 PasteSpecial 吗?
  • 很难说.. 也许如果您尝试使用xlPasteValues 而不是xlPasteAll 并且也许还使用xlPasteSpecialOperationNone 而不是xlPasteSpecialOperationAdd,因为您正在粘贴到一个空白工作表中。此外,在使用完 COM 对象后从内存中释放它们也很重要:$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet); $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb); $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl); [System.GC]::Collect(); [System.GC]::WaitForPendingFinalizers()

标签: excel powershell csv


【解决方案1】:

感谢@kshkarin 和@Theo,现在没有显示错误,所有数据都被复制到 XLSX 中。完成的代码以防万一:

#import multiple CSV files into separate Excel worksheets
$inputfolder='C:\somefolder’
$mergedwb='C:\somefolder\importtemplate.xlsx'

$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
$wb = $excel.Workbooks.Add()

Get-ChildItem $inputfolder\*.csv | ForEach-Object {
    if ((Import-Csv $_.FullName).Length -gt 0) {
        $csvBook = $excel.Workbooks.Open($_.FullName)
        $csvBook.ActiveSheet.Copy($wb.Worksheets($wb.Worksheets.Count))
        $csvBook.Close()
    }
}

$wb.Sheets.Item('sheet1').Delete()
$wb.Sheets.Item('sheet2').Delete()

$wb.SaveAs($mergedwb)
$wb.Close()
$excel.Quit()

$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet); 
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb); 
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl); 
[System.GC]::Collect(); [System.GC]::WaitForPendingFinalizers()

【讨论】:

    【解决方案2】:

    试试这个 - 它会在新的Workbook 中打开 CSV 文件,然后将工作表内容复制到 Excel XLSX 文件中的新工作表,奖励 PS 将检查 CSV 是否为空。

    $excel = New-Object -ComObject Excel.Application
    $excel.Visible = $true
    $wb = $excel.Workbooks.Add()
    
    Get-ChildItem $CSVPath\*.csv | ForEach-Object {
        if ((Import-Csv $_.FullName).Length -gt 0) {
            $csvBook = $excel.Workbooks.Open($_.FullName)
            $csvBook.ActiveSheet.Copy($wb.Worksheets($wb.Worksheets.Count))
            $csvBook.Close()
        }
    }
    

    【讨论】:

    • 这看起来不错。我需要再测试几次,但这似乎会将所有 CSV 复制到不同工作表上的一个 XLSX 中。
    • @Paul1384 欢迎来到SO,请阅读stackoverflow.com/help/someone-answers
    • 嗨,很抱歉回到这个帖子。我正在尝试使用服务帐户在服务器上运行。我在服务器上有 Excel,但未经许可。有没有办法在不打开盒子上的 Excel 的情况下运行相同的脚本?我认为没有但想要求保存 Office 许可证。谢谢,
    • 如果没有安装 Office 并获得许可,此脚本将无法运行,但是,如果您真的想避免购买另一个许可证,那么可能 python 将是可行的方法,请阅读此 -stackoverflow.com/questions/54518337/…跨度>
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 2018-07-14
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多