powershell

powershellでcsvをエクセルファイル化

EPPlus .NET ライブラリを使う方法と、ImportExcel(Powershellモジュール)を使う方法があるようですが今回はImportExcel(Powershellモジュール)を利用します。前提条件として以下スクリプトはPowerShell 7.xを前提とします。

ImportExcelモジュールのダウンロード

今回なるべく既存環境を触りたくなかったので、専用のフォルダを作成しここにモジュールをダウンロードし利用の際都度パスを通して使う事にします。

Save-Module -Name ImportExcel -Path C:\powershell-pj\pj1\modules
利用の際はImportExcelモジュールをパスに通す
$env:PSModulePath = "C:\powershell-pj\pj1\modules;" + $env:PSModulePath  
utf-8のCSVファイルをエクセルファイル化
# UTF-8で作成したcsvファイルを用意
$csvPath = "C:\powershell-pj\pj1\test_utf8.csv"

# 作成するエクセルファイル
$excelPath = "C:\powershell-pj\pj1\test_output.xlsx"

# CSV をインポートし、すべての値を「文字列化」
$csvData = Import-Csv -Path $csvPath | ForEach-Object {
    $row = $_ | Select-Object *
    foreach ($prop in $row.PSObject.Properties) {
        $prop.Value = "$($prop.Value)"  # 全データを明示的に文字列化
    }
    $row
}

# 文字列として扱うために `-NumberFormat` を "@" に設定
$csvData | Export-Excel -Path $excelPath -WorksheetName "importdata" -NumberFormat "@"
Shift_JISのCSVファイルをエクセルファイル化
# CSVファイルのパス(Shift_JIS)
$csvPath = "C:\powershell-pj\pj1\test_sjis.csv"
# 出力するExcelファイルのパス
$excelPath = "C:\powershell-pj\pj1\test_output.xlsx"

# Shift_JIS で StreamReader を使って先頭101行(ヘッダ+100行)だけ読み込む
$encoding = [System.Text.Encoding]::GetEncoding("shift_jis")
$reader = [System.IO.StreamReader]::new($csvPath, $encoding)

# 最初の101行(0番目:ヘッダ, 1〜100番目:データ)
$lines = @()
for ($i = 0; $i -lt 101 -and !$reader.EndOfStream; $i++) {
    $lines += $reader.ReadLine()
}
$reader.Close()

# 行が不足していた場合は終了
if ($lines.Count -lt 2) {
    Write-Host "データが不足しているため、出力をスキップします。"
    exit
}

# ConvertFrom-Csv で PowerShell オブジェクトに変換
$csvData = $lines | ConvertFrom-Csv

# すべて文字列化
$csvData = $csvData | ForEach-Object {
    $row = $_ | Select-Object *
    foreach ($prop in $row.PSObject.Properties) {
        $prop.Value = "$($prop.Value)"
    }
    $row
}

# Excelファイルに出力
$csvData | Export-Excel -Path $excelPath -WorksheetName "preview_100" -NumberFormat "@"
Powershell 5用(Shift_JIS CSV前提)
param(
    [Parameter(Mandatory=$true)]
    [string]$InputFile,

    [Parameter(Mandatory=$true)]
    [string]$OutputFile,

    [Parameter(Mandatory=$false)]
    [int]$MaxRows = 200,

    [Parameter(Mandatory=$false)]
    [int]$HeaderRow = 1,

    [Parameter(Mandatory=$false)]
    [int]$StartRow = 2,

    [Parameter(Mandatory=$false)]
    [bool]$IncludeHeader = $true
)


$data = @()

$reader = [System.IO.StreamReader]::new($InputFile, [System.Text.Encoding]::GetEncoding("shift_jis"))

for ($i = 1; $i -lt $HeaderRow; $i++) {
    $null = $reader.ReadLine()
}
$headerLine = $reader.ReadLine()
if (-not $headerLine) {
    Write-Error "指定されたHeaderRow行目にヘッダーが見つかりません。"
    exit 1
}
$headers = ($headerLine -split ',') | ForEach-Object { $_.Trim('"') }

for ($i = $HeaderRow + 1; $i -lt $StartRow; $i++) {
    $null = $reader.ReadLine()
}

$lineCount = 0
while (($line = $reader.ReadLine()) -and ($lineCount -lt $MaxRows)) {
    $fields = ($line -split ',') | ForEach-Object { $_.Trim('"') }

    $hash = @{}
    for ($i = 0; $i -lt $headers.Length; $i++) {
        $hash[$headers[$i]] = if ($i -lt $fields.Length) { $fields[$i] } else { $null }
    }

    $obj = [PSCustomObject]$hash
    $data += $obj

    $lineCount++
}

$reader.Close()

if ($IncludeHeader) {
    $data | Export-Excel -Path $OutputFile -WorksheetName "Sheet1" -ClearSheet -AutoSize
} else {
    $data | Export-Excel -Path $OutputFile -WorksheetName "Sheet1" -ClearSheet -AutoSize -NoHeader
}
.\toExcel.ps1 -InputFile "C:\download\address\01000-22.0a\01_2023.csv" -OutputFile "C:\download\address\01000-22.0a\output.xlsx" -HeaderRow 1 -MaxRows 20  -StartRow 2 -IncludeHeader $false

Powershell 7用(Shift_JIS CSV前提)
$InputFile  入力用のCSVファイルのパス
$OutputFile  出力用のExcelファイルのパス
$MaxRows
# Export-Excel 用のモジュールパスを設定
$env:PSModulePath = "C:\powershell-pj\pj1\modules;" + $env:PSModulePath

param(
    [Parameter(Mandatory=$true)]
    [string]$InputFile,

    [Parameter(Mandatory=$true)]
    [string]$OutputFile,

    [Parameter(Mandatory=$false)]
    [int]$MaxRows = 0,  # 0 の場合はすべての行を読み込む

    [Parameter(Mandatory=$false)]
    [int]$HeaderRow = 1,

    [Parameter(Mandatory=$false)]
    [int]$StartRow = 2,

    [Parameter(Mandatory=$false)]
    [bool]$IncludeHeader = $true
)

# ファイルの総行数を取得
$TotalLines = (Get-Content -Path $InputFile | Measure-Object -Line).Lines

if ($MaxRows -gt 0 -and $MaxRows -gt $TotalLines) {
    Write-Warning "MaxRows ($MaxRows) がファイルのレコード件数 ($TotalLines) を超えています。"
}

$reader = [System.IO.StreamReader]::new($InputFile, [System.Text.Encoding]::GetEncoding("shift_jis"))

# ヘッダー取得
for ($i = 1; $i -lt $HeaderRow; $i++) {
    $null = $reader.ReadLine()
}
$headerLine = $reader.ReadLine()
if (-not $headerLine) {
    Write-Error "指定されたHeaderRow行目にヘッダーが見つかりません。"
    exit 1
}

# ヘッダー情報
$headers = $headerLine -split ','

# Excel の初期化
Export-Excel -Path $OutputFile -WorksheetName "Sheet1" -ClearSheet

# データ処理
$data = @()
$lineCount = 0

while ($line = $reader.ReadLine()) {
    if ($line -eq $null -or ($MaxRows -gt 0 -and $lineCount -ge $MaxRows)) {
        break
    }

    $fields = $line -split ','
    $dataObject = [PSCustomObject]@{}

    for ($i = 0; $i -lt $headers.Length; $i++) {
        $dataObject | Add-Member -MemberType NoteProperty -Name $headers[$i] -Value $(if ($i -lt $fields.Length) { $fields[$i] } else { $null })
    }

    $data += $dataObject
    $lineCount++
}

$reader.Close()

# Excel に書き出し(ヘッダー有無を制御)
if ($IncludeHeader) {
    $data | Export-Excel -Path $OutputFile -WorksheetName "Sheet1" -AutoSize
} else {
    $data | Export-Excel -Path $OutputFile -WorksheetName "Sheet1" -AutoSize -NoHeader
}
.\toExcel-7.ps1 -InputFile .\01_2023-test-nodq.csv -OutputFile .\output-test-200.xlsx -MaxRows 300  -StartRow 4 -IncludeHeader $false
スポンサーリンク
タイトルとURLをコピーしました