【问题标题】:How do i convert an xlsx file into a csv file, using powershell?如何使用 powershell 将 xlsx 文件转换为 csv 文件?
【发布时间】:2020-07-28 08:39:05
【问题描述】:

如何使用 Powershell 将 xlsx 文件转换为 csv 文件并为每个单元格添加双引号?

我需要将很多文件从 .xlsx 转换为 csv。 除此之外,每个单元格都必须用双引号引起来,并且必须添加分号分隔符。

我制作了一个 VBA 脚本来执行从 .xlsx 到 .csv 的转换并添加双引号,但每个文件最多需要几个小时。

我希望使用 powershell 会更快。

有人知道如何在 Powershell 中重写此功能吗?

非常感谢您的帮助!

我在 VBA 中的做法:

Sub ConvertToCSV()
 Dim DestFile As String
 Dim FileNum As Integer
 Dim ColumnCount As Integer
 Dim RowCount As Long
 Dim StrFile As String


Application.ScreenUpdating = False

StrFile = Dir("C:\Users\example\*PLZ*")

Do While Len(StrFile) > 0

        Workbooks.Open ("C:\Users\example\" & StrFile)

            Range("A1").Select
            Selection.CurrentRegion.Select


            NameWithoutExtension = Left(StrFile, Len(StrFile) - 5)
            DestFile = "C:\Users\example\" & NameWithoutExtension
            FileNum = FreeFile()
            Open DestFile For Output As #FileNum


            If Err <> 0 Then
            MsgBox "Cannot open filename " & DestFile
            End
            End If
            On Error GoTo 0



                For RowCount = 1 To Selection.Rows.Count

                       ' Loop for each column in selection.
                          For ColumnCount = 1 To Selection.Columns.Count

                            OldText = Selection.Cells(RowCount, ColumnCount).Text
                            MiddleText = Replace(OldText, "\", "/")
                            NewText = Replace(MiddleText, """", "\""")

                            ' Write current cell's text to file with quotation marks.
                             Print #FileNum, """" & NewText & """";

                             ' Check if cell is in last column.
                             If ColumnCount = Selection.Columns.Count Then
                                ' If so, then write a blank line.
                                Print #FileNum,
                             Else
                                ' Otherwise, write a comma.
                                Print #FileNum, ";";
                             End If
                          ' Start next iteration of ColumnCount loop.
                          Next ColumnCount
                       ' Start next iteration of RowCount loop.
                       Next RowCount

                       ' Close destination file.
                       Close #FileNum


        ActiveWorkbook.Close


    StrFile = Dir

Loop

MsgBox ("Done")
End Sub

【问题讨论】:

  • 我编辑了问题,现在更清楚了吗?
  • 你听说过ImportExcel这个模块吗?这可以让你的生活更轻松...... ;-)
  • 天哪...不要遍历所有单元格...只需另存为 csv...lol ThisWorkbook.SaveAs "my\file.csv", xlFileFormat.xlCSV
  • ImportExcel 描述为here。将此与 Export-csv 结合使用,相当简单。
  • 您好,感谢您的回复。我将研究 ImportExcel。 @Sancarn 每个单元格都必须用双引号封装,这就是为什么不是 possible 只保存为 CSV 文件。否则解决方案会像你说的那样简单。

标签: excel vba powershell csv xlsx


【解决方案1】:

这个真的没必要用powershell,你只需要在VBA中使用正确的方法...

代码未经测试,但认为应该可以正常工作...

Sub ConvertToCSV()
  Application.ScreenUpdating = False

  Dim StrFile As String
  StrFile = Dir("C:\Users\example\*PLZ*")

  Do While Len(StrFile) > 0
    'Open workbook
    Dim wb as workbook
    set wb = Workbooks.Open("C:\Users\example\" & StrFile)

    'Save workbook to new location
    Dim DestFile As String
    DestFile = "C:\Users\example\" & Left(StrFile, Len(StrFile) - 5)
    wb.saveAs destFile, xlFileFormat.xlCSV

    'Ensure no alerts while close
    Application.displayAlerts = false
      wb.close false
    Application.displayAlerts = true

    'Continue loop
    StrFile = Dir
  Loop
  Application.ScreenUpdating = True
End Sub

编辑:

抱歉,我没有看到需要引用字符串的要求。可以对您的代码进行一些补丁,这将使其运行速度显着加快,关键是首先将文件转换为数组:

我已尝试使您的代码与以前一样接近。请注意,您当前使用分号分隔文件...

Sub ConvertToCSV()
    Dim DestFile As String
    Dim FileNum As Integer
    Dim ColumnCount As Integer
    Dim RowCount As Long
    Dim StrFile As String


  Application.ScreenUpdating = False

  StrFile = Dir("C:\Users\example\*PLZ*")

  Do While Len(StrFile) > 0
    'Open workbook and store in variable
    Dim wb as workbook
    set wb = Workbooks.Open("C:\Users\example\" & StrFile)

    'Get data as array
    Dim r as range, v as variant
    set r = wb.ActiveSheet.Range("A1").CurrentRegion
    v = r.value2

    'Get dest path
    NameWithoutExtension = Left(StrFile, Len(StrFile) - 5)
    DestFile = "C:\Users\example\" & NameWithoutExtension
    FileNum = FreeFile()

    'Try open file
    On Error Resume Next
      Open DestFile For Output As #FileNum

      'If error then end
      If Err <> 0 Then
        MsgBox "Cannot open filename " & DestFile
        End
      End If
    On Error GoTo 0

    'Loop over array
    Dim i as long, j as long
    For i = 1 To ubound(v,1)
      For j = 1 To ubound(v,2)
        OldText = v(i,j)
        MiddleText = Replace(OldText, "\", "/")
        NewText = Replace(MiddleText, """", "\""")

        ' Write current cell's text to file with quotation marks.
        Print #FileNum, """" & NewText & """";

        ' Check if cell is in last column.
        If j = ubound(v,2) Then
          ' If so, then write a blank line.
          Print #FileNum,
        Else
          ' Otherwise, write a comma.
          Print #FileNum, ";";
        End If
      Next j 'Next column
    Next i 'Next row

    ' Close destination file.
    Close #FileNum

    'Close workbook
    wb.Close false

    'Get next file path
    StrFile = Dir    
  Loop

  MsgBox ("Done")
End Sub

注意:如果您的数据集很大,这可能会导致内存不足错误。如果是这样,请使用 powershell。

Import-Excel .\Book1.xlsx | Export-Csv .\book1.csv

【讨论】:

  • 据我所知,这并没有封装细胞。可能使用 powershell 的原因是速度的提高。您在 VBA 中是否有封装的方法,但仍然比我自己的脚本快得多?
  • @Sancarn 使用这种方法在 Excel 中构建字符串,然后将其写入输出文件一次会比逐个单元格地写入要快吗?
  • @Applecore 取决于目标文件的存储位置。如果目标文件存储在服务器上,那么是的,您是绝对正确的。如果目标文件存储在同一台 PC 上,那么我相当肯定 IO 比 VBA 的字符串连接要快。但实际上,最好先写入临时文件,然后再将文件复制到服务器。见aivosto.com/articles/stringopt2.html#huge
猜你喜欢
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2015-07-04
  • 1970-01-01
  • 2018-07-22
  • 2017-06-24
相关资源
最近更新 更多