PowerShell の用途として多いと思われるのが、CSV ファイルを読み込んで処理を行うことです。バッチの定番ですからね。
ただ、UTF-8 の CSV ファイルを1行ずつ読み込んで Excel に取り込むとなると .NET Framework の機能を利用することになります。
この記事では、.NET Framework の Microsoft.VisualBasic.FileIO.TextFieldParser クラスを利用したサンプルスクリプトを提示します。
なお、TextFieldParser を利用すると、CSV ファイルを簡単に扱うことができます。
まず、以下のようなデータが UTF-8 で users.csv で保存されているとします。
"001","山田太郎" "002","佐藤花子" "003","田中次郎"
サンプルスクリプトを実行した結果は、以下のようになります。
サンプルスクリプトは以下のようになります。
# # UTF-8のCSVファイルをExcelにインポートするスクリプト # # アセンブリをロードする [void][reflection.assembly]::LoadWithPartialName("Microsoft.VisualBasic") # スクリプトの親フォルダのパスを取得する $path = Split-Path $MyInvocation.MyCommand.Path -Parent # CSV ファイルのパスを作成する $csvPath = Join-Path $path "users.csv" # Excel の保存先のパスを作成する $xlsPath = Join-Path $path "users.xlsx" # CSV ファイルのエンコーディングを指定する $enc = [System.Text.Encoding]::UTF8 # パーサーで CSV ファイルを開く $parser = New-Object -TypeName Microsoft.VisualBasic.FileIO.TextFieldParser $csvPath, $enc # CSV ファイルが可変長であることを指定する $parser.TextFieldType = [Microsoft.VisualBasic.FileIO.FieldType]::Delimited # CSV ファイルがカンマ区切りであることを指定する $parser.SetDelimiters(","); # CSV ファイルの区切り文字がダブルクォーテーションであることを明示する $parser.HasFieldsEnclosedInQuotes = $true # Excel を起動する $xls = New-Object -ComObject Excel.Application # WorkBook を追加する $wb = $xls.WorkBooks.Add() # シートを選択する $ws = $wb.WorkSheets.Item("Sheet1") # 変数を初期化する $i = 1 $j = 1 # 最終レコードまで読み込む While($parser.EndOfData -eq $false) { # カンマでテキストを区切り配列に格納する $fields = $parser.ReadFields() # 配列を順番に処理する foreach ($field in $fields) { # セルの書式を「文字列」にする $ws.Cells.Item($i, $j).NumberFormat = "@" # セルに値を設定する $ws.Cells.Item($i, $j).Value = $field # 列を1つ進める $j++ } # 行を1つ進める $i++ # 変数初期化 $j = 1 } # ファイルが既存の場合警告メッセージを表示しないようにする $xls.DisplayAlerts = $false # Excel ファイルを保存する $wb.SaveAs([ref]$xlsPath.ToString()) #$wb.SaveAs([ref]$xlsPath.ToString(), -4143) # xls形式の時はこちらを使用する # 警告メッセージの表示を元に戻す $xls.DisplayAlerts = $true # WorkBook を閉じる $wb.Close() # Excel を終了する $xls.Quit() # CSV ファイルを閉じる $parser.Close() # COM 参照を解放する [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($ws) [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($wb) [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($xls)