https://github.com/dfinke/ImportExcel

エクセルファイルのデータをPowerShellに取り込む - Qiita

PowerShellでExcelを使用する

以下は、PowerShellを使用して、COMオブジェクトを使わずにExcelファイルをXML解析し、新しいXMLファイルを作成して保存するスクリプトです。

# Excelファイルのパスを指定
$excelFilePath = "C:\\path\\to\\your\\file.xlsx"

# 出力するXMLファイルのパスを指定
$outputXmlPath = "C:\\path\\to\\your\\output.xml"

# 一時フォルダを作成
$tempFolderPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Path $tempFolderPath | Out-Null

# 他のユーザーがファイルを開いていても読み取れるようにファイルストリームを作成
$stream = [System.IO.File]::Open($excelFilePath, 'Open', 'Read', 'ReadWrite')

# ZipArchiveを使用してExcelファイル(ZIP形式)を読み込む
$zipArchive = New-Object System.IO.Compression.ZipArchive($stream, [System.IO.Compression.ZipArchiveMode]::Read)

# 必要なファイルを一時フォルダに解凍
foreach ($entry in $zipArchive.Entries) {
    $destinationPath = Join-Path $tempFolderPath $entry.FullName
    $destinationDir = [System.IO.Path]::GetDirectoryName($destinationPath)
    if (!(Test-Path $destinationDir)) {
        New-Item -ItemType Directory -Path $destinationDir | Out-Null
    }
    if ($entry.Name) {
        $entryStream = $entry.Open()
        $fileStream = [System.IO.File]::Create($destinationPath)
        $entryStream.CopyTo($fileStream)
        $entryStream.Close()
        $fileStream.Close()
    }
}

$zipArchive.Dispose()
$stream.Close()

# sharedStrings.xmlを読み込む(共有文字列の取得用)
$sharedStringsPath = Join-Path $tempFolderPath "xl\\sharedStrings.xml"
if (Test-Path $sharedStringsPath) {
    [xml]$sharedStringsXml = Get-Content -Path $sharedStringsPath -Raw -Encoding UTF8

    # 名前空間マネージャを作成
    $namespaceManager = New-Object System.Xml.XmlNamespaceManager($sharedStringsXml.NameTable)
    $namespaceManager.AddNamespace("x", '<http://schemas.openxmlformats.org/spreadsheetml/2006/main>')

    $sharedStrings = @{}
    $index = 0
    foreach ($si in $sharedStringsXml.SelectNodes('//x:si', $namespaceManager)) {
        if ($si.t) {
            $sharedStrings[$index] = $si.t.'#text'
        } elseif ($si.r) {
            # リッチテキストの場合、全てのテキストノードを連結
            $text = ""
            foreach ($r in $si.r) {
                $text += $r.t.'#text'
            }
            $sharedStrings[$index] = $text
        }
        $index++
    }
}

# シートのXMLファイルを読み込む
$sheetFiles = Get-ChildItem -Path (Join-Path $tempFolderPath "xl\\worksheets") -Filter "sheet*.xml"
$newXml = New-Object System.Xml.XmlDocument
$root = $newXml.CreateElement("Workbook")
$newXml.AppendChild($root) | Out-Null

foreach ($sheetFile in $sheetFiles) {
    [xml]$sheetXml = Get-Content -Path $sheetFile.FullName -Raw -Encoding UTF8

    # 名前空間マネージャを作成
    $namespaceManager = New-Object System.Xml.XmlNamespaceManager($sheetXml.NameTable)
    $namespaceManager.AddNamespace("x", '<http://schemas.openxmlformats.org/spreadsheetml/2006/main>')

    # シート要素を作成
    $sheetElement = $newXml.CreateElement("Sheet")
    $sheetName = [System.IO.Path]::GetFileNameWithoutExtension($sheetFile.Name)
    $sheetElement.SetAttribute("Name", $sheetName)
    $root.AppendChild($sheetElement) | Out-Null

    # セルの値を取得
    $cells = $sheetXml.SelectNodes('//x:sheetData/x:row/x:c', $namespaceManager)

    foreach ($cell in $cells) {
        $cellRef = $cell.r
        $cellValueType = $cell.t
        $cellValue = $cell.v

        # セルに値がない場合はスキップ
        if (-not $cellValue) {
            continue
        }

        # 共有文字列の場合の処理
        if ($cellValueType -eq "s") {
            $cellText = $sharedStrings[$cellValue]
        } else {
            $cellText = $cellValue
        }

        $cellElement = $newXml.CreateElement("Cell")
        $cellElement.SetAttribute("Reference", $cellRef)
        $cellElement.InnerText = $cellText
        $sheetElement.AppendChild($cellElement) | Out-Null
    }
}

# 新しいXMLファイルを保存
$newXml.Save($outputXmlPath)

# 一時フォルダを削除
Remove-Item -Recurse -Force $tempFolderPath

説明:

  1. Excelファイルのパスを指定

    $excelFilePath に解析したいExcelファイルのパスを指定します。

  2. 出力するXMLファイルのパスを指定

    $outputXmlPath に保存したいXMLファイルのパスを指定します。

  3. 一時フォルダを作成

    一時的な作業フォルダを作成します。

  4. Excelファイルを解凍

    System.IO.Compression.ZipFile クラスを使用して、Excelファイル(実際にはZIP形式)を一時フォルダに解凍します。

  5. 共有文字列の読み込み

    共有文字列を格納している sharedStrings.xml を読み込み、インデックスと文字列のハッシュテーブルを作成します。

  6. シートのXMLファイルを読み込む

    解凍したフォルダ内の xl\\\\worksheets ディレクトリからシートのXMLファイル(例:sheet1.xml)を取得します。

  7. 新しいXMLドキュメントを作成

    Workbook ルート要素を持つ新しいXMLドキュメントを作成します。

  8. 各シートの処理

  9. XMLファイルを保存

    最終的に作成したXMLドキュメントを指定したパスに保存します。

  10. 一時フォルダを削除

    作業で使用した一時フォルダを削除してクリーンアップします。

注意点: