テクセル

PowerShell で LibreOffice の Calc 操作


PowerShell で LibreOffice の Calc 操作を行います。 Calc の操作には、「CalcAuto.dll」を使用します。

プログラム例

開く Calc ファイルと CalcAuto.dll は、実行するスクリプトファイルと同じフォルダに置きます。


# calcAtTest1.ps1

Set-StrictMode -Version latest

Add-Type -Path (Join-Path $PSScriptRoot "./CalcAuto.dll")

$sCalcFile = $PSScriptRoot + "\calcTest1.ods"    # 開くCalc ファイル名

$libOffice = New-Object CalcAuto.LibreOffice

$libCalcd = $libOffice.calcOpen($sCalcFile)  # calcファイル開
# $libCalcd = $libOffice.calcOpen()            # 新規で空のドキュメントを開く場合

$sheets = $libCalcd.sheets
$ic = $sheets.getCount()                     # シート数
Write-Host $ic

$sheet = $sheets.getByName("Sheet1")   # Sheet1 選択
$libCalcd.getCurrentController().setActiveSheet($sheet)    # Sheet1 をアクティブに 前面表示

$sv = $sheet.getCellRangeByName("B3").String     # B3 の値を文字列で取得
Write-Host $sv
$va = $sheet.getCellByPosition(1,3).Value        # B4 の値を数値で取得
Write-Host $va

$range = $sheet.getCellRangeByName("B6")
$range.String = "房総半島"                                     # B6 へ文字列書き込み
$range.CharHeightAsian = 12.5                                  # 文字の大きさ
$range.CharWeightAsian = [CalcAuto.FontWeight]::BOLD           # BOLD
$range.CharColor = [System.Drawing.Color]::White.ToArgb()      # 文字色白
$range.CellBackColor = [System.Drawing.Color]::Blue.ToArgb()   # セルバック色

$cell = $sheet.getCellByPosition(1, 6)                         # B7
$cell.Value = 5678.123                                         # B7 へ数値書き込み
$cell.CharHeight = 12.0                                        # 文字の大きさ
$cell.CharColor = [System.Drawing.Color]::Red.ToArgb()         # 文字色
$cell.CellBackColor = [System.Drawing.Color]::Aqua.ToArgb()    # セルバック

$sr = Read-Host "保存しますか? y/n"
if ($sr -eq "y"){
   $sfname = $PSScriptRoot + "\calcTestS.ods"    # 保存ファイル名
   if (Test-Path $sfname){
      Remove-Item $sfname     # 削除
   }   
   $libCalcd.storeAsURL($sfname)  # 名前を付けて保存
#   [void]$libCalcd.store()       # 上書き保存 
}

$sr = Read-Host "印刷しますか? y/n"
if ($sr -eq "y"){
   $libCalcd.setPrinter("LBP****")   # 印刷プリンタを指定 
   $libCalcd.Print(1, "1")           # 印刷部数 1 1ページ目 印刷
}

$libCalcd.calcClose()       # calcファイル閉じる
$libOffice.terminate()      # libreoffice 終了
   

「$PSScriptRoot」は、スクリプトが存在するフォルダパスです。

以下の例における変数 $sheets, $sheet, $range, $cell については、上記プログラム例を参照して下さい。

1.ファイル開


$sCalcFile = $PSScriptRoot + "¥calcTest1.ods"    # 開く Calc ファイル名
$libCalcd = $libOffice.calcOpen($sCalcFile)    # calcファイル開

# $libCalcd = $libOffice.calcOpen()            # 新規で空のドキュメントを開く場合
   

2.ファイル閉、終了


$libCalcd.calcClose()             # calcファイル閉

$libOffice.terminate()            # libreoffice 終了 ※1
   

※1 開いている全ての libreoffice ファイルを閉じます。

3.シート


$sheets = $libCalcd.sheets        # sheetsオブジェクトを取得
$ic = $sheets.getCount()          # シート数
Write-Host $ic

$sheet = $sheets.getByName("Sheet1")   # Sheet1 選択
$sheet = $sheets.getByIndex(0)         # インデックス番号でシート選択 0~
$libCalcd.getCurrentController().setActiveSheet($sheet)    # シートをアクティブに 前面表示

$br = $sheets.hasByName("Sheet1") # 「Sheet1」 の存在確認 $true で存在

Write-Host $sheet.Name            # シート名
$sheet.Name = "住所"              # シート名変更
   

1) 全シート名の取得

全てのシート名を取得します。


[string[]]$sSheetList = New-Object string[] 0 # 全シート名をセットする変数 ※1
$ir = $sheets.getSheetList([ref]$sSheetList)
Write-Host $sSheetList
   

※1 string 配列を配列数 0 で初期化し、getSheetList関数に参照渡しします。

2) シートの追加

シートの追加関数 insertNewByName(追加するシート名, 追加位置)
追加位置は、0~ の値


$sheets.insertNewByName("住所", 0)     # 先頭に追加
$sheets.insertNewByName("請求書", 2)   # 2番目のシートの次に追加
   

3) シートのコピー

シートのコピー関数 copyByName(コピーするシート名, コピー先シート名, コピー先の位置)
コピー先位置は、0~ の値


$sheets.copyByName("Sheet1", "CopySheet", 0)  # コピー位置 0 は、先頭
   

4) シートの削除

シートの削除関数 removeByName(削除するシート名)


$sheets.removeByName("Sheet1")      # Sheet1を削除
   

4.セル

1) 値


$range = $sheet.getCellRangeByName("B3")       # B3 Rangeで選択
$sv = $range.String                            # 文字列で取得 ※1
Write-Host $sv
$range.String = "春は、あけぼの。"             # 文字列書き込み
$sheet.getCellRangeByName("D3").String = "夏は、`n夜。"          # セル内で改行 改行部に LF セット

$sheet.getCellRangeByName("A11:D15").String = "屏風ヶ浦"         # A11:D15 に同じ値がセットされます。

$range.CharColor = [System.Drawing.Color]::White.ToArgb()       # 文字色白 RGB値
$range.CellBackColor = [System.Drawing.Color]::Blue.ToArgb()    # セルバック色青 RGB値
$range.CharFontNameAsian = "MS 明朝"                          # 文字フォント
$range.CharWeightAsian = [CalcAuto.FontWeight]::BOLD            # BOLD:太字 NORMAL:標準
$range.CharHeightAsian = 14                                     # 文字の大きさ ポイント

$cell = $sheet.getCellByPosition(1, 4)        # B5 Cellで選択 (列No.、行No.) 0~の数字
$dv = $cell.Value                             # 数値で取得 ※2
Write-Host $dv
$cell.Value = 5566                            # 数字書き込み
$cell.CharColor = [System.Drawing.Color]::FromArgb(0xff, 0xff, 0xff).ToArgb()  # RGB値で色指定
$cell.CellBackColor = [System.Drawing.Color]::FromArgb(0, 0, 0xff).ToArgb()

# 数式
$sheet.getCellRangeByName("B9").Formula = "=SUM(B5:B8)"    # 数式の設定
$sf = $sheet.getCellRangeByName("B9").Formula              # 数式の取得
Write-Host $sf

# セルのタイプ
[CalcAuto.CellContentType]$cellType = $sheet.getCellRangeByName("B3").getType()   # ※3
Write-Host $cellType.ToString()
   
  1. セルが空白の時は、 "" となります。セル内で改行がある場合は改行部に LF がセットされます。
  2. Valueによる取得値は、Double型です。セルが文字、空白の時は、0 となります。また、日付型を取得した場合は、シリアル値となります。
    日付のシリアル値(Double型)からPowerShell(.NET)のDateTime型に変換 $dta = [DateTime]::FromOADate($dv)
  3. セルのタイプ CellContentType EMPTY :値なし、 VALUE :数値、 TEXT :文字列、FORMULA :数式

2) セル値を配列で読み書き


$ardata = $sheet.getCellRangeByName("B2:E3").getDataArray() # セル B2:E3 データを配列で取得
Write-Host $ardata[0, 0], $ardata[0, 1],  $ardata[0, 2],  $ardata[0, 3]
Write-Host $ardata[1, 0], $ardata[1, 1],  $ardata[1, 2],  $ardata[1, 3]

$arw = New-Object "object[,]" 2, 4               # 書き込み用配列定義 2行4列
$arw[0, 0] = "果物"; $arw[0, 1] = "りんご"; $arw[0, 2] = "みかん"; $arw[0, 3] = "バナナ"
$arw[1, 0] = "個数"; $arw[1, 1] = 12; $arw[1, 2] = 25; $arw[1, 3] = 15
$sheet.getCellRangeByName("B5:E6").setDataArray($arw)    # 配列データを B5:E6 へ書き込み
   

配列でセル値を読み書きするには非ジャグ配列を使用します。

3) 数値の書式

セルの数値書式を設定します。フォーマット用文字列を GetNumberFormatId 関数に渡し、書式コードを取得します。書式コードを NumberFormat にセットします。GetNumberFormatId 関数は、日本語のみに対応しています。


$sheet.getCellByPosition(2, 1).Value = "12345.67"
$id = $libCalcd.GetNumberFormatId("#,##0.000")    # 3桁区切り小数点以下3桁 id取得
$sheet.getCellByPosition(2, 1).NumberFormat = $id # idセット 12,345.670
Write-Host $id

# 書式の例
$sheet.getCellRangeByName("C2:C7").Value = 12345.67
$sheet.getCellByPosition(2, 1).NumberFormat = $libCalcd.GetNumberFormatId("#,###")          # 3桁区切り 12,346
$sheet.getCellByPosition(2, 2).NumberFormat = $libCalcd.GetNumberFormatId("0.000")          # 小数点以下3桁 12345.670
# 正の数で青色、負の数で赤色、0で黒色 表示 ※1
$sheet.getCellByPosition(2, 3).NumberFormat = $libCalcd.GetNumberFormatId("[BLUE]#,##0;[RED]-#,##0;[BLACK]0")
$sheet.getCellByPosition(2, 4).NumberFormat = $libCalcd.GetNumberFormatId("[BLACK]#,##0;[RED]△#,##0") # 3桁区切り マイナスで△赤色
$sheet.getCellByPosition(2, 5).NumberFormat = $libCalcd.GetNumberFormatId("[$¥-411]#,##0") # 円記号 3桁区切り \12,346 ※2
$sheet.getCellByPosition(2, 6).NumberFormat = $libCalcd.GetNumberFormatId("@")              # テキスト

$sheet.getCellRangeByName("C2:C7").NumberFormat = $libCalcd.GetNumberFormatId("#,###0.0") # C2:C7のすべてのセル 3桁区切り 小数点以下1桁

# 日付例
$sheet.getCellRangeByName("D2:D5").Value = [DateTime]::Parse("2024/09/05 09:05:22").ToOADAte() # シリアル値
$sheet.getCellByPosition(3, 1).NumberFormat = $libCalcd.GetNumberFormatId("YY/MM/DD HH:MM:SS") # => 24/09/05 09:05:22 ※3
$sheet.getCellByPosition(3, 2).NumberFormat = $libCalcd.GetNumberFormatId("YY/MM/DD")          # =>  24/09/05
$sheet.getCellByPosition(3, 3).NumberFormat = $libCalcd.GetNumberFormatId("YY年MM月DD日 (AAA)") # => 24年09月05 (火)
$sheet.getCellByPosition(3, 4).NumberFormat = $libCalcd.GetNumberFormatId("YY年MM月DD日 (AAAA)") # => 24年09月05 (火曜日)

# 和暦表示例
$sheet.getCellRangeByName("D10:D15").Value = [DateTime]::Parse("2024/11/05").ToOADAte()
$sheet.getCellByPosition(3, 9).NumberFormat = $libCalcd.GetNumberFormatId("G E/MM/DD") # => R 6/11/05
$sheet.getCellByPosition(3, 10).NumberFormat = $libCalcd.GetNumberFormatId("GG E/MM/DD") # => 令 6/11/05
$sheet.getCellByPosition(3, 11).NumberFormat = $libCalcd.GetNumberFormatId("GGG E/MM/DD") # => 令和 6/11/05
$sheet.getCellByPosition(3, 12).NumberFormat = $libCalcd.GetNumberFormatId("GGG E年MM月DD日 (AAA)") # => 令和 6年11月05日 (火)
$sheet.getCellByPosition(3, 13).NumberFormat = $libCalcd.GetNumberFormatId("G E(YYYY)/MM/DD") # => R 6(2024)/11/05
$sheet.getCellByPosition(3, 14).NumberFormat = $libCalcd.GetNumberFormatId("YYYY(G E)/MM/DD") # => 2024(R 6)/11/05

$dtime = [DateTime]::Parse("1868/1/1")
$sheet.getCellByPosition(2, 14).Value = $dtime.ToOADate()      # 日付のシリアル値
$sheet.getCellByPosition(2, 14).NumberFormat = $libCalcd.GetNumberFormatId("GGG E/MM/DD") # => 明治 1/01/01 ※4
   
  1. セミコロン区切りで [正の数の書式; 負の数の書式; ゼロの書式] と書式設定します。
  2. 「411」は、ロケールIDで日本語を表します。
    ロケールID番号(lcidパラメータ) 表中 japan 1041 を16進表示 0x411 とした値
  3. M または、 MM は、時(H,HH)または、秒(S,SS)の時刻形式と組み合わされて使用されてない場合は月が表示されます。
  4. 元号 明治 は、西暦1868年から表示されます。それ以前の年では西暦で表示されます。

数の書式コード

4) Range値から列、行No.取得


# B2:D3 の列行No.
$rangeAdd = $sheet.getCellRangeByName("B2:D3").getRangeAddress()
$startColumn = $rangeAdd.StartColumn   # 開始列No.
$endColumn = $rangeAdd.EndColumn       # 終了列No.
$startRow = $rangeAdd.StartRow         # 開始行No.
$endRow = $rangeAdd.EndRow             # 終了行No.
$sa = "(" + $startColumn.ToString() + "," + $startRow.ToString() + ")~(" + $endColumn.ToString() + "," + $endRow.ToString() + ")"
Write-Host $sa     # => (1,1)~(3,2)

# B5 の列行No.
$rangeAdd = $sheet.getCellRangeByName("B5").getRangeAddress()
$startColumn = $rangeAdd.StartColumn   # 開始列No.
$endColumn = $rangeAdd.EndColumn       # 終了列No.
$startRow = $rangeAdd.StartRow         # 開始行No.
$endRow = $rangeAdd.EndRow             # 終了行No.
$sa = "(" + $startColumn.ToString() + "," + $startRow.ToString() + ")~(" + $endColumn.ToString() + "," + $endRow.ToString() + ")"
Write-Host $sa     # => (1,4)~(1,4)
   

5) セル内容の配置


# 縦方向
$sheet.getCellByPosition(1, 5).VertJustify = [CalcAuto.CellVertJustify]::CENTER    # 中央
$sheet.getCellByPosition(1, 6).VertJustify = [CalcAuto.CellVertJustify]::BOTTOM    # 下

$sheet.getCellRangeByName("B3:C4").VertJustify = [CalcAuto.CellVertJustify]::TOP   # 上
$sheet.getCellRangeByName("B3:C4").VertJustify = [CalcAuto.CellVertJustify]::CENTER # 中央

# 横方向
$sheet.getCellByPosition(1, 4).HoriJustify = [CalcAuto.CellHoriJustify]::LEFT      # 左
$sheet.getCellByPosition(1, 5).HoriJustify = [CalcAuto.CellHoriJustify]::CENTER    # 中央

#$sheet.getCellRangeByName("B3:C4").HoriJustify = [CalcAuto.CellHoriJustify]::LEFT # 左
$sheet.getCellRangeByName("B3:C4").HoriJustify = [CalcAuto.CellHoriJustify]::CENTER # 中央
   

CellVertJustify のメンバー
TOP: 上、CENTER: 中央、BOTTOM: 下、 STANDARD: 標準
CellHoriJustify のメンバー
LEFT: 左、CENTER: 中央、RIGHT: 右、 REPEAT: 繰り返し、BLOCK: 折り返し、STANDARD: 標準

6) 罫線


$bdrline = $libOffice.BorderLine()
$bdrline.Color = [System.Drawing.Color]::Red.ToArgb()    # 色
$bdrline.LineStyle = [CalcAuto.BorderLineStyle]::SOLID   # 線のスタイル 実線 ※1
$bdrline.LineWidth = 35                                  # 線の幅 0.35mm 1pt ※2
# $bdrline.LineWidth = 88                                # 2.5pt
$sheet.getCellByPosition(1, 1).BottomBorder = $bdrline

$range = $sheet.getCellRangeByName("D5:F7")
$range.TopBorder = $bdrline
$range.RightBorder = $bdrline
$range.LeftBorder = $bdrline
$range.BottomBorder = $bdrline
   
  1. 線のスタイル BorderLineStyle のメンバー NONE:罫線なし、SOLID:実線、DOTTED:点線、DASHED:破線、FINE_DASHED:極細破線、DOUBLE_THIN:細二重線、DASH_DOT:一点鎖線、DASH_DOT_DOT:二点鎖線
  2. LineWidth 0.01mm単位で設定 pt(ポイント) × 35.278 の整数値 (1pt ≒ 0.35278mm)

7) セル内容のクリア


$sheet.getCellRangeByName("C9:C10").clearContents()   # すべてクリア

$sheet.getCellByPosition(2, 8).clearContents()        # セル C9 すべてクリア

# クリアする内容を指定 ※1
$cflg = [CalcAuto.CellFlags]::VALUE -bor [CalcAuto.CellFlags]::DATETIME -bor [CalcAuto.CellFlags]::STRING
$sheet.getCellRangeByName("B2:B7").clearContents($cflg)

$sheet.getCellByPosition(1, 1).clearContents($cflg)     # セル B2
   

※1 列挙型 CellFlags からクリアする内容を指定します。複数指定する場合は、ビットOR (-bor) します。

CellFlags のメンバー

メンバー 内容
VALUE 日付や時刻として書式設定されていない数値
DATETIME 日付や時刻として書式設定されている数値
STRING 文字列
ANNOTATION セルに付けられたコメント
FORMULA 計算式
HARDATTR セルに直接指定した書式
STYLES 間接的に設定した書式
OBJECTS セルに配置された図形描画オブジェクト
EDITATTR セル内の一部のテキストに対してのみ施された書式

8) セル範囲のコピー

copyRange(コピー先セルアドレス, コピー元rangeアドレス)


$rangeAddress = $sheet.getCellRangeByName("B2:E3").getRangeAddress()      # コピー元 B2:E3 のアドレス取得
$cellAddress = $sheet.getCellByPosition(2, 4).getCellAddress()            # コピー先 C5 のアドレス取得
# $cellAddress = $sheet.getCellRangeByName("C5").getCellAddress()         # getCellRangeByName でセルアドレスを取得する場合は、単一のセルを指定
$sheet.copyRange($cellAddress, $rangeAddress)                             # B2:E3 -> C5:F6 へコピー

# 別シートからコピー
$sheet3 = $sheets.getByName("Sheet3")                            # Sheet3 選択
$ranges = $sheet3.getCellRangeByName("B2:E3").getRangeAddress()  # Sheet3 のコピー元アドレス
$sheet = $sheets.getByName("Sheet1")                             # Sheet1 選択
$celld = $sheet.getCellByPosition(1, 9).getCellAddress()         # Sheet1 のコピー先アドレス B10
# $celld = $sheet.getCellRangeByName("B10").getCellAddress()     # Sheet1 のコピー先アドレス getCellRangeByName を使用する場合
$sheet.copyRange($celld, $ranges)       # Sheet3 の B2:E3 -> Sheet1 の B10:E11 へコピー
   

copyRange は、書式を含めてすべてコピーされます。

8) セルの幅と高さ


$cells = $sheet.getCellByPosition(1, 2)   # B3
$iw = $cells.getColumns().Width           # セルの幅取得
Write-Host $iw
$ih = $cells.getRows().Height             # セルの高さ取得
Write-Host $ih

$cells.getColumns().Width = 1500          # セルの幅設定
$cells.getRows().Height = 1000            # セルの高さ設定

$range = $sheet.getCellRangeByName("B3")
#$range = $sheet.getCellRangeByName("B3:C5") # B3セルが対象となります。
$iw = $range.getColumns().Width           # セルの幅取得
Write-Host $iw
$ih = $range.getRows().Height             # セルの高さ取得
Write-Host $ih

$range = $sheet.getCellRangeByName("B3:C5") # B3:C5 範囲のセル幅、高さを設定
$range.getColumns().Width = 1600
$range.getRows().Height = 800
   

幅、高さは、センチメートル単位設定の場合 10μm単位の整数です。 例 3022 -> 3.022 cm
単位の変更は、メニュバー[ツール]-[オプション]によるオプションダイアログの左ツリー Libreoffice Calc のメトリックで センチメートル、ミリメートル、インチ、パイカ、ポイント からの選択により行います。


# 列幅の最適化
$sheet.getCellRangeByName("C1").getColumns().OptimalWidth = $true  # C列幅
$sheet.getCellByPosition(3, 0).getColumns().OptimalWidth = $true   # D列幅

# 行高さの最適化
$sheet.getCellRangeByName("D4").getRows().OptimalHeight = $true    # 4行目高さ
$sheet.getCellByPosition(3, 4).getRows().OptimalHeight = $true     # 5行目高さ
   

5.保存


   $sfname = $PSScriptRoot + "\calcTestS.ods"
   $libCalcd.storeAsURL($sfname)                 # 名前を付けて保存

   [void]$libCalcd.store()                       # 上書き保存
   

6.印刷


$libCalcd.Print(1, "1")                          # 印刷部数、印刷ページを指定 ※1

$libCalcd.setPrinter("LBP****")                  # 印刷プリンタを指定

# 印刷関係のダイアログを表示
$libCalcd.showDialog([CalcAuto.Dialog]::PRINTERSETUP)    # プリンターの設定 ダイアログ (プリンタ選択)
$libCalcd.showDialog([CalcAuto.Dialog]::PRINT)           # 印刷 ダイアログ
$libCalcd.showDialog([CalcAuto.Dialog]::PRINTPREVIEW)    # 印刷プレビュー ダイアログ
   

アクティブシートが印刷されます。
※1 印刷プリンタを指定しない場合は、通常使うプリンタに印刷されます。

7.バージョン情報

本DLLのバージョン情報を取得します。getVersion は、static 関数です。


[string]$sv = ""
$sr = [CalcAuto.calcAuto]::getVersion([ref]$sv)
Write-Host ($sr + " :" + $sv) 
   

□ CalcAuto.dll

CalcAuto.dll は、LibreOffice Calc の操作を行う.NET用のDLL(32ビット、64ビット版)です。 実行には .NET Framework 4.5 が必要です。C# でも使用可能です。
CalcAuto.dll の関数、プロパティ

CalcAuto.dll については、こちらから問い合わせください。

PowerShellメモ
©2024-2025 TEXCELL CORPORATION
テクセル株式会社